Compare commits

..

6 Commits

Author SHA1 Message Date
Alex Voloshyn
0eff90a904
wip 2021-07-29 19:25:10 -07:00
Kyle Fleming
431bd74c29 [tmp] 2021-06-30 10:59:37 -10:00
Kyle Fleming
6acaf5bf83 Move thread safety of DefaultServiceProvider for better encapsulation 2021-06-29 20:06:27 -10:00
Kyle Fleming
a35ac627a9 Move Connection objects to GrpcConnection namespace 2021-06-29 20:06:27 -10:00
Kyle Fleming
b4dd03d96b Minor tweaks 2021-06-29 20:06:27 -10:00
Kyle Fleming
c6b7a04694 Use local LibMobileCoin 2021-06-25 15:45:11 -10:00
87 changed files with 722 additions and 2651 deletions

View File

@ -171,8 +171,8 @@ jobs:
- print-tool-versions
- run: make build
- run: make test
#- run: make docs
#- run: make lint-docs
- run: make docs
- run: make lint-docs
- store_artifacts: { path: output }
- store_test_results: { path: output/scan }
- store_artifacts: { path: ~/Library/Logs/DiagnosticReports }
@ -221,11 +221,11 @@ workflows:
name: build-and-test-xcode-<< matrix.xcode-version >>
matrix:
parameters:
xcode-version: [*default-xcode-version]
#- generate-docs:
#filters:
#branches: { only: master }
#- deploy-docs:
#requires: [ build-and-test, generate-docs ]
#filters:
#branches: { only: master }
xcode-version: ["11.7.0", *default-xcode-version]
- generate-docs:
filters:
branches: { only: master }
- deploy-docs:
requires: [ build-and-test, generate-docs ]
filters:
branches: { only: master }

View File

@ -5,28 +5,6 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [1.2.0-pre2] - 2021-10-27
### Added
- Support for Apple's Bitcode. Reduces compressed "downloadable" size by 25% (#80)
### Changed
- Upgraded LibMobileCoin to v1.2.0-pre3 (#80)
- Updated Trust Root Certificate (#78)
## [1.2.0-pre0] - 2021-09-17
### Added
- HTTP Interface to API for Network Robustness (#73)
- Apple Silicon M1 & Mac Catalyst Support (#73)
### Changed
- Upgraded LibMobileCoin & Fog to v1.2.0-pre1 (#73)
## [1.1.0] - 2021-06-10
### Added

View File

@ -298,7 +298,7 @@
IPHONEOS_DEPLOYMENT_TARGET = 13.4;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
ONLY_ACTIVE_ARCH = NO;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
@ -368,7 +368,6 @@
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_ASSET_PATHS = "\"Example/Preview Content\"";
DEVELOPMENT_TEAM = 8JT9JJD9Y5;
ENABLE_ONLY_ACTIVE_RESOURCES = NO;
ENABLE_PREVIEWS = YES;
INFOPLIST_FILE = Example/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
@ -376,7 +375,6 @@
"$(inherited)",
"@executable_path/Frameworks",
);
ONLY_ACTIVE_ARCH = NO;
PRODUCT_BUNDLE_IDENTIFIER = com.mobilecoin.Example;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
@ -392,7 +390,6 @@
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_ASSET_PATHS = "\"Example/Preview Content\"";
DEVELOPMENT_TEAM = 8JT9JJD9Y5;
ENABLE_ONLY_ACTIVE_RESOURCES = NO;
ENABLE_PREVIEWS = YES;
INFOPLIST_FILE = Example/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
@ -470,7 +467,6 @@
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_ASSET_PATHS = "\"Example/Preview Content\"";
DEVELOPMENT_TEAM = 8JT9JJD9Y5;
ENABLE_ONLY_ACTIVE_RESOURCES = NO;
ENABLE_PREVIEWS = YES;
INFOPLIST_FILE = Example/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 10.0;

View File

@ -1,5 +1,5 @@
source 'https://rubygems.org' do
gem 'cocoapods', '~> 1.11'
gem 'cocoapods', '~> 1.8', '< 1.10'
gem 'cocoapods-binary', :git => 'https://github.com/mobilecoinofficial/cocoapods-binary.git', :tag => 'v0.4.4.rev5'
gem 'cocoapods-repo-update'
gem 'cocoapods-keys'

View File

@ -14,72 +14,69 @@ GEM
GEM
remote: https://rubygems.org/
specs:
CFPropertyList (3.0.4)
rexml
CFPropertyList (3.0.3)
RubyInline (3.12.5)
ZenTest (~> 4.3)
ZenTest (4.12.0)
activesupport (6.1.4.1)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 1.6, < 2)
minitest (>= 5.1)
tzinfo (~> 2.0)
zeitwerk (~> 2.3)
addressable (2.8.0)
activesupport (4.2.11.3)
i18n (~> 0.7)
minitest (~> 5.1)
thread_safe (~> 0.3, >= 0.3.4)
tzinfo (~> 1.1)
addressable (2.7.0)
public_suffix (>= 2.0.2, < 5.0)
algoliasearch (1.27.5)
httpclient (~> 2.8, >= 2.8.3)
json (>= 1.5.1)
artifactory (3.0.15)
atomos (0.1.3)
aws-eventstream (1.2.0)
aws-partitions (1.520.0)
aws-sdk-core (3.121.3)
aws-eventstream (1.1.1)
aws-partitions (1.470.0)
aws-sdk-core (3.114.3)
aws-eventstream (~> 1, >= 1.0.2)
aws-partitions (~> 1, >= 1.239.0)
aws-sigv4 (~> 1.1)
jmespath (~> 1.0)
aws-sdk-kms (1.50.0)
aws-sdk-core (~> 3, >= 3.121.2)
aws-sdk-kms (1.44.0)
aws-sdk-core (~> 3, >= 3.112.0)
aws-sigv4 (~> 1.1)
aws-sdk-s3 (1.104.0)
aws-sdk-core (~> 3, >= 3.121.2)
aws-sdk-s3 (1.96.1)
aws-sdk-core (~> 3, >= 3.112.0)
aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.4)
aws-sigv4 (1.4.0)
aws-sigv4 (~> 1.1)
aws-sigv4 (1.2.3)
aws-eventstream (~> 1, >= 1.0.2)
babosa (1.0.4)
claide (1.0.3)
cocoapods (1.11.2)
addressable (~> 2.8)
cocoapods (1.9.3)
activesupport (>= 4.0.2, < 5)
claide (>= 1.0.2, < 2.0)
cocoapods-core (= 1.11.2)
cocoapods-core (= 1.9.3)
cocoapods-deintegrate (>= 1.0.3, < 2.0)
cocoapods-downloader (>= 1.4.0, < 2.0)
cocoapods-downloader (>= 1.2.2, < 2.0)
cocoapods-plugins (>= 1.0.0, < 2.0)
cocoapods-search (>= 1.0.0, < 2.0)
cocoapods-stats (>= 1.0.0, < 2.0)
cocoapods-trunk (>= 1.4.0, < 2.0)
cocoapods-try (>= 1.1.0, < 2.0)
colored2 (~> 3.1)
escape (~> 0.0.4)
fourflusher (>= 2.3.0, < 3.0)
gh_inspector (~> 1.0)
molinillo (~> 0.8.0)
molinillo (~> 0.6.6)
nap (~> 1.0)
ruby-macho (>= 1.0, < 3.0)
xcodeproj (>= 1.21.0, < 2.0)
cocoapods-core (1.11.2)
activesupport (>= 5.0, < 7)
addressable (~> 2.8)
ruby-macho (~> 1.4)
xcodeproj (>= 1.14.0, < 2.0)
cocoapods-core (1.9.3)
activesupport (>= 4.0.2, < 6)
algoliasearch (~> 1.0)
concurrent-ruby (~> 1.1)
fuzzy_match (~> 2.0.4)
nap (~> 1.0)
netrc (~> 0.11)
public_suffix (~> 4.0)
typhoeus (~> 1.0)
cocoapods-deintegrate (1.0.5)
cocoapods-downloader (1.5.1)
cocoapods-deintegrate (1.0.4)
cocoapods-downloader (1.4.0)
cocoapods-keys (2.2.1)
dotenv
osx_keychain
@ -87,8 +84,9 @@ GEM
nap
cocoapods-repo-update (0.0.4)
cocoapods (~> 1.0, >= 1.3.0)
cocoapods-search (1.0.1)
cocoapods-trunk (1.6.0)
cocoapods-search (1.0.0)
cocoapods-stats (1.1.0)
cocoapods-trunk (1.5.0)
nap (>= 0.8, < 2.0)
netrc (~> 0.11)
cocoapods-try (1.2.0)
@ -96,27 +94,24 @@ GEM
colored2 (3.1.2)
commander (4.6.0)
highline (~> 2.0.0)
concurrent-ruby (1.1.9)
concurrent-ruby (1.1.8)
declarative (0.0.20)
digest-crc (0.6.4)
digest-crc (0.6.3)
rake (>= 12.0.0, < 14.0.0)
domain_name (0.5.20190701)
unf (>= 0.0.5, < 1.0.0)
dotenv (2.7.6)
emoji_regex (3.2.3)
emoji_regex (3.2.2)
escape (0.0.4)
ethon (0.15.0)
ffi (>= 1.15.0)
excon (0.88.0)
faraday (1.8.0)
ethon (0.12.0)
ffi (>= 1.3.0)
excon (0.82.0)
faraday (1.4.2)
faraday-em_http (~> 1.0)
faraday-em_synchrony (~> 1.0)
faraday-excon (~> 1.1)
faraday-httpclient (~> 1.0.1)
faraday-net_http (~> 1.0)
faraday-net_http_persistent (~> 1.1)
faraday-patron (~> 1.0)
faraday-rack (~> 1.0)
multipart-post (>= 1.2, < 3)
ruby2_keywords (>= 0.0.4)
faraday-cookie_jar (0.0.7)
@ -125,17 +120,14 @@ GEM
faraday-em_http (1.0.0)
faraday-em_synchrony (1.0.0)
faraday-excon (1.1.0)
faraday-httpclient (1.0.1)
faraday-net_http (1.0.1)
faraday-net_http_persistent (1.2.0)
faraday-patron (1.0.0)
faraday-rack (1.0.0)
faraday_middleware (1.2.0)
faraday-net_http_persistent (1.1.0)
faraday_middleware (1.0.0)
faraday (~> 1.0)
fastimage (2.2.5)
fastlane (2.197.0)
fastimage (2.2.4)
fastlane (2.186.0)
CFPropertyList (>= 2.3, < 4.0.0)
addressable (>= 2.8, < 3.0.0)
addressable (>= 2.3, < 3.0.0)
artifactory (~> 3.0)
aws-sdk-s3 (~> 1.0)
babosa (>= 1.0.3, < 2.0.0)
@ -150,7 +142,7 @@ GEM
faraday_middleware (~> 1.0)
fastimage (>= 2.1.0, < 3.0.0)
gh_inspector (>= 1.1.2, < 2.0.0)
google-apis-androidpublisher_v3 (~> 0.3)
google-apis-androidpublisher_v3 (~> 0.1)
google-apis-playcustomapp_v1 (~> 0.1)
google-cloud-storage (~> 1.31)
highline (~> 2.0)
@ -159,7 +151,6 @@ GEM
mini_magick (>= 4.9.4, < 5.0.0)
multipart-post (~> 2.0.0)
naturally (~> 2.2)
optparse (~> 0.1.1)
plist (>= 3.1.0, < 4.0.0)
rubyzip (>= 2.0.0, < 3.0.0)
security (= 0.1.3)
@ -172,34 +163,35 @@ GEM
xcodeproj (>= 1.13.0, < 2.0.0)
xcpretty (~> 0.3.0)
xcpretty-travis-formatter (>= 0.0.3)
ffi (1.15.4)
ffi (1.15.0)
fourflusher (2.3.1)
fuzzy_match (2.0.4)
gh_inspector (1.1.3)
google-apis-androidpublisher_v3 (0.13.0)
google-apis-core (>= 0.4, < 2.a)
google-apis-core (0.4.1)
google-apis-androidpublisher_v3 (0.6.0)
google-apis-core (~> 0.1)
google-apis-core (0.3.0)
addressable (~> 2.5, >= 2.5.1)
googleauth (>= 0.16.2, < 2.a)
httpclient (>= 2.8.1, < 3.a)
googleauth (~> 0.14)
httpclient (>= 2.8.1, < 3.0)
mini_mime (~> 1.0)
representable (~> 3.0)
retriable (>= 2.0, < 4.a)
retriable (>= 2.0, < 4.0)
rexml
signet (~> 0.14)
webrick
google-apis-iamcredentials_v1 (0.8.0)
google-apis-core (>= 0.4, < 2.a)
google-apis-playcustomapp_v1 (0.6.0)
google-apis-core (>= 0.4, < 2.a)
google-apis-storage_v1 (0.9.0)
google-apis-core (>= 0.4, < 2.a)
google-apis-iamcredentials_v1 (0.4.0)
google-apis-core (~> 0.1)
google-apis-playcustomapp_v1 (0.3.0)
google-apis-core (~> 0.1)
google-apis-storage_v1 (0.4.0)
google-apis-core (~> 0.1)
google-cloud-core (1.6.0)
google-cloud-env (~> 1.0)
google-cloud-errors (~> 1.0)
google-cloud-env (1.5.0)
faraday (>= 0.17.3, < 2.0)
google-cloud-errors (1.2.0)
google-cloud-storage (1.34.1)
google-cloud-errors (1.1.0)
google-cloud-storage (1.32.0)
addressable (~> 2.5)
digest-crc (~> 0.4)
google-apis-iamcredentials_v1 (~> 0.1)
@ -207,40 +199,39 @@ GEM
google-cloud-core (~> 1.6)
googleauth (>= 0.16.2, < 2.a)
mini_mime (~> 1.0)
googleauth (1.1.0)
googleauth (0.16.2)
faraday (>= 0.17.3, < 2.0)
jwt (>= 1.4, < 3.0)
memoist (~> 0.16)
multi_json (~> 1.11)
os (>= 0.9, < 2.0)
signet (>= 0.16, < 2.a)
signet (~> 0.14)
highline (2.0.3)
http-cookie (1.0.4)
domain_name (~> 0.5)
httpclient (2.8.3)
i18n (1.8.10)
i18n (0.9.5)
concurrent-ruby (~> 1.0)
jmespath (1.4.0)
json (2.6.1)
jwt (2.3.0)
json (2.5.1)
jwt (2.2.3)
memoist (0.16.2)
mini_magick (4.11.0)
mini_mime (1.1.2)
mini_mime (1.1.0)
minitest (5.14.4)
molinillo (0.8.0)
molinillo (0.6.6)
multi_json (1.15.0)
multipart-post (2.0.0)
nanaimo (0.3.0)
nap (1.1.0)
naturally (2.2.1)
netrc (0.11.0)
optparse (0.1.1)
os (1.1.1)
osx_keychain (1.0.2)
RubyInline (~> 3)
plist (3.6.0)
public_suffix (4.0.6)
rake (13.0.6)
rake (13.0.3)
representable (3.1.1)
declarative (< 0.1.0)
trailblazer-option (>= 0.1.1, < 0.2.0)
@ -248,12 +239,12 @@ GEM
retriable (3.1.2)
rexml (3.2.5)
rouge (2.0.7)
ruby-macho (2.5.1)
ruby2_keywords (0.0.5)
rubyzip (2.3.2)
ruby-macho (1.4.0)
ruby2_keywords (0.0.4)
rubyzip (2.3.0)
security (0.1.3)
signet (0.16.0)
addressable (~> 2.8)
signet (0.15.0)
addressable (~> 2.3)
faraday (>= 0.17.3, < 2.0)
jwt (>= 1.5, < 3.0)
multi_json (~> 1.10)
@ -263,6 +254,7 @@ GEM
terminal-notifier (2.0.0)
terminal-table (1.8.0)
unicode-display_width (~> 1.1, >= 1.1.1)
thread_safe (0.3.6)
trailblazer-option (0.1.1)
tty-cursor (0.7.1)
tty-screen (0.8.1)
@ -270,33 +262,31 @@ GEM
tty-cursor (~> 0.7)
typhoeus (1.4.0)
ethon (>= 0.9.0)
tzinfo (2.0.4)
concurrent-ruby (~> 1.0)
tzinfo (1.2.9)
thread_safe (~> 0.1)
uber (0.1.0)
unf (0.1.4)
unf_ext
unf_ext (0.0.8)
unicode-display_width (1.8.0)
unf_ext (0.0.7.7)
unicode-display_width (1.7.0)
webrick (1.7.0)
word_wrap (1.0.0)
xcodeproj (1.21.0)
xcodeproj (1.19.0)
CFPropertyList (>= 2.3.3, < 4.0)
atomos (~> 0.1.3)
claide (>= 1.0.2, < 2.0)
colored2 (~> 3.1)
nanaimo (~> 0.3.0)
rexml (~> 3.2.4)
xcpretty (0.3.0)
rouge (~> 2.0.7)
xcpretty-travis-formatter (1.0.1)
xcpretty (~> 0.2, >= 0.0.7)
zeitwerk (2.5.1)
PLATFORMS
ruby
DEPENDENCIES
cocoapods (~> 1.11)!
cocoapods (~> 1.8, < 1.10)!
cocoapods-binary!
cocoapods-keys!
cocoapods-repo-update!

View File

@ -3,6 +3,7 @@ source 'https://cdn.cocoapods.org/'
platform :ios, '10.0'
plugin 'cocoapods-repo-update'
plugin 'cocoapods-binary'
keep_source_code_for_prebuilt_frameworks!
plugin 'cocoapods-keys', {
:project => "MobileCoin",
@ -25,14 +26,14 @@ target 'Example' do
# pod 'MobileCoin', git: 'https://github.com/mobilecoinofficial/MobileCoin-Swift.git'
# pod 'MobileCoin/Core', git: 'https://github.com/mobilecoinofficial/MobileCoin-Swift.git', testspecs: ['Tests', 'IntegrationTests']
pod 'LibMobileCoin'
# pod 'LibMobileCoin', path: '../Vendor/libmobilecoin-ios-artifacts'
# pod 'LibMobileCoin', binary: true
pod 'LibMobileCoin', path: '../Vendor/libmobilecoin-ios-artifacts'
# pod 'LibMobileCoin', podspec: '../Vendor/libmobilecoin-ios-artifacts/LibMobileCoin.podspec'
# pod 'LibMobileCoin', git: 'https://github.com/the-real-adammork/libmobilecoin-ios-artifacts.git'
# pod 'LibMobileCoin', git: 'https://github.com/mobilecoinofficial/libmobilecoin-ios-artifacts.git'
pod 'gRPC-Swift'
pod 'SwiftProtobuf'
pod 'SwiftLint'
pod 'gRPC-Swift', binary: true
pod 'SwiftProtobuf', binary: true
pod 'SwiftLint', binary: true
end
post_install do |installer|
@ -81,12 +82,4 @@ post_install do |installer|
config.build_settings["OTHER_LDFLAGS"] << ' -framework "Keys"'
end
end
# Disable bitcode on test targets
installer.pods_project.targets.each do |target|
next unless ['MobileCoin-Unit-Core-IntegrationTests', 'MobileCoin-UI-Core-PerformanceTests', 'MobileCoin-Unit-Core-Tests'].find_index(target.name) != nil
target.build_configurations.each do |config|
config.build_settings['ENABLE_BITCODE'] = 'NO'
end
end
end

View File

@ -1,129 +1,110 @@
PODS:
- _NIODataStructures (2.32.3)
- CGRPCZlib (1.5.0)
- CNIOAtomics (2.32.3)
- CNIOBoringSSL (2.15.1)
- CNIOBoringSSLShims (2.15.1):
- CNIOBoringSSL (= 2.15.1)
- CNIODarwin (2.32.3)
- CNIOHTTPParser (2.32.3)
- CNIOLinux (2.32.3)
- CNIOWindows (2.32.3)
- gRPC-Swift (1.5.0):
- CGRPCZlib (= 1.5.0)
- CGRPCZlib (1.0.0)
- CNIOAtomics (2.27.0)
- CNIOBoringSSL (2.10.5)
- CNIOBoringSSLShims (2.10.5):
- CNIOBoringSSL (= 2.10.5)
- CNIODarwin (2.27.0)
- CNIOHTTPParser (2.27.0)
- CNIOLinux (2.27.0)
- CNIOWindows (2.27.0)
- gRPC-Swift (1.0.0):
- CGRPCZlib (= 1.0.0)
- Logging (< 2.0.0, >= 1.4.0)
- SwiftNIO (< 3.0.0, >= 2.32.0)
- SwiftNIO (< 3.0.0, >= 2.22.0)
- SwiftNIOExtras (< 2.0.0, >= 1.4.0)
- SwiftNIOHTTP2 (< 2.0.0, >= 1.18.2)
- SwiftNIOSSL (< 3.0.0, >= 2.14.0)
- SwiftNIOTransportServices (< 2.0.0, >= 1.11.1)
- SwiftNIOHTTP2 (< 2.0.0, >= 1.16.1)
- SwiftNIOSSL (< 3.0.0, >= 2.8.0)
- SwiftNIOTransportServices (< 2.0.0, >= 1.6.0)
- SwiftProtobuf (< 2.0.0, >= 1.9.0)
- Keys (1.0.1)
- LibMobileCoin (1.2.0-pre3):
- gRPC-Swift
- LibMobileCoin (1.1.0):
- gRPC-Swift (~> 1.0.0)
- SwiftProtobuf (~> 1.5)
- Logging (1.4.0)
- MobileCoin (1.2.0-pre2):
- MobileCoin/Core (= 1.2.0-pre2)
- MobileCoin/Core (1.2.0-pre2):
- gRPC-Swift
- LibMobileCoin (~> 1.2.0-pre3)
- MobileCoin (1.1.0):
- MobileCoin/Core (= 1.1.0)
- MobileCoin/Core (1.1.0):
- gRPC-Swift (~> 1.0)
- LibMobileCoin (~> 1.1)
- Logging (~> 1.4)
- SwiftLint
- SwiftNIO
- SwiftNIOHPACK
- SwiftNIOHTTP1
- SwiftProtobuf
- MobileCoin/Core/IntegrationTests (1.2.0-pre2):
- gRPC-Swift
- LibMobileCoin (~> 1.2.0-pre3)
- SwiftNIO (~> 2.22)
- SwiftNIOHPACK (~> 1.16)
- SwiftNIOHTTP1 (~> 2.18)
- SwiftProtobuf (~> 1.5)
- MobileCoin/Core/IntegrationTests (1.1.0):
- gRPC-Swift (~> 1.0)
- LibMobileCoin (~> 1.1)
- Logging (~> 1.4)
- SwiftLint
- SwiftNIO
- SwiftNIOHPACK
- SwiftNIOHTTP1
- SwiftProtobuf
- MobileCoin/Core/PerformanceTests (1.2.0-pre2):
- gRPC-Swift
- LibMobileCoin (~> 1.2.0-pre3)
- SwiftNIO (~> 2.22)
- SwiftNIOHPACK (~> 1.16)
- SwiftNIOHTTP1 (~> 2.18)
- SwiftProtobuf (~> 1.5)
- MobileCoin/Core/PerformanceTests (1.1.0):
- gRPC-Swift (~> 1.0)
- LibMobileCoin (~> 1.1)
- Logging (~> 1.4)
- SwiftLint
- SwiftNIO
- SwiftNIOHPACK
- SwiftNIOHTTP1
- SwiftProtobuf
- MobileCoin/Core/Tests (1.2.0-pre2):
- gRPC-Swift
- LibMobileCoin (~> 1.2.0-pre3)
- SwiftNIO (~> 2.22)
- SwiftNIOHPACK (~> 1.16)
- SwiftNIOHTTP1 (~> 2.18)
- SwiftProtobuf (~> 1.5)
- MobileCoin/Core/Tests (1.1.0):
- gRPC-Swift (~> 1.0)
- LibMobileCoin (~> 1.1)
- Logging (~> 1.4)
- SwiftLint
- SwiftNIO
- SwiftNIOHPACK
- SwiftNIOHTTP1
- SwiftProtobuf
- SwiftLint (0.45.0)
- SwiftNIO (2.32.3):
- SwiftNIOCore (= 2.32.3)
- SwiftNIOEmbedded (= 2.32.3)
- SwiftNIOPosix (= 2.32.3)
- SwiftNIOConcurrencyHelpers (2.32.3):
- CNIOAtomics (= 2.32.3)
- SwiftNIOCore (2.32.3):
- CNIOLinux (= 2.32.3)
- SwiftNIOConcurrencyHelpers (= 2.32.3)
- SwiftNIOEmbedded (2.32.3):
- _NIODataStructures (= 2.32.3)
- SwiftNIOCore (= 2.32.3)
- SwiftNIOExtras (1.10.2):
- SwiftNIO (< 3, >= 2.32.0)
- SwiftNIOFoundationCompat (2.32.3):
- SwiftNIO (= 2.32.3)
- SwiftNIOCore (= 2.32.3)
- SwiftNIOHPACK (1.18.3):
- SwiftNIO (< 3, >= 2.32.0)
- SwiftNIOConcurrencyHelpers (< 3, >= 2.32.0)
- SwiftNIOCore (< 3, >= 2.32.0)
- SwiftNIOHTTP1 (< 3, >= 2.32.0)
- SwiftNIOHTTP1 (2.32.3):
- CNIOHTTPParser (= 2.32.3)
- SwiftNIO (= 2.32.3)
- SwiftNIOConcurrencyHelpers (= 2.32.3)
- SwiftNIOCore (= 2.32.3)
- SwiftNIOHTTP2 (1.18.3):
- SwiftNIO (< 3, >= 2.32.0)
- SwiftNIOConcurrencyHelpers (< 3, >= 2.32.0)
- SwiftNIOCore (< 3, >= 2.32.0)
- SwiftNIOHPACK (= 1.18.3)
- SwiftNIOHTTP1 (< 3, >= 2.32.0)
- SwiftNIOTLS (< 3, >= 2.32.0)
- SwiftNIOPosix (2.32.3):
- _NIODataStructures (= 2.32.3)
- CNIODarwin (= 2.32.3)
- CNIOLinux (= 2.32.3)
- CNIOWindows (= 2.32.3)
- SwiftNIOConcurrencyHelpers (= 2.32.3)
- SwiftNIOCore (= 2.32.3)
- SwiftNIOSSL (2.15.1):
- CNIOBoringSSL (= 2.15.1)
- CNIOBoringSSLShims (= 2.15.1)
- SwiftNIO (< 3, >= 2.32.0)
- SwiftNIOConcurrencyHelpers (< 3, >= 2.32.0)
- SwiftNIOCore (< 3, >= 2.32.0)
- SwiftNIOTLS (< 3, >= 2.32.0)
- SwiftNIOTLS (2.32.3):
- SwiftNIO (= 2.32.3)
- SwiftNIOCore (= 2.32.3)
- SwiftNIOTransportServices (1.11.3):
- SwiftNIO (< 3, >= 2.32.0)
- SwiftNIOConcurrencyHelpers (< 3, >= 2.32.0)
- SwiftNIOFoundationCompat (< 3, >= 2.32.0)
- SwiftNIOTLS (< 3, >= 2.32.0)
- SwiftProtobuf (1.18.0)
- SwiftNIO (~> 2.22)
- SwiftNIOHPACK (~> 1.16)
- SwiftNIOHTTP1 (~> 2.18)
- SwiftProtobuf (~> 1.5)
- SwiftLint (0.43.1)
- SwiftNIO (2.27.0):
- CNIODarwin (= 2.27.0)
- CNIOLinux (= 2.27.0)
- CNIOWindows (= 2.27.0)
- SwiftNIOConcurrencyHelpers (= 2.27.0)
- SwiftNIOConcurrencyHelpers (2.27.0):
- CNIOAtomics (= 2.27.0)
- SwiftNIOExtras (1.8.0):
- SwiftNIO (< 3, >= 2.9.0)
- SwiftNIOFoundationCompat (2.27.0):
- SwiftNIO (= 2.27.0)
- SwiftNIOHPACK (1.16.3):
- SwiftNIO (< 3, >= 2.18.0)
- SwiftNIOConcurrencyHelpers (< 3, >= 2.18.0)
- SwiftNIOHTTP1 (< 3, >= 2.18.0)
- SwiftNIOHTTP1 (2.27.0):
- CNIOHTTPParser (= 2.27.0)
- SwiftNIO (= 2.27.0)
- SwiftNIOConcurrencyHelpers (= 2.27.0)
- SwiftNIOHTTP2 (1.16.3):
- SwiftNIO (< 3, >= 2.18.0)
- SwiftNIOConcurrencyHelpers (< 3, >= 2.18.0)
- SwiftNIOHPACK (= 1.16.3)
- SwiftNIOHTTP1 (< 3, >= 2.18.0)
- SwiftNIOTLS (< 3, >= 2.18.0)
- SwiftNIOSSL (2.10.5):
- CNIOBoringSSL (= 2.10.5)
- CNIOBoringSSLShims (= 2.10.5)
- SwiftNIO (< 3, >= 2.15.0)
- SwiftNIOConcurrencyHelpers (< 3, >= 2.15.0)
- SwiftNIOTLS (< 3, >= 2.15.0)
- SwiftNIOTLS (2.27.0):
- SwiftNIO (= 2.27.0)
- SwiftNIOTransportServices (1.9.2):
- SwiftNIO (< 3, >= 2.19.0)
- SwiftNIOConcurrencyHelpers (< 3, >= 2.19.0)
- SwiftNIOFoundationCompat (< 3, >= 2.19.0)
- SwiftNIOTLS (< 3, >= 2.19.0)
- SwiftProtobuf (1.15.0)
DEPENDENCIES:
- gRPC-Swift
- Keys (from `Pods/CocoaPodsKeys`)
- LibMobileCoin
- LibMobileCoin (from `../Vendor/libmobilecoin-ios-artifacts`)
- MobileCoin (from `..`)
- MobileCoin/Core (from `..`)
- MobileCoin/Core/IntegrationTests (from `..`)
@ -134,7 +115,6 @@ DEPENDENCIES:
SPEC REPOS:
trunk:
- _NIODataStructures
- CGRPCZlib
- CNIOAtomics
- CNIOBoringSSL
@ -144,19 +124,15 @@ SPEC REPOS:
- CNIOLinux
- CNIOWindows
- gRPC-Swift
- LibMobileCoin
- Logging
- SwiftLint
- SwiftNIO
- SwiftNIOConcurrencyHelpers
- SwiftNIOCore
- SwiftNIOEmbedded
- SwiftNIOExtras
- SwiftNIOFoundationCompat
- SwiftNIOHPACK
- SwiftNIOHTTP1
- SwiftNIOHTTP2
- SwiftNIOPosix
- SwiftNIOSSL
- SwiftNIOTLS
- SwiftNIOTransportServices
@ -165,40 +141,38 @@ SPEC REPOS:
EXTERNAL SOURCES:
Keys:
:path: Pods/CocoaPodsKeys
LibMobileCoin:
:path: "../Vendor/libmobilecoin-ios-artifacts"
MobileCoin:
:path: ".."
SPEC CHECKSUMS:
_NIODataStructures: e2077c7dc7c1d6c93e698c85fe04d663a17f53a4
CGRPCZlib: db324e4e4e71262d48faceb86b52dd7d4f71ff62
CNIOAtomics: 4dde57e1838a29a9b23ef91617505f34751cdbe5
CNIOBoringSSL: c99129423da079a9eb74bcfc7cfec41a6775cf94
CNIOBoringSSLShims: 902ae35fea0b6be5eefb4fdce906751886cfa46f
CNIODarwin: 0489511f8486443af71ff986ccd5abbc680ae713
CNIOHTTPParser: f7a6816f7ddbe7dfa57a74cd36dc2db2c53b56e8
CNIOLinux: 5921dfefbc4bbe017380b34c510855622147ea41
CNIOWindows: f5aa9dfb401b440a7b4c9cd911e53e981a787193
gRPC-Swift: 8942047451bf81413077e6b94bf4213e47b181cc
CGRPCZlib: b0c9d704a12fa667f1824ffff20688f191945989
CNIOAtomics: 43316aa185f4bd639aa0a9cd49741151bbe8de7f
CNIOBoringSSL: 7ff9c35139a115f93269915b9555044d741b2ac9
CNIOBoringSSLShims: 6edde63429e353ba78992b2d4d1b0627752a4a43
CNIODarwin: 9eb3c09e9f3fc5ed47cecdd032aad926df81e3a6
CNIOHTTPParser: c6051552c5f332e4ec0756581e5cbd5632ca24e6
CNIOLinux: 79227941d64216792c3c59238b0106b9e0df25bc
CNIOWindows: f2baa102255e986467578337ffa2f777cb6bdf7f
gRPC-Swift: 77154009a019e97f8c4bd8f2bb75fe9726801157
Keys: a576f4c9c1c641ca913a959a9c62ed3f215a8de9
LibMobileCoin: f3c44fb94b8647bd5cac3aedf0b1ca24f6cc7201
LibMobileCoin: b6f5200b484ceac10bf988a42c1168e1d443bacc
Logging: beeb016c9c80cf77042d62e83495816847ef108b
MobileCoin: 339e51b8739b7ea2f0519cc7bdde8c4e05c2b374
SwiftLint: e5c7f1fba68eccfc51509d5b2ce1699f5502e0c7
SwiftNIO: bb336ceef32850e9671d3fa0e0cc2b9add3b5948
SwiftNIOConcurrencyHelpers: ca2594e10749655f42baf5468212be83d2f94fe3
SwiftNIOCore: 9deed6620f80c7c82e8e2c2ffb9864495416d892
SwiftNIOEmbedded: b7ccf12b402dff35a5d4356990a6253621e4337d
SwiftNIOExtras: 70f09aa8eca3ab6baeaf1993da9c855b6e95e97f
SwiftNIOFoundationCompat: d3b888766e7c67354a4e4e145d38edf9586efa0c
SwiftNIOHPACK: e2fc784ce453bec4c058b21071e89fb7e542ac30
SwiftNIOHTTP1: 349a16aae363250cd49f430a9fdb93cff518adfa
SwiftNIOHTTP2: a0322f3dcecd949e03df65f4dac106411df0f12c
SwiftNIOPosix: e4988a8dcfd5a6319bde219d7a3d0acc5fbe7a89
SwiftNIOSSL: 7c2ddcbcbb2a8188468b7fe9c2bc6124df4b3772
SwiftNIOTLS: 1b8290ec775238ccc714ed842d929494df95a2c2
SwiftNIOTransportServices: 1fbbdb58510af3c53a838a1dbea98f18132dc952
SwiftProtobuf: c3c12645230d9b09c72267e0de89468c5543bd86
MobileCoin: c59b70afc472ffab517ffebae90a7cfc8a28259c
SwiftLint: 99f82d07b837b942dd563c668de129a03fc3fb52
SwiftNIO: 81d33ce8c500b7e41b6cdde5f2f12330b9750219
SwiftNIOConcurrencyHelpers: 23fc68bac541a465162d7225d2c743edd2f1012c
SwiftNIOExtras: aa561b71020cd6844f722cf4513fb176c577414d
SwiftNIOFoundationCompat: 0e52ac0e2c9b7b60ff9141eebb64f5a82d974118
SwiftNIOHPACK: 38e855a72ae0c5176485ddd039b3933b99daa2b7
SwiftNIOHTTP1: 846277d7fc7661fba655540e529d7ba3c728ca50
SwiftNIOHTTP2: de7eff9d32fd347338f85b86c6fd0e13c3fbd1a0
SwiftNIOSSL: 6a1f0499a5319e823eae0b6f053ecb502bcce3f5
SwiftNIOTLS: 4f8df225f03393f08e0b47b4d876ae38167f8a27
SwiftNIOTransportServices: 896c9a4ac98698d32aa2feea7657ade219ae80bb
SwiftProtobuf: 3320217e9d8fb75f36b40282e78c482640fd75dd
PODFILE CHECKSUM: 46e25fe8f13c4beb3ac1e4ab1a9512960701d05d
PODFILE CHECKSUM: a0d081de36bb0e26c2f240e65e5e63f9f111ec19
COCOAPODS: 1.11.2
COCOAPODS: 1.9.3

View File

@ -1,4 +1,4 @@
source 'https://rubygems.org' do
gem 'cocoapods', '~> 1.11'
gem 'cocoapods', '~> 1.8', '< 1.10'
gem 'jazzy'
end

View File

@ -4,117 +4,109 @@ GEM
GEM
remote: https://rubygems.org/
specs:
CFPropertyList (3.0.4)
rexml
activesupport (6.1.4.1)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 1.6, < 2)
minitest (>= 5.1)
tzinfo (~> 2.0)
zeitwerk (~> 2.3)
addressable (2.8.0)
public_suffix (>= 2.0.2, < 5.0)
CFPropertyList (3.0.3)
activesupport (4.2.11.3)
i18n (~> 0.7)
minitest (~> 5.1)
thread_safe (~> 0.3, >= 0.3.4)
tzinfo (~> 1.1)
algoliasearch (1.27.5)
httpclient (~> 2.8, >= 2.8.3)
json (>= 1.5.1)
atomos (0.1.3)
claide (1.0.3)
cocoapods (1.11.2)
addressable (~> 2.8)
cocoapods (1.9.3)
activesupport (>= 4.0.2, < 5)
claide (>= 1.0.2, < 2.0)
cocoapods-core (= 1.11.2)
cocoapods-core (= 1.9.3)
cocoapods-deintegrate (>= 1.0.3, < 2.0)
cocoapods-downloader (>= 1.4.0, < 2.0)
cocoapods-downloader (>= 1.2.2, < 2.0)
cocoapods-plugins (>= 1.0.0, < 2.0)
cocoapods-search (>= 1.0.0, < 2.0)
cocoapods-stats (>= 1.0.0, < 2.0)
cocoapods-trunk (>= 1.4.0, < 2.0)
cocoapods-try (>= 1.1.0, < 2.0)
colored2 (~> 3.1)
escape (~> 0.0.4)
fourflusher (>= 2.3.0, < 3.0)
gh_inspector (~> 1.0)
molinillo (~> 0.8.0)
molinillo (~> 0.6.6)
nap (~> 1.0)
ruby-macho (>= 1.0, < 3.0)
xcodeproj (>= 1.21.0, < 2.0)
cocoapods-core (1.11.2)
activesupport (>= 5.0, < 7)
addressable (~> 2.8)
ruby-macho (~> 1.4)
xcodeproj (>= 1.14.0, < 2.0)
cocoapods-core (1.9.3)
activesupport (>= 4.0.2, < 6)
algoliasearch (~> 1.0)
concurrent-ruby (~> 1.1)
fuzzy_match (~> 2.0.4)
nap (~> 1.0)
netrc (~> 0.11)
public_suffix (~> 4.0)
typhoeus (~> 1.0)
cocoapods-deintegrate (1.0.5)
cocoapods-downloader (1.5.1)
cocoapods-deintegrate (1.0.4)
cocoapods-downloader (1.4.0)
cocoapods-plugins (1.0.0)
nap
cocoapods-search (1.0.1)
cocoapods-trunk (1.6.0)
cocoapods-search (1.0.0)
cocoapods-stats (1.1.0)
cocoapods-trunk (1.5.0)
nap (>= 0.8, < 2.0)
netrc (~> 0.11)
cocoapods-try (1.2.0)
colored2 (3.1.2)
concurrent-ruby (1.1.9)
concurrent-ruby (1.1.8)
escape (0.0.4)
ethon (0.15.0)
ethon (0.14.0)
ffi (>= 1.15.0)
ffi (1.15.4)
ffi (1.15.0)
fourflusher (2.3.1)
fuzzy_match (2.0.4)
gh_inspector (1.1.3)
httpclient (2.8.3)
i18n (1.8.10)
i18n (0.9.5)
concurrent-ruby (~> 1.0)
jazzy (0.14.1)
jazzy (0.13.7)
cocoapods (~> 1.5)
mustache (~> 1.1)
open4 (~> 1.3)
open4
redcarpet (~> 3.4)
rexml (~> 3.2)
rouge (>= 2.0.6, < 4.0)
sassc (~> 2.1)
sqlite3 (~> 1.3)
xcinvoke (~> 0.3.0)
json (2.6.1)
json (2.5.1)
liferaft (0.0.6)
minitest (5.14.4)
molinillo (0.8.0)
molinillo (0.6.6)
mustache (1.1.1)
nanaimo (0.3.0)
nap (1.1.0)
netrc (0.11.0)
open4 (1.3.4)
public_suffix (4.0.6)
redcarpet (3.5.1)
rexml (3.2.5)
rouge (3.26.1)
ruby-macho (2.5.1)
rouge (3.26.0)
ruby-macho (1.4.0)
sassc (2.4.0)
ffi (~> 1.9)
sqlite3 (1.4.2)
thread_safe (0.3.6)
typhoeus (1.4.0)
ethon (>= 0.9.0)
tzinfo (2.0.4)
concurrent-ruby (~> 1.0)
tzinfo (1.2.9)
thread_safe (~> 0.1)
xcinvoke (0.3.0)
liferaft (~> 0.0.6)
xcodeproj (1.21.0)
xcodeproj (1.19.0)
CFPropertyList (>= 2.3.3, < 4.0)
atomos (~> 0.1.3)
claide (>= 1.0.2, < 2.0)
colored2 (~> 3.1)
nanaimo (~> 0.3.0)
rexml (~> 3.2.4)
zeitwerk (2.5.1)
PLATFORMS
ruby
DEPENDENCIES
cocoapods (~> 1.11)!
cocoapods (~> 1.8, < 1.10)!
jazzy!
BUNDLED WITH

View File

@ -3,7 +3,7 @@ Pod::Spec.new do |s|
# ――― Spec Metadata ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
s.name = "MobileCoin"
s.version = "1.2.0-pre2"
s.version = "1.1.0"
s.summary = "A library for communicating with MobileCoin network"
s.author = "MobileCoin"
@ -11,11 +11,7 @@ Pod::Spec.new do |s|
s.license = { :type => "GPLv3" }
s.source = {
:git => "https://github.com/mobilecoinofficial/MobileCoin-Swift.git",
:tag => "v#{s.version}",
:submodules => true
}
s.source = { :git => "https://github.com/mobilecoinofficial/MobileCoin-Swift.git", :tag => "v#{s.version}" }
# ――― Platform Specifics ――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
@ -32,20 +28,20 @@ Pod::Spec.new do |s|
"Sources/**/*.{h,m,swift}",
]
subspec.dependency "LibMobileCoin", "~> 1.2.0-pre3"
subspec.dependency "LibMobileCoin", "~> 1.1"
subspec.dependency "gRPC-Swift"
subspec.dependency "gRPC-Swift", "~> 1.0"
subspec.dependency "Logging", "~> 1.4"
subspec.dependency "SwiftNIO"
subspec.dependency "SwiftNIOHPACK"
subspec.dependency "SwiftNIOHTTP1"
subspec.dependency "SwiftProtobuf"
subspec.dependency "SwiftNIO", "~> 2.22"
subspec.dependency "SwiftNIOHPACK", "~> 1.16"
subspec.dependency "SwiftNIOHTTP1", "~> 2.18"
subspec.dependency "SwiftProtobuf", "~> 1.5"
subspec.test_spec do |test_spec|
test_spec.source_files = "Tests/{Unit,Common}/**/*.swift"
test_spec.resources = [
"Tests/Common/FixtureData/**/*",
"Vendor/libmobilecoin-ios-artifacts/Vendor/mobilecoin/test-vectors/vectors/**/*",
"Vendor/libmobilecoin-ios-artifacts/Vendor/fog/mobilecoin/test-vectors/vectors/**/*",
]
end
@ -76,14 +72,14 @@ Pod::Spec.new do |s|
# intermediary frameworks. These must be speicifed here for CocoaPods to set them
# on the framework target and any testspec targets for this pod.
pod_target_xcconfig = {
"GCC_OPTIMIZATION_LEVEL" => "z",
"LLVM_LTO" => "YES",
"ENABLE_BITCODE" => "YES",
"SUPPORTS_MACCATALYST" => "YES",
# The LibMobileCoin vendored binary doesn't include support for bitcode.
"ENABLE_BITCODE" => "NO",
# The LibMobileCoin vendored binary doesn't include support for Mac Catalyst.
"SUPPORTS_MACCATALYST" => "NO",
# The LibMobileCoin vendored binary doesn't include support for 32-bit
# architectures or for arm64 iphonesimulator.
"VALID_ARCHS[sdk=iphoneos*]" => "arm64",
"VALID_ARCHS[sdk=iphonesimulator*]" => "x86_64 arm64",
"VALID_ARCHS[sdk=iphonesimulator*]" => "x86_64",
}
unless ENV["MC_ENABLE_WARN_LONG_COMPILE_TIMES"].nil?
@ -110,5 +106,5 @@ Pod::Spec.new do |s|
},
]
end
end
end

View File

@ -9,6 +9,7 @@ MobileCoin is a privacy-preserving payments network designed for use on mobile d
# Sending your First Payment
* You must read and accept the [Terms of Use for MobileCoins and MobileCoin Wallets](./TERMS-OF-USE.md) to use MobileCoin Software.
* Please note that currently, MobileCoin Wallets are not available for download or use by U.S. persons or entities, persons or entities located in the U.S., or persons or entities in other prohibited jurisdictions.
### Note to Developers

View File

@ -142,7 +142,6 @@ public enum TransactionSubmissionError: Error {
case invalidTransaction(String = String())
case feeError(String = String())
case tombstoneBlockTooFar(String = String())
case missingMemo(String = String())
case inputsAlreadySpent(String = String())
}
@ -152,8 +151,6 @@ extension TransactionSubmissionError: CustomStringConvertible {
switch self {
case .connectionError(let connectionError):
return "\(connectionError)"
case .missingMemo(let reason):
return "Missing memo error\(!reason.isEmpty ? ": \(reason)" : "")"
case .feeError(let reason):
return "Fee error\(!reason.isEmpty ? ": \(reason)" : "")"
case .invalidTransaction(let reason):

View File

@ -74,7 +74,7 @@ final class FogView {
}.collectResult()
}.flatMap { txOutRecords in
txOutRecords.map { txOutRecord in
LedgerTxOut.make(txOutRecord: txOutRecord, viewKey: accountKey.viewPrivateKey)
LedgerTxOut.make(txOutRecord: txOutRecord)
}.collectResult()
}.map { txOuts in
let foundTxOuts = Self.ownedTxOuts(validating: txOuts, accountKey: accountKey)
@ -179,10 +179,10 @@ struct FogSearchAttempt {
}
extension LedgerTxOut {
fileprivate static func make(txOutRecord: FogView_TxOutRecord, viewKey: RistrettoPrivate)
fileprivate static func make(txOutRecord: FogView_TxOutRecord)
-> Result<LedgerTxOut, ConnectionError>
{
guard let ledgerTxOut = LedgerTxOut(txOutRecord, viewKey: viewKey) else {
guard let ledgerTxOut = LedgerTxOut(txOutRecord) else {
let errorMessage = "Invalid TxOut returned from Fog View. TxOutRecord: " +
"\(redacting: txOutRecord.serializedDataInfallible.base64EncodedString())"
logger.error(errorMessage)

View File

@ -10,24 +10,18 @@ struct KnownTxOut: TxOutProtocol {
let keyImage: KeyImage
init?(_ ledgerTxOut: LedgerTxOut, accountKey: AccountKey) {
guard let value = ledgerTxOut.value(accountKey: accountKey),
let keyImage = ledgerTxOut.keyImage(accountKey: accountKey),
let commitment = TxOutUtils.reconstructCommitment(
maskedValue: ledgerTxOut.maskedValue,
publicKey: ledgerTxOut.publicKey,
viewPrivateKey:accountKey.viewPrivateKey)
let keyImage = ledgerTxOut.keyImage(accountKey: accountKey)
else {
return nil
}
self.commitment = commitment
self.ledgerTxOut = ledgerTxOut
self.value = value
self.keyImage = keyImage
}
var commitment: Data32
var commitment: Data32 { ledgerTxOut.commitment }
var maskedValue: UInt64 { ledgerTxOut.maskedValue }
var targetKey: RistrettoPublic { ledgerTxOut.targetKey }
var publicKey: RistrettoPublic { ledgerTxOut.publicKey }
@ -37,4 +31,3 @@ struct KnownTxOut: TxOutProtocol {
extension KnownTxOut: Equatable {}
extension KnownTxOut: Hashable {}

View File

@ -30,8 +30,8 @@ extension LedgerTxOut: Equatable {}
extension LedgerTxOut: Hashable {}
extension LedgerTxOut {
init?(_ txOutRecord: FogView_TxOutRecord, viewKey: RistrettoPrivate) {
guard let partialTxOut = PartialTxOut(txOutRecord, viewKey: viewKey) else {
init?(_ txOutRecord: FogView_TxOutRecord) {
guard let partialTxOut = PartialTxOut(txOutRecord) else {
return nil
}
let globalIndex = txOutRecord.txOutGlobalIndex

View File

@ -40,17 +40,27 @@ extension PartialTxOut {
publicKey: publicKey)
}
init?(_ txOutRecord: FogView_TxOutRecord, viewKey: RistrettoPrivate) {
guard let targetKey = RistrettoPublic(txOutRecord.txOutTargetKeyData),
let publicKey = RistrettoPublic(txOutRecord.txOutPublicKeyData),
let commitment = TxOutUtils.reconstructCommitment(
maskedValue: txOutRecord.txOutAmountMaskedValue,
publicKey: publicKey,
viewPrivateKey: viewKey)
init?(_ txOut: FogView_FogTxOut) {
guard let commitment = Data32(txOut.amount.commitment.data),
let targetKey = RistrettoPublic(txOut.targetKey.data),
let publicKey = RistrettoPublic(txOut.publicKey.data)
else {
return nil
}
self.init(
commitment: commitment,
maskedValue: txOut.amount.maskedValue,
targetKey: targetKey,
publicKey: publicKey)
}
init?(_ txOutRecord: FogView_TxOutRecord) {
guard let commitment = Data32(txOutRecord.txOutAmountCommitmentData),
let targetKey = RistrettoPublic(txOutRecord.txOutTargetKeyData),
let publicKey = RistrettoPublic(txOutRecord.txOutPublicKeyData)
else {
return nil
}
self.init(
commitment: commitment,
maskedValue: txOutRecord.txOutAmountMaskedValue,

View File

@ -6,7 +6,7 @@ import Foundation
import LibMobileCoin
protocol TxOutProtocol {
var commitment: Data32 { get }
var commitment: Data32 { get }
var maskedValue: UInt64 { get }
var targetKey: RistrettoPublic { get }
var publicKey: RistrettoPublic { get }
@ -23,6 +23,7 @@ extension TxOutProtocol {
func matchesAnySubaddress(accountKey: AccountKey) -> Bool {
TxOutUtils.matchesAnySubaddress(
commitment: commitment,
maskedValue: maskedValue,
publicKey: publicKey,
viewPrivateKey: accountKey.viewPrivateKey)
@ -39,6 +40,7 @@ extension TxOutProtocol {
/// own `TxOut` or because ` TxOut` values are incongruent.
func value(accountKey: AccountKey) -> UInt64? {
TxOutUtils.value(
commitment: commitment,
maskedValue: maskedValue,
publicKey: publicKey,
viewPrivateKey: accountKey.viewPrivateKey)
@ -55,6 +57,16 @@ extension TxOutProtocol {
}
}
extension FogView_FogTxOut {
init(_ txOut: TxOutProtocol) {
self.init()
self.amount =
External_Amount(commitment: txOut.commitment, maskedValue: txOut.maskedValue)
self.targetKey = External_CompressedRistretto(txOut.targetKey)
self.publicKey = External_CompressedRistretto(txOut.publicKey)
}
}
extension FogView_TxOutRecord {
init(_ txOut: TxOutProtocol) {
self.init()

View File

@ -9,24 +9,27 @@ import LibMobileCoin
enum TxOutUtils {
static func matchesAnySubaddress(
commitment: Data32,
maskedValue: UInt64,
publicKey: RistrettoPublic,
viewPrivateKey: RistrettoPrivate
) -> Bool {
var mcAmount = McTxOutAmount(masked_value: maskedValue)
return publicKey.asMcBuffer { publicKeyPtr in
viewPrivateKey.asMcBuffer { viewPrivateKeyPtr in
var matches = false
// Safety: mc_tx_out_matches_any_subaddress is infallible when preconditions are
// upheld.
withMcInfallible {
mc_tx_out_matches_any_subaddress(
&mcAmount,
publicKeyPtr,
viewPrivateKeyPtr,
&matches)
commitment.asMcBuffer { commitmentPtr in
var mcAmount = McTxOutAmount(commitment: commitmentPtr, masked_value: maskedValue)
return publicKey.asMcBuffer { publicKeyPtr in
viewPrivateKey.asMcBuffer { viewPrivateKeyPtr in
var matches = false
// Safety: mc_tx_out_matches_any_subaddress is infallible when preconditions are
// upheld.
withMcInfallible {
mc_tx_out_matches_any_subaddress(
&mcAmount,
publicKeyPtr,
viewPrivateKeyPtr,
&matches)
}
return matches
}
return matches
}
}
}
@ -59,48 +62,6 @@ enum TxOutUtils {
}
}
static func reconstructCommitment(
maskedValue: UInt64,
publicKey: RistrettoPublic,
viewPrivateKey: RistrettoPrivate
) -> Data32? {
var mcAmount = McTxOutAmount(masked_value: maskedValue)
return publicKey.asMcBuffer { publicKeyBufferPtr in
viewPrivateKey.asMcBuffer { viewPrivateKeyPtr in
switch Data32.make(withMcMutableBuffer: { bufferPtr, errorPtr in
mc_tx_out_reconstruct_commitment(
&mcAmount,
publicKeyBufferPtr,
viewPrivateKeyPtr,
bufferPtr,
&errorPtr)
}) {
case .success(let bytes):
// Safety: It's safe to skip validation because
// mc_tx_out_get_subaddress_spend_public_key should always return a valid
// RistrettoPublic on success.
return bytes as Data32
case .failure(let error):
switch error.errorCode {
case .invalidInput:
// Safety: This condition indicates a programming error and can only
// happen if arguments to mc_tx_out_get_subaddress_spend_public_key are
// supplied incorrectly.
// FIXME
logger.warning("error: \(redacting: error)")
return nil
default:
// Safety: mc_fog_resolver_add_report_response should not throw
// non-documented errors.
// FIXME
logger.warning("Unhandled LibMobileCoin error: \(redacting: error)")
return nil
}
}
}
}
}
static func subaddressSpentPublicKey(
targetKey: RistrettoPublic,
publicKey: RistrettoPublic,
@ -143,39 +104,42 @@ enum TxOutUtils {
/// - Returns: `nil` when `viewPrivateKey` cannot unmask value, either because `viewPrivateKey`
/// does not own `TxOut` or because `TxOut` values are incongruent.
static func value(
commitment: Data32,
maskedValue: UInt64,
publicKey: RistrettoPublic,
viewPrivateKey: RistrettoPrivate
) -> UInt64? {
var mcAmount = McTxOutAmount(masked_value: maskedValue)
return publicKey.asMcBuffer { publicKeyPtr in
viewPrivateKey.asMcBuffer { viewKeyBufferPtr in
var valueOut: UInt64 = 0
switch withMcError({ errorPtr in
mc_tx_out_get_value(
&mcAmount,
publicKeyPtr,
viewKeyBufferPtr,
&valueOut,
&errorPtr)
}) {
case .success:
return valueOut
case .failure(let error):
switch error.errorCode {
case .transactionCrypto:
// Indicates either `commitment`/`maskedValue`/`publicKey` values are
// incongruent or `viewPrivateKey` does not own `TxOut`. However, it's
// not possible to determine which, only that the provided `commitment`
// doesn't match the computed commitment.
return nil
case .invalidInput:
// Safety: This condition indicates a programming error and can only
// happen if arguments to mc_tx_out_get_value are supplied incorrectly.
logger.fatalError("error: \(redacting: error)")
default:
// Safety: mc_tx_out_get_value should not throw non-documented errors.
logger.fatalError("Unhandled LibMobileCoin error: \(redacting: error)")
commitment.asMcBuffer { commitmentPtr in
var mcAmount = McTxOutAmount(commitment: commitmentPtr, masked_value: maskedValue)
return publicKey.asMcBuffer { publicKeyPtr in
viewPrivateKey.asMcBuffer { viewKeyBufferPtr in
var valueOut: UInt64 = 0
switch withMcError({ errorPtr in
mc_tx_out_get_value(
&mcAmount,
publicKeyPtr,
viewKeyBufferPtr,
&valueOut,
&errorPtr)
}) {
case .success:
return valueOut
case .failure(let error):
switch error.errorCode {
case .transactionCrypto:
// Indicates either `commitment`/`maskedValue`/`publicKey` values are
// incongruent or `viewPrivateKey` does not own `TxOut`. However, it's
// not possible to determine which, only that the provided `commitment`
// doesn't match the computed commitment.
return nil
case .invalidInput:
// Safety: This condition indicates a programming error and can only
// happen if arguments to mc_tx_out_get_value are supplied incorrectly.
logger.fatalError("error: \(redacting: error)")
default:
// Safety: mc_tx_out_get_value should not throw non-documented errors.
logger.fatalError("Unhandled LibMobileCoin error: \(redacting: error)")
}
}
}
}

View File

@ -150,7 +150,7 @@ extension FogLedger_BlockRequest {
}
}
extension FogLedger_BlockData {
extension FogLedger_Block {
var timestampDate: Date {
get { Date(timeIntervalSince1970: TimeInterval(timestamp)) }
set { timestamp = UInt64(newValue.timeIntervalSince1970) }

View File

@ -1,24 +0,0 @@
//
// Copyright (c) 2020-2021 MobileCoin. All rights reserved.
//
import Foundation
enum AttestedCallError: Error {
case aeadError(AeadError)
case invalidInput(String)
}
extension AttestedCallError: CustomStringConvertible {
var description: String {
"Attested call error: " + {
switch self {
case .aeadError(let innerError):
return "\(innerError)"
case .invalidInput(let reason):
return "Invalid input: \(reason)"
}
}()
}
}

View File

@ -0,0 +1,54 @@
//
// Copyright (c) 2020-2021 MobileCoin. All rights reserved.
//
import Foundation
//class AttestedConnection<Service> {
// private let inner: SerialDispatchLock<Inner>
//
// init(connectionOptionWrapper: ConnectionOptionWrapper<Service>, targetQueue: DispatchQueue?) {
// let inner = Inner(connectionOptionWrapper: connectionOptionWrapper)
// self.inner = .init(inner, targetQueue: targetQueue)
// }
//
// func setConnectionOptionWrapper(_ connectionOptionWrapper: ConnectionOptionWrapper<Service>) {
// inner.accessAsync { $0.connectionOptionWrapper = connectionOptionWrapper }
// }
//
// func setAuthorization(credentials: BasicCredentials) {
// inner.accessAsync { $0.setAuthorization(credentials: credentials) }
// }
//}
//
//extension AttestedConnection {
// private struct Inner {
// var connectionOptionWrapper: ConnectionOptionWrapper<ServiceType> {
// didSet {
// if let credentials = authorizationCredentials {
// switch connectionOptionWrapper {
// case .grpc(grpcService: let grpcService):
// grpcService.setAuthorization(credentials: credentials)
// case .http(httpService: let httpService):
// httpService.setAuthorization(credentials: credentials)
// }
// }
// }
// }
// private var authorizationCredentials: BasicCredentials?
//
// init(connectionOptionWrapper: ConnectionOptionWrapper<ServiceType>) {
// self.connectionOptionWrapper = connectionOptionWrapper
// }
//
// mutating func setAuthorization(credentials: BasicCredentials) {
// self.authorizationCredentials = credentials
// switch connectionOptionWrapper {
// case .grpc(grpcService: let grpcService):
// grpcService.setAuthorization(credentials: credentials)
// case .http(httpService: let httpService):
// httpService.setAuthorization(credentials: credentials)
// }
// }
// }
//}

View File

@ -25,7 +25,7 @@ class Connection<GrpcService: ConnectionProtocol, HttpService: ConnectionProtoco
func setTransportProtocolOption(_ transportProtocolOption: TransportProtocol.Option) {
let connectionOptionWrapper = connectionOptionWrapperFactory(transportProtocolOption)
inner.accessAsync { $0.connectionOptionWrapper = connectionOptionWrapper }
}
}
func setAuthorization(credentials: BasicCredentials) {
inner.accessAsync { $0.setAuthorization(credentials: credentials) }

View File

@ -1,13 +1,11 @@
//
// Copyright (c) 2020-2021 MobileCoin. All rights reserved.
//
// swiftlint:disable all
import Foundation
import GRPC
import NIOHPACK
import NIOHTTP1
import NIOSSL
final class ConnectionSession {
private static var ephemeralCookieStorage: HTTPCookieStorage {
@ -23,22 +21,6 @@ final class ConnectionSession {
private let cookieStorage: HTTPCookieStorage
var authorizationCredentials: BasicCredentials?
private var cookieHeaders : [String:String] {
guard let cookies = cookieStorage.cookies(for: url) else { return [:] }
return HTTPCookie.requestHeaderFields(with: cookies)
}
private var authorizationHeades : [String: String] {
guard let credentials = authorizationCredentials else { return [:] }
return ["Authorization" : credentials.authorizationHeaderValue]
}
var requestHeaders: [String : String] {
var headers : [String: String] = [:]
headers.merge(cookieHeaders) { (_, new) in new }
headers.merge(authorizationHeades) { (_, new) in new }
return headers
}
convenience init(config: ConnectionConfigProtocol) {
self.init(url: config.url, authorization: config.authorization)
}
@ -57,10 +39,6 @@ final class ConnectionSession {
func processResponse(headers: HPACKHeaders) {
processCookieHeader(headers: headers)
}
func processResponse(headers: [AnyHashable : Any]) {
processCookieHeader(headers: headers)
}
}
extension ConnectionSession {
@ -69,11 +47,15 @@ extension ConnectionSession {
hpackHeaders.add(httpHeaders: ["Authorization": credentials.authorizationHeaderValue])
}
}
}
// GRPC
extension ConnectionSession {
private func addCookieHeader(to hpackHeaders: inout HPACKHeaders) {
if let cookies = cookieStorage.cookies(for: url) {
hpackHeaders.add(httpHeaders: HTTPCookie.requestHeaderFields(with: cookies))
}
}
private func processCookieHeader(headers: HPACKHeaders) {
let http1Headers = Dictionary(
headers.map { ($0.name.capitalized, $0.value) },
@ -84,28 +66,6 @@ extension ConnectionSession {
for: url)
receivedCookies.forEach(cookieStorage.setCookie)
}
private func addCookieHeader(to hpackHeaders: inout HPACKHeaders) {
if let cookies = cookieStorage.cookies(for: url) {
hpackHeaders.add(httpHeaders: HTTPCookie.requestHeaderFields(with: cookies))
}
}
private func processCookieHeader(headers: [AnyHashable: Any]) {
let http1Headers = Dictionary(
headers.compactMap({ (key: AnyHashable, value: Any) -> (name: String, value: String)? in
guard let name = key as? String else { return nil }
guard let value = value as? String else { return nil }
return (name:name, value:value)
}).map { ($0.name.capitalized, $0.value) },
uniquingKeysWith: { k, _ in k })
let receivedCookies = HTTPCookie.cookies(
withResponseHeaderFields: http1Headers,
for: url)
receivedCookies.forEach(cookieStorage.setCookie)
}
}
extension HPACKHeaders {

View File

@ -17,7 +17,6 @@ final class BlockchainConnection:
init(
config: ConnectionConfig<ConsensusUrl>,
channelManager: GrpcChannelManager,
httpRequester: HttpRequester?,
targetQueue: DispatchQueue?
) {
self.config = config
@ -34,13 +33,7 @@ final class BlockchainConnection:
channelManager: channelManager,
targetQueue: targetQueue))
case .http:
guard let requester = httpRequester else {
logger.fatalError("Transport Protocol is .http but no HttpRequester provided")
}
return .http(httpService: BlockchainHttpConnection(
config: config,
requester: RestApiRequester(requester: requester, baseUrl: config.url.httpBasedUrl),
targetQueue: targetQueue))
return .http(httpService: BlockchainHttpConnection())
}
},
transportProtocolOption: config.transportProtocolOption,

View File

@ -18,7 +18,6 @@ final class ConsensusConnection:
init(
config: AttestedConnectionConfig<ConsensusUrl>,
channelManager: GrpcChannelManager,
httpRequester: HttpRequester?,
targetQueue: DispatchQueue?,
rng: (@convention(c) (UnsafeMutableRawPointer?) -> UInt64)? = securityRNG,
rngContext: Any? = nil
@ -41,15 +40,7 @@ final class ConsensusConnection:
rng: rng,
rngContext: rngContext))
case .http:
guard let requester = httpRequester else {
logger.fatalError("Transport Protocol is .http but no HttpRequester provided")
}
return .http(httpService: ConsensusHttpConnection(
config: config,
requester: RestApiRequester(requester: requester, baseUrl: config.url.httpBasedUrl),
targetQueue: targetQueue,
rng: rng,
rngContext: rngContext))
return .http(httpService: ConsensusHttpConnection())
}
},
transportProtocolOption: config.transportProtocolOption,

View File

@ -16,7 +16,6 @@ final class FogBlockConnection:
init(
config: ConnectionConfig<FogUrl>,
channelManager: GrpcChannelManager,
httpRequester: HttpRequester?,
targetQueue: DispatchQueue?
) {
self.config = config
@ -33,13 +32,7 @@ final class FogBlockConnection:
channelManager: channelManager,
targetQueue: targetQueue))
case .http:
guard let requester = httpRequester else {
logger.fatalError("Transport Protocol is .http but no HttpRequester provided")
}
return .http(httpService: FogBlockHttpConnection(
config: config,
requester: RestApiRequester(requester: requester, baseUrl: config.url.httpBasedUrl),
targetQueue: targetQueue))
return .http(httpService: FogBlockHttpConnection())
}
},
transportProtocolOption: config.transportProtocolOption,

View File

@ -18,7 +18,6 @@ final class FogKeyImageConnection:
init(
config: AttestedConnectionConfig<FogUrl>,
channelManager: GrpcChannelManager,
httpRequester: HttpRequester?,
targetQueue: DispatchQueue?,
rng: (@convention(c) (UnsafeMutableRawPointer?) -> UInt64)? = securityRNG,
rngContext: Any? = nil
@ -41,15 +40,7 @@ final class FogKeyImageConnection:
rng: rng,
rngContext: rngContext))
case .http:
guard let requester = httpRequester else {
logger.fatalError("Transport Protocol is .http but no HttpRequester provided")
}
return .http(httpService: FogKeyImageHttpConnection(
config: config,
requester: RestApiRequester(requester: requester, baseUrl: config.url.httpBasedUrl),
targetQueue: targetQueue,
rng: rng,
rngContext: rngContext))
return .http(httpService: FogKeyImageHttpConnection())
}
},
transportProtocolOption: config.transportProtocolOption,

View File

@ -18,7 +18,6 @@ final class FogMerkleProofConnection:
init(
config: AttestedConnectionConfig<FogUrl>,
channelManager: GrpcChannelManager,
httpRequester: HttpRequester?,
targetQueue: DispatchQueue?,
rng: (@convention(c) (UnsafeMutableRawPointer?) -> UInt64)? = securityRNG,
rngContext: Any? = nil
@ -41,15 +40,7 @@ final class FogMerkleProofConnection:
rng: rng,
rngContext: rngContext))
case .http:
guard let requester = httpRequester else {
logger.fatalError("Transport Protocol is .http but no HttpRequester provided")
}
return .http(httpService: FogMerkleProofHttpConnection(
config: config,
requester: RestApiRequester(requester: requester, baseUrl: config.url.httpBasedUrl),
targetQueue: targetQueue,
rng: rng,
rngContext: rngContext))
return .http(httpService: FogMerkleProofHttpConnection())
}
},
transportProtocolOption: config.transportProtocolOption,

View File

@ -17,7 +17,6 @@ final class FogReportConnection:
url: FogUrl,
transportProtocolOption: TransportProtocol.Option,
channelManager: GrpcChannelManager,
httpRequester: HttpRequester?,
targetQueue: DispatchQueue?
) {
self.url = url
@ -34,13 +33,7 @@ final class FogReportConnection:
channelManager: channelManager,
targetQueue: targetQueue))
case .http:
guard let requester = httpRequester else {
logger.fatalError("Transport Protocol is .http but no HttpRequester provided")
}
return .http(httpService: FogReportHttpConnection(
url: url,
requester: RestApiRequester(requester: requester, baseUrl: url.httpBasedUrl),
targetQueue: targetQueue))
return .http(httpService: FogReportHttpConnection())
}
},
transportProtocolOption: transportProtocolOption,

View File

@ -17,7 +17,6 @@ final class FogUntrustedTxOutConnection:
init(
config: ConnectionConfig<FogUrl>,
channelManager: GrpcChannelManager,
httpRequester: HttpRequester?,
targetQueue: DispatchQueue?
) {
self.config = config
@ -34,13 +33,7 @@ final class FogUntrustedTxOutConnection:
channelManager: channelManager,
targetQueue: targetQueue))
case .http:
guard let requester = httpRequester else {
logger.fatalError("Transport Protocol is .http but no HttpRequester provided")
}
return .http(httpService: FogUntrustedTxOutHttpConnection(
config: config,
requester: RestApiRequester(requester: requester, baseUrl: config.url.httpBasedUrl),
targetQueue: targetQueue))
return .http(httpService: FogUntrustedTxOutHttpConnection())
}
},
transportProtocolOption: config.transportProtocolOption,

View File

@ -10,7 +10,7 @@ final class FogViewConnection:
Connection<FogViewGrpcConnection, FogViewHttpConnection>, FogViewService
{
private let config: AttestedConnectionConfig<FogUrl>
private let channelManager: GrpcChannelManager
// private let channelManager: GrpcChannelManager
private let targetQueue: DispatchQueue?
private let rng: (@convention(c) (UnsafeMutableRawPointer?) -> UInt64)?
private let rngContext: Any?
@ -24,7 +24,7 @@ final class FogViewConnection:
rngContext: Any? = nil
) {
self.config = config
self.channelManager = channelManager
// self.channelManager = channelManager
self.targetQueue = targetQueue
self.rng = rng
self.rngContext = rngContext
@ -40,13 +40,13 @@ final class FogViewConnection:
rng: rng,
rngContext: rngContext))
case .http:
guard let requester = httpRequester else {
logger.fatalError("Transport Protocol is .http but no HttpRequester provided")
}
let httpClientWrapper = HttpClientWrapper(
config: config,
httpRequester: httpRequester)
return .http(
httpService: FogViewHttpConnection(
config: config,
requester: RestApiRequester(requester: requester, baseUrl: config.url.httpBasedUrl),
client: httpClientWrapper,
targetQueue: targetQueue,
rng: rng,
rngContext: rngContext))

View File

@ -33,7 +33,7 @@ extension ClientConnection {
{
let builder: Builder
if config.useTls {
let secureBuilder = ClientConnection.usingTLSBackedByNIOSSL(on: group)
let secureBuilder = ClientConnection.secure(group: group)
if let trustRoots = config.trustRoots {
secureBuilder.withTLS(trustRoots: .certificates(trustRoots))
}

View File

@ -6,6 +6,24 @@ import Foundation
import LibMobileCoin
import SwiftProtobuf
enum AttestedCallError: Error {
case aeadError(AeadError)
case invalidInput(String)
}
extension AttestedCallError: CustomStringConvertible {
var description: String {
"Attested call error: " + {
switch self {
case .aeadError(let innerError):
return "\(innerError)"
case .invalidInput(let reason):
return "Invalid input: \(reason)"
}
}()
}
}
protocol AttestedGrpcCallable: GrpcCallable {
associatedtype InnerRequestAad = ()
associatedtype InnerRequest

View File

@ -1,79 +0,0 @@
//
// Copyright (c) 2020-2021 MobileCoin. All rights reserved.
//
import Foundation
class ArbitraryHttpConnection {
private let inner: SerialDispatchLock<Inner>
init(url: MobileCoinUrlProtocol, targetQueue: DispatchQueue?) {
let inner = Inner(url: url)
self.inner = .init(inner, targetQueue: targetQueue)
}
func performCall<Call: HttpCallable>(
_ call: Call,
request: Call.Request,
completion: @escaping (Result<Call.Response, ConnectionError>) -> Void
) {
func performCallCallback(callResult: HttpCallResult<Call.Response>) {
inner.accessAsync {
let result = $0.processResponse(callResult: callResult)
switch result {
case .success:
logger.info("Call complete. url: \($0.url)", logFunction: false)
case .failure(let connectionError):
let errorMessage =
"Connection failure. url: \($0.url), error: \(connectionError)"
switch connectionError {
case .connectionFailure, .serverRateLimited:
logger.warning(errorMessage, logFunction: false)
case .authorizationFailure, .invalidServerResponse,
.attestationVerificationFailed, .outdatedClient:
logger.error(errorMessage, logFunction: false)
}
}
completion(result)
}
}
inner.accessAsync {
logger.info("Performing call... url: \($0.url)", logFunction: false)
let callOptions = $0.requestCallOptions()
call.call(request: request, callOptions: callOptions, completion: performCallCallback)
}
}
}
extension ArbitraryHttpConnection {
private struct Inner {
let url: MobileCoinUrlProtocol
private let session: ConnectionSession
init(url: MobileCoinUrlProtocol) {
self.url = url
self.session = ConnectionSession(url: url)
}
func requestCallOptions() -> HTTPCallOptions {
logger.debug(session.requestHeaders.debugDescription)
return HTTPCallOptions(headers: session.requestHeaders)
}
func processResponse<Response>(callResult: HttpCallResult<Response>)
-> Result<Response, ConnectionError>
{
guard callResult.status.isOk, let response = callResult.response else {
return .failure(.connectionFailure(String(describing: callResult.status)))
}
if let metadata = callResult.metadata {
session.processResponse(headers: metadata.allHeaderFields)
}
return .success(response)
}
}
}

View File

@ -6,9 +6,8 @@
// swiftlint:disable multiline_function_chains operator_usage_whitespace
import Foundation
import GRPC
import LibMobileCoin
import NIO
import NIOHPACK
enum AttestedHttpConnectionError: Error {
case connectionError(ConnectionError)
@ -29,19 +28,16 @@ extension AttestedHttpConnectionError: CustomStringConvertible {
}
class AttestedHttpConnection: ConnectionProtocol {
private let requester: RestApiRequester
private let inner: SerialCallbackLock<Inner>
init(
client: AttestableHttpClient,
requester: RestApiRequester,
config: AttestedConnectionConfigProtocol,
targetQueue: DispatchQueue?,
rng: (@convention(c) (UnsafeMutableRawPointer?) -> UInt64)? = securityRNG,
rngContext: Any? = nil
) {
let inner = Inner(client: client, requester: requester, config: config, rng: rng, rngContext: rngContext)
self.requester = requester
let inner = Inner(client: client, config: config, rng: rng, rngContext: rngContext)
self.inner = .init(inner, targetQueue: targetQueue)
}
@ -114,7 +110,6 @@ extension AttestedHttpConnection {
private let url: MobileCoinUrlProtocol
private let session: ConnectionSession
private let client: AttestableHttpClient
private let requester: RestApiRequester
private let attestAke: AttestAke
private let responderId: String
@ -124,7 +119,6 @@ extension AttestedHttpConnection {
init(
client: AttestableHttpClient,
requester: RestApiRequester,
config: AttestedConnectionConfigProtocol,
rng: (@convention(c) (UnsafeMutableRawPointer?) -> UInt64)? = securityRNG,
rngContext: Any? = nil
@ -132,7 +126,6 @@ extension AttestedHttpConnection {
self.url = config.url
self.session = ConnectionSession(config: config)
self.client = client
self.requester = requester
self.attestAke = AttestAke()
self.responderId = config.url.responderId
self.attestationVerifier = AttestationVerifier(attestation: config.attestation)
@ -269,7 +262,7 @@ extension AttestedHttpConnection {
rngContext: rngContext)
doPerformCall(
AuthHttpCallableWrapper(authCallable: client.authCallable, requester: requester),
AuthHttpCallableWrapper(authCallable: client.authCallable),
request: request
) {
completion(
@ -330,38 +323,29 @@ extension AttestedHttpConnection {
request: Call.Request,
completion: @escaping (Result<Call.Response, AttestedHttpConnectionError>) -> Void
) {
let callOptions = requestCallOptions()
call.call(request: request, callOptions: callOptions) {
call.call(request: request) {
completion(self.processResponse(callResult: $0))
}
}
private func requestCallOptions() -> HTTPCallOptions {
HTTPCallOptions(headers: session.requestHeaders)
}
private func processResponse<Response>(callResult: HttpCallResult<Response>)
-> Result<Response, AttestedHttpConnectionError>
{
// Basic credential authorization failure
guard callResult.status.isOk else {
guard callResult.httpResponse.statusCode != 401 else {
return .failure(.connectionError(.authorizationFailure("url: \(url)")))
}
// Attestation failure, reattest
guard callResult.status.code != 403 else {
guard callResult.httpResponse.statusCode != 403 else {
return .failure(.attestationFailure())
}
guard callResult.status.code == 200, let response = callResult.response else {
guard callResult.httpResponse.statusCode == 200, let response = callResult.responsePayload else {
return .failure(.connectionError(
.connectionFailure("url: \(url), status: \(callResult.status.code)")))
}
if let metadata = callResult.metadata {
session.processResponse(headers: metadata.allHeaderFields)
.connectionFailure("url: \(url), status: \(callResult.httpResponse.statusCode)")))
}
session.processResponse(headers: HPACKHeaders(callResult.headers))
return .success(response)
}

View File

@ -1,17 +0,0 @@
//
// Copyright (c) 2020-2021 MobileCoin. All rights reserved.
//
import Foundation
public struct HTTPCallOptions {
var headers: [String : String]
var timeoutIntervalForRequest : TimeInterval?
var timeoutIntervalForResource : TimeInterval?
}
extension HTTPCallOptions {
public init() {
self.init(headers: [:], timeoutIntervalForRequest: 30, timeoutIntervalForResource: 30)
}
}

View File

@ -1,24 +0,0 @@
//
// Copyright (c) 2020-2021 MobileCoin. All rights reserved.
//
import Foundation
import SwiftProtobuf
/// A HTTP client.
public protocol HTTPClient {
/// The call options to use should the user not provide per-call options.
var defaultHTTPCallOptions: HTTPCallOptions { get set }
}
extension HTTPClient {
public func makeUnaryCall<Request,Response>(
path: String,
request: Request,
callOptions: HTTPCallOptions? = nil,
responseType: Response.Type = Response.self
) -> HTTPUnaryCall<Request, Response> where Request : SwiftProtobuf.Message, Response : SwiftProtobuf.Message {
HTTPUnaryCall(path: path, options: callOptions, requestPayload: request, responseType: responseType)
}
}

View File

@ -1,39 +0,0 @@
//
// Copyright (c) 2020-2021 MobileCoin. All rights reserved.
//
import Foundation
import SwiftProtobuf
public protocol HTTPClientCall {
/// The type of the request message for the call.
associatedtype RequestPayload: SwiftProtobuf.Message
/// The type of the response message for the call.
associatedtype ResponsePayload: SwiftProtobuf.Message
/// The resource path (generated)
var path: String { get }
/// The http method to use for the call
var method: HTTPMethod { get }
var requestPayload: RequestPayload? { get set }
/// The response message returned from the service if the call is successful. This may be failed
/// if the call encounters an error.
///
/// Callers should rely on the `status` of the call for the canonical outcome.
var responseType: ResponsePayload.Type { get set }
/// The options used to make the session.
var options: HTTPCallOptions? { get }
/// Response metadata.
var metadata: HTTPURLResponse? { get }
/// Status of this call.
///
var status: HTTPStatus? { get }
}

View File

@ -1,14 +0,0 @@
//
// Copyright (c) 2020-2021 MobileCoin. All rights reserved.
//
import Foundation
public enum HTTPMethod : String {
case GET
case POST
case PUT
case HEAD
case PATCH
case DELETE
}

View File

@ -1,18 +0,0 @@
//
// Copyright (c) 2020-2021 MobileCoin. All rights reserved.
//
import Foundation
public struct HTTPResponse {
public let httpUrlResponse: HTTPURLResponse
public let responseData: Data?
public var statusCode: Int {
httpUrlResponse.statusCode
}
public var allHeaderFields: [AnyHashable: Any] {
httpUrlResponse.allHeaderFields
}
}

View File

@ -1,59 +0,0 @@
//
// Copyright (c) 2020-2021 MobileCoin. All rights reserved.
//
import Foundation
import GRPC
/// Encapsulates the result of a HTTP call.
public struct HTTPStatus : Error {
/// The REST status code
public var code: Int
/// The status message
public var message: String?
/// Whether the status is '.ok'.
public var isOk: Bool {
(200...299).contains(code)
}
/// The default status to return for succeeded calls.
///
/// - Important: This should *not* be used when checking whether a returned status has an 'ok'
/// status code. Use `HTTPStatus.isOk` or check the code directly.
public static let ok: HTTPStatus = .init(code: 200, message: "Success")
/// "Internal server error" status.
public static let processingError: HTTPStatus = .init(code: 500, message: "Error")
}
extension HTTPStatus : CustomStringConvertible {
public var description: String {
codeDescription + (message ?? "")
}
private var codeDescription: String {
switch code {
case 1:
return "Unknown Error: "
case 200:
return "Success: "
case 400:
return "Invalid Arguments: "
case 403:
return "Unauthorized: "
case 404:
return "Not Found: "
case 500:
return "Error: "
case 501:
return "Unimplemented: "
case 503:
return "Unavailable: "
default:
return ""
}
}
}

View File

@ -1,34 +0,0 @@
//
// Copyright (c) 2020-2021 MobileCoin. All rights reserved.
//
import Foundation
import SwiftProtobuf
/// A unary http call. The request is sent on initialization.
///
/// Note: while this object is a `struct`, its implementation delegates to `Call`. It therefore
/// has reference semantics.
public struct HTTPUnaryCall<RequestPayload:SwiftProtobuf.Message, ResponsePayload:SwiftProtobuf.Message> : HTTPClientCall {
public var path: String
public var method: HTTPMethod = .POST
public var response: ResponsePayload?
/// The options used in the URLSession
public var options: HTTPCallOptions?
/// The initial metadata returned from the server.
public var metadata: HTTPURLResponse?
/// The request message sent to the server
public var requestPayload: RequestPayload?
/// The response returned by the server.
public var responseType: ResponsePayload.Type
public var responsePayload: ResponsePayload?
/// The final status of the the RPC.
public var status: HTTPStatus?
}

View File

@ -1,144 +0,0 @@
//
// Copyright (c) 2020-2021 MobileCoin. All rights reserved.
//
import Foundation
import LibMobileCoin
import SwiftProtobuf
protocol AttestedHttpCallable: HttpCallable {
associatedtype InnerRequestAad = ()
associatedtype InnerRequest
associatedtype InnerResponseAad = ()
associatedtype InnerResponse
func processRequest(
requestAad: InnerRequestAad,
request: InnerRequest,
attestAkeCipher: AttestAke.Cipher
) -> Result<Request, AeadError>
func processResponse(
response: Response,
attestAkeCipher: AttestAke.Cipher
) -> Result<(responseAad: InnerResponseAad, response: InnerResponse),
AttestedHttpConnectionError>
}
extension AttestedHttpCallable where InnerRequestAad == (), InnerRequest == Request {
func processRequest(
requestAad: InnerRequestAad,
request: InnerRequest,
attestAkeCipher: AttestAke.Cipher
) -> Result<Request, AeadError> {
.success(request)
}
}
extension AttestedHttpCallable where InnerResponseAad == (), InnerResponse == Response {
func processResponse(response: Response, attestAkeCipher: AttestAke.Cipher)
-> Result<(responseAad: InnerResponseAad, response: InnerResponse),
AttestedHttpConnectionError>
{
.success((responseAad: (), response: response))
}
}
extension AttestedHttpCallable
where InnerRequestAad == (),
Request == Attest_Message,
InnerRequest: InfallibleDataSerializable
{
func processRequest(
requestAad: InnerRequestAad,
request: InnerRequest,
attestAkeCipher: AttestAke.Cipher
) -> Result<Attest_Message, AeadError> {
let aad = Data()
let plaintext = request.serializedDataInfallible
return attestAkeCipher.encryptMessage(aad: aad, plaintext: plaintext)
}
}
extension AttestedHttpCallable
where InnerResponseAad == (),
Response == Attest_Message,
InnerResponse: Message
{
func processResponse(
response: Attest_Message,
attestAkeCipher: AttestAke.Cipher
) -> Result<(responseAad: InnerResponseAad, response: InnerResponse),
AttestedHttpConnectionError>
{
guard response.aad == Data() else {
return .failure(.connectionError(.invalidServerResponse(
"\(Self.self) received unexpected aad: " +
"\(redacting: response.aad.base64EncodedString()), message: " +
"\(redacting: response.serializedDataInfallible.base64EncodedString())")))
}
return attestAkeCipher.decryptMessage(response)
.mapError { _ in .attestationFailure() }
.flatMap { plaintext in
guard let response = try? InnerResponse(serializedData: plaintext) else {
return .failure(.connectionError(.invalidServerResponse(
"Failed to deserialized attested message plaintext into " +
"\(InnerResponse.self). plaintext: " +
"\(redacting: plaintext.base64EncodedString())")))
}
return .success((responseAad: (), response: response))
}
}
}
extension AttestedHttpCallable
where InnerRequestAad: InfallibleDataSerializable,
Request == Attest_Message,
InnerRequest: InfallibleDataSerializable
{
func processRequest(
requestAad: InnerRequestAad,
request: InnerRequest,
attestAkeCipher: AttestAke.Cipher
) -> Result<Attest_Message, AeadError> {
let aad = requestAad.serializedDataInfallible
let plaintext = request.serializedDataInfallible
return attestAkeCipher.encryptMessage(aad: aad, plaintext: plaintext)
}
}
extension AttestedHttpCallable
where InnerResponseAad: Message,
Response == Attest_Message,
InnerResponse: Message
{
func processResponse(
response: Attest_Message,
attestAkeCipher: AttestAke.Cipher
) -> Result<(responseAad: InnerResponseAad, response: InnerResponse),
AttestedHttpConnectionError>
{
guard let responseAad = try? InnerResponseAad(serializedData: response.aad) else {
return .failure(.connectionError(.invalidServerResponse(
"Failed to deserialized attested message aad into \(InnerResponseAad.self). aad: " +
"\(redacting: response.aad.base64EncodedString())")))
}
return attestAkeCipher.decryptMessage(response)
.mapError { _ in .attestationFailure() }
.flatMap { plaintext in
guard let plaintextResponse = try? InnerResponse(serializedData: plaintext) else {
return .failure(.connectionError(.invalidServerResponse(
"Failed to deserialized attested message plaintext into " +
"\(InnerResponse.self). plaintext: " +
"\(redacting: plaintext.base64EncodedString())")))
}
return .success((responseAad: responseAad, response: plaintextResponse))
}
}
}

View File

@ -1,57 +0,0 @@
//
// Copyright (c) 2020-2021 MobileCoin. All rights reserved.
//
import Foundation
import GRPC
import LibMobileCoin
protocol AuthHttpCallable {
var requester: RestApiRequester { get }
func auth(
_ request: Attest_AuthMessage,
callOptions: HTTPCallOptions?,
completion: @escaping (HttpCallResult<Attest_AuthMessage>) -> Void)
}
protocol AuthHttpCallee {
func auth(
_ request: Attest_AuthMessage,
callOptions: HTTPCallOptions?
) -> HTTPUnaryCall<Attest_AuthMessage, Attest_AuthMessage>
}
protocol QueryHttpCallee {
func query(
_ request: Attest_Message,
callOptions: HTTPCallOptions?
) -> HTTPUnaryCall<Attest_Message, Attest_Message>
}
protocol OutputsHttpCallee {
func getOutputs(
_ request: Attest_Message,
callOptions: HTTPCallOptions?
) -> HTTPUnaryCall<Attest_Message, Attest_Message>
}
protocol CheckKeyImagesCallee {
func checkKeyImages(
_ request: Attest_Message,
callOptions: HTTPCallOptions?
) -> HTTPUnaryCall<Attest_Message, Attest_Message>
}
struct AuthHttpCallableWrapper: HttpCallable {
let authCallable: AuthHttpCallable
let requester: RestApiRequester
func call(
request: Attest_AuthMessage,
callOptions: HTTPCallOptions?,
completion: @escaping (HttpCallResult<Attest_AuthMessage>) -> Void
) {
authCallable.auth(request, callOptions: callOptions, completion: completion)
}
}

View File

@ -1,65 +0,0 @@
//
// Copyright (c) 2020-2021 MobileCoin. All rights reserved.
//
// swiftlint:disable all
import Foundation
import LibMobileCoin
protocol AuthQueryHttpCalleeAndClient : QueryHttpCallee, AuthHttpCallee, HTTPClient {}
struct AuthHttpCallableClientWrapper<WrappedClient:HTTPClient & AuthHttpCallee>: AuthHttpCallableClient, HTTPClient {
public var defaultHTTPCallOptions: HTTPCallOptions {
get {
return client.defaultHTTPCallOptions
}
set {
logger.warning("defaultHTTPOptions set not implemented")
}
}
let client : WrappedClient
let requester: RestApiRequester
func auth(_ request: Attest_AuthMessage, callOptions: HTTPCallOptions?)
-> HTTPUnaryCall<Attest_AuthMessage, Attest_AuthMessage> {
client.auth(request, callOptions: callOptions)
}
func auth(
_ request: Attest_AuthMessage,
callOptions: HTTPCallOptions?,
completion: @escaping (HttpCallResult<Attest_AuthMessage>) -> Void) {
let clientCall = auth(request, callOptions: callOptions)
requester.makeRequest(call: clientCall, completion: completion)
}
}
extension AuthHttpCallableClientWrapper where WrappedClient : QueryHttpCallee {
func query(
_ request: Attest_Message,
callOptions: HTTPCallOptions?
) -> HTTPUnaryCall<Attest_Message, Attest_Message> {
client.query(request, callOptions: callOptions)
}
}
extension AuthHttpCallableClientWrapper where WrappedClient : OutputsHttpCallee {
func getOutputs(
_ request: Attest_Message,
callOptions: HTTPCallOptions?
) -> HTTPUnaryCall<Attest_Message, Attest_Message> {
client.getOutputs(request, callOptions: callOptions)
}
}
extension AuthHttpCallableClientWrapper where WrappedClient : CheckKeyImagesCallee {
func checkKeyImages(
_ request: Attest_Message,
callOptions: HTTPCallOptions?
) -> HTTPUnaryCall<Attest_Message, Attest_Message> {
client.checkKeyImages(request, callOptions: callOptions)
}
}

View File

@ -1,23 +0,0 @@
//
// Copyright (c) 2020-2021 MobileCoin. All rights reserved.
//
import Foundation
public protocol HttpCallable {
associatedtype Request
associatedtype Response
var requester: RestApiRequester { get }
func call(
request: Request,
callOptions: HTTPCallOptions?,
completion: @escaping (HttpCallResult<Response>) -> Void)
}
extension HttpCallable {
func call(request: Request, completion: @escaping (HttpCallResult<Response>) -> Void) {
call(request: request, callOptions: nil, completion: completion)
}
}

View File

@ -1,9 +0,0 @@
//
// Copyright (c) 2020-2021 MobileCoin. All rights reserved.
//
import Foundation
protocol AttestableHttpClient {
var authCallable: AuthHttpCallable { get }
}

View File

@ -1,29 +0,0 @@
//
// Copyright (c) 2020-2021 MobileCoin. All rights reserved.
//
import Foundation
import GRPC
import LibMobileCoin
protocol AuthHttpCallableClient: AttestableHttpClient, AuthHttpCallable {
func auth(_ request: Attest_AuthMessage, callOptions: HTTPCallOptions?)
-> HTTPUnaryCall<Attest_AuthMessage, Attest_AuthMessage>
}
extension AuthHttpCallableClient {
var authCallable: AuthHttpCallable {
self
}
}
extension AuthHttpCallableClient {
func auth(
_ request: Attest_AuthMessage,
callOptions: HTTPCallOptions?,
completion: @escaping (HttpCallResult<Attest_AuthMessage>) -> Void
) {
let clientCall = auth(request, callOptions: callOptions)
requester.makeRequest(call: clientCall, completion: completion)
}
}

View File

@ -1,20 +0,0 @@
//
// Copyright (c) 2020-2021 MobileCoin. All rights reserved.
//
import Foundation
import GRPC
protocol HttpCallableClient: HttpCallable {
func call(request: Request, callOptions: CallOptions?) -> UnaryCall<Request, Response>
}
extension HttpCallableClient {
func call(
request: Request,
callOptions: CallOptions?,
completion: @escaping (UnaryCallResult<Response>) -> Void
) {
call(request: request, callOptions: callOptions).callResult.whenSuccess(completion)
}
}

View File

@ -0,0 +1,46 @@
//
// Copyright (c) 2020-2021 MobileCoin. All rights reserved.
//
// swiftlint:disable multiline_parameters_brackets
import Foundation
final class HttpClientWrapper: AttestableHttpClient {
private let httpRequester: HttpRequester?
private let headers: [String: String]
private let config: ConnectionConfigProtocol
private let httpMethod = HTTPMethod.post
var authCallable: AuthHttpCallable { get {
AuthHttpCallable
} }
required init(config: ConnectionConfigProtocol, httpRequester: HttpRequester?) {
self.httpRequester = httpRequester
self.config = config
self.headers = [:]
}
func request(
body: Data?,
completion: @escaping (Result<Data?, Error>) -> Void) {
if let requester = httpRequester {
requester.request(
url: config.url.url,
method: httpMethod,
headers: headers,
body: body) { httpResponse in
switch httpResponse {
case .success(let response):
return completion(.success(response.responseData))
case .failure(let error):
return completion(.failure(error))
}
}
} else {
return completion(
.failure(InvalidInputError("HttpRequester was not set in the Network config")))
}
}
}

View File

@ -1,99 +0,0 @@
//
// Copyright (c) 2020-2021 MobileCoin. All rights reserved.
//
import Foundation
class HttpConnection: ConnectionProtocol {
private let inner: SerialDispatchLock<Inner>
init(config: ConnectionConfigProtocol, targetQueue: DispatchQueue?) {
let inner = Inner(config: config)
self.inner = .init(inner, targetQueue: targetQueue)
}
func setAuthorization(credentials: BasicCredentials) {
inner.accessAsync {
$0.setAuthorization(credentials: credentials)
}
}
func performCall<Call: HttpCallable>(
_ call: Call,
request: Call.Request,
completion: @escaping (Result<Call.Response, ConnectionError>) -> Void
) {
func performCallCallback(callResult: HttpCallResult<Call.Response>) {
inner.accessAsync {
let result = $0.processResponse(callResult: callResult)
switch result {
case .success:
logger.info("Call complete. url: \($0.url)", logFunction: false)
case .failure(let connectionError):
let errorMessage =
"Connection failure. url: \($0.url), error: \(connectionError)"
switch connectionError {
case .connectionFailure, .serverRateLimited:
logger.warning(errorMessage, logFunction: false)
case .authorizationFailure, .invalidServerResponse,
.attestationVerificationFailed, .outdatedClient:
logger.error(errorMessage, logFunction: false)
}
}
completion(result)
}
}
inner.accessAsync {
logger.info("Performing call... url: \($0.url)", logFunction: false)
call.call(request: request, callOptions: $0.requestCallOptions(), completion: performCallCallback)
}
}
func performCall<Call: HttpCallable>(
_ call: Call,
completion: @escaping (Result<Call.Response, ConnectionError>) -> Void
) where Call.Request == () {
performCall(call, request: (), completion: completion)
}
}
extension HttpConnection {
private struct Inner {
let url: MobileCoinUrlProtocol
private let session: ConnectionSession
init(config: ConnectionConfigProtocol) {
self.url = config.url
self.session = ConnectionSession(config: config)
}
func setAuthorization(credentials: BasicCredentials) {
session.authorizationCredentials = credentials
}
func requestCallOptions() -> HTTPCallOptions {
logger.debug(session.requestHeaders.debugDescription)
return HTTPCallOptions(headers: session.requestHeaders)
}
func processResponse<Response>(callResult: HttpCallResult<Response>)
-> Result<Response, ConnectionError>
{
guard [403, 401].contains(callResult.status.code) == false else {
return .failure(.authorizationFailure("url: \(url)"))
}
guard callResult.status.isOk, let response = callResult.response else {
return .failure(.connectionFailure("url: \(url), status: \(callResult.status)"))
}
if let metadata = callResult.metadata {
session.processResponse(headers: metadata.allHeaderFields)
}
return .success(response)
}
}
}

View File

@ -4,42 +4,15 @@
import Foundation
import LibMobileCoin
import SwiftProtobuf
final class BlockchainHttpConnection: HttpConnection, BlockchainService {
private let client: ConsensusCommon_BlockchainAPIRestClient
private let requester: RestApiRequester
init(
config: ConnectionConfig<ConsensusUrl>,
requester: RestApiRequester,
targetQueue: DispatchQueue?
) {
self.client = ConsensusCommon_BlockchainAPIRestClient()
self.requester = requester
super.init(config: config, targetQueue: targetQueue)
}
final class BlockchainHttpConnection: ConnectionProtocol, BlockchainService {
func getLastBlockInfo(
completion:
@escaping (Result<ConsensusCommon_LastBlockInfoResponse, ConnectionError>) -> Void
) {
performCall(GetLastBlockInfoCall(client: client, requester: requester), completion: completion)
}
}
extension BlockchainHttpConnection {
private struct GetLastBlockInfoCall: HttpCallable {
let client: ConsensusCommon_BlockchainAPIRestClient
let requester: RestApiRequester
func call(
request: (),
callOptions: HTTPCallOptions?,
completion: @escaping (HttpCallResult<ConsensusCommon_LastBlockInfoResponse>) -> Void
) {
let clientCall = client.getLastBlockInfo(Google_Protobuf_Empty())
requester.makeRequest(call: clientCall, completion: completion)
}
}
func setAuthorization(credentials: BasicCredentials) {
}
}

View File

@ -5,58 +5,14 @@
import Foundation
import LibMobileCoin
final class ConsensusHttpConnection: AttestedHttpConnection, ConsensusService {
private let client: ConsensusClient_ConsensusClientAPIRestClient
private let requester: RestApiRequester
init(
config: AttestedConnectionConfig<ConsensusUrl>,
requester: RestApiRequester,
targetQueue: DispatchQueue?,
rng: (@convention(c) (UnsafeMutableRawPointer?) -> UInt64)? = securityRNG,
rngContext: Any? = nil
) {
// Solve for shared channel TLS/Certs
self.requester = requester
self.client = ConsensusClient_ConsensusClientAPIRestClient()
super.init(
client: AuthHttpCallableClientWrapper(client: Attest_AttestedApiRestClient(), requester: self.requester),
requester: self.requester,
config: config,
targetQueue: targetQueue,
rng: rng,
rngContext: rngContext)
}
final class ConsensusHttpConnection: ConnectionProtocol, ConsensusService {
func proposeTx(
_ tx: External_Tx,
completion: @escaping (Result<ConsensusCommon_ProposeTxResponse, ConnectionError>) -> Void
) {
performAttestedCall(
ProposeTxCall(client: client, requester: requester),
request: tx,
completion: completion)
}
func setAuthorization(credentials: BasicCredentials) {
}
}
extension ConsensusHttpConnection {
private struct ProposeTxCall: AttestedHttpCallable {
typealias InnerRequest = External_Tx
typealias InnerResponse = ConsensusCommon_ProposeTxResponse
let client: ConsensusClient_ConsensusClientAPIRestClient
let requester: RestApiRequester
func call(
request: Attest_Message,
callOptions: HTTPCallOptions?,
completion: @escaping (HttpCallResult<ConsensusCommon_ProposeTxResponse>) -> Void
) {
let clientCall = client.clientTxPropose(request, callOptions: callOptions)
requester.makeRequest(call: clientCall, completion: completion)
}
}
}
extension Attest_AttestedApiRestClient: AuthHttpCallee, HTTPClient {}

View File

@ -1,46 +1,18 @@
//
// Copyright (c) 2020-2021 MobileCoin. All rights reserved.
//
// swiftlint:disable all
import Foundation
import LibMobileCoin
final class FogBlockHttpConnection: HttpConnection, FogBlockService {
private let client: FogLedger_FogBlockAPIRestClient
private let requester: RestApiRequester
init(
config: ConnectionConfig<FogUrl>,
requester: RestApiRequester,
targetQueue: DispatchQueue?
) {
self.client = FogLedger_FogBlockAPIRestClient()
self.requester = requester
super.init(config: config, targetQueue: targetQueue)
}
final class FogBlockHttpConnection: ConnectionProtocol, FogBlockService {
func getBlocks(
request: FogLedger_BlockRequest,
completion: @escaping (Result<FogLedger_BlockResponse, ConnectionError>) -> Void
) {
performCall(GetBlocksCall(client: client, requester: requester), request: request, completion: completion)
}
}
extension FogBlockHttpConnection {
private struct GetBlocksCall: HttpCallable {
let client: FogLedger_FogBlockAPIRestClient
let requester: RestApiRequester
func call(
request: FogLedger_BlockRequest,
callOptions: HTTPCallOptions?,
completion: @escaping (HttpCallResult<FogLedger_BlockResponse>) -> Void
) {
let clientCall = client.getBlocks(request, callOptions: callOptions)
requester.makeRequest(call: clientCall, completion: completion)
}
}
func setAuthorization(credentials: BasicCredentials) {
}
}

View File

@ -5,57 +5,14 @@
import Foundation
import LibMobileCoin
final class FogKeyImageHttpConnection: AttestedHttpConnection, FogKeyImageService {
private let client: AuthHttpCallableClientWrapper<FogLedger_FogKeyImageAPIRestClient>
private let requester : RestApiRequester
init(
config: AttestedConnectionConfig<FogUrl>,
requester: RestApiRequester,
targetQueue: DispatchQueue?,
rng: (@convention(c) (UnsafeMutableRawPointer?) -> UInt64)? = securityRNG,
rngContext: Any? = nil
) {
self.requester = requester
self.client = AuthHttpCallableClientWrapper(client: FogLedger_FogKeyImageAPIRestClient(), requester: self.requester)
super.init(
client: self.client,
requester: self.requester,
config: config,
targetQueue: targetQueue,
rng: rng,
rngContext: rngContext)
}
final class FogKeyImageHttpConnection: ConnectionProtocol, FogKeyImageService {
func checkKeyImages(
request: FogLedger_CheckKeyImagesRequest,
completion: @escaping (Result<FogLedger_CheckKeyImagesResponse, ConnectionError>) -> Void
) {
performAttestedCall(
CheckKeyImagesCall(client: client, requester: self.requester),
request: request,
completion: completion)
}
func setAuthorization(credentials: BasicCredentials) {
}
}
extension FogKeyImageHttpConnection {
private struct CheckKeyImagesCall: AttestedHttpCallable {
typealias InnerRequest = FogLedger_CheckKeyImagesRequest
typealias InnerResponse = FogLedger_CheckKeyImagesResponse
let client: AuthHttpCallableClientWrapper<FogLedger_FogKeyImageAPIRestClient>
let requester: RestApiRequester
func call(
request: Attest_Message,
callOptions: HTTPCallOptions?,
completion: @escaping (HttpCallResult<Attest_Message>) -> Void
) {
let unaryCall = client.checkKeyImages(request, callOptions: callOptions)
requester.makeRequest(call: unaryCall, completion: completion)
}
}
}
extension FogLedger_FogKeyImageAPIRestClient: AuthHttpCallee, CheckKeyImagesCallee, HTTPClient {}

View File

@ -5,57 +5,14 @@
import Foundation
import LibMobileCoin
final class FogMerkleProofHttpConnection: AttestedHttpConnection, FogMerkleProofService {
private let client: AuthHttpCallableClientWrapper<FogLedger_FogMerkleProofAPIRestClient>
private let requester : RestApiRequester
init(
config: AttestedConnectionConfig<FogUrl>,
requester: RestApiRequester,
targetQueue: DispatchQueue?,
rng: (@convention(c) (UnsafeMutableRawPointer?) -> UInt64)? = securityRNG,
rngContext: Any? = nil
) {
self.requester = requester
self.client = AuthHttpCallableClientWrapper(client:FogLedger_FogMerkleProofAPIRestClient(), requester: self.requester)
super.init(
client: self.client,
requester: self.requester,
config: config,
targetQueue: targetQueue,
rng: rng,
rngContext: rngContext)
}
final class FogMerkleProofHttpConnection: ConnectionProtocol, FogMerkleProofService {
func getOutputs(
request: FogLedger_GetOutputsRequest,
completion: @escaping (Result<FogLedger_GetOutputsResponse, ConnectionError>) -> Void
) {
performAttestedCall(
GetOutputsCall(client: client, requester: self.requester),
request: request,
completion: completion)
}
func setAuthorization(credentials: BasicCredentials) {
}
}
extension FogMerkleProofHttpConnection {
private struct GetOutputsCall: AttestedHttpCallable {
typealias InnerRequest = FogLedger_GetOutputsRequest
typealias InnerResponse = FogLedger_GetOutputsResponse
let client: AuthHttpCallableClientWrapper<FogLedger_FogMerkleProofAPIRestClient>
let requester: RestApiRequester
func call(
request: Attest_Message,
callOptions: HTTPCallOptions?,
completion: @escaping (HttpCallResult<Attest_Message>) -> Void
) {
let unaryCall = client.getOutputs(request, callOptions: callOptions)
requester.makeRequest(call: unaryCall, completion: completion)
}
}
}
extension FogLedger_FogMerkleProofAPIRestClient: AuthHttpCallee, OutputsHttpCallee {}

View File

@ -5,36 +5,10 @@
import Foundation
import LibMobileCoin
final class FogReportHttpConnection: ArbitraryHttpConnection, FogReportService {
private let client: Report_ReportAPIRestClient
let requester: RestApiRequester
init(url: FogUrl, requester: RestApiRequester, targetQueue: DispatchQueue?) {
self.client = Report_ReportAPIRestClient()
self.requester = requester
super.init(url: url, targetQueue: targetQueue)
}
final class FogReportHttpConnection: FogReportService {
func getReports(
request: Report_ReportRequest,
completion: @escaping (Result<Report_ReportResponse, ConnectionError>) -> Void
) {
performCall(GetReportsCall(client: client, requester: requester), request: request, completion: completion)
}
}
extension FogReportHttpConnection {
private struct GetReportsCall: HttpCallable {
let client: Report_ReportAPIRestClient
let requester: RestApiRequester
func call(
request: Report_ReportRequest,
callOptions: HTTPCallOptions?,
completion: @escaping (HttpCallResult<Report_ReportResponse>) -> Void
) {
let unaryCall = client.getReports(request, callOptions: callOptions)
requester.makeRequest(call: unaryCall, completion: completion)
}
}
}

View File

@ -5,40 +5,14 @@
import Foundation
import LibMobileCoin
final class FogUntrustedTxOutHttpConnection: HttpConnection, FogUntrustedTxOutService {
private let client: FogLedger_FogUntrustedTxOutApiRestClient
private let requester : RestApiRequester
init(
config: ConnectionConfig<FogUrl>,
requester: RestApiRequester,
targetQueue: DispatchQueue?
) {
self.client = FogLedger_FogUntrustedTxOutApiRestClient()
self.requester = requester
super.init(config: config, targetQueue: targetQueue)
}
final class FogUntrustedTxOutHttpConnection: ConnectionProtocol, FogUntrustedTxOutService {
func getTxOuts(
request: FogLedger_TxOutRequest,
completion: @escaping (Result<FogLedger_TxOutResponse, ConnectionError>) -> Void
) {
performCall(GetTxOutsCall(client: client, requester: self.requester), request: request, completion: completion)
}
}
extension FogUntrustedTxOutHttpConnection {
private struct GetTxOutsCall: HttpCallable {
let client: FogLedger_FogUntrustedTxOutApiRestClient
let requester: RestApiRequester
func call(
request: FogLedger_TxOutRequest,
callOptions: HTTPCallOptions?,
completion: @escaping (HttpCallResult<FogLedger_TxOutResponse>) -> Void
) {
let unaryCall = client.getTxOuts(request, callOptions: callOptions)
requester.makeRequest(call: unaryCall, completion: completion)
}
}
func setAuthorization(credentials: BasicCredentials) {
}
}

View File

@ -6,58 +6,23 @@ import Foundation
import LibMobileCoin
final class FogViewHttpConnection: AttestedHttpConnection, FogViewService {
private let client: AuthHttpCallableClientWrapper<FogView_FogViewAPIRestClient>
private let requester : RestApiRequester
init(
config: AttestedConnectionConfig<FogUrl>,
requester: RestApiRequester,
client: HttpClientWrapper,
targetQueue: DispatchQueue?,
rng: (@convention(c) (UnsafeMutableRawPointer?) -> UInt64)? = securityRNG,
rngContext: Any? = nil
) {
self.requester = requester
self.client = AuthHttpCallableClientWrapper(client: FogView_FogViewAPIRestClient(), requester: self.requester)
super.init(
client: self.client,
requester: self.requester,
config: config,
targetQueue: targetQueue,
rng: rng,
rngContext: rngContext)
super.init(client: client, config: config, targetQueue: targetQueue)
}
func query(
requestAad: FogView_QueryRequestAAD,
request: FogView_QueryRequest,
completion: @escaping (Result<FogView_QueryResponse, ConnectionError>) -> Void
) {
performAttestedCall(
EnclaveRequestCall(client: client, requester:requester),
requestAad: requestAad,
request: request,
completion: completion)
}
}
extension FogViewHttpConnection {
private struct EnclaveRequestCall: AttestedHttpCallable {
typealias InnerRequestAad = FogView_QueryRequestAAD
typealias InnerRequest = FogView_QueryRequest
typealias InnerResponse = FogView_QueryResponse
let client: AuthHttpCallableClientWrapper<FogView_FogViewAPIRestClient>
let requester: RestApiRequester
func call(
request: Attest_Message,
callOptions: HTTPCallOptions?,
completion: @escaping (HttpCallResult<Attest_Message>) -> Void
) {
let clientCall = client.query(request, callOptions: callOptions)
requester.makeRequest(call: clientCall, completion: completion)
}
}
}
extension FogView_FogViewAPIRestClient: AuthHttpCallee, QueryHttpCallee, HTTPClient {}

View File

@ -1,90 +0,0 @@
//
// DO NOT EDIT.
//
// Generated by the protocol buffer compiler.
// Source: attest.proto
//
// swiftlint:disable all
//
// Copyright 2018, gRPC Authors All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
import NIO
import SwiftProtobuf
import LibMobileCoin
//// A server-authenticated service for SGX enclaves. The responder is the
//// attesting enclave, and the client is unauthenticated. When described
//// within the noise protocol, this is similar to the "IX" style key exchange:
////
//// ```txt
//// IX:
//// -> e, s
//// <- e, ee, se, s, es
//// ->
//// <-
//// ```
////
//// The first two messages are contained within the Auth and AuthResponse
///
/// Usage: instantiate `Attest_AttestedApiRestClient`, then call methods of this protocol to make API calls.
public protocol Attest_AttestedApiRestClientProtocol: HTTPClient {
var serviceName: String { get }
func auth(
_ request: Attest_AuthMessage,
callOptions: HTTPCallOptions?
) -> HTTPUnaryCall<Attest_AuthMessage, Attest_AuthMessage>
}
extension Attest_AttestedApiRestClientProtocol {
public var serviceName: String {
return "attest.AttestedApi"
}
//// This API call is made when one enclave wants to start a mutually-
//// authenticated key-exchange session with an enclave.
///
/// - Parameters:
/// - request: Request to send to Auth.
/// - callOptions: Call options.
/// - Returns: A `UnaryCall` with futures for the metadata, status and response.
public func auth(
_ request: Attest_AuthMessage,
callOptions: HTTPCallOptions? = nil
) -> HTTPUnaryCall<Attest_AuthMessage, Attest_AuthMessage> {
return self.makeUnaryCall(
path: "/attest.AttestedApi/Auth",
request: request,
callOptions: callOptions ?? self.defaultHTTPCallOptions
)
}
}
public final class Attest_AttestedApiRestClient: Attest_AttestedApiRestClientProtocol {
public var defaultHTTPCallOptions: HTTPCallOptions
/// Creates a client for the attest.AttestedApi service.
///
/// - Parameters:
/// - defaultHTTPCallOptions: Options to use for each service call if the user doesn't provide them.
public init(
defaultHTTPCallOptions: HTTPCallOptions = HTTPCallOptions()
) {
self.defaultHTTPCallOptions = defaultHTTPCallOptions
}
}

View File

@ -1,59 +0,0 @@
//
// Copyright (c) 2020-2021 MobileCoin. All rights reserved.
//
// swiftlint:disable all
import Foundation
import SwiftProtobuf
import LibMobileCoin
///// Usage: instantiate `ConsensusClient_ConsensusClientAPIRestClient`, then call methods of this protocol to make APIRest calls.
public protocol ConsensusClient_ConsensusClientAPIRestClientProtocol: HTTPClient {
var serviceName: String { get }
func clientTxPropose(
_ request: Attest_Message,
callOptions: HTTPCallOptions?
) -> HTTPUnaryCall<Attest_Message, ConsensusCommon_ProposeTxResponse>
}
extension ConsensusClient_ConsensusClientAPIRestClientProtocol {
public var serviceName: String {
return "consensus_client.ConsensusClientAPI"
}
//// This APIRest call is made with an encrypted payload for the enclave,
//// indicating a new value to be acted upon.
///
/// - Parameters:
/// - request: Request to send to ClientTxPropose.
/// - callOptions: Call options.
/// - Returns: A `HTTPUnaryCall` with futures for the metadata, status and response.
public func clientTxPropose(
_ request: Attest_Message,
callOptions: HTTPCallOptions? = nil
) -> HTTPUnaryCall<Attest_Message, ConsensusCommon_ProposeTxResponse> {
return self.makeUnaryCall(
path: "/consensus_client.ConsensusClientAPI/ClientTxPropose",
request: request,
callOptions: callOptions ?? self.defaultHTTPCallOptions
)
}
}
public final class ConsensusClient_ConsensusClientAPIRestClient: ConsensusClient_ConsensusClientAPIRestClientProtocol {
public var defaultHTTPCallOptions: HTTPCallOptions
/// Creates a client for the consensus_client.ConsensusClientAPIRest service.
///
/// - Parameters:
/// - channel: `HTTPChannel` to the service host.
/// - defaultHTTPCallOptions: Options to use for each service call if the user doesn't provide them.
/// - interceptors: A factory providing interceptors for each RPC.
public init(
defaultHTTPCallOptions: HTTPCallOptions = HTTPCallOptions()
) {
self.defaultHTTPCallOptions = defaultHTTPCallOptions
}
}

View File

@ -1,84 +0,0 @@
//
// Copyright (c) 2020-2021 MobileCoin. All rights reserved.
//
// swiftlint:disable all
import Foundation
import NIO
import SwiftProtobuf
import LibMobileCoin
//// Blockchain APIRest shared between clients and peers.
///
/// Usage: instantiate `ConsensusCommon_BlockchainAPIRestClient`, then call methods of this protocol to make APIRest calls.
public protocol ConsensusCommon_BlockchainAPIRestClientProtocol: HTTPClient {
var serviceName: String { get }
func getLastBlockInfo(
_ request: SwiftProtobuf.Google_Protobuf_Empty,
callOptions: HTTPCallOptions?
) -> HTTPUnaryCall<SwiftProtobuf.Google_Protobuf_Empty, ConsensusCommon_LastBlockInfoResponse>
func getBlocks(
_ request: ConsensusCommon_BlocksRequest,
callOptions: HTTPCallOptions?
) ->HTTPUnaryCall<ConsensusCommon_BlocksRequest, ConsensusCommon_BlocksResponse>
}
extension ConsensusCommon_BlockchainAPIRestClientProtocol {
public var serviceName: String {
return "consensus_common.BlockchainAPI"
}
/// Unary call to GetLastBlockInfo
///
/// - Parameters:
/// - request: Request to send to GetLastBlockInfo.
/// - callOptions: Call options.
/// - Returns: A `UnaryCall` with futures for the metadata, status and response.
public func getLastBlockInfo(
_ request: SwiftProtobuf.Google_Protobuf_Empty,
callOptions: HTTPCallOptions? = nil
) ->HTTPUnaryCall<SwiftProtobuf.Google_Protobuf_Empty, ConsensusCommon_LastBlockInfoResponse> {
return self.makeUnaryCall(
path: "/consensus_common.BlockchainAPI/GetLastBlockInfo",
request: request,
callOptions: callOptions ?? self.defaultHTTPCallOptions
)
}
/// Unary call to GetBlocks
///
/// - Parameters:
/// - request: Request to send to GetBlocks.
/// - callOptions: Call options.
/// - Returns: A `UnaryCall` with futures for the metadata, status and response.
public func getBlocks(
_ request: ConsensusCommon_BlocksRequest,
callOptions: HTTPCallOptions? = nil
) ->HTTPUnaryCall<ConsensusCommon_BlocksRequest, ConsensusCommon_BlocksResponse> {
return self.makeUnaryCall(
path: "/consensus_common.BlockchainAPI/GetBlocks",
request: request,
callOptions: callOptions ?? self.defaultHTTPCallOptions
)
}
}
public final class ConsensusCommon_BlockchainAPIRestClient: ConsensusCommon_BlockchainAPIRestClientProtocol {
public var defaultHTTPCallOptions: HTTPCallOptions
/// Creates a client for the consensus_common.BlockchainAPIRest service.
///
/// - Parameters:
/// - channel: `GRPCChannel` to the service host.
/// - defaultHTTPCallOptions: Options to use for each service call if the user doesn't provide them.
/// - interceptors: A factory providing interceptors for each RPC.
public init(
defaultHTTPCallOptions: HTTPCallOptions = HTTPCallOptions()
) {
self.defaultHTTPCallOptions = defaultHTTPCallOptions
}
}

View File

@ -1,276 +0,0 @@
//
// DO NOT EDIT.
//
// Generated by the protocol buffer compiler.
// Source: ledger.proto
//
// swiftlint:disable all
//
// Copyright 2018, gRPC Authors All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
import SwiftProtobuf
import LibMobileCoin
/// Usage: instantiate `FogLedger_FogMerkleProofAPIRestClient`, then call methods of this protocol to make API calls.
public protocol FogLedger_FogMerkleProofAPIRestClientProtocol: HTTPClient {
var serviceName: String { get }
func auth(
_ request: Attest_AuthMessage,
callOptions: HTTPCallOptions?
) -> HTTPUnaryCall<Attest_AuthMessage, Attest_AuthMessage>
func getOutputs(
_ request: Attest_Message,
callOptions: HTTPCallOptions?
) -> HTTPUnaryCall<Attest_Message, Attest_Message>
}
extension FogLedger_FogMerkleProofAPIRestClientProtocol {
public var serviceName: String {
return "fog_ledger.FogMerkleProofAPI"
}
//// This is called to perform mc-noise IX key exchange with the enclave,
//// before calling GetOutputs.
///
/// - Parameters:
/// - request: Request to send to Auth.
/// - callOptions: Call options.
/// - Returns: A `UnaryCall` with futures for the metadata, status and response.
public func auth(
_ request: Attest_AuthMessage,
callOptions: HTTPCallOptions? = nil
) -> HTTPUnaryCall<Attest_AuthMessage, Attest_AuthMessage> {
return self.makeUnaryCall(
path: "/fog_ledger.FogMerkleProofAPI/Auth",
request: request,
callOptions: callOptions ?? self.defaultHTTPCallOptions
)
}
//// Get TxOut's and merkle proofs of membership for these outputs
//// These requests can be the user's "real" outputs from fog view, in order
//// to get the needed merkle proof, or their mixins for RingCT.
///
/// - Parameters:
/// - request: Request to send to GetOutputs.
/// - callOptions: Call options.
/// - Returns: A `UnaryCall` with futures for the metadata, status and response.
public func getOutputs(
_ request: Attest_Message,
callOptions: HTTPCallOptions? = nil
) -> HTTPUnaryCall<Attest_Message, Attest_Message> {
return self.makeUnaryCall(
path: "/fog_ledger.FogMerkleProofAPI/GetOutputs",
request: request,
callOptions: callOptions ?? self.defaultHTTPCallOptions
)
}
}
public final class FogLedger_FogMerkleProofAPIRestClient: FogLedger_FogMerkleProofAPIRestClientProtocol {
public var defaultHTTPCallOptions: HTTPCallOptions
/// Creates a client for the fog_ledger.FogMerkleProofAPI service.
///
/// - Parameters:
/// - defaultHTTPCallOptions: Options to use for each service call if the user doesn't provide them.
public init(
defaultHTTPCallOptions: HTTPCallOptions = HTTPCallOptions()
) {
self.defaultHTTPCallOptions = defaultHTTPCallOptions
}
}
/// Usage: instantiate `FogLedger_FogKeyImageAPIRestClient`, then call methods of this protocol to make API calls.
public protocol FogLedger_FogKeyImageAPIRestClientProtocol: HTTPClient {
var serviceName: String { get }
func auth(
_ request: Attest_AuthMessage,
callOptions: HTTPCallOptions?
) -> HTTPUnaryCall<Attest_AuthMessage, Attest_AuthMessage>
func checkKeyImages(
_ request: Attest_Message,
callOptions: HTTPCallOptions?
) -> HTTPUnaryCall<Attest_Message, Attest_Message>
}
extension FogLedger_FogKeyImageAPIRestClientProtocol {
public var serviceName: String {
return "fog_ledger.FogKeyImageAPI"
}
//// This is called to perform IX key exchange with the enclave before calling GetOutputs.
///
/// - Parameters:
/// - request: Request to send to Auth.
/// - callOptions: Call options.
/// - Returns: A `UnaryCall` with futures for the metadata, status and response.
public func auth(
_ request: Attest_AuthMessage,
callOptions: HTTPCallOptions? = nil
) -> HTTPUnaryCall<Attest_AuthMessage, Attest_AuthMessage> {
return self.makeUnaryCall(
path: "/fog_ledger.FogKeyImageAPI/Auth",
request: request,
callOptions: callOptions ?? self.defaultHTTPCallOptions
)
}
//// Check if key images have appeared in the ledger, and if so, when
///
/// - Parameters:
/// - request: Request to send to CheckKeyImages.
/// - callOptions: Call options.
/// - Returns: A `UnaryCall` with futures for the metadata, status and response.
public func checkKeyImages(
_ request: Attest_Message,
callOptions: HTTPCallOptions? = nil
) -> HTTPUnaryCall<Attest_Message, Attest_Message> {
return self.makeUnaryCall(
path: "/fog_ledger.FogKeyImageAPI/CheckKeyImages",
request: request,
callOptions: callOptions ?? self.defaultHTTPCallOptions
)
}
}
public final class FogLedger_FogKeyImageAPIRestClient: FogLedger_FogKeyImageAPIRestClientProtocol {
public var defaultHTTPCallOptions: HTTPCallOptions
/// Creates a client for the fog_ledger.FogKeyImageAPI service.
///
/// - Parameters:
/// - defaultHTTPCallOptions: Options to use for each service call if the user doesn't provide them.
public init(
defaultHTTPCallOptions: HTTPCallOptions = HTTPCallOptions()
) {
self.defaultHTTPCallOptions = defaultHTTPCallOptions
}
}
/// Usage: instantiate `FogLedger_FogBlockAPIRestClient`, then call methods of this protocol to make API calls.
public protocol FogLedger_FogBlockAPIRestClientProtocol: HTTPClient {
var serviceName: String { get }
func getBlocks(
_ request: FogLedger_BlockRequest,
callOptions: HTTPCallOptions?
) -> HTTPUnaryCall<FogLedger_BlockRequest, FogLedger_BlockResponse>
}
extension FogLedger_FogBlockAPIRestClientProtocol {
public var serviceName: String {
return "fog_ledger.FogBlockAPI"
}
//// Request for all of the TxOuts for a particular range of blocks.
//// This is meant to help the users recover from "missed blocks" i.e.
//// data loss in the fog service.
///
/// - Parameters:
/// - request: Request to send to GetBlocks.
/// - callOptions: Call options.
/// - Returns: A `UnaryCall` with futures for the metadata, status and response.
public func getBlocks(
_ request: FogLedger_BlockRequest,
callOptions: HTTPCallOptions? = nil
) -> HTTPUnaryCall<FogLedger_BlockRequest, FogLedger_BlockResponse> {
return self.makeUnaryCall(
path: "/fog_ledger.FogBlockAPI/GetBlocks",
request: request,
callOptions: callOptions ?? self.defaultHTTPCallOptions
)
}
}
public final class FogLedger_FogBlockAPIRestClient: FogLedger_FogBlockAPIRestClientProtocol {
public var defaultHTTPCallOptions: HTTPCallOptions
/// Creates a client for the fog_ledger.FogBlockAPI service.
///
/// - Parameters:
/// - defaultHTTPCallOptions: Options to use for each service call if the user doesn't provide them.
public init(
defaultHTTPCallOptions: HTTPCallOptions = HTTPCallOptions()
) {
self.defaultHTTPCallOptions = defaultHTTPCallOptions
}
}
/// Usage: instantiate `FogLedger_FogUntrustedTxOutApiRestClient`, then call methods of this protocol to make API calls.
public protocol FogLedger_FogUntrustedTxOutApiRestClientProtocol: HTTPClient {
var serviceName: String { get }
func getTxOuts(
_ request: FogLedger_TxOutRequest,
callOptions: HTTPCallOptions?
) -> HTTPUnaryCall<FogLedger_TxOutRequest, FogLedger_TxOutResponse>
}
extension FogLedger_FogUntrustedTxOutApiRestClientProtocol {
public var serviceName: String {
return "fog_ledger.FogUntrustedTxOutApi"
}
//// This can be used by a sender who may be sharing their private keys across
//// multiple parties / devices, to confirm that a transaction that they sent
//// landed in the blockchain, by confirming that one of the random keys from
//// a TxOut that they produced appears in the ledger.
////
//// Given the TxOut.pubkey value, we return if it is found, and the num_blocks
//// value, allowing Alice to determine that her transactions succeeded, or if
//// num_blocks exceeded her tombstone value, conclude that it failed somehow.
//// We also return the global tx out index. We don't currently return the block
//// index or time stamp in which the TxOut appeared.
////
//// This API is NOT attested and Bob, the recipient, SHOULD NOT use it in connection
//// to the same TxOut, as that will leak the transaction graph to fog operator,
//// which breaks the privacy statement for fog as a whole.
///
/// - Parameters:
/// - request: Request to send to GetTxOuts.
/// - callOptions: Call options.
/// - Returns: A `UnaryCall` with futures for the metadata, status and response.
public func getTxOuts(
_ request: FogLedger_TxOutRequest,
callOptions: HTTPCallOptions? = nil
) -> HTTPUnaryCall<FogLedger_TxOutRequest, FogLedger_TxOutResponse> {
return self.makeUnaryCall(
path: "/fog_ledger.FogUntrustedTxOutApi/GetTxOuts",
request: request,
callOptions: callOptions ?? self.defaultHTTPCallOptions
)
}
}
public final class FogLedger_FogUntrustedTxOutApiRestClient: FogLedger_FogUntrustedTxOutApiRestClientProtocol {
public var defaultHTTPCallOptions: HTTPCallOptions
/// Creates a client for the fog_ledger.FogUntrustedTxOutApi service.
///
/// - Parameters:
/// - defaultHTTPCallOptions: Options to use for each service call if the user doesn't provide them.
public init(
defaultHTTPCallOptions: HTTPCallOptions = HTTPCallOptions()
) {
self.defaultHTTPCallOptions = defaultHTTPCallOptions
}
}

View File

@ -1,78 +0,0 @@
//
// DO NOT EDIT.
//
// Generated by the protocol buffer compiler.
// Source: report.proto
//
// swiftlint:disable all
//
// Copyright 2018, gRPC Authors All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
import NIO
import SwiftProtobuf
import LibMobileCoin
//// The public API for getting reports
///
/// Usage: instantiate `Report_ReportAPIRestClient`, then call methods of this protocol to make API calls.
public protocol Report_ReportAPIRestClientProtocol: HTTPClient {
var serviceName: String { get }
func getReports(
_ request: Report_ReportRequest,
callOptions: HTTPCallOptions?
) -> HTTPUnaryCall<Report_ReportRequest, Report_ReportResponse>
}
extension Report_ReportAPIRestClientProtocol {
public var serviceName: String {
return "report.ReportAPI"
}
//// Get all available pubkeys, with Intel SGX reports, fog urls, and expiry info
///
/// - Parameters:
/// - request: Request to send to GetReports.
/// - callOptions: Call options.
/// - Returns: A `UnaryCall` with futures for the metadata, status and response.
public func getReports(
_ request: Report_ReportRequest,
callOptions: HTTPCallOptions? = nil
) -> HTTPUnaryCall<Report_ReportRequest, Report_ReportResponse> {
return self.makeUnaryCall(
path: "/report.ReportAPI/GetReports",
request: request,
callOptions: callOptions ?? self.defaultHTTPCallOptions
)
}
}
public final class Report_ReportAPIRestClient: Report_ReportAPIRestClientProtocol {
public var defaultHTTPCallOptions: HTTPCallOptions
/// Creates a client for the report.ReportAPI service.
///
/// - Parameters:
/// - channel: `GRPCChannel` to the service host.
/// - defaultHTTPCallOptions: Options to use for each service call if the user doesn't provide them.
public init(
defaultHTTPCallOptions: HTTPCallOptions = HTTPCallOptions()
) {
self.defaultHTTPCallOptions = defaultHTTPCallOptions
}
}

View File

@ -1,96 +0,0 @@
//
// DO NOT EDIT.
//
// Generated by the protocol buffer compiler.
// Source: view.proto
//
// swiftlint:disable all
//
// Copyright 2018, gRPC Authors All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
import SwiftProtobuf
import LibMobileCoin
/// Usage: instantiate `FogView_FogViewAPIRestClient`, then call methods of this protocol to make API calls.
public protocol FogView_FogViewAPIRestClientProtocol: HTTPClient {
var serviceName: String { get }
func auth(
_ request: Attest_AuthMessage,
callOptions: HTTPCallOptions?
) -> HTTPUnaryCall<Attest_AuthMessage, Attest_AuthMessage>
func query(
_ request: Attest_Message,
callOptions: HTTPCallOptions?
) -> HTTPUnaryCall<Attest_Message, Attest_Message>
}
extension FogView_FogViewAPIRestClientProtocol {
public var serviceName: String {
return "fog_view.FogViewAPI"
}
//// This is called to perform IX key exchange with the enclave before calling GetOutputs.
///
/// - Parameters:
/// - request: Request to send to Auth.
/// - callOptions: Call options.
/// - Returns: A `UnaryCall` with futures for the metadata, status and response.
public func auth(
_ request: Attest_AuthMessage,
callOptions: HTTPCallOptions? = nil
) -> HTTPUnaryCall<Attest_AuthMessage, Attest_AuthMessage> {
return self.makeUnaryCall(
path: "/fog_view.FogViewAPI/Auth",
request: request,
callOptions: callOptions ?? self.defaultHTTPCallOptions
)
}
//// Input should be an encrypted QueryRequest, result is an encrypted QueryResponse
///
/// - Parameters:
/// - request: Request to send to Query.
/// - callOptions: Call options.
/// - Returns: A `UnaryCall` with futures for the metadata, status and response.
public func query(
_ request: Attest_Message,
callOptions: HTTPCallOptions? = nil
) -> HTTPUnaryCall<Attest_Message, Attest_Message> {
return self.makeUnaryCall(
path: "/fog_view.FogViewAPI/Query",
request: request,
callOptions: callOptions ?? self.defaultHTTPCallOptions
)
}
}
public final class FogView_FogViewAPIRestClient: FogView_FogViewAPIRestClientProtocol {
public var defaultHTTPCallOptions: HTTPCallOptions
/// Creates a client for the fog_view.FogViewAPI service.
///
/// - Parameters:
/// - defaultHTTPCallOptions: Options to use for each service call if the user doesn't provide them.
public init(
defaultHTTPCallOptions: HTTPCallOptions = HTTPCallOptions()
) {
self.defaultHTTPCallOptions = defaultHTTPCallOptions
}
}

View File

@ -2,11 +2,9 @@
// Copyright (c) 2020-2021 MobileCoin. All rights reserved.
//
// swiftlint:disable all
// swiftlint:disable multiline_parameters_brackets
import Foundation
import SwiftProtobuf
import NIOSSL
public protocol HttpRequester {
func request(
@ -14,98 +12,32 @@ public protocol HttpRequester {
method: HTTPMethod,
headers: [String: String]?,
body: Data?,
completion: @escaping (Result<HTTPResponse, Error>) -> Void)
completion: @escaping (HTTPResult) -> Void)
}
public class RestApiRequester {
let requester: HttpRequester
let baseUrl: URL
let trustRoots: [NIOSSLCertificate]?
let prefix: String = "gw"
var challengeDelegate: URLSessionDelegate?
public enum HTTPMethod {
case get
case post
case put
case head
case patch
case delete
}
init(requester: HttpRequester, baseUrl: URL, trustRoots: [NIOSSLCertificate]? = []) {
self.requester = requester
self.baseUrl = baseUrl
self.trustRoots = trustRoots
public struct HTTPResponse {
public let httpUrlResponse: HTTPURLResponse
public let responseData: Data?
public var statusCode: Int {
httpUrlResponse.statusCode
}
public var allHeaderFields: [AnyHashable: Any] {
httpUrlResponse.allHeaderFields
}
}
protocol Requester {
func makeRequest<T: HTTPClientCall>(call: T, completion: @escaping (HttpCallResult<T.ResponsePayload>) -> Void)
}
extension RestApiRequester : Requester {
private func completeURL(path: String) -> URL? {
.prefix(baseUrl, pathComponents:[prefix, path])
}
public func makeRequest<T: HTTPClientCall>(call: T, completion: @escaping (HttpCallResult<T.ResponsePayload>) -> Void) {
guard let url = completeURL(path: call.path) else {
completion(HttpCallResult(status: HTTPStatus(code: 1, message: "could not construct URL")))
return
}
var request = URLRequest(url: url.absoluteURL)
request.addProtoHeaders()
request.addHeaders(call.options?.headers ?? [:])
do {
request.httpBody = try call.requestPayload?.serializedData()
} catch let error {
completion(HttpCallResult(status: HTTPStatus(code: 1, message: error.localizedDescription)))
}
requester.request(url: url, method: call.method, headers: request.allHTTPHeaderFields, body: request.httpBody) { result in
switch result {
case .failure(let error):
completion(HttpCallResult(status: HTTPStatus(code: 1, message: error.localizedDescription)))
case .success(let httpResponse):
let response = httpResponse.httpUrlResponse
logger.info("Http Request url: \(url)")
logger.info("Status code: \(response.statusCode)")
let responsePayload : T.ResponsePayload? = {
guard let data = httpResponse.responseData,
let responsePayload = try? T.ResponsePayload.init(serializedData: data)
else {
return nil
}
return responsePayload
}()
let result = HttpCallResult(status: HTTPStatus(code: response.statusCode, message: ""), metadata: response, response: responsePayload)
completion(result)
}
}
}
}
fileprivate extension URL {
static func prefix(_ url: URL, pathComponents: [String]) -> URL? {
let prunedComponents = pathComponents.map({ $0.hasPrefix("/") ? String($0.dropFirst()) : $0})
var components = URLComponents()
components.scheme = url.scheme
components.host = url.host
components.path = "/" + (url.pathComponents + prunedComponents).joined(separator: "/")
return components.url
}
}
fileprivate extension URLRequest {
mutating func addProtoHeaders() {
let contentType = (fieldName:"Content-Type", value:"application/x-protobuf")
self.setValue(contentType.value, forHTTPHeaderField: contentType.fieldName)
let accept = (fieldName:"Accept", value:"application/x-protobuf")
self.addValue(accept.value, forHTTPHeaderField: accept.fieldName)
}
mutating func addHeaders(_ headers: [String:String]) {
headers.forEach { headerFieldName, value in
self.setValue(value, forHTTPHeaderField: headerFieldName)
}
}
public enum HTTPResult {
case success(response: HTTPResponse)
case failure(error: Error)
}

View File

@ -30,7 +30,7 @@ struct NetworkConfig {
var fogUserAuthorization: BasicCredentials?
var httpRequester: HttpRequester?
init(consensusUrl: ConsensusUrl, fogUrl: FogUrl, attestation: AttestationConfig) {
self.consensusUrl = consensusUrl
self.fogUrl = fogUrl

View File

@ -18,18 +18,16 @@ final class DefaultServiceProvider: ServiceProvider {
init(networkConfig: NetworkConfig, targetQueue: DispatchQueue?) {
let channelManager = GrpcChannelManager()
let inner = Inner(channelManager: channelManager, httpRequester: networkConfig.httpRequester, targetQueue: targetQueue)
let inner = Inner(channelManager: channelManager, targetQueue: targetQueue)
self.inner = .init(inner, targetQueue: targetQueue)
self.consensus = ConsensusConnection(
config: networkConfig.consensus,
channelManager: channelManager,
httpRequester: networkConfig.httpRequester,
targetQueue: targetQueue)
self.blockchain = BlockchainConnection(
config: networkConfig.blockchain,
channelManager: channelManager,
httpRequester: networkConfig.httpRequester,
targetQueue: targetQueue)
self.view = FogViewConnection(
config: networkConfig.fogView,
@ -39,22 +37,18 @@ final class DefaultServiceProvider: ServiceProvider {
self.merkleProof = FogMerkleProofConnection(
config: networkConfig.fogMerkleProof,
channelManager: channelManager,
httpRequester: networkConfig.httpRequester,
targetQueue: targetQueue)
self.keyImage = FogKeyImageConnection(
config: networkConfig.fogKeyImage,
channelManager: channelManager,
httpRequester: networkConfig.httpRequester,
targetQueue: targetQueue)
self.block = FogBlockConnection(
config: networkConfig.fogBlock,
channelManager: channelManager,
httpRequester: networkConfig.httpRequester,
targetQueue: targetQueue)
self.untrustedTxOut = FogUntrustedTxOutConnection(
config: networkConfig.fogUntrustedTxOut,
channelManager: channelManager,
httpRequester: networkConfig.httpRequester,
targetQueue: targetQueue)
}
@ -100,19 +94,16 @@ final class DefaultServiceProvider: ServiceProvider {
}
}
// TODO
extension DefaultServiceProvider {
private struct Inner {
private let targetQueue: DispatchQueue?
private let channelManager: GrpcChannelManager
private let httpRequester: HttpRequester?
private var reportUrlToReportConnection: [GrpcChannelConfig: FogReportConnection] = [:]
private(set) var transportProtocolOption: TransportProtocol.Option
init(channelManager: GrpcChannelManager, httpRequester: HttpRequester?, targetQueue: DispatchQueue?) {
init(channelManager: GrpcChannelManager, targetQueue: DispatchQueue?) {
self.targetQueue = targetQueue
self.httpRequester = httpRequester
self.channelManager = channelManager
self.transportProtocolOption = TransportProtocol.grpc.option
}
@ -124,7 +115,6 @@ extension DefaultServiceProvider {
url: fogReportUrl,
transportProtocolOption: transportProtocolOption,
channelManager: channelManager,
httpRequester: httpRequester,
targetQueue: targetQueue)
reportUrlToReportConnection[config] = reportConnection
return reportConnection

View File

@ -1,5 +1,4 @@
//
// Copyright (c) 2020-2021 MobileCoin. All rights reserved.
//
@ -79,6 +78,7 @@ public struct Receipt {
func unmaskValue(accountKey: AccountKey) -> Result<UInt64, InvalidInputError> {
guard let value = TxOutUtils.value(
commitment: commitment,
maskedValue: maskedValue,
publicKey: txOutPublicKeyTyped,
viewPrivateKey: accountKey.viewPrivateKey)
@ -103,6 +103,7 @@ public struct Receipt {
}
guard let value = TxOutUtils.value(
commitment: commitment,
maskedValue: maskedValue,
publicKey: txOutPublicKeyTyped,
viewPrivateKey: accountKey.viewPrivateKey)
@ -112,7 +113,7 @@ public struct Receipt {
return value
}
enum ReceivedStatus {
case notReceived(knownToBeNotReceivedBlockCount: UInt64?)
case received(block: BlockMetadata)

View File

@ -59,8 +59,6 @@ struct TransactionSubmitter {
return .failure(.feeError())
case .tombstoneBlockTooFar:
return .failure(.tombstoneBlockTooFar())
case .missingMemo:
return .failure(.missingMemo("Missing memo"))
case .containsSpentKeyImage, .containsExistingOutputPublicKey:
// This exact Tx might have already been submitted (and succeeded), or else the
// inputs were already spent by another Tx.

View File

@ -1,24 +0,0 @@
//
// Copyright (c) 2020-2021 MobileCoin. All rights reserved.
//
import Foundation
import GRPC
import NIO
import NIOHPACK
public struct HttpCallResult<ResponsePayload> {
let status: HTTPStatus
let metadata: HTTPURLResponse?
let response: ResponsePayload?
}
extension HttpCallResult {
init(
status: HTTPStatus
) {
self.init(status: status, metadata: nil, response: nil)
}
}

View File

@ -1,18 +0,0 @@
//
// Copyright (c) 2020-2021 MobileCoin. All rights reserved.
//
#ifndef MobileCoin_Bridging_Header_h
#define MobileCoin_Bridging_Header_h
#endif /* MobileCoin_Bridging_Header_h */
#ifndef TestBridgingHeader_h
#define TestBridgingHeader_h
#endif /* TestBridgingHeader_h */
#include "TestBridgingHeader.h"

View File

@ -1,11 +0,0 @@
//
// Copyright (c) 2020-2021 MobileCoin. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface TestBridgingHeader : NSObject
- (id)init;
@end

View File

@ -1,16 +0,0 @@
//
// Copyright (c) 2020-2021 MobileCoin. All rights reserved.
//
#import <Foundation/Foundation.h>
#include "TestBridgingHeader.h"
@implementation TestBridgingHeader
- (id)init
{
return self;
}
@end

View File

@ -1,132 +1,190 @@
# **TERMS OF USE** **FOR MOBILECOINS AND MOBILECOIN WALLETS**
**MobileCoins are not offered or sold to U.S. Persons or entities or other Prohibited Persons regardless of their location. Purchasers of MobileCoins may not transact, transfers, or trade MobileCoins in the United States or with U.S. Persons or entities, or persons or entities present in the United States.**
The MobileCoin Network uses an open source software protocol commonly known as the MobileCoin protocol. The MobileCoin protocol is designed to enable holders of digital tokens known as MobileCoins to send and receive peer-to-peer payments securely and privately through a digital wallet that can send and receive MobileCoins (MobileCoin Wallets). MobileCoins and MobileCoin Wallets enable a simple, secure, and private medium of exchange for consumers in countries of operation to manage and move their money using a currency of equivalent value across countries.
# TERMS OF USE FOR MOBILECOINS AND MOBILECOIN WALLETS
The MobileCoin Network operates utilizing an open source software protocol commonly known as the MobileCoin protocol. The MobileCoin protocol is designed to enable holders of digital tokens known as MobileCoins to send and receive peer-to-peer payments securely and privately through a digital wallet that is capable of sending and receiving MobileCoins (MobileCoin Wallets). MobileCoins enable a simple, secure, and private medium of exchange for consumers in countries of operation to manage and move their money using personal mobile devices and a currency of equivalent value across countries.
These Terms of Use for MobileCoins and MobileCoin Wallets (Terms) govern:
- MobileCoins and their use and transfer; and
- MobileCoin Wallets and their access and use.
Please read these Terms carefully before you start to use any MobileCoins and any MobileCoin Wallet. By acquiring or otherwise obtaining MobileCoins, using or transferring MobileCoins or obtaining, accessing or using a MobileCoin Wallet, you acknowledge that you have read, understand, and completely agree to be bound by these Terms. You also agree to require any transferee of your MobileCoins and any holder of a MobileCoin Wallet facilitated by you to be subject to these Terms. These Terms may be enforced against you by MobileCoin TS Ltd., MobileCoin U.S., LLC or other authorized entities (which are collectively referred to in these Terms as the Compliance Entities). These Terms may be amended, changed, or updated by the Compliance Entities at any time and without prior notice to you by posting at [www.buymobilecoin.us](https://www.buymobilecoin.us/). Your continued use of any MobileCoins and any MobileCoin Wallets following the posting of any amendment, change, or update means that you accept and agree to the amended, changed, or updated Terms. These Terms are first effective as of August 17, 2021 and supersede any previous versions.
Please read these Terms carefully before you start to use any MobileCoins and any MobileCoin Wallet. By acquiring or otherwise obtaining MobileCoins, using or transferring MobileCoins or obtaining, accessing or using a MobileCoin Wallet, you acknowledge that you have read, understand, and completely agree to be bound by these Terms. You also agree to require any transferee of your MobileCoins and any holder of a MobileCoin Wallet facilitated by you to be subject to these Terms. These Terms may be enforced against you by MobileCoin TS Ltd. or other authorized entities (which are collectively referred to in these Terms as the Compliance Entities). These Terms may be amended, changed, or updated by the Compliance Entities at any time and without prior notice to you by posting at the MobileCoin TS Ltd. Website at http://www.buymobilecoin.com/. Your continued use of any MobileCoins and any MobileCoin Wallets following the posting of any amendment, change, or update means that you accept and agree to the amended, changed, or updated Terms. These Terms are first effective as of November 23, 2020.
Access or use of any MobileCoin Wallets or use or transfer of any MobileCoins is void where such access, use or transfer is prohibited by, would constitute a violation of, or would be subject to penalties under applicable laws. Such access or use of MobileCoin Wallets or use or transfer of any MobileCoins which is void will not be the basis for the assertion or recognition of any interest, right, remedy, power, or privilege. \[Please also consult the applicable Terms of Sale and Access and Use of the Site, available at the MobileCoin U.S. LLC website at [www.buymobilecoin.us](https://www.buymobilecoin.us/) or the MobileCoin TS Ltd. website at [www.buymobilecoin.com](https://www.buymobilecoin.com). Information on the way personal information is handled is included in the appropriate Privacy Policy, available at [www.buymobilecoin.us](https://www.buymobilecoin.us/) or [www.buymobilecoin.com](https://www.buymobilecoin.com/).\]
Access or use of any MobileCoin Wallets or use or transfer of any MobileCoins is void where such access, use or transfer is prohibited by, would constitute a violation of, or would be subject to penalties under applicable laws, and will not be the basis for the assertion or recognition of any interest, right, remedy, power, or privilege. Please also consult the Terms of Sale and Access and Use of the Site, available at the MobileCoin TS Ltd. website at http://www.buymobilecoin.com/. Information on the way personal information is handled is included in the Privacy Policy, available at http://www.buymobilecoin.com/.
## **Limitations on Access or Use of MobileCoin Wallets and Use and Transfer of MobileCoins**
## Limitations on Access or Use of MobileCoin Wallets and Use and Transfer of MobileCoins
The right to access or use MobileCoin Wallets and use or transfer MobileCoins is a personal, restricted, non-exclusive, non-sublicensable, revocable, limited license, and it is subject to the limitations and obligations in these Terms. Every Prohibited Person is strictly prohibited from directly or indirectly transacting, transferring, holding, owning, accessing or using any MobileCoins and any MobileCoin Wallets in any way.
You are a Prohibited Person if you are:
The right to access or use MobileCoin Wallets and use or transfer MobileCoins is a personal, restricted, non-exclusive, non-transferable, non-sublicensable, revocable, limited license, and it is subject to the limitations and obligations in these Terms. Every **Prohibited Person** and **U.S. Person** is strictly prohibited from directly or indirectly transacting, transferring, holding, owning, accessing or using any MobileCoins and any MobileCoin Wallets in any way.
You are a **Prohibited Person** if you are:
1. an individual or entity present in or subject to the jurisdiction of any jurisdiction in which the distribution or offer of or transaction in MobileCoins is unlawful or who is restricted or prohibited by applicable law, including without limitation, anti-money laundering laws, counter-terrorist financing laws, anti-corruption laws, and economic sanctions laws, from purchasing or otherwise obtaining MobileCoins or transacting in MobileCoins;
2. an individual or entity present in or subject to the jurisdiction of Cuba, Democratic People&#39;s Republic of Korea (North Korea), Iran, Syria or Crimea (a region of Ukraine annexed by the Russian Federation) (a Prohibited Jurisdiction);
3. a government or government official of any Prohibited Jurisdiction or of Venezuela or any subdivision thereof;
4. an individual or entity subject to asset freezing or blocking sanctions imposed by the United Nations, British Virgin Islands, United Kingdom, European Union, or United States or any entity owned 50 percent or more by one or more such persons (a Sanctioned Person);
2. an individual or entity present in or subject to the jurisdiction of Cuba, Democratic Peoples Republic of Korea (North Korea), Iran, Syria or Crimea (a region of Ukraine annexed by the Russian Federation) (a Prohibited Jurisdiction);
3. a government or government official of any Prohibited Jurisdiction or of Venezuela or any subdivision thereof;
4. an individual or entity subject to asset freezing or blocking sanctions imposed by the United Nations, British Virgin Islands, United Kingdom, European Union, or United States or any entity owned 50 percent or more by one or more such persons (a Sanctioned Person);
5. a person under 18 years of age; or
6. any other individual or entity whose dealings in MobileCoins or use of a MobileCoin Wallet could expose the Compliance Entities to civil or criminal liability or cause the Compliance Entities to engage in sanctionable conduct.
## **MobileCoin Wallets**
You are a **“U.S. Person”** if you are:
1. (i) a U.S. citizen, (ii) a U.S. lawful permanent resident, protected individual or asylee under the U.S. Immigration and Nationality Act, (iii) an individual present in the U.S. in a non-immigrant status which carries an allowable admission period exceeding 6 months, (iv) an individual or entity present in the U.S., or (v) an individual or entity acting for the financial or other benefit of or on behalf of any U.S. Person;
No MobileCoin Wallet may be operated for and no order or transaction in a MobileCoin Wallet may be used for the financial or other benefit of or on behalf of a Prohibited Person. Persons, whether or not Prohibited Persons, are prohibited from operating a MobileCoin Wallet in any way or otherwise transacting on or using any MobileCoins and any MobileCoin Wallets while they or any individual (including any fiduciary, dealer, trustee, executor or administrator), agency or branch operating their MobileCoin Wallet on their behalf is present in any jurisdiction in which MobileCoins are unlawful.
2. a corporation, partnership, or other entity established or organized in or under the laws of the United States;
Certain software comprising MobileCoin Wallets is available to the public without charge on an open source basis. This software is provided &quot;as is&quot; without warranty of any kind. However, MobileCoin Wallets linked to a mobile messaging application may integrate software from a third party. MobileCoin Wallets must be accessed through a telephone, computer or other equipment as well as a network connection through telecommunication lines or other utility. None of these components of the MobileCoin Wallet is provided or controlled by the Compliance Entities. The Compliance Entities are not responsible for the accuracy or reliability of any open-source software or of any software, hardware, information, or advice provided by third parties or for their privacy and security policies and procedures.
3. a corporation, partnership, or other entity formed by a U.S. Person principally for the purpose of investing in securities, unless it is organized or incorporated, and owned, by accredited investors who are not natural persons, estates or trusts;
4. an estate of which any executor or administrator is a U.S. Person (unless this executor or administrator is a professional fiduciary and shares with a non-U.S. Person investment discretion with respect to the assets of an estate that is governed by foreign law);
5. a trust if the trustee is a U.S. Person (unless this trustee is a professional fiduciary and shares with a non-U.S. Person investment discretion with respect to the trust assets and no beneficiary of the trust (and no settlor if the trust is revocable) is a U.S. Person);
6. an agency or branch of a non-U.S. entity located in the U.S.;
7. a non-discretionary account or similar account held by a dealer or other fiduciary for the benefit or account of a U.S. Person;
8. any discretionary account or similar account held by a dealer or other fiduciary organized, incorporated, or resident in the U.S. (held for the exclusive benefit or account of non-U.S. Persons); or
9. any government or government official of the United States.
In these Terms, United States or U.S. means the several states of the United States of America, the District of Columbia, Puerto Rico, the Virgin Islands, and the insular possessions of the United States of America.
## MobileCoin Wallets
No MobileCoin Wallet may be operated for and no order or transaction in a MobileCoin Wallet may be for the financial or other benefit of or on behalf of a Prohibited Person or U.S. Person. Persons, whether or not Prohibited Persons, are prohibited from operating a MobileCoin Wallet in any way or otherwise transacting on or using any MobileCoins and any MobileCoin Wallets while they or any individual (including any fiduciary, dealer, trustee, executor or administrator), agency or branch operating their MobileCoin Wallet on their behalf is present in the United States or any jurisdiction in which MobileCoins are unlawful.
Certain software comprising MobileCoin Wallets is available to the public without charge on an open source basis. This software is provided “as is” and “as available,” without warranty of any kind. However, MobileCoin Wallets linked to a Signal mobile messaging application or any other mobile messaging applications may integrate software from a third party. MobileCoin Wallets must be accessed through a telephone, computer or other equipment as well as a network connection through telecommunication lines or other utility. None of these components of the MobileCoin Wallet is provided or controlled by the Compliance Entities. The Compliance Entities and their Associates are not responsible for the accuracy or reliability of any open-source software or of any software, hardware, information, or advice provided by third parties or for their privacy and security policies and procedures.
Access to and use of your MobileCoin Wallet may from time to time be unavailable, delayed, limited or slowed due to failures of hardware, software, utility services or other causes outside the control of the Compliance Entities. You may suffer losses as a result of these delays and limitations. You assume all risks associated with the operation, performance and security of a MobileCoin Wallet. You are responsible for maintaining the security of your MobileCoin Wallet and any password or other security designed to limit access.
In addition to these Terms, you may be bound by any additional terms required by your third-party providers. These third parties&#39; terms may apply to your use of the MobileCoin Wallets. Please be aware that these Terms do not govern third parties&#39; relationships with you. These third parties, and not any Compliance Entity, are responsible for any product or service warranties, whether express or implied by law, provided to you.
In addition to these Terms, you may be bound by any additional terms required by your third-party providers. These third parties terms may apply to your use of the MobileCoin Wallets. Please be aware that these Terms do not govern third parties relationships with you. These third parties, and not any Compliance Entity, are responsible for any product or service warranties, whether express or implied by law, provided to you.
## **Nature of MobileCoins and Transactions in MobileCoins**
## Nature of MobileCoins and Transactions in MobileCoins
MobileCoins are digital tokens. Digital tokens such as MobileCoins are not legal tender, are not backed by any government, and are not insured. MobileCoins do not provide you with any ownership of any physical asset or ownership or other interest or rights of any form with respect to the Compliance Entities or any affiliate or its revenue or assets, including any voting, distribution, redemption, liquidation, proprietary (including all forms of intellectual property), or other financial or legal rights. MobileCoins are distributed and offered on an as-is, and, are offered without any representation as to merchantability or fitness for any particular purpose.
MobileCoins are digital tokens. Digital tokens such as MobileCoins are not legal tender, are not backed by any government, and are not insured. MobileCoins do not provide you with any ownership of any physical asset or ownership or other interest or rights of any form with respect to the Compliance Entities or any affiliate or its revenue or assets, including any voting, distribution, redemption, liquidation, proprietary (including all forms of intellectual property), or other financial or legal rights. MobileCoins are distributed and offered on an as-is, where-is basis and, without limiting the generality of the foregoing, are offered without any representation as to merchantability or fitness for any particular purpose.
You accept that the Compliance Entities may be required to share your user information with other contractual third parties, including financial institutions, or as required under applicable laws or demanded upon a lawful request by any government. When information includes personal data under European Union law and/or California law, the terms of the Privacy Policy will apply. Please consult the appropriate Privacy Policy available at [www.buymobilecoin.us](https://www.buymobilecoin.us/) and [www.buymobilecoin.com](https://www.buymobilecoin.com/).
You accept that the Compliance Entities may be required to share your user information with other contractual third parties, including financial institutions, or as required under applicable laws or demanded upon a lawful request by any government. When information includes personal data under European Union law, the terms of the Privacy Policy will apply. Please consult the Privacy Policy available at the MobileCoin TS Ltd. website at http://www.buymobilecoin.com/.
You accept all consequences of sending MobileCoins. MobileCoin transactions are not reversible or refundable. Once you send MobileCoins to an address, whether intentionally or by a fraudulent or accidental transaction, you accept the risk that you may lose access to, and any claim on, those MobileCoins indefinitely or permanently.
You accept all consequences of sending MobileCoins. MobileCoin transactions are not reversible. Once you send MobileCoins to an address, whether intentionally or by a fraudulent or accidental transaction, you accept the risk that you may lose access to, and any claim on, those MobileCoins indefinitely or permanently.
## **Prohibited Uses and Transfers of MobileCoins and Uses of MobileCoin Wallets**
## Prohibited Uses and Transfers of MobileCoins and Uses of MobileCoin Wallets
You may not:
- use or transfer MobileCoins or access or use a MobileCoin Wallet for any illegal purposes;
- use or transfer MobileCoins or access or use a MobileCoin Wallet in order to disguise the origin or nature of illicit proceeds of, or to further, any breach of applicable laws, or to transact or deal in any contraband funds, property, or proceeds;
- use or transfer MobileCoins or access or use a MobileCoin Wallet if such conduct is prohibited, penalized, or otherwise sanctionable under any applicable laws, including without limitation anti-money laundering laws, counter-terrorist financing laws, anti-corruption laws, and economic sanctions laws or would expose the Compliance Entities or their affiliates to liability under any applicable laws;
- use or transfer MobileCoins or access or use a MobileCoin Wallet or any third party services to facilitate, approve, evade, avoid, or circumvent any applicable laws, including anti-money laundering laws, counterterrorist financing laws, anti-corruption laws, and economic sanctions laws;
- use, or transfer MobileCoins with a Prohibited Person or any individual or entity prohibited from using, transacting, transferring, trading, or receiving MobileCoins by these Terms or applicable laws;
- use, transact, transfer, or trade MobileCoins (i) in the U.S.; (ii) with U.S. Persons; (iii) with persons or entities present in the U.S.; or (iv) if you are a U.S. Person, which includes but is not limited to while you are present in the U.S.;
- transfer MobileCoins to a Prohibited Person, a U.S. Person, or any individual or entity prohibited from using, transacting, transferring, trading, or receiving MobileCoins by these Terms or applicable laws;
- use or transfer MobileCoins or access or use a MobileCoin Wallet or any third party services to facilitate, approve, evade, avoid, or circumvent any applicable laws, including anti-money laundering laws, counter-terrorist financing laws, anti-corruption laws, and economic sanctions laws;
- use a U.S. financial institution in connection with any dealings involving MobileCoins or MobileCoin Wallets or the Compliance Entities;
- use or transfer MobileCoins or access or use a MobileCoin Wallet to evade taxes under applicable laws;
- use or transfer MobileCoins or access or use a MobileCoin Wallet to interfere with or subvert the rights or obligations of the Compliance Entities or the rights or obligations of any other individual or entity;
- use or transfer MobileCoins or access or use a MobileCoin Wallet by using misleading or inaccurate information or to take advantage of any technical glitch, malfunction, failure, delay, default, or security breach;
- use or transfer MobileCoins or access or use a MobileCoin Wallet to engage in conduct that is detrimental to the Compliance Entities or to any other individual or entity;
- falsify or materially omit any information provided to or provide misleading or inaccurate information requested by the Compliance Entities or impersonate another individual or entity or misrepresent your affiliation with an individual or entity;
- falsify any information provided to the Compliance Entities or impersonate another individual or entity or misrepresent your affiliation with an individual or entity;
- falsify or materially omit any information or provide misleading or inaccurate information requested by the Compliance Entities;
- cause injury to, or attempt to harm, the Compliance Entities or any other individual or entity through your access to or use of any MobileCoins and any MobileCoin Wallets; or
- violate, promote, or cause a violation of, or conspire or attempt to violate these Terms or applicable laws.
Any of these uses may be described in these Terms as a Prohibited Use. Should your actions or inaction result in Loss being suffered by the Compliance Entities or any Associates, you will pay an amount to the Compliance Entities or the Associates so as to render the Compliance Entities or the Associates whole, including the amount of taxes or penalties that might be imposed on the Compliance Entities or the Associates.
In these Terms, Associates of the Compliance Entities means the successors, assignees and affiliates of MobileCoin TS Ltd., MobileCoin U.S., LLC and their respective shareholders, directors, officers, affiliates, employees, contractors, agents, partners, insurers, attorneys, and any licensors of technology to the Compliance Entities.
In these Terms, Associates of the Compliance Entities means the successors, assignees and affiliates of MobileCoin TS Ltd. and their respective shareholders, directors, officers, affiliates, employees, contractors, agents, partners, insurers, attorneys, and any licensors of technology to the Compliance Entities.
In these Terms, Losses means any claim, application, loss, injury, delay, accident, cost, business interruption costs, or any other expenses (including attorneys&#39; fees or the costs of any claim or suit), including any incidental, direct, indirect, general, special, punitive, exemplary, or consequential damages, loss of goodwill or business profits, work stoppage, data loss, computer failure or malfunction, or any and all other commercial losses;
In these Terms, Losses means any claim, application, loss, injury, delay, accident, cost, business interruption costs, or any other expenses (including attorneys fees or the costs of any claim or suit), including any incidental, direct, indirect, general, special, punitive, exemplary, or consequential damages, loss of goodwill or business profits, work stoppage, data loss, computer failure or malfunction, or any and all other commercial losses;
## **Intellectual Property**
## Intellectual Property
The MobileCoin name and logo are protected trademarks. You agree not to copy, modify, display, or use these trademarks without written permission from the Compliance Entities. All rights not expressly granted to you in these Terms are reserved.
The MobileCoin name and logo are protected trademarks. You agree not to appropriate, copy, reproduce, modify, display, or use these trademarks without express, prior, written permission from the Compliance Entities. All rights not expressly granted to you in these Terms are reserved.
## **Your Representations and Warranties**
## Your Representations and Warranties
You represent and warrant to the Compliance Entities on the date of your acceptance of these Terms and each day on which you use or transfer MobileCoins or use a MobileCoin Wallet, in each case with reference to the facts and circumstances existing at such date, as follows:
You represent and warrant to the Compliance Entities on the date of your acceptance or deemed acceptance of these Terms and each day on which you use or transfer MobileCoins or each time you access or use a MobileCoin Wallet, in each case with reference to the facts and circumstances existing at such date, as follows:
- that, if you are an individual, you are 18 years of age or older and that you have the capacity to contract under applicable laws;
- that, if you are acting on behalf of a legal entity, (i) such legal entity is duly organized and validly existing under the applicable laws of the jurisdiction of its organization; and (ii) you are duly authorized by such legal entity to act on its behalf;
- that neither you nor any individual or entity acting on your behalf is a Prohibited Person or otherwise prohibited or restricted from purchasing or otherwise obtaining MobileCoins, using or transferring MobileCoins or accessing or using MobileCoin Wallets;
- that neither you nor any individual or entity acting on your behalf is a Prohibited Person or U.S. Person, or otherwise prohibited or restricted from purchasing or otherwise obtaining MobileCoins, using or transferring MobileCoins or accessing or using MobileCoin Wallets;
- that you will not engage in any Prohibited Uses or transfers, as described above;
- that you comply with the laws of your country of establishment, incorporation, residence, or location and, as applicable, the country from which you use any MobileCoins and any MobileCoin Wallets;
- that you understand and acknowledge that the Compliance Entities are not registered with or licensed by any financial regulatory authority in the British Virgin Islands, United States or elsewhere; and that accordingly, no British Virgin Islands, United States or other financial regulatory authority has passed upon the contents of these Terms or the merits of purchasing or using MobileCoins, nor have these Terms been filed with, or reviewed by any British Virgin Islands, United States or other financial regulatory authority;
- that you understand and acknowledge that the Compliance Entities are not registered with or licensed by any financial regulatory authority in the British Virgin Islands or elsewhere; and that accordingly, no British Virgin Islands or other financial regulatory authority has passed upon the contents of these Terms or the merits of purchasing or using MobileCoins, nor have these Terms been filed with, or reviewed by any British Virgin Islands or other financial regulatory authority;
- that you have had the opportunity to seek legal, accounting, taxation and other professional advice regarding these Terms, any MobileCoins and any MobileCoin Wallets;
- that you are currently in compliance with, and must, at your own cost and expense, comply with all laws that relate to or affect these Terms, including anti-money laundering laws, counter-terrorist financing laws, anti-corruption laws, economic sanctions laws, Tax Information Exchange Laws or other tax laws;
- that you will not utilize any virtual private network, proxy service, or any other third-party service, or network for the purpose of disguising or misrepresenting your IP address or location in order to download or use the MobileCoin Wallet in a manner prohibited in these Terms;
- that you consent to any and all tax and information reporting under anti-money laundering laws, counter-terrorist financing laws, anti-corruption laws, economic sanctions laws, Tax Information Exchange Laws or other tax laws as the Compliance Entities may reasonably determine and to extent permitted by law;
- that neither you nor any of your affiliates are acting directly or indirectly (i) on behalf of or for the benefit of a Prohibited Person; (ii) in violation of or as prohibited, restricted, or penalized under applicable economic sanctions laws; or (iii) in any way that would violate, be inconsistent with, penalized under, or cause the omission of filing of any report required under applicable anti-money laundering laws, counter-terrorist financing laws, or economic sanctions laws;
- that neither you nor any of your affiliates is: (i) itself or owned (beneficially or of record) or controlled by a Prohibited Person; (ii) involved in any transaction, transfer, or conduct that is likely to result in you or your affiliates becoming a Prohibited Person; (iii) residing or domiciled in a Prohibited Jurisdiction; (iv) transferring any funds, where denominated in MobileCoin or another cryptocurrency or fiat currency, to, from, or through a Prohibited Jurisdiction in connection to any dealings or conduct with or involving the Compliance Entities; (v) a government or government official of a Prohibited Jurisdiction; or (vi) otherwise a Prohibited Person;
- that neither you nor any of your affiliates is: (i) itself or owned (beneficially or of record) or controlled by a Prohibited Person; (ii) involved in any transaction, transfer, or conduct that is likely to result in you or your affiliates becoming a Prohibited Person; (iii) residing or domiciled in a Prohibited Jurisdiction or the United States; (iv) transferring any funds, where denominated in MobileCoin or another cryptocurrency or fiat currency, to, from, or through a Prohibited Jurisdiction or the United States in connection to any dealings or conduct with or involving the Compliance Entities; (v) a government or government official of a Prohibited Jurisdiction; or (vi) otherwise a Prohibited Person;
- that you will fairly and promptly report all income associated with your use, transaction, transfer, or trade of MobileCoins and access and use MobileCoin Wallets, as applicable, pursuant to applicable laws and pay any and all taxes thereon;
- that you will accurately and promptly inform the Compliance Entities if you know or have reason to know whether any of the foregoing representations or warranties no longer is correct or becomes incorrect; and
- you will use, transact, transfer, and trade MobileCoins and access and use your MobileCoin Wallet for consumptive, and not for investment, purposes.
In these Terms, Tax Information Exchange Laws means laws relating to the exchange of information relating to taxes between governments, including United States Foreign Account Tax Compliance Act, as enacted by Title V, Subtitle A of the Hiring Incentives to Restore Employment Act, P.L 111-147 (2010), as amended; and common reporting standard or the Standard for Automatic Exchange of Financial Account Information.
## **No Representations or Advice by the Compliance Entities**
## No Representations or Advice by the Compliance Entities
The Compliance Entities make no warranties, or guarantees to you of any kind and, to the extent permitted by applicable laws, the Compliance Entities expressly disclaim all representations, warranties, covenants or guarantees, express, implied or statutory, with respect to MobileCoins and any MobileCoin Wallet. The MobileCoins and the MobileCoin Wallet are distributed and offered strictly on an as-is, and, without limiting the generality of the foregoing, are distributed and offered without any representation as to merchantability or fitness for any particular purpose. The Compliance Entities do not provide any investment, legal, accounting, tax or other advice.
The Compliance Entities make no representations, warranties, covenants or guarantees to you of any kind and, to the extent permitted by applicable laws, the Compliance Entities expressly disclaim all representations, warranties, covenants or guarantees, express, implied or statutory, with respect to MobileCoins and any MobileCoin Wallet. The MobileCoins and the MobileCoin Wallet are distributed and offered strictly on an as-is, where-is basis and, without limiting the generality of the foregoing, are distributed and offered without any representation as to merchantability or fitness for any particular purpose. The Compliance Entities do not provide any investment, legal, accounting, tax or other advice.
## **Limitation of Liability, Release, and Indemnity**
## Limitation of Liability, Release, and Indemnity
Important: Except as may be provided for in these Terms, the Compliance Entities assume no liability or responsibility for and will have no liability or responsibility for any Losses directly or indirectly arising out of or related to:
**Important: Except as may be provided for in these Terms, the Compliance Entities assume no liability or responsibility for and will have no liability or responsibility for any Losses directly or indirectly arising out of or related to:**
- these Terms,
- MobileCoins and their use and transfer,
- your MobileCoin Wallet, and your access and use of it,
- to the extent permitted by law, any stolen, lost, or unauthorized use of your personal information, any breach of security or data breach related to your personal information, or any criminal or other third-party act affecting the Compliance Entities, or
- any unauthorized representation, suggestion, statement, or claim made about MobileCoins or the MobileCoin Wallet.
- **these Terms,**
You agree to release the Compliance Entities and its Associates from liability for any and all Losses, and you will indemnify and save and hold the Compliance Entities and its Associates harmless from and against all Losses. The foregoing limitations of liability will apply, to the extent permitted by law, whether the alleged liability or losses are based on contract, negligence, tort, unjust enrichment, strict liability, violation of law or regulation, or any other basis, even if the Compliance Entities and its Associates have been advised of or should have known of the possibility of such losses and damages, and without regard to the success or effectiveness of any other remedies.
- **MobileCoins and their use and transfer,**
## **Electronic Communications**
- **your MobileCoin Wallet, and your access and use of it,**
You agree and consent to receive electronically all communications, agreements, receipts and disclosures that the Compliance Entities may provide in connection with these Terms. Information in relation to how we may communicate with you and your rights in that respect can be found in the appropriate Privacy Policy at [www.buymobilecoin.us](https://www.buymobilecoin.us/) or [www.buymobilecoin.com](https://www.buymobilecoin.com/).
- **to the extent permitted by law, any stolen, lost, or unauthorized use of your personal information, any breach of security or data breach related to your personal information, or any criminal or other third-party act affecting the Compliance Entities, or**
## **Miscellaneous**
- **any representation, suggestion, statement, or claim made about MobileCoins or the MobileCoin Wallet.**
Any right or remedy of the Compliance Entities set forth in these Terms is in addition to, and not in lieu of, any other right or remedy whether described in these Terms, at law or in equity. The Compliance Entities&#39; failure or delay in exercising any right, power, or privilege under these Terms will not operate as a waiver thereof. If any portion of these Terms is found to be invalid or unenforceable for any reason, the invalid or unenforceable provision shall be severed from these Terms. Severance of invalid or unenforceable provisions of any of these Terms will not affect the validity or enforceability of any other of these Terms, all of which will remain in full force and effect. The Compliance Entities will have no responsibility or liability for any failure or delay in performance, or any loss or damage that you may incur, due to any Force Majeure or circumstance or event beyond its control. You may not assign or transfer any of your rights or obligations under these Terms, without the Compliance Entities&#39; prior written consent, including by operation of law or in connection with any change of control, and any such assignment or transfer by you without the Compliance Entities&#39; prior written consent shall be null and void and of no effect. The Compliance Entities may assign or transfer any or all of its rights or obligations under these Terms, without notice or your consent. If there is a conflict between these Terms and any other agreement with the Compliance Entities, these Terms will control unless the other agreement specifically identifies these Terms and declares that the other agreement supersedes these Terms. These Terms do not create any third-party beneficiary rights in any person, save that any Compliance Entity or any of its respective Associates may rely on these Terms in any action, suit, proceeding or other dispute brought against it by you, to exercise any right or to benefit from any limitation expressly provided to it hereunder and to enforce such provisions of these Terms as if party hereto.
**You agree to release the Compliance Entities and its Associates from liability for any and all Losses, and you will indemnify and save and hold the Compliance Entities and its Associates harmless from and against all Losses. The foregoing limitations of liability will apply, to the extent permitted by law, whether the alleged liability or losses are based on contract, negligence, tort, unjust enrichment, strict liability, violation of law or regulation, or any other basis, even if the Compliance Entities and its Associates have been advised of or should have known of the possibility of such losses and damages, and without regard to the success or effectiveness of any other remedies.**
## **Governing Law and Resolution of Disputes**
## Electronic Communications
Any dispute, claim, controversy or action arising out of or related to (a) these Terms or the existence, breach, termination, enforcement, interpretation or validity thereof or (b) your MobileCoins or MobileCoin Wallet, will be subject to the exclusive jurisdiction of the courts of the British Virgin Islands. This provision expressly applies to any claim, whether in tort, contract or otherwise, against the Compliance Entities.
You agree and consent to receive electronically all communications, agreements, documents, receipts, notices and disclosures that the Compliance Entities may provide in connection with these Terms. Information in relation to how we may communicate with you and your rights in that respect can be found in the Privacy Policy at http://www.buymobilecoin.com/.
You irrevocably and unconditionally agree and consent to the jurisdiction and venue of the courts of the British Virgin Islands, and you waive any objections. The foregoing shall be without prejudice to any applicable provisions of mandatory consumer protection law under the laws of your country of residence, to the extent that these offer you more protection.
## Miscellaneous
Any right or remedy of the Compliance Entities set forth in these Terms is in addition to, and not in lieu of, any other right or remedy whether described in these Terms, at law or in equity. The Compliance Entities failure or delay in exercising any right, power, or privilege under these Terms will not operate as a waiver thereof. The invalidity or unenforceability of any of these Terms will not affect the validity or enforceability of any other of these Terms, all of which will remain in full force and effect. The Compliance Entities will have no responsibility or liability for any failure or delay in performance, or any loss or damage that you may incur, due to any Force Majeure or circumstance or event beyond its control. You may not assign or transfer any of your rights or obligations under these Terms, without the Compliance Entities prior written consent, including by operation of law or in connection with any change of control. The Compliance Entities may assign or transfer any or all of it rights or obligations under these Terms, without notice or your consent. If there is a conflict between these Terms and any other agreement you may have with the Compliance Entities, these Terms will control unless the other agreement specifically identifies these Terms and declares that the other agreement supersedes these Terms. If one or more provisions of these Terms is invalidated or declared ineffective, all other provisions of these Terms shall remain in full force and effect. These Terms do not create any third-party beneficiary rights in any person, save that any Compliance Entity or any of its respective Associates may rely on these Terms in any action, suit, proceeding or other dispute brought against it by you, to exercise any right or to benefit from any limitation expressly provided to it hereunder and to enforce such provisions of these Terms as if party hereto.
## Governing Law and Resolution of Disputes
Any dispute, claim, controversy or action arising out of or related to (a) these Terms or the existence, breach, termination, enforcement, interpretation or validity thereof or (b) your MobileCoins or MobileCoin Wallet, will be subject to the exclusive jurisdiction of the courts of the British Virgin Islands. For the avoidance of doubt, and without limiting the generality of the foregoing, this provision expressly applies to any claim, whether in tort, contract or otherwise, against the Compliance Entities.
You irrevocably and unconditionally agree and consent to the jurisdiction and venue of the courts of the British Virgin Islands, and you waive any objections thereto, including under the doctrine of forum non conveniens or other similar doctrines. The foregoing shall be without prejudice to any applicable provisions of mandatory consumer protection law under the laws of your country of residence, to the extent that these offer you more protection.
Any complaint or dispute is personal to you and you agree that it will not be brought as a class action, class arbitration or any other type of representative proceeding. There will be no class action in which you attempt to resolve a complaint or dispute as a representative of another individual or group of individuals, save with the express agreement in writing of the relevant Compliance Entity.
JURY TRIAL WAIVER: TO THE FULLEST EXTENT PERMITTED BY APPLICABLE LAW, THE PARTIES HEREBY IRREVOCABLY AND UNCONDITIONALLY WAIVE ALL RIGHT TO TRIAL BY JURY IN ANY LEGAL ACTION OR PROCEEDING OF ANY KIND WHATSOVER ARISING OUT OF OR RELATING TO THESE TERMS OR ANY BREACH THEREOF, ANY USE OR ATTEMPTED USE OR TRANSFER OF MOBILECOINS OR USE OR ATTEMPED USE OF A MOBILECOIN WALLET BY YOU, AND/OR ANY OTHER MATTER INVOLVING THE PARTIES.
JURY TRIAL WAIVER: TO THE FULLEST EXTENT PERMITTED BY APPLICABLE LAW, THE PARTIES HEREBY IRREVOCABLY AND UNCONDITIONALLY WAIVE ALL RIGHT TO TRIAL BY JURY IN ANY LEGAL ACTION OR PROCEEDING OF ANY KIND WHATSOVER ARISING OUT OF OR RELATING TO THESE TERMS OR ANY BREACH THEREOF, ANY USE OR ATTEMPTED USE OR TRANSFER OF MOBILECOINS OR USE OR ATTEMPED USE OF A MOBILECOIN WALLET BY YOU, AND/OR ANY OTHER MATTER INVOLVING THE PARTIES.
## **Language and Contact**
## Language and Contact
These Terms and any information or notifications that are provided under these Terms shall be in English.
These Terms and any information or notifications that are provided under these Terms shall be in English.
If you have any questions relating to these Terms, your rights and obligations arising from these Terms and/or your use of any MobileCoins and any MobileCoin Wallets, please use the question form at [www.buymobilecoin.us](https://www.buymobilecoin.us/) or the MobileCoin TS Ltd. website at [www.buymobilecoin.com](https://www.buymobilecoin.com/).
If you have any questions relating to these Terms, your rights and obligations arising from these Terms and/or your use of any MobileCoins and any MobileCoin Wallets or any other matter, please utilize the question form on the MobileCoin TS Ltd. website at http://www.buymobilecoin.com/.

View File

@ -108,7 +108,7 @@ extension NetworkPreset {
return "mc://node1.test.mobilecoin.com"
case .alpha, .mobiledev, .master, .build, .demo, .diogenes, .drakeley, .eran:
return "mc://node1.\(self).mobilecoin.com"
return "mc://consensus.\(self).mobilecoin.com"
}
}
var fogUrl: String {
@ -133,13 +133,13 @@ extension NetworkPreset {
"709ab90621e3a8d9eb26ed9e2830e091beceebd55fb01c5d7c31d27e83b9b0d1"
private static let testNetConsensusMrEnclaveHex =
"9659ea738275b3999bf1700398b60281be03af5cb399738a89b49ea2496595af"
"9268c3220a5260e51e4b586f00e4677fed2b80380f1eeaf775af60f8e880fde8"
private static let testNetFogViewMrEnclaveHex =
"e154f108c7758b5aa7161c3824c176f0c20f63012463bf3cc5651e678f02fb9e"
"4e598799faa4bb08a3bd55c0bcda7e1d22e41151d0c591f6c2a48b3562b0881e"
private static let testNetFogLedgerMrEnclaveHex =
"768f7bea6171fb83d775ee8485e4b5fcebf5f664ca7e8b9ceef9c7c21e9d9bf3"
"7330c9987f21b91313b39dcdeaa7da8da5ca101c929f5740c207742c762e6dcd"
private static let testNetFogReportMrEnclaveHex =
"a4764346f91979b4906d4ce26102228efe3aba39216dec1e7d22e6b06f919f11"
"185875464ccd67a879d58181055383505a719b364b12d56d9bef90a40bed07ca"
private static let devMrSignerHex =
"7ee5e29d74623fdbc6fbf1454be6f3bb0b86c12366b7b478ad13353e44de8411"
@ -258,37 +258,21 @@ extension NetworkPreset {
private static let trustRootsB64 = [
/// MobileCoin-managed Consensus and Fog services use Let's Encrypt with an intermediate
/// certificate ISRG Root X1 that's self-signed https://crt.sh/?id=9314791
/// certificate that's cross-signed by IdenTrust's "DST Root CA X3": https://crt.sh/?d=8395
"""
MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw\
TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh\
cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4\
WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu\
ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY\
MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc\
h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+\
0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U\
A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW\
T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH\
B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC\
B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv\
KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn\
OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn\
jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw\
qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI\
rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV\
HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq\
hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL\
ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ\
3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK\
NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5\
ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur\
TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC\
jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc\
oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq\
4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA\
mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d\
emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc=
MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/MSQwIgYDVQQKExtEaWdpdGF\
sIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMTDkRTVCBSb290IENBIFgzMB4XDTAwMDkzMDIxMTIxOVoXDT\
IxMDkzMDE0MDExNVowPzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQDEw5EU\
1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAN+v6ZdQCINXtMxiZfaQguzH0yxr\
MMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmTrE4Orz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoO\
ifooUMM0RoOEqOLl5CjH9UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9bxiqKqy69cK\
3FCxolkHRyxXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40du\
tolucbY38EVAjqr2m7xPi71XAicPNaDaeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB\
/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQMA0GCSqGSIb3DQEBBQUAA4I\
BAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69ikugdB/OEIKcdBodfpga3csTS7MgROSR6cz8fa\
XbauX+5v3gTt23ADq1cEmv8uXrAvHRAosZy5Q6XkjEGB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ip\
xZzR8srzJmwN0jP41ZL9c8PDHIyh8bwRLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5JDGFoqgCWjBH4d1QB7wC\
CZAA62RjYJsWvIjJEubSfZGL+T0yjWW06XyxV3bqxbYoOb8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ
""",
]
@ -325,40 +309,26 @@ extension NetworkPreset {
}
final class TestHttpRequester: HttpRequester {
let configuration : URLSessionConfiguration = {
let config = URLSessionConfiguration.default
config.timeoutIntervalForRequest = 30
config.timeoutIntervalForResource = 30
return config
}()
func request(
url: URL,
method: HTTPMethod,
headers: [String: String]?,
body: Data?,
completion: @escaping (Result<HTTPResponse, Error>) -> Void
completion: @escaping (HTTPResult) -> Void
) {
var request = URLRequest(url: url.absoluteURL)
request.httpMethod = method.rawValue
headers?.forEach({ key, value in
request.setValue(value, forHTTPHeaderField: key)
})
request.httpBody = body
let session = URLSession(configuration: configuration)
let task = session.dataTask(with: request) {data, response, error in
let task = URLSession.shared.dataTask(with: url) {data, response, error in
if let error = error {
completion(.failure(error))
completion(.failure(error: error))
return
}
guard let response = response as? HTTPURLResponse else {
completion(.failure(ConnectionError.invalidServerResponse("No Response")))
guard let response = response as? HTTPURLResponse,
(200...299).contains(response.statusCode) else {
completion(.failure(error: ConnectionError.invalidServerResponse("")))
return
}
let httpResponse = HTTPResponse(httpUrlResponse: response, responseData: data)
completion(.success(httpResponse))
completion(.success(response: httpResponse))
}
task.resume()
}
@ -500,7 +470,7 @@ extension NetworkPreset {
case .mainNet, .testNet:
return false
case .alpha, .mobiledev, .master, .build, .demo, .diogenes, .drakeley, .eran:
return false
return true
}
}
var consensusCredentials: BasicCredentials? {

View File

@ -103,11 +103,11 @@ extension MockFogService {
}
}
var blockServiceBlocks: [FogLedger_BlockData] {
var blockServiceBlocks: [FogLedger_Block] {
var cummulativeTxOutCount: UInt64 = 0
return blockServiceTxOuts.enumerated().map { index, txOuts in
cummulativeTxOutCount += UInt64(txOuts.count)
var block = FogLedger_BlockData()
var block = FogLedger_Block()
block.index = UInt64(index)
block.globalTxoCount = cummulativeTxOutCount
block.outputs = txOuts.map { External_TxOut($0) }

View File

@ -9,7 +9,7 @@ import NIOSSL
import XCTest
enum IntegrationTestFixtures {
static let network: NetworkPreset = .testNet
static let network: NetworkPreset = .mobiledev
}
extension IntegrationTestFixtures {
@ -105,9 +105,7 @@ extension IntegrationTestFixtures {
accountKey: AccountKey,
config: MobileCoinClient.Config
) throws -> MobileCoinClient {
var mutableConfig = config
mutableConfig.httpRequester = TestHttpRequester()
let client = try MobileCoinClient.make(accountKey: accountKey, config: mutableConfig).get()
let client = try MobileCoinClient.make(accountKey: accountKey, config: config).get()
if let consensusCredentials = network.consensusCredentials {
client.setConsensusBasicAuthorization(
username: consensusCredentials.username,

View File

@ -164,7 +164,6 @@ extension ConsensusConnectionIntTests {
ConsensusConnection(
config: networkConfig.consensus,
channelManager: GrpcChannelManager(),
httpRequester: networkConfig.httpRequester,
targetQueue: DispatchQueue.main)
}
}

View File

@ -156,7 +156,6 @@ extension FogBlockConnectionIntTests {
FogBlockConnection(
config: networkConfig.fogBlock,
channelManager: GrpcChannelManager(),
httpRequester: TestHttpRequester(),
targetQueue: DispatchQueue.main)
}
}

View File

@ -121,7 +121,6 @@ extension FogKeyImageConnectionIntTests {
FogKeyImageConnection(
config: networkConfig.fogKeyImage,
channelManager: GrpcChannelManager(),
httpRequester: TestHttpRequester(),
targetQueue: DispatchQueue.main)
}
}

View File

@ -160,7 +160,6 @@ extension FogMerkleProofConnectionIntTests {
FogMerkleProofConnection(
config: networkConfig.fogMerkleProof,
channelManager: GrpcChannelManager(),
httpRequester: TestHttpRequester(),
targetQueue: DispatchQueue.main)
}
}

View File

@ -32,9 +32,8 @@ extension FogReportConnectionIntTests {
let url = try FogUrl.make(string: IntegrationTestFixtures.network.fogReportUrl).get()
return FogReportConnection(
url: url,
transportProtocolOption: try IntegrationTestFixtures.network.networkConfig().transportProtocol.option,
transportProtocolOption: .grpc,
channelManager: GrpcChannelManager(),
httpRequester: TestHttpRequester(),
targetQueue: DispatchQueue.main)
}
}

View File

@ -62,7 +62,6 @@ extension FogUntrustedTxOutConnectionIntTests {
FogUntrustedTxOutConnection(
config: networkConfig.fogUntrustedTxOut,
channelManager: GrpcChannelManager(),
httpRequester: TestHttpRequester(),
targetQueue: DispatchQueue.main)
}
}

View File

@ -250,7 +250,7 @@ extension FogViewConnectionIntTests {
FogViewConnection(
config: networkConfig.fogView,
channelManager: GrpcChannelManager(),
httpRequester: TestHttpRequester(),
httpRequester: nil,
targetQueue: DispatchQueue.main)
}
}

View File

@ -33,4 +33,9 @@ class TxOutTests: XCTestCase {
XCTAssertEqual(txOut.value(accountKey: recipientAccountKey), fixture.value)
}
func testValueFailsWithWrongAccountKey() throws {
let fixture = try TxOut.Fixtures.Default()
XCTAssertNil(fixture.txOut.value(accountKey: fixture.wrongAccountKey))
}
}

@ -1 +1 @@
Subproject commit 7a4abb1010ece2b3650456b00c7f6a6e8d071d68
Subproject commit 2fc988beaf2cf51efb8bcf1bef99ce12e2a6e9b9