diff --git a/.env b/.env
new file mode 100644
index 0000000..6aa760b
--- /dev/null
+++ b/.env
@@ -0,0 +1,4 @@
+SCHEME="Example"
+APP_IDENTIFIER="com.walletconnect.web3modal.sample"
+MATCH_IDENTIFIERS="com.walletconnect.web3modal.sample"
+APPLE_ID="6469691466"
diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
new file mode 100644
index 0000000..ce7b5d7
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -0,0 +1,38 @@
+---
+name: Bug report
+about: Create a report to help us improve
+title: ''
+labels: bug
+assignees: ''
+
+---
+
+**Describe the bug**
+A clear and concise description of what the bug is.
+
+**SDK Version**
+ - Client: [e.g. Swift]
+ - Version [e.g. 22]
+
+**To Reproduce**
+Steps to reproduce the behavior:
+1. Go to '...'
+2. Click on '....'
+3. Scroll down to '....'
+4. See error
+
+**Expected behavior**
+A clear and concise description of what you expected to happen.
+
+**Screenshots**
+If applicable, add screenshots to help explain your problem.
+
+
+**Device (please complete the following information):**
+ - Device: [e.g. iPhone6]
+ - OS: [e.g. iOS8.1]
+ - Browser [e.g. stock browser, safari]
+ - Version [e.g. 22]
+
+**Additional context**
+Add any other context about the problem here.
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
new file mode 100644
index 0000000..bf16912
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/config.yml
@@ -0,0 +1,8 @@
+blank_issues_enabled: false
+contact_links:
+ - name: Ask a question
+ url: https://github.com/WalletConnect/walletconnect-monorepo/discussions/new?category=swift-ios
+ about: Ask questions and discuss with other community members.
+ - name: View our FAQ
+ url: https://walletconnect.com/faq
+ about: See our frequently asked questions
diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md
new file mode 100644
index 0000000..11fc491
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/feature_request.md
@@ -0,0 +1,20 @@
+---
+name: Feature request
+about: Suggest an idea for this project
+title: ''
+labels: enhancement
+assignees: ''
+
+---
+
+**Is your feature request related to a problem? Please describe.**
+A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
+
+**Describe the solution you'd like**
+A clear and concise description of what you want to happen.
+
+**Describe alternatives you've considered**
+A clear and concise description of any alternative solutions or features you've considered.
+
+**Additional context**
+Add any other context or screenshots about the feature request here.
diff --git a/.github/new-file b/.github/new-file
new file mode 100644
index 0000000..5482abc
--- /dev/null
+++ b/.github/new-file
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
new file mode 100644
index 0000000..a45ea4c
--- /dev/null
+++ b/.github/pull_request_template.md
@@ -0,0 +1,24 @@
+# Description
+
+
+
+Resolves # (issue)
+
+## How Has This Been Tested?
+
+
+
+
+
+## Due Dilligence
+
+* [ ] Breaking change
+* [ ] Requires a documentation update
diff --git a/.github/workflows/azure-webapps-node.yml b/.github/workflows/azure-webapps-node.yml
new file mode 100644
index 0000000..fdb0e0c
--- /dev/null
+++ b/.github/workflows/azure-webapps-node.yml
@@ -0,0 +1,78 @@
+# This workflow will build and push a node.js application to an Azure Web App when a commit is pushed to your default branch.
+#
+# This workflow assumes you have already created the target Azure App Service web app.
+# For instructions see https://docs.microsoft.com/en-us/azure/app-service/quickstart-nodejs?tabs=linux&pivots=development-environment-cli
+#
+# To configure this workflow:
+#
+# 1. Download the Publish Profile for your Azure Web App. You can download this file from the Overview page of your Web App in the Azure Portal.
+# For more information: https://docs.microsoft.com/en-us/azure/app-service/deploy-github-actions?tabs=applevel#generate-deployment-credentials
+#
+# 2. Create a secret in your repository named AZURE_WEBAPP_PUBLISH_PROFILE, paste the publish profile contents as the value of the secret.
+# For instructions on obtaining the publish profile see: https://docs.microsoft.com/azure/app-service/deploy-github-actions#configure-the-github-secret
+#
+# 3. Change the value for the AZURE_WEBAPP_NAME. Optionally, change the AZURE_WEBAPP_PACKAGE_PATH and NODE_VERSION environment variables below.
+#
+# For more information on GitHub Actions for Azure: https://github.com/Azure/Actions
+# For more information on the Azure Web Apps Deploy action: https://github.com/Azure/webapps-deploy
+# For more samples to get started with GitHub Action workflows to deploy to Azure: https://github.com/Azure/actions-workflow-samples
+
+on:
+ push:
+ branches: [ "develop" ]
+ workflow_dispatch:
+
+env:
+ AZURE_WEBAPP_NAME: your-app-name # set this to your application's name
+ AZURE_WEBAPP_PACKAGE_PATH: '.' # set this to the path to your web app project, defaults to the repository root
+ NODE_VERSION: '14.x' # set this to the node version to use
+
+permissions:
+ contents: read
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+
+ - name: Set up Node.js
+ uses: actions/setup-node@v3
+ with:
+ node-version: ${{ env.NODE_VERSION }}
+ cache: 'npm'
+
+ - name: npm install, build, and test
+ run: |
+ npm install
+ npm run build --if-present
+ npm run test --if-present
+
+ - name: Upload artifact for deployment job
+ uses: actions/upload-artifact@v3
+ with:
+ name: node-app
+ path: .
+
+ deploy:
+ permissions:
+ contents: none
+ runs-on: ubuntu-latest
+ needs: build
+ environment:
+ name: 'Development'
+ url: ${{ steps.deploy-to-webapp.outputs.webapp-url }}
+
+ steps:
+ - name: Download artifact from build job
+ uses: actions/download-artifact@v3
+ with:
+ name: node-app
+
+ - name: 'Deploy to Azure WebApp'
+ id: deploy-to-webapp
+ uses: azure/webapps-deploy@v2
+ with:
+ app-name: ${{ env.AZURE_WEBAPP_NAME }}
+ publish-profile: ${{ secrets.AZURE_WEBAPP_PUBLISH_PROFILE }}
+ package: ${{ env.AZURE_WEBAPP_PACKAGE_PATH }}
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 0000000..9671466
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,59 @@
+name: ci
+
+on:
+ pull_request:
+ branches:
+ - develop
+ - main
+
+concurrency:
+ group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && github.event.pull_request.number || github.ref_name }}
+ cancel-in-progress: ${{ github.event_name == 'pull_request' }}
+
+jobs:
+ test:
+ runs-on: macos-latest-xlarge
+ timeout-minutes: 15
+ strategy:
+ fail-fast: false
+ matrix:
+ type: [unit-tests]
+
+ steps:
+ - uses: actions/checkout@v3
+ with:
+ ref: ${{ github.event.pull_request.head.sha }}
+
+ # Package Unit tests
+ - name: Run tests
+ if: matrix.type == 'unit-tests'
+ shell: bash
+ run: make unit_tests
+
+# - name: Danger
+# env:
+# DANGER_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+# run:
+# rm -rf xcov_report |
+# /opt/homebrew/opt/ruby/bin/bundle install |
+# /opt/homebrew/opt/ruby/bin/bundle exec danger
+
+ - name: Publish Test Report
+ uses: mikepenz/action-junit-report@v3
+ if: success() || failure()
+ with:
+ check_name: ${{ matrix.type }} junit report
+ report_paths: 'test_results/report.junit'
+
+ - name: Zip test artifacts
+ if: always()
+ shell: bash
+ run: test -d "test_results" && zip artifacts.zip -r ./test_results || echo "Nothing to zip"
+
+ - name: Upload test artifacts
+ if: always()
+ uses: actions/upload-artifact@v3
+ with:
+ name: ${{ matrix.type }} test_results
+ path: ./artifacts.zip
+ if-no-files-found: warn
diff --git a/.github/workflows/deploy_pages.yml b/.github/workflows/deploy_pages.yml
new file mode 100644
index 0000000..9901d0c
--- /dev/null
+++ b/.github/workflows/deploy_pages.yml
@@ -0,0 +1,46 @@
+# Simple workflow for deploying static content to GitHub Pages
+name: Deploy static content to Pages
+
+on:
+ # Runs on pushes targeting the default branch
+ push:
+ branches: ["main"]
+
+ # Allows you to run this workflow manually from the Actions tab
+ workflow_dispatch:
+
+# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
+permissions:
+ contents: read
+ pages: write
+ id-token: write
+
+# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
+# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
+concurrency:
+ group: "pages"
+ cancel-in-progress: false
+
+jobs:
+ # Single deploy job since we're just deploying
+ deploy:
+ environment:
+ name: github-pages
+ url: ${{ steps.deployment.outputs.page_url }}
+ runs-on:
+ group: apple-silicon
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v3
+ - name: Generate docs
+ shell: bash
+ run: |
+ ./generate_docs.sh
+ - name: Upload artifact
+ uses: actions/upload-pages-artifact@v1
+ with:
+ # Upload just docs directory
+ path: 'docs'
+ - name: Deploy to GitHub Pages
+ id: deployment
+ uses: actions/deploy-pages@v2
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
new file mode 100644
index 0000000..791ffde
--- /dev/null
+++ b/.github/workflows/release.yml
@@ -0,0 +1,38 @@
+name: release
+
+on:
+ workflow_dispatch:
+
+jobs:
+ build:
+ runs-on: macos-latest-xlarge
+
+ steps:
+ - uses: actions/checkout@v3
+
+ - uses: actions/cache@v3
+ with:
+ path: |
+ .build
+ SourcePackagesCache
+ DerivedDataCache
+ key: ${{ runner.os }}-spm-${{ hashFiles('**/Package.resolved') }}
+ restore-keys: |
+ ${{ runner.os }}-spm-
+
+ - name: Release
+ shell: /bin/zsh -e {0}
+ env:
+ LANGUAGE: en_US.UTF-8
+ LC_ALL: en_US.UTF-8
+ LANG: en_US.UTF-8
+ MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }}
+ GH_TOKEN: ${{ secrets.GH_TOKEN }}
+ GH_USER: ${{ secrets.GH_USER }}
+ APPLE_ISSUER_ID: ${{ secrets.APPLE_ISSUER_ID }}
+ APPLE_KEY_ID: ${{ secrets.APPLE_KEY_ID }}
+ APPLE_KEY_CONTENT: ${{ secrets.APPLE_KEY_CONTENT }}
+ run: |
+ git config --global user.name "radeknovis"
+ git config --global user.email "radek@walletconnect.com"
+ make release TOKEN=$(echo -n $GH_USER:$GH_TOKEN | base64) PROJECT_ID=${{ secrets.PROJECT_ID }}
diff --git a/.github/workflows/swift.yml b/.github/workflows/swift.yml
new file mode 100644
index 0000000..2acc2fa
--- /dev/null
+++ b/.github/workflows/swift.yml
@@ -0,0 +1,22 @@
+# This workflow will build a Swift project
+# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-swift
+
+name: Swift
+
+on:
+ push:
+ branches: [ "develop" ]
+ pull_request:
+ branches: [ "develop" ]
+
+jobs:
+ build:
+
+ runs-on: macos-latest
+
+ steps:
+ - uses: actions/checkout@v3
+ - name: Build
+ run: swift build -v
+ - name: Run tests
+ run: swift test -v
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..91bf9ac
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,101 @@
+# Xcode
+#
+# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
+
+## User settings
+xcuserdata/
+
+## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9)
+*.xcscmblueprint
+*.xccheckout
+
+## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4)
+build/
+DerivedData/
+*.moved-aside
+*.pbxuser
+!default.pbxuser
+*.mode1v3
+!default.mode1v3
+*.mode2v3
+!default.mode2v3
+*.perspectivev3
+!default.perspectivev3
+
+## Obj-C/Swift specific
+*.hmap
+
+## App packaging
+*.ipa
+*.dSYM.zip
+*.dSYM
+
+## Playgrounds
+timeline.xctimeline
+playground.xcworkspace
+
+# Swift Package Manager
+#
+# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
+# Packages/
+# Package.pins
+# Package.resolved
+# *.xcodeproj
+#
+# Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata
+# hence it is not needed unless you have added a package configuration file to your project
+# .swiftpm
+
+.build/
+
+# CocoaPods
+#
+# We recommend against adding the Pods directory to your .gitignore. However
+# you should judge for yourself, the pros and cons are mentioned at:
+# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
+#
+# Pods/
+#
+# Add this line if you want to avoid checking in source code from the Xcode workspace
+# *.xcworkspace
+
+# Carthage
+#
+# Add this line if you want to avoid checking in source code from Carthage dependencies.
+# Carthage/Checkouts
+
+Carthage/Build/
+
+# Accio dependency management
+Dependencies/
+.accio/
+
+# fastlane
+#
+# It is recommended to not store the screenshots in the git repo.
+# Instead, use fastlane to re-generate the screenshots whenever they are needed.
+# For more information about the recommended setup visit:
+# https://docs.fastlane.tools/best-practices/source-control/#source-control
+
+fastlane/report.xml
+fastlane/Preview.html
+fastlane/screenshots/**/*.png
+fastlane/test_output
+
+# Code Injection
+#
+# After new code Injection tools there's a generated folder /iOSInjectionProject
+# https://github.com/johnno1962/injectionforxcode
+
+iOSInjectionProject/
+
+ExampleApp/Web3Modal/Sources/WCModal/Secrets/secrets.json
+
+DerivedDataCache/
+
+test_results/
+Sample/Example/Secrets/secrets.json
+
+fastlane/xcov_report/
+
+xcov_report/
diff --git a/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata b/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..919434a
--- /dev/null
+++ b/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/.swiftpm/xcode/xcshareddata/xcschemes/Web3Modal.xcscheme b/.swiftpm/xcode/xcshareddata/xcschemes/Web3Modal.xcscheme
new file mode 100644
index 0000000..c37dbae
--- /dev/null
+++ b/.swiftpm/xcode/xcshareddata/xcschemes/Web3Modal.xcscheme
@@ -0,0 +1,66 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.swiftpm/xcode/xcshareddata/xcschemes/Web3ModalTests.xcscheme b/.swiftpm/xcode/xcshareddata/xcschemes/Web3ModalTests.xcscheme
new file mode 100644
index 0000000..33dbc5a
--- /dev/null
+++ b/.swiftpm/xcode/xcshareddata/xcschemes/Web3ModalTests.xcscheme
@@ -0,0 +1,53 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.swiftpm/xcode/xcshareddata/xcschemes/Web3ModalUI.xcscheme b/.swiftpm/xcode/xcshareddata/xcschemes/Web3ModalUI.xcscheme
new file mode 100644
index 0000000..79cec88
--- /dev/null
+++ b/.swiftpm/xcode/xcshareddata/xcschemes/Web3ModalUI.xcscheme
@@ -0,0 +1,66 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.swiftpm/xcode/xcshareddata/xcschemes/Web3ModalUITests.xcscheme b/.swiftpm/xcode/xcshareddata/xcschemes/Web3ModalUITests.xcscheme
new file mode 100644
index 0000000..01e8327
--- /dev/null
+++ b/.swiftpm/xcode/xcshareddata/xcschemes/Web3ModalUITests.xcscheme
@@ -0,0 +1,53 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.vscode/launch.json b/.vscode/launch.json
new file mode 100644
index 0000000..2ba986f
--- /dev/null
+++ b/.vscode/launch.json
@@ -0,0 +1,15 @@
+{
+ // Use IntelliSense to learn about possible attributes.
+ // Hover to view descriptions of existing attributes.
+ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
+ "version": "0.2.0",
+ "configurations": [
+ {
+ "type": "chrome",
+ "request": "launch",
+ "name": "Launch Chrome against localhost",
+ "url": "http://localhost:8080",
+ "webRoot": "${workspaceFolder}"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/Dangerfile b/Dangerfile
new file mode 100644
index 0000000..94fb9c0
--- /dev/null
+++ b/Dangerfile
@@ -0,0 +1,6 @@
+xcov.report(
+ scheme: 'swift-web3modal-Package',
+ minimum_coverage_percentage: 20.0,
+ xccov_file_direct_path: 'test_results/swift-web3modal-Package.xcresult',
+ include_targets: 'Web3Modal,Web3ModalUI',
+)
diff --git a/Gemfile b/Gemfile
new file mode 100644
index 0000000..bd341ea
--- /dev/null
+++ b/Gemfile
@@ -0,0 +1,5 @@
+source "https://rubygems.org"
+
+gem "xcov", "~> 1.8"
+gem "danger", "~> 9.4"
+gem "danger-xcov", git: 'https://github.com/getyourguide/danger-xcov.git'
diff --git a/Gemfile.lock b/Gemfile.lock
new file mode 100644
index 0000000..290b57d
--- /dev/null
+++ b/Gemfile.lock
@@ -0,0 +1,270 @@
+GIT
+ remote: https://github.com/getyourguide/danger-xcov.git
+ revision: 10cc78b6dcbf949e460625cc9a68b5e1b786d115
+ specs:
+ danger-xcov (0.5.0)
+ danger (>= 2.1)
+ xcov (>= 1.8.0)
+
+GEM
+ remote: https://rubygems.org/
+ specs:
+ CFPropertyList (3.0.6)
+ rexml
+ addressable (2.8.6)
+ public_suffix (>= 2.0.2, < 6.0)
+ artifactory (3.0.15)
+ atomos (0.1.3)
+ aws-eventstream (1.3.0)
+ aws-partitions (1.887.0)
+ aws-sdk-core (3.191.0)
+ aws-eventstream (~> 1, >= 1.3.0)
+ aws-partitions (~> 1, >= 1.651.0)
+ aws-sigv4 (~> 1.8)
+ jmespath (~> 1, >= 1.6.1)
+ aws-sdk-kms (1.77.0)
+ aws-sdk-core (~> 3, >= 3.191.0)
+ aws-sigv4 (~> 1.1)
+ aws-sdk-s3 (1.143.0)
+ aws-sdk-core (~> 3, >= 3.191.0)
+ aws-sdk-kms (~> 1)
+ aws-sigv4 (~> 1.8)
+ aws-sigv4 (1.8.0)
+ aws-eventstream (~> 1, >= 1.0.2)
+ babosa (1.0.4)
+ claide (1.1.0)
+ claide-plugins (0.9.2)
+ cork
+ nap
+ open4 (~> 1.3)
+ colored (1.2)
+ colored2 (3.1.2)
+ commander (4.6.0)
+ highline (~> 2.0.0)
+ cork (0.3.0)
+ colored2 (~> 3.1)
+ danger (9.4.2)
+ claide (~> 1.0)
+ claide-plugins (>= 0.9.2)
+ colored2 (~> 3.1)
+ cork (~> 0.1)
+ faraday (>= 0.9.0, < 3.0)
+ faraday-http-cache (~> 2.0)
+ git (~> 1.13)
+ kramdown (~> 2.3)
+ kramdown-parser-gfm (~> 1.0)
+ no_proxy_fix
+ octokit (>= 4.0)
+ terminal-table (>= 1, < 4)
+ declarative (0.0.20)
+ digest-crc (0.6.5)
+ rake (>= 12.0.0, < 14.0.0)
+ domain_name (0.6.20240107)
+ dotenv (2.8.1)
+ emoji_regex (3.2.3)
+ excon (0.109.0)
+ faraday (1.10.3)
+ faraday-em_http (~> 1.0)
+ faraday-em_synchrony (~> 1.0)
+ faraday-excon (~> 1.1)
+ faraday-httpclient (~> 1.0)
+ faraday-multipart (~> 1.0)
+ faraday-net_http (~> 1.0)
+ faraday-net_http_persistent (~> 1.0)
+ faraday-patron (~> 1.0)
+ faraday-rack (~> 1.0)
+ faraday-retry (~> 1.0)
+ ruby2_keywords (>= 0.0.4)
+ faraday-cookie_jar (0.0.7)
+ faraday (>= 0.8.0)
+ http-cookie (~> 1.0.0)
+ faraday-em_http (1.0.0)
+ faraday-em_synchrony (1.0.0)
+ faraday-excon (1.1.0)
+ faraday-http-cache (2.5.0)
+ faraday (>= 0.8)
+ faraday-httpclient (1.0.1)
+ faraday-multipart (1.0.4)
+ multipart-post (~> 2)
+ faraday-net_http (1.0.1)
+ faraday-net_http_persistent (1.2.0)
+ faraday-patron (1.0.0)
+ faraday-rack (1.0.0)
+ faraday-retry (1.0.3)
+ faraday_middleware (1.2.0)
+ faraday (~> 1.0)
+ fastimage (2.3.0)
+ fastlane (2.219.0)
+ CFPropertyList (>= 2.3, < 4.0.0)
+ addressable (>= 2.8, < 3.0.0)
+ artifactory (~> 3.0)
+ aws-sdk-s3 (~> 1.0)
+ babosa (>= 1.0.3, < 2.0.0)
+ bundler (>= 1.12.0, < 3.0.0)
+ colored
+ commander (~> 4.6)
+ dotenv (>= 2.1.1, < 3.0.0)
+ emoji_regex (>= 0.1, < 4.0)
+ excon (>= 0.71.0, < 1.0.0)
+ faraday (~> 1.0)
+ faraday-cookie_jar (~> 0.0.6)
+ 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-playcustomapp_v1 (~> 0.1)
+ google-cloud-env (>= 1.6.0, < 2.0.0)
+ google-cloud-storage (~> 1.31)
+ highline (~> 2.0)
+ http-cookie (~> 1.0.5)
+ json (< 3.0.0)
+ jwt (>= 2.1.0, < 3)
+ mini_magick (>= 4.9.4, < 5.0.0)
+ multipart-post (>= 2.0.0, < 3.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)
+ simctl (~> 1.6.3)
+ terminal-notifier (>= 2.0.0, < 3.0.0)
+ terminal-table (~> 3)
+ tty-screen (>= 0.6.3, < 1.0.0)
+ tty-spinner (>= 0.8.0, < 1.0.0)
+ word_wrap (~> 1.0.0)
+ xcodeproj (>= 1.13.0, < 2.0.0)
+ xcpretty (~> 0.3.0)
+ xcpretty-travis-formatter (>= 0.0.3)
+ gh_inspector (1.1.3)
+ git (1.19.0)
+ addressable (~> 2.8)
+ rchardet (~> 1.8)
+ google-apis-androidpublisher_v3 (0.54.0)
+ google-apis-core (>= 0.11.0, < 2.a)
+ google-apis-core (0.11.3)
+ addressable (~> 2.5, >= 2.5.1)
+ googleauth (>= 0.16.2, < 2.a)
+ httpclient (>= 2.8.1, < 3.a)
+ mini_mime (~> 1.0)
+ representable (~> 3.0)
+ retriable (>= 2.0, < 4.a)
+ rexml
+ google-apis-iamcredentials_v1 (0.17.0)
+ google-apis-core (>= 0.11.0, < 2.a)
+ google-apis-playcustomapp_v1 (0.13.0)
+ google-apis-core (>= 0.11.0, < 2.a)
+ google-apis-storage_v1 (0.31.0)
+ google-apis-core (>= 0.11.0, < 2.a)
+ google-cloud-core (1.6.1)
+ google-cloud-env (>= 1.0, < 3.a)
+ google-cloud-errors (~> 1.0)
+ google-cloud-env (1.6.0)
+ faraday (>= 0.17.3, < 3.0)
+ google-cloud-errors (1.3.1)
+ google-cloud-storage (1.47.0)
+ addressable (~> 2.8)
+ digest-crc (~> 0.4)
+ google-apis-iamcredentials_v1 (~> 0.1)
+ google-apis-storage_v1 (~> 0.31.0)
+ google-cloud-core (~> 1.6)
+ googleauth (>= 0.16.2, < 2.a)
+ mini_mime (~> 1.0)
+ googleauth (1.8.1)
+ faraday (>= 0.17.3, < 3.a)
+ jwt (>= 1.4, < 3.0)
+ multi_json (~> 1.11)
+ os (>= 0.9, < 2.0)
+ signet (>= 0.16, < 2.a)
+ highline (2.0.3)
+ http-cookie (1.0.5)
+ domain_name (~> 0.5)
+ httpclient (2.8.3)
+ jmespath (1.6.2)
+ json (2.7.1)
+ jwt (2.7.1)
+ kramdown (2.4.0)
+ rexml
+ kramdown-parser-gfm (1.1.0)
+ kramdown (~> 2.0)
+ mini_magick (4.12.0)
+ mini_mime (1.1.5)
+ multi_json (1.15.0)
+ multipart-post (2.4.0)
+ nanaimo (0.3.0)
+ nap (1.1.0)
+ naturally (2.2.1)
+ no_proxy_fix (0.1.2)
+ octokit (8.0.0)
+ faraday (>= 1, < 3)
+ sawyer (~> 0.9)
+ open4 (1.3.4)
+ optparse (0.4.0)
+ os (1.1.4)
+ plist (3.7.1)
+ public_suffix (5.0.4)
+ rake (13.1.0)
+ rchardet (1.8.0)
+ representable (3.2.0)
+ declarative (< 0.1.0)
+ trailblazer-option (>= 0.1.1, < 0.2.0)
+ uber (< 0.2.0)
+ retriable (3.1.2)
+ rexml (3.2.6)
+ rouge (2.0.7)
+ ruby2_keywords (0.0.5)
+ rubyzip (2.3.2)
+ sawyer (0.9.2)
+ addressable (>= 2.3.5)
+ faraday (>= 0.17.3, < 3)
+ security (0.1.3)
+ signet (0.18.0)
+ addressable (~> 2.8)
+ faraday (>= 0.17.5, < 3.a)
+ jwt (>= 1.5, < 3.0)
+ multi_json (~> 1.10)
+ simctl (1.6.10)
+ CFPropertyList
+ naturally
+ slack-notifier (2.4.0)
+ terminal-notifier (2.0.0)
+ terminal-table (3.0.2)
+ unicode-display_width (>= 1.1.1, < 3)
+ trailblazer-option (0.1.2)
+ tty-cursor (0.7.1)
+ tty-screen (0.8.2)
+ tty-spinner (0.9.3)
+ tty-cursor (~> 0.7)
+ uber (0.1.0)
+ unicode-display_width (2.5.0)
+ word_wrap (1.0.0)
+ xcodeproj (1.24.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)
+ xcov (1.8.1)
+ fastlane (>= 2.141.0, < 3.0.0)
+ multipart-post
+ slack-notifier
+ terminal-table
+ xcodeproj
+ xcresult (~> 0.2.0)
+ xcpretty (0.3.0)
+ rouge (~> 2.0.7)
+ xcpretty-travis-formatter (1.0.1)
+ xcpretty (~> 0.2, >= 0.0.7)
+ xcresult (0.2.1)
+
+PLATFORMS
+ arm64-darwin-22
+ ruby
+
+DEPENDENCIES
+ danger (~> 9.4)
+ danger-xcov!
+ xcov (~> 1.8)
+
+BUNDLED WITH
+ 2.5.1
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..261eeb9
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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.
diff --git a/Makefile b/Makefile
new file mode 100755
index 0000000..f27bbf2
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,5 @@
+unit_tests:
+ ./run_tests.sh --scheme swift-web3modal-Package
+
+release:
+ fastlane release_testflight token:$(TOKEN) project_id:$(PROJECT_ID)
\ No newline at end of file
diff --git a/Package.resolved b/Package.resolved
new file mode 100644
index 0000000..06d75eb
--- /dev/null
+++ b/Package.resolved
@@ -0,0 +1,59 @@
+{
+ "pins" : [
+ {
+ "identity" : "qrcode",
+ "kind" : "remoteSourceControl",
+ "location" : "https://github.com/WalletConnect/QRCode",
+ "state" : {
+ "revision" : "263f280d2c8144adfb0b6676109846cfc8dd552b",
+ "version" : "14.3.1"
+ }
+ },
+ {
+ "identity" : "swift-qrcode-generator",
+ "kind" : "remoteSourceControl",
+ "location" : "https://github.com/dagronf/swift-qrcode-generator",
+ "state" : {
+ "revision" : "5ca09b6a2ad190f94aa3d6ddef45b187f8c0343b",
+ "version" : "1.0.3"
+ }
+ },
+ {
+ "identity" : "swift-snapshot-testing",
+ "kind" : "remoteSourceControl",
+ "location" : "https://github.com/pointfreeco/swift-snapshot-testing",
+ "state" : {
+ "revision" : "f29e2014f6230cf7d5138fc899da51c7f513d467",
+ "version" : "1.10.0"
+ }
+ },
+ {
+ "identity" : "swiftimagereadwrite",
+ "kind" : "remoteSourceControl",
+ "location" : "https://github.com/dagronf/SwiftImageReadWrite",
+ "state" : {
+ "revision" : "5596407d1cf61b953b8e658fa8636a471df3c509",
+ "version" : "1.1.6"
+ }
+ },
+ {
+ "identity" : "wallet-mobile-sdk",
+ "kind" : "remoteSourceControl",
+ "location" : "https://github.com/WalletConnect/wallet-mobile-sdk",
+ "state" : {
+ "revision" : "b6dfb7d6b8447c7c5b238a10443a1ac28223f38f",
+ "version" : "1.0.0"
+ }
+ },
+ {
+ "identity" : "walletconnectswiftv2",
+ "kind" : "remoteSourceControl",
+ "location" : "https://github.com/WalletConnect/WalletConnectSwiftV2",
+ "state" : {
+ "revision" : "4f93c19f02b5b9ae0a984794cae542b9ca1b7471",
+ "version" : "1.13.0"
+ }
+ }
+ ],
+ "version" : 2
+}
diff --git a/Package.swift b/Package.swift
new file mode 100644
index 0000000..3e6f068
--- /dev/null
+++ b/Package.swift
@@ -0,0 +1,84 @@
+// swift-tools-version: 5.8
+// The swift-tools-version declares the minimum version of Swift required to build this package.
+
+import PackageDescription
+
+let package = Package(
+ name: "swift-web3modal",
+ platforms: [
+ .iOS(.v13),
+ ],
+ products: [
+ .library(
+ name: "Web3Modal",
+ targets: ["Web3Modal"]
+ ),
+ .library(
+ name: "Web3ModalUI",
+ targets: ["Web3ModalUI"]
+ )
+ ],
+ dependencies: [
+ .package(
+ url: "https://github.com/WalletConnect/WalletConnectSwiftV2",
+ .upToNextMinor(from: "1.13.0")
+ ),
+ .package(
+ url: "https://github.com/WalletConnect/QRCode",
+ .upToNextMinor(from: "14.3.1")
+ ),
+ .package(
+ url: "https://github.com/pointfreeco/swift-snapshot-testing",
+ .upToNextMinor(from: "1.10.0")
+ ),
+ .package(name: "CoinbaseWalletSDK", url: "https://github.com/WalletConnect/wallet-mobile-sdk", from: "1.0.0"),
+ ],
+ targets: [
+ .target(
+ name: "Web3Modal",
+ dependencies: [
+ "QRCode",
+ .product(
+ name: "WalletConnect",
+ package: "WalletConnectSwiftV2"
+ ),
+ "Web3ModalUI",
+ "Web3ModalBackport",
+ "CoinbaseWalletSDK"
+ ],
+ resources: [
+ .process("Resources/Assets.xcassets"),
+ .copy("PackageConfig.json")
+ ]
+ ),
+ .target(
+ name: "Web3ModalUI",
+ dependencies: [
+ "Web3ModalBackport"
+ ],
+ resources: [
+ .process("Resources/Assets.xcassets")
+ ]
+ ),
+ .target(
+ name: "Web3ModalBackport"
+ ),
+
+ // MARK: - Test Targets
+
+ .testTarget(
+ name: "Web3ModalTests",
+ dependencies: [
+ "Web3Modal",
+ .product(name: "SnapshotTesting", package: "swift-snapshot-testing")
+ ]
+ ),
+ .testTarget(
+ name: "Web3ModalUITests",
+ dependencies: [
+ "Web3ModalUI",
+ .product(name: "SnapshotTesting", package: "swift-snapshot-testing")
+ ]
+ )
+ ]
+)
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..8078d1f
--- /dev/null
+++ b/README.md
@@ -0,0 +1,8 @@
+
+#### 📚 [Documentation](https://docs.walletconnect.com/web3modal/ios/about)
+
+#### 🔗 [Website](https://web3modal.com)
+
+# Web3Modal
+
+Your on-ramp to web3 multichain. Web3Modal is a versatile library that makes it super easy to connect users with your Dapp and start interacting with the blockchain.
diff --git a/Sample/.gitignore b/Sample/.gitignore
new file mode 100644
index 0000000..7979e00
--- /dev/null
+++ b/Sample/.gitignore
@@ -0,0 +1 @@
+.sentryclirc
\ No newline at end of file
diff --git a/Sample/Example.xcodeproj/project.pbxproj b/Sample/Example.xcodeproj/project.pbxproj
new file mode 100644
index 0000000..5c76605
--- /dev/null
+++ b/Sample/Example.xcodeproj/project.pbxproj
@@ -0,0 +1,536 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 60;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 23F6FD03919B41DE98CAFCD3 /* Sentry in Frameworks */ = {isa = PBXBuildFile; productRef = BD206AA550964C49AE94A3CA /* Sentry */; };
+ 84D9CCC32B9708E4001EDEE3 /* Starscream in Frameworks */ = {isa = PBXBuildFile; productRef = 84D9CCC22B9708E4001EDEE3 /* Starscream */; };
+ CF0BCCE52AB0886400A2866C /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CF0BCCE42AB0886400A2866C /* ContentView.swift */; };
+ CF25F3A22B40C7070030B3DC /* Web3Modal in Frameworks */ = {isa = PBXBuildFile; productRef = CF25F3A12B40C7070030B3DC /* Web3Modal */; };
+ CF25F3A42B40C7070030B3DC /* Web3ModalUI in Frameworks */ = {isa = PBXBuildFile; productRef = CF25F3A32B40C7070030B3DC /* Web3ModalUI */; };
+ CF3B9AD02ACDBA3A00984D53 /* Web3Modal in Frameworks */ = {isa = PBXBuildFile; productRef = CF3B9ACF2ACDBA3A00984D53 /* Web3Modal */; };
+ CF3B9AD22ACDBA3A00984D53 /* Web3ModalUI in Frameworks */ = {isa = PBXBuildFile; productRef = CF3B9AD12ACDBA3A00984D53 /* Web3ModalUI */; };
+ CFA99B922AD0549F00EB5331 /* WCSocketFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = CFA99B912AD0549F00EB5331 /* WCSocketFactory.swift */; };
+ CFD6A70F2ADE8DE2002B402C /* Atlantis in Frameworks */ = {isa = PBXBuildFile; productRef = CFD6A70E2ADE8DE2002B402C /* Atlantis */; };
+ CFD720782A9CC60600636CAF /* ExampleApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = CFD720772A9CC60600636CAF /* ExampleApp.swift */; };
+ CFD7207A2A9CC60600636CAF /* ComponentLibraryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CFD720792A9CC60600636CAF /* ComponentLibraryView.swift */; };
+ CFD7207C2A9CC60700636CAF /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = CFD7207B2A9CC60700636CAF /* Assets.xcassets */; };
+ CFD720802A9CC60700636CAF /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = CFD7207F2A9CC60700636CAF /* Preview Assets.xcassets */; };
+ CFEAAF0A2B6C0B3A001565F5 /* InputConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = CFEAAF092B6C0B3A001565F5 /* InputConfig.swift */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXFileReference section */
+ CF0BCCE42AB0886400A2866C /* ContentView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; };
+ CF533D032ADD411A00B3441C /* web3modal-swift */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = "web3modal-swift"; path = ..; sourceTree = ""; };
+ CF74C5C62B323048007B0926 /* swift-web3modal-Package.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = "swift-web3modal-Package.xctestplan"; sourceTree = ""; };
+ CFA99B912AD0549F00EB5331 /* WCSocketFactory.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WCSocketFactory.swift; sourceTree = ""; };
+ CFD6A7102ADE8E26002B402C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; };
+ CFD720742A9CC60600636CAF /* Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Example.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ CFD720772A9CC60600636CAF /* ExampleApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExampleApp.swift; sourceTree = ""; };
+ CFD720792A9CC60600636CAF /* ComponentLibraryView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComponentLibraryView.swift; sourceTree = ""; };
+ CFD7207B2A9CC60700636CAF /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
+ CFD7207D2A9CC60700636CAF /* Example.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Example.entitlements; sourceTree = ""; };
+ CFD7207F2A9CC60700636CAF /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; };
+ CFEAAF082B6C0A58001565F5 /* Configuration.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Configuration.xcconfig; sourceTree = ""; };
+ CFEAAF092B6C0B3A001565F5 /* InputConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InputConfig.swift; sourceTree = ""; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ CFD720712A9CC60600636CAF /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 84D9CCC32B9708E4001EDEE3 /* Starscream in Frameworks */,
+ CF3B9AD02ACDBA3A00984D53 /* Web3Modal in Frameworks */,
+ CFD6A70F2ADE8DE2002B402C /* Atlantis in Frameworks */,
+ CF25F3A42B40C7070030B3DC /* Web3ModalUI in Frameworks */,
+ CF3B9AD22ACDBA3A00984D53 /* Web3ModalUI in Frameworks */,
+ CF25F3A22B40C7070030B3DC /* Web3Modal in Frameworks */,
+ 23F6FD03919B41DE98CAFCD3 /* Sentry in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ CFD7206B2A9CC60600636CAF = {
+ isa = PBXGroup;
+ children = (
+ CF74C5C62B323048007B0926 /* swift-web3modal-Package.xctestplan */,
+ CF533D032ADD411A00B3441C /* web3modal-swift */,
+ CFD720762A9CC60600636CAF /* Example */,
+ CFD720752A9CC60600636CAF /* Products */,
+ CFD720AF2A9CC71600636CAF /* Frameworks */,
+ );
+ sourceTree = "";
+ };
+ CFD720752A9CC60600636CAF /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ CFD720742A9CC60600636CAF /* Example.app */,
+ );
+ name = Products;
+ sourceTree = "";
+ };
+ CFD720762A9CC60600636CAF /* Example */ = {
+ isa = PBXGroup;
+ children = (
+ CFD6A7102ADE8E26002B402C /* Info.plist */,
+ CFA99B912AD0549F00EB5331 /* WCSocketFactory.swift */,
+ CFD720772A9CC60600636CAF /* ExampleApp.swift */,
+ CFD720792A9CC60600636CAF /* ComponentLibraryView.swift */,
+ CFEAAF082B6C0A58001565F5 /* Configuration.xcconfig */,
+ CF0BCCE42AB0886400A2866C /* ContentView.swift */,
+ CFD7207B2A9CC60700636CAF /* Assets.xcassets */,
+ CFD7207D2A9CC60700636CAF /* Example.entitlements */,
+ CFD7207E2A9CC60700636CAF /* Preview Content */,
+ CFEAAF092B6C0B3A001565F5 /* InputConfig.swift */,
+ );
+ path = Example;
+ sourceTree = "";
+ };
+ CFD7207E2A9CC60700636CAF /* Preview Content */ = {
+ isa = PBXGroup;
+ children = (
+ CFD7207F2A9CC60700636CAF /* Preview Assets.xcassets */,
+ );
+ path = "Preview Content";
+ sourceTree = "";
+ };
+ CFD720AF2A9CC71600636CAF /* Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ );
+ name = Frameworks;
+ sourceTree = "";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ CFD720732A9CC60600636CAF /* Example */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = CFD720992A9CC60800636CAF /* Build configuration list for PBXNativeTarget "Example" */;
+ buildPhases = (
+ CFD720702A9CC60600636CAF /* Sources */,
+ CFD720712A9CC60600636CAF /* Frameworks */,
+ CFD720722A9CC60600636CAF /* Resources */,
+ E330D833155D4B53B676C733 /* Upload Debug Symbols to Sentry */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = Example;
+ packageProductDependencies = (
+ CF3B9ACF2ACDBA3A00984D53 /* Web3Modal */,
+ CF3B9AD12ACDBA3A00984D53 /* Web3ModalUI */,
+ CFD6A70E2ADE8DE2002B402C /* Atlantis */,
+ BD206AA550964C49AE94A3CA /* Sentry */,
+ CF25F3A12B40C7070030B3DC /* Web3Modal */,
+ CF25F3A32B40C7070030B3DC /* Web3ModalUI */,
+ 84D9CCC22B9708E4001EDEE3 /* Starscream */,
+ );
+ productName = Example;
+ productReference = CFD720742A9CC60600636CAF /* Example.app */;
+ productType = "com.apple.product-type.application";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ CFD7206C2A9CC60600636CAF /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ BuildIndependentTargetsInParallel = 1;
+ LastSwiftUpdateCheck = 1500;
+ LastUpgradeCheck = 1500;
+ TargetAttributes = {
+ CFD720732A9CC60600636CAF = {
+ CreatedOnToolsVersion = 15.0;
+ };
+ };
+ };
+ buildConfigurationList = CFD7206F2A9CC60600636CAF /* Build configuration list for PBXProject "Example" */;
+ compatibilityVersion = "Xcode 14.0";
+ developmentRegion = en;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ en,
+ Base,
+ );
+ mainGroup = CFD7206B2A9CC60600636CAF;
+ packageReferences = (
+ CFD6A70D2ADE8DE2002B402C /* XCRemoteSwiftPackageReference "atlantis" */,
+ CF25F3A02B40C7070030B3DC /* XCLocalSwiftPackageReference ".." */,
+ F4A0329B6CFF49E682D3DFE7 /* XCRemoteSwiftPackageReference "sentry-cocoa" */,
+ 84D9CCC12B9708E4001EDEE3 /* XCRemoteSwiftPackageReference "Starscream" */,
+ );
+ productRefGroup = CFD720752A9CC60600636CAF /* Products */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ CFD720732A9CC60600636CAF /* Example */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ CFD720722A9CC60600636CAF /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ CFD720802A9CC60700636CAF /* Preview Assets.xcassets in Resources */,
+ CFD7207C2A9CC60700636CAF /* Assets.xcassets in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXShellScriptBuildPhase section */
+ E330D833155D4B53B676C733 /* Upload Debug Symbols to Sentry */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ "${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}/Contents/Resources/DWARF/${TARGET_NAME}",
+ );
+ name = "Upload Debug Symbols to Sentry";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "# This script is responsable to upload debug symbols and source context for Sentry.\nif which sentry-cli >/dev/null; then\nexport SENTRY_ORG=walletconnect\nexport SENTRY_PROJECT=web3modal-sample\nERROR=$(sentry-cli debug-files upload --include-sources \"$DWARF_DSYM_FOLDER_PATH\" 2>&1 >/dev/null)\nif [ ! $? -eq 0 ]; then\necho \"warning: sentry-cli - $ERROR\"\nfi\nelse\necho \"warning: sentry-cli not installed, download from https://github.com/getsentry/sentry-cli/releases\"\nfi\n";
+ };
+/* End PBXShellScriptBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ CFD720702A9CC60600636CAF /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ CFEAAF0A2B6C0B3A001565F5 /* InputConfig.swift in Sources */,
+ CFD7207A2A9CC60600636CAF /* ComponentLibraryView.swift in Sources */,
+ CFD720782A9CC60600636CAF /* ExampleApp.swift in Sources */,
+ CF0BCCE52AB0886400A2866C /* ContentView.swift in Sources */,
+ CFA99B922AD0549F00EB5331 /* WCSocketFactory.swift in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin XCBuildConfiguration section */
+ CFD720972A9CC60800636CAF /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = CFEAAF082B6C0A58001565F5 /* Configuration.xcconfig */;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ COPY_PHASE_STRIP = NO;
+ DEAD_CODE_STRIPPING = YES;
+ DEBUG_INFORMATION_FORMAT = dwarf;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_TESTABILITY = YES;
+ ENABLE_USER_SCRIPT_SANDBOXING = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu17;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "DEBUG=1",
+ "$(inherited)",
+ );
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 15.0;
+ LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
+ MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
+ MTL_FAST_MATH = YES;
+ ONLY_ACTIVE_ARCH = YES;
+ SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)";
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+ };
+ name = Debug;
+ };
+ CFD720982A9CC60800636CAF /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = CFEAAF082B6C0A58001565F5 /* Configuration.xcconfig */;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ COPY_PHASE_STRIP = NO;
+ DEAD_CODE_STRIPPING = YES;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ ENABLE_NS_ASSERTIONS = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_USER_SCRIPT_SANDBOXING = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu17;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 15.0;
+ LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ MTL_FAST_MATH = YES;
+ SWIFT_COMPILATION_MODE = wholemodule;
+ };
+ name = Release;
+ };
+ CFD7209A2A9CC60800636CAF /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = CFEAAF082B6C0A58001565F5 /* Configuration.xcconfig */;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
+ CODE_SIGN_ENTITLEMENTS = Example/Example.entitlements;
+ CODE_SIGN_IDENTITY = "Apple Development";
+ CODE_SIGN_STYLE = Automatic;
+ CURRENT_PROJECT_VERSION = 16;
+ DEAD_CODE_STRIPPING = YES;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ DEVELOPMENT_ASSET_PATHS = "\"Example/Preview Content\"";
+ DEVELOPMENT_TEAM = W5R8AG9K22;
+ ENABLE_HARDENED_RUNTIME = YES;
+ ENABLE_PREVIEWS = YES;
+ GENERATE_INFOPLIST_FILE = YES;
+ INFOPLIST_FILE = Example/Info.plist;
+ INFOPLIST_KEY_CFBundleDisplayName = "Web3Modal Sample";
+ INFOPLIST_KEY_NSCameraUsageDescription = "Web3Modal requires access to your phone’s camera.";
+ INFOPLIST_KEY_NSLocalNetworkUsageDescription = "Atlantis would use Bonjour Service to discover Proxyman app from your local network.";
+ "INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES;
+ "INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphonesimulator*]" = YES;
+ "INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphoneos*]" = YES;
+ "INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphonesimulator*]" = YES;
+ "INFOPLIST_KEY_UILaunchScreen_Generation[sdk=iphoneos*]" = YES;
+ "INFOPLIST_KEY_UILaunchScreen_Generation[sdk=iphonesimulator*]" = YES;
+ "INFOPLIST_KEY_UIStatusBarStyle[sdk=iphoneos*]" = UIStatusBarStyleDefault;
+ "INFOPLIST_KEY_UIStatusBarStyle[sdk=iphonesimulator*]" = UIStatusBarStyleDefault;
+ INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait";
+ INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown";
+ IPHONEOS_DEPLOYMENT_TARGET = 15.0;
+ LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks";
+ "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks";
+ MACOSX_DEPLOYMENT_TARGET = 13.0;
+ MARKETING_VERSION = 1.0;
+ PRODUCT_BUNDLE_IDENTIFIER = com.walletconnect.web3modal.sample;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ PROJECT_ID = "$(PROJECT_ID)";
+ PROVISIONING_PROFILE_SPECIFIER = "";
+ SDKROOT = auto;
+ SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
+ SUPPORTS_MACCATALYST = NO;
+ SWIFT_EMIT_LOC_STRINGS = YES;
+ SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Debug;
+ };
+ CFD7209B2A9CC60800636CAF /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = CFEAAF082B6C0A58001565F5 /* Configuration.xcconfig */;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
+ CODE_SIGN_ENTITLEMENTS = Example/Example.entitlements;
+ CODE_SIGN_IDENTITY = "Apple Development";
+ CODE_SIGN_STYLE = Automatic;
+ CURRENT_PROJECT_VERSION = 16;
+ DEAD_CODE_STRIPPING = YES;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ DEVELOPMENT_ASSET_PATHS = "\"Example/Preview Content\"";
+ DEVELOPMENT_TEAM = W5R8AG9K22;
+ ENABLE_HARDENED_RUNTIME = YES;
+ ENABLE_PREVIEWS = YES;
+ GENERATE_INFOPLIST_FILE = YES;
+ INFOPLIST_FILE = Example/Info.plist;
+ INFOPLIST_KEY_CFBundleDisplayName = "Web3Modal Sample";
+ INFOPLIST_KEY_NSCameraUsageDescription = "Web3Modal requires access to your phone’s camera.";
+ INFOPLIST_KEY_NSLocalNetworkUsageDescription = "Atlantis would use Bonjour Service to discover Proxyman app from your local network.";
+ "INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES;
+ "INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphonesimulator*]" = YES;
+ "INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphoneos*]" = YES;
+ "INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphonesimulator*]" = YES;
+ "INFOPLIST_KEY_UILaunchScreen_Generation[sdk=iphoneos*]" = YES;
+ "INFOPLIST_KEY_UILaunchScreen_Generation[sdk=iphonesimulator*]" = YES;
+ "INFOPLIST_KEY_UIStatusBarStyle[sdk=iphoneos*]" = UIStatusBarStyleDefault;
+ "INFOPLIST_KEY_UIStatusBarStyle[sdk=iphonesimulator*]" = UIStatusBarStyleDefault;
+ INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait";
+ INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown";
+ IPHONEOS_DEPLOYMENT_TARGET = 15.0;
+ LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks";
+ "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks";
+ MACOSX_DEPLOYMENT_TARGET = 13.0;
+ MARKETING_VERSION = 1.0;
+ PRODUCT_BUNDLE_IDENTIFIER = com.walletconnect.web3modal.sample;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ PROJECT_ID = "$(PROJECT_ID)";
+ PROVISIONING_PROFILE_SPECIFIER = "";
+ SDKROOT = auto;
+ SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
+ SUPPORTS_MACCATALYST = NO;
+ SWIFT_EMIT_LOC_STRINGS = YES;
+ SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ CFD7206F2A9CC60600636CAF /* Build configuration list for PBXProject "Example" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ CFD720972A9CC60800636CAF /* Debug */,
+ CFD720982A9CC60800636CAF /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ CFD720992A9CC60800636CAF /* Build configuration list for PBXNativeTarget "Example" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ CFD7209A2A9CC60800636CAF /* Debug */,
+ CFD7209B2A9CC60800636CAF /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+
+/* Begin XCLocalSwiftPackageReference section */
+ CF25F3A02B40C7070030B3DC /* XCLocalSwiftPackageReference ".." */ = {
+ isa = XCLocalSwiftPackageReference;
+ relativePath = ..;
+ };
+/* End XCLocalSwiftPackageReference section */
+
+/* Begin XCRemoteSwiftPackageReference section */
+ 84D9CCC12B9708E4001EDEE3 /* XCRemoteSwiftPackageReference "Starscream" */ = {
+ isa = XCRemoteSwiftPackageReference;
+ repositoryURL = "https://github.com/daltoniam/Starscream";
+ requirement = {
+ kind = upToNextMajorVersion;
+ minimumVersion = 3.1.2;
+ };
+ };
+ CFD6A70D2ADE8DE2002B402C /* XCRemoteSwiftPackageReference "atlantis" */ = {
+ isa = XCRemoteSwiftPackageReference;
+ repositoryURL = "https://github.com/ProxymanApp/atlantis";
+ requirement = {
+ kind = upToNextMajorVersion;
+ minimumVersion = 1.22.0;
+ };
+ };
+ F4A0329B6CFF49E682D3DFE7 /* XCRemoteSwiftPackageReference "sentry-cocoa" */ = {
+ isa = XCRemoteSwiftPackageReference;
+ repositoryURL = "https://github.com/getsentry/sentry-cocoa/";
+ requirement = {
+ kind = upToNextMajorVersion;
+ minimumVersion = 8.0.0;
+ };
+ };
+/* End XCRemoteSwiftPackageReference section */
+
+/* Begin XCSwiftPackageProductDependency section */
+ 84D9CCC22B9708E4001EDEE3 /* Starscream */ = {
+ isa = XCSwiftPackageProductDependency;
+ package = 84D9CCC12B9708E4001EDEE3 /* XCRemoteSwiftPackageReference "Starscream" */;
+ productName = Starscream;
+ };
+ BD206AA550964C49AE94A3CA /* Sentry */ = {
+ isa = XCSwiftPackageProductDependency;
+ package = F4A0329B6CFF49E682D3DFE7 /* XCRemoteSwiftPackageReference "sentry-cocoa" */;
+ productName = Sentry;
+ };
+ CF25F3A12B40C7070030B3DC /* Web3Modal */ = {
+ isa = XCSwiftPackageProductDependency;
+ productName = Web3Modal;
+ };
+ CF25F3A32B40C7070030B3DC /* Web3ModalUI */ = {
+ isa = XCSwiftPackageProductDependency;
+ productName = Web3ModalUI;
+ };
+ CF3B9ACF2ACDBA3A00984D53 /* Web3Modal */ = {
+ isa = XCSwiftPackageProductDependency;
+ productName = Web3Modal;
+ };
+ CF3B9AD12ACDBA3A00984D53 /* Web3ModalUI */ = {
+ isa = XCSwiftPackageProductDependency;
+ productName = Web3ModalUI;
+ };
+ CFD6A70E2ADE8DE2002B402C /* Atlantis */ = {
+ isa = XCSwiftPackageProductDependency;
+ package = CFD6A70D2ADE8DE2002B402C /* XCRemoteSwiftPackageReference "atlantis" */;
+ productName = Atlantis;
+ };
+/* End XCSwiftPackageProductDependency section */
+ };
+ rootObject = CFD7206C2A9CC60600636CAF /* Project object */;
+}
diff --git a/Sample/Example.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Sample/Example.xcodeproj/project.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..919434a
--- /dev/null
+++ b/Sample/Example.xcodeproj/project.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/Sample/Example.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Sample/Example.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
new file mode 100644
index 0000000..18d9810
--- /dev/null
+++ b/Sample/Example.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
@@ -0,0 +1,8 @@
+
+
+
+
+ IDEDidComputeMac32BitWarning
+
+
+
diff --git a/Sample/Example.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Sample/Example.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved
new file mode 100644
index 0000000..bf41bdf
--- /dev/null
+++ b/Sample/Example.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved
@@ -0,0 +1,86 @@
+{
+ "pins" : [
+ {
+ "identity" : "atlantis",
+ "kind" : "remoteSourceControl",
+ "location" : "https://github.com/ProxymanApp/atlantis",
+ "state" : {
+ "revision" : "cfa72085bce2600b28e47fdbbbfa2d5b96f0392b",
+ "version" : "1.22.0"
+ }
+ },
+ {
+ "identity" : "qrcode",
+ "kind" : "remoteSourceControl",
+ "location" : "https://github.com/WalletConnect/QRCode",
+ "state" : {
+ "revision" : "263f280d2c8144adfb0b6676109846cfc8dd552b",
+ "version" : "14.3.1"
+ }
+ },
+ {
+ "identity" : "sentry-cocoa",
+ "kind" : "remoteSourceControl",
+ "location" : "https://github.com/getsentry/sentry-cocoa/",
+ "state" : {
+ "revision" : "74cf23b2946c92550fb1185612077151497e648e",
+ "version" : "8.17.1"
+ }
+ },
+ {
+ "identity" : "swift-qrcode-generator",
+ "kind" : "remoteSourceControl",
+ "location" : "https://github.com/dagronf/swift-qrcode-generator",
+ "state" : {
+ "revision" : "5ca09b6a2ad190f94aa3d6ddef45b187f8c0343b",
+ "version" : "1.0.3"
+ }
+ },
+ {
+ "identity" : "swift-snapshot-testing",
+ "kind" : "remoteSourceControl",
+ "location" : "https://github.com/pointfreeco/swift-snapshot-testing",
+ "state" : {
+ "revision" : "bb0ea08db8e73324fe6c3727f755ca41a23ff2f4",
+ "version" : "1.14.2"
+ }
+ },
+ {
+ "identity" : "swift-syntax",
+ "kind" : "remoteSourceControl",
+ "location" : "https://github.com/apple/swift-syntax.git",
+ "state" : {
+ "revision" : "74203046135342e4a4a627476dd6caf8b28fe11b",
+ "version" : "509.0.0"
+ }
+ },
+ {
+ "identity" : "swiftimagereadwrite",
+ "kind" : "remoteSourceControl",
+ "location" : "https://github.com/dagronf/SwiftImageReadWrite",
+ "state" : {
+ "revision" : "5596407d1cf61b953b8e658fa8636a471df3c509",
+ "version" : "1.1.6"
+ }
+ },
+ {
+ "identity" : "wallet-mobile-sdk",
+ "kind" : "remoteSourceControl",
+ "location" : "https://github.com/coinbase/wallet-mobile-sdk.git",
+ "state" : {
+ "revision" : "4aa89e682f8d7ab1515d85d0797f0d25306bb56a",
+ "version" : "1.0.5"
+ }
+ },
+ {
+ "identity" : "walletconnectswiftv2",
+ "kind" : "remoteSourceControl",
+ "location" : "https://github.com/WalletConnect/WalletConnectSwiftV2",
+ "state" : {
+ "revision" : "f2db5e796976e6294b40da01c443f39a16b4732a",
+ "version" : "1.12.0"
+ }
+ }
+ ],
+ "version" : 2
+}
diff --git a/Sample/Example.xcodeproj/xcshareddata/xcschemes/Example.xcscheme b/Sample/Example.xcodeproj/xcshareddata/xcschemes/Example.xcscheme
new file mode 100644
index 0000000..8897b11
--- /dev/null
+++ b/Sample/Example.xcodeproj/xcshareddata/xcschemes/Example.xcscheme
@@ -0,0 +1,101 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Sample/Example/Assets.xcassets/AccentColor.colorset/Contents.json b/Sample/Example/Assets.xcassets/AccentColor.colorset/Contents.json
new file mode 100644
index 0000000..eb87897
--- /dev/null
+++ b/Sample/Example/Assets.xcassets/AccentColor.colorset/Contents.json
@@ -0,0 +1,11 @@
+{
+ "colors" : [
+ {
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sample/Example/Assets.xcassets/AppIcon.appiconset/Contents.json b/Sample/Example/Assets.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644
index 0000000..78d34c2
--- /dev/null
+++ b/Sample/Example/Assets.xcassets/AppIcon.appiconset/Contents.json
@@ -0,0 +1,116 @@
+{
+ "images" : [
+ {
+ "filename" : "Icon-App-20x20@2x.png",
+ "idiom" : "iphone",
+ "scale" : "2x",
+ "size" : "20x20"
+ },
+ {
+ "filename" : "Icon-App-20x20@3x.png",
+ "idiom" : "iphone",
+ "scale" : "3x",
+ "size" : "20x20"
+ },
+ {
+ "filename" : "Icon-App-29x29@2x.png",
+ "idiom" : "iphone",
+ "scale" : "2x",
+ "size" : "29x29"
+ },
+ {
+ "filename" : "Icon-App-29x29@3x.png",
+ "idiom" : "iphone",
+ "scale" : "3x",
+ "size" : "29x29"
+ },
+ {
+ "filename" : "Icon-App-40x40@2x.png",
+ "idiom" : "iphone",
+ "scale" : "2x",
+ "size" : "40x40"
+ },
+ {
+ "filename" : "Icon-App-40x40@3x.png",
+ "idiom" : "iphone",
+ "scale" : "3x",
+ "size" : "40x40"
+ },
+ {
+ "filename" : "Icon-App-60x60@2x.png",
+ "idiom" : "iphone",
+ "scale" : "2x",
+ "size" : "60x60"
+ },
+ {
+ "filename" : "Icon-App-60x60@3x.png",
+ "idiom" : "iphone",
+ "scale" : "3x",
+ "size" : "60x60"
+ },
+ {
+ "filename" : "Icon-App-20x20@1x.png",
+ "idiom" : "ipad",
+ "scale" : "1x",
+ "size" : "20x20"
+ },
+ {
+ "filename" : "Icon-App-20x20@2x-1.png",
+ "idiom" : "ipad",
+ "scale" : "2x",
+ "size" : "20x20"
+ },
+ {
+ "filename" : "Icon-App-29x29@1x.png",
+ "idiom" : "ipad",
+ "scale" : "1x",
+ "size" : "29x29"
+ },
+ {
+ "filename" : "Icon-App-29x29@2x-1.png",
+ "idiom" : "ipad",
+ "scale" : "2x",
+ "size" : "29x29"
+ },
+ {
+ "filename" : "Icon-App-40x40@1x.png",
+ "idiom" : "ipad",
+ "scale" : "1x",
+ "size" : "40x40"
+ },
+ {
+ "filename" : "Icon-App-40x40@2x-1.png",
+ "idiom" : "ipad",
+ "scale" : "2x",
+ "size" : "40x40"
+ },
+ {
+ "filename" : "Icon-App-76x76@1x.png",
+ "idiom" : "ipad",
+ "scale" : "1x",
+ "size" : "76x76"
+ },
+ {
+ "filename" : "Icon-App-76x76@2x.png",
+ "idiom" : "ipad",
+ "scale" : "2x",
+ "size" : "76x76"
+ },
+ {
+ "filename" : "Icon-App-83.5x83.5@2x.png",
+ "idiom" : "ipad",
+ "scale" : "2x",
+ "size" : "83.5x83.5"
+ },
+ {
+ "filename" : "ItunesArtwork@2x.png",
+ "idiom" : "ios-marketing",
+ "scale" : "1x",
+ "size" : "1024x1024"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sample/Example/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/Sample/Example/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
new file mode 100644
index 0000000..e8b3b92
Binary files /dev/null and b/Sample/Example/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ
diff --git a/Sample/Example/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x-1.png b/Sample/Example/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x-1.png
new file mode 100644
index 0000000..7f3a702
Binary files /dev/null and b/Sample/Example/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x-1.png differ
diff --git a/Sample/Example/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/Sample/Example/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
new file mode 100644
index 0000000..7f3a702
Binary files /dev/null and b/Sample/Example/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ
diff --git a/Sample/Example/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/Sample/Example/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
new file mode 100644
index 0000000..d38db76
Binary files /dev/null and b/Sample/Example/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ
diff --git a/Sample/Example/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/Sample/Example/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
new file mode 100644
index 0000000..941819f
Binary files /dev/null and b/Sample/Example/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ
diff --git a/Sample/Example/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x-1.png b/Sample/Example/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x-1.png
new file mode 100644
index 0000000..d71e54b
Binary files /dev/null and b/Sample/Example/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x-1.png differ
diff --git a/Sample/Example/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/Sample/Example/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
new file mode 100644
index 0000000..d71e54b
Binary files /dev/null and b/Sample/Example/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ
diff --git a/Sample/Example/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/Sample/Example/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
new file mode 100644
index 0000000..dd60b86
Binary files /dev/null and b/Sample/Example/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ
diff --git a/Sample/Example/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/Sample/Example/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
new file mode 100644
index 0000000..7f3a702
Binary files /dev/null and b/Sample/Example/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ
diff --git a/Sample/Example/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x-1.png b/Sample/Example/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x-1.png
new file mode 100644
index 0000000..5c06655
Binary files /dev/null and b/Sample/Example/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x-1.png differ
diff --git a/Sample/Example/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/Sample/Example/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
new file mode 100644
index 0000000..5c06655
Binary files /dev/null and b/Sample/Example/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ
diff --git a/Sample/Example/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/Sample/Example/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
new file mode 100644
index 0000000..0fdab5f
Binary files /dev/null and b/Sample/Example/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ
diff --git a/Sample/Example/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/Sample/Example/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
new file mode 100644
index 0000000..0fdab5f
Binary files /dev/null and b/Sample/Example/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ
diff --git a/Sample/Example/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/Sample/Example/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
new file mode 100644
index 0000000..3b88e17
Binary files /dev/null and b/Sample/Example/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ
diff --git a/Sample/Example/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/Sample/Example/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
new file mode 100644
index 0000000..d0c9a1a
Binary files /dev/null and b/Sample/Example/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ
diff --git a/Sample/Example/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/Sample/Example/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
new file mode 100644
index 0000000..03bb3d0
Binary files /dev/null and b/Sample/Example/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ
diff --git a/Sample/Example/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/Sample/Example/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
new file mode 100644
index 0000000..fd505b5
Binary files /dev/null and b/Sample/Example/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ
diff --git a/Sample/Example/Assets.xcassets/AppIcon.appiconset/ItunesArtwork@2x.png b/Sample/Example/Assets.xcassets/AppIcon.appiconset/ItunesArtwork@2x.png
new file mode 100644
index 0000000..f527fe6
Binary files /dev/null and b/Sample/Example/Assets.xcassets/AppIcon.appiconset/ItunesArtwork@2x.png differ
diff --git a/Sample/Example/Assets.xcassets/Contents.json b/Sample/Example/Assets.xcassets/Contents.json
new file mode 100644
index 0000000..73c0059
--- /dev/null
+++ b/Sample/Example/Assets.xcassets/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sample/Example/ComponentLibraryView.swift b/Sample/Example/ComponentLibraryView.swift
new file mode 100644
index 0000000..226f3e8
--- /dev/null
+++ b/Sample/Example/ComponentLibraryView.swift
@@ -0,0 +1,53 @@
+import SwiftUI
+import Web3Modal
+
+
+struct ComponentLibraryView: View {
+ var body: some View {
+ listView
+ .navigationTitle("Components")
+ }
+
+ var listView: some View {
+ Group {
+#if DEBUG
+ List {
+ NavigationLink(destination: AccountButtonPreviewView()) {
+ Text("AccountButton")
+ }
+ NavigationLink(destination: NetworkButtonPreviewView()) {
+ Text("NetworkButton")
+ }
+ NavigationLink(destination: W3MButtonStylePreviewView()) {
+ Text("W3MButton")
+ }
+ NavigationLink(destination: W3MCardSelectStylePreviewView()) {
+ Text("W3MCardSelect")
+ }
+ NavigationLink(destination: W3MTagPreviewView()) {
+ Text("W3MTag")
+ }
+ NavigationLink(destination: W3MListSelectStylePreviewView()) {
+ Text("W3MListSelect")
+ }
+ NavigationLink(destination: W3MActionEntryStylePreviewView()) {
+ Text("W3MActionEntry")
+ }
+ NavigationLink(destination: QRCodeViewPreviewView()) {
+ Text("QRCode")
+ }
+ NavigationLink(destination: W3MChipButtonStylePreviewView()) {
+ Text("W3MChipButtonStyle")
+ }
+ NavigationLink(destination: W3MListItemButtonStylePreviewView()) {
+ Text("W3MListItemButtonStyle")
+ }
+ NavigationLink(destination: ToastViewPreviewView()) {
+ Text("ToastView")
+ }
+ }
+ .listStyle(.plain)
+#endif
+ }
+ }
+}
diff --git a/Sample/Example/Configuration.xcconfig b/Sample/Example/Configuration.xcconfig
new file mode 100644
index 0000000..16b8a91
--- /dev/null
+++ b/Sample/Example/Configuration.xcconfig
@@ -0,0 +1,2 @@
+// Uncomment next line and paste your project id. Get this on: https://cloud.walletconnect.com/sign-in
+PROJECT_ID = 9bfe94c9cbf74aaa0597094ef561f703
diff --git a/Sample/Example/ContentView.swift b/Sample/Example/ContentView.swift
new file mode 100644
index 0000000..8b5590d
--- /dev/null
+++ b/Sample/Example/ContentView.swift
@@ -0,0 +1,58 @@
+import SwiftUI
+import Web3Modal
+
+struct ContentView: View {
+ @State var showUIComponents: Bool = false
+ @EnvironmentObject var socketConnectionManager: SocketConnectionManager
+
+
+ var body: some View {
+ NavigationView {
+ VStack {
+ Spacer()
+
+ Web3ModalButton()
+
+ Web3ModalNetworkButton()
+
+ Spacer()
+
+ Button("Personal sign") {
+ requestPersonalSign()
+ Web3Modal.instance.launchCurrentWallet()
+ }
+ .buttonStyle(W3MButtonStyle())
+
+ NavigationLink(destination: ComponentLibraryView(), isActive: $showUIComponents) {
+ Button("UI components") {
+ showUIComponents = true
+ }
+ .buttonStyle(W3MButtonStyle())
+ }
+ }
+ .overlay(
+ HStack {
+ Circle()
+ .fill(socketConnectionManager.socketConnected ? Color.Success100 : Color.Error100)
+ .frame(width: 10, height: 10)
+
+ Text("Socket \(socketConnectionManager.socketConnected ? "Connected" : "Disconnected")")
+ .font(.system(size: 12, weight: .semibold))
+ .foregroundColor(socketConnectionManager.socketConnected ? Color.Success100 : Color.Error100)
+ },
+ alignment: .top
+ )
+ }
+ }
+
+ func requestPersonalSign() {
+ Task {
+ do {
+ guard let address = Web3Modal.instance.getAddress() else { return }
+ try await Web3Modal.instance.request(.personal_sign(address: address, message: "Hello there!"))
+ } catch {
+ print(error)
+ }
+ }
+ }
+}
diff --git a/Sample/Example/Example.entitlements b/Sample/Example/Example.entitlements
new file mode 100644
index 0000000..6da47ed
--- /dev/null
+++ b/Sample/Example/Example.entitlements
@@ -0,0 +1,14 @@
+
+
+
+
+ com.apple.security.app-sandbox
+
+ com.apple.security.application-groups
+
+ group.com.walletconnect.web3modal
+
+ com.apple.security.files.user-selected.read-only
+
+
+
diff --git a/Sample/Example/ExampleApp.swift b/Sample/Example/ExampleApp.swift
new file mode 100644
index 0000000..521ad06
--- /dev/null
+++ b/Sample/Example/ExampleApp.swift
@@ -0,0 +1,116 @@
+import Combine
+import Sentry
+import SwiftUI
+import UIKit
+import WalletConnectSign
+import Web3Modal
+
+#if DEBUG
+import Atlantis
+#endif
+
+
+class SocketConnectionManager: ObservableObject {
+ @Published var socketConnected: Bool = false
+}
+
+@main
+class ExampleApp: App {
+ private var disposeBag = Set()
+ private var socketConnectionManager = SocketConnectionManager()
+
+
+ @State var alertMessage: String = ""
+
+ required init() {
+ #if DEBUG
+ Atlantis.start()
+ #endif
+
+ let projectId = InputConfig.projectId
+
+ // We're tracking Crash Reports / Issues from the Demo App to keep improving the SDK
+ SentrySDK.start { options in
+ options.dsn = "https://8b29c857724b94a32ac07ced45452702@o1095249.ingest.sentry.io/4506394479099904"
+ options.debug = false
+ options.enableTracing = true
+ }
+
+ SentrySDK.configureScope { scope in
+ scope.setContext(value: ["projectId": projectId], key: "Project")
+ }
+
+ let metadata = AppMetadata(
+ name: "Web3Modal Swift Dapp",
+ description: "Web3Modal DApp sample",
+ url: "www.web3modal.com",
+ icons: ["https://avatars.githubusercontent.com/u/37784886"],
+ redirect: .init(native: "w3mdapp://", universal: nil)
+ )
+
+ Networking.configure(
+ groupIdentifier: "group.com.walletconnect.web3modal",
+ projectId: projectId,
+ socketFactory: DefaultSocketFactory()
+ )
+
+ Web3Modal.configure(
+ projectId: projectId,
+ metadata: metadata,
+ customWallets: [
+ .init(
+ id: "swift-sample",
+ name: "Swift Sample Wallet",
+ homepage: "https://walletconnect.com/",
+ imageUrl: "https://avatars.githubusercontent.com/u/37784886?s=200&v=4",
+ order: 1,
+ mobileLink: "walletapp://"
+ )
+ ]
+ ) { error in
+ SentrySDK.capture(error: error)
+
+ print(error)
+ }
+ setup()
+
+ }
+
+ func setup() {
+ Web3Modal.instance.socketConnectionStatusPublisher.receive(on: DispatchQueue.main).sink { [unowned self] status in
+ print("Socket connection status: \(status)")
+ self.socketConnectionManager.socketConnected = (status == .connected)
+
+ }.store(in: &disposeBag)
+ Web3Modal.instance.logger.setLogging(level: .debug)
+ }
+
+ var body: some Scene {
+ WindowGroup { [unowned self] in
+ ContentView()
+ .environmentObject(socketConnectionManager)
+ .onOpenURL { url in
+ Web3Modal.instance.handleDeeplink(url)
+ }
+ .alert(
+ "Response",
+ isPresented: .init(
+ get: { !self.alertMessage.isEmpty },
+ set: { _ in self.alertMessage = "" }
+ )
+ ) {
+ Button("Dismiss", role: .cancel) {}
+ } message: {
+ Text(alertMessage)
+ }
+ .onReceive(Web3Modal.instance.sessionResponsePublisher, perform: { response in
+ switch response.result {
+ case let .response(value):
+ self.alertMessage = "Session response: \(value.stringRepresentation)"
+ case let .error(error):
+ self.alertMessage = "Session error: \(error)"
+ }
+ })
+ }
+ }
+}
diff --git a/Sample/Example/Info.plist b/Sample/Example/Info.plist
new file mode 100644
index 0000000..13f42f3
--- /dev/null
+++ b/Sample/Example/Info.plist
@@ -0,0 +1,72 @@
+
+
+
+
+ CFBundleURLTypes
+
+
+ CFBundleTypeRole
+ Editor
+ CFBundleURLName
+ w3mdapp
+ CFBundleURLSchemes
+
+ w3mdapp
+
+
+
+ ITSAppUsesNonExemptEncryption
+
+ LSApplicationQueriesSchemes
+
+ metamask
+ trust
+ safe
+ rainbow
+ uniswap
+ zerion
+ imtokenv2
+ spot
+ omni
+ dfw
+ tpoutside
+ robinhood-wallet
+ frontier
+ blockchain-wallet
+ safepalwallet
+ bitkeep
+ oneinch
+ exodus
+ bnc
+ ledgerlive
+ mewwallet
+ awallet
+ keyring
+ lobstr
+ ontoprovider
+ mathwallet
+ unstoppabledomains
+ obvious
+ fireblocks-wc
+ ambire
+ internetmoney
+ walletnow
+ bitcoincom
+ coin98
+ arculuswc
+ cryptobrowser
+ chainapp
+ huddln
+ verso
+ haha
+ modularwallet
+ coinomi
+
+ NSBonjourServices
+
+ _Proxyman._tcp
+
+ PROJECT_ID
+ $(PROJECT_ID)
+
+
diff --git a/Sample/Example/InputConfig.swift b/Sample/Example/InputConfig.swift
new file mode 100644
index 0000000..d710282
--- /dev/null
+++ b/Sample/Example/InputConfig.swift
@@ -0,0 +1,16 @@
+import Foundation
+
+struct InputConfig {
+
+ static var projectId: String {
+ guard let projectId = config(for: "PROJECT_ID"), !projectId.isEmpty else {
+ fatalError("PROJECT_ID is either not defined or empty in Configuration.xcconfig")
+ }
+
+ return projectId
+ }
+
+ private static func config(for key: String) -> String? {
+ return Bundle.main.object(forInfoDictionaryKey: key) as? String
+ }
+}
diff --git a/Sample/Example/Preview Content/Preview Assets.xcassets/Contents.json b/Sample/Example/Preview Content/Preview Assets.xcassets/Contents.json
new file mode 100644
index 0000000..73c0059
--- /dev/null
+++ b/Sample/Example/Preview Content/Preview Assets.xcassets/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sample/Example/WCSocketFactory.swift b/Sample/Example/WCSocketFactory.swift
new file mode 100644
index 0000000..fc929b2
--- /dev/null
+++ b/Sample/Example/WCSocketFactory.swift
@@ -0,0 +1,14 @@
+import Foundation
+import WalletConnectRelay
+import Starscream
+
+extension WebSocket: WebSocketConnecting { }
+
+struct DefaultSocketFactory: WebSocketFactory {
+ func create(with url: URL) -> WebSocketConnecting {
+ let socket = WebSocket(url: url)
+ let queue = DispatchQueue(label: "com.walletconnect.sdk.sockets", attributes: .concurrent)
+ socket.callbackQueue = queue
+ return socket
+ }
+}
diff --git a/Sample/swift-web3modal-Package.xctestplan b/Sample/swift-web3modal-Package.xctestplan
new file mode 100644
index 0000000..dd3dc38
--- /dev/null
+++ b/Sample/swift-web3modal-Package.xctestplan
@@ -0,0 +1,44 @@
+{
+ "configurations" : [
+ {
+ "id" : "829C9690-2201-4591-80FD-185F8D8FD18F",
+ "name" : "Test Scheme Action",
+ "options" : {
+
+ }
+ }
+ ],
+ "defaultOptions" : {
+ "codeCoverage" : {
+ "targets" : [
+ {
+ "containerPath" : "container:",
+ "identifier" : "Web3Modal",
+ "name" : "Web3Modal"
+ },
+ {
+ "containerPath" : "container:",
+ "identifier" : "Web3ModalUI",
+ "name" : "Web3ModalUI"
+ }
+ ]
+ }
+ },
+ "testTargets" : [
+ {
+ "target" : {
+ "containerPath" : "container:",
+ "identifier" : "Web3ModalTests",
+ "name" : "Web3ModalTests"
+ }
+ },
+ {
+ "target" : {
+ "containerPath" : "container:",
+ "identifier" : "Web3ModalUITests",
+ "name" : "Web3ModalUITests"
+ }
+ }
+ ],
+ "version" : 1
+}
diff --git a/Sources/Web3Modal/Analytics/AnalyticsEvent.swift b/Sources/Web3Modal/Analytics/AnalyticsEvent.swift
new file mode 100644
index 0000000..cb0f0bb
--- /dev/null
+++ b/Sources/Web3Modal/Analytics/AnalyticsEvent.swift
@@ -0,0 +1,28 @@
+enum AnalyticsEvent: Equatable {
+ case MODAL_LOADED
+ case MODAL_OPEN(connected: Bool)
+ case MODAL_CLOSE(connected: Bool)
+ case CLICK_ALL_WALLETS
+ case SELECT_WALLET(name: String, platform: Method)
+ case CLICK_NETWORKS
+// case OPEN_ACTIVITY_VIEW //
+ case SWITCH_NETWORK(network: Chain)
+ case CONNECT_SUCCESS(method: Method, name: String)
+ case CONNECT_ERROR(message: String)
+ case DISCONNECT_SUCCESS
+ case DISCONNECT_ERROR
+ case CLICK_WALLET_HELP
+ case CLICK_NETWORK_HELP
+ case CLICK_GET_WALLET
+
+
+ enum Method: String {
+ case qrcode = "qrcode"
+ case mobile = "mobile"
+ }
+
+// enum Platform: String {
+// case qrcode = "QR"
+// case mobile = "mobile"
+// }
+}
diff --git a/Sources/Web3Modal/Analytics/AnalyticsEventMapper.swift b/Sources/Web3Modal/Analytics/AnalyticsEventMapper.swift
new file mode 100644
index 0000000..e1ddb24
--- /dev/null
+++ b/Sources/Web3Modal/Analytics/AnalyticsEventMapper.swift
@@ -0,0 +1,4 @@
+protocol AnalyticsEventMapper {
+ func eventName(for event: AnalyticsEvent) -> String
+ func parameters(for event: AnalyticsEvent) -> [String: String]
+}
diff --git a/Sources/Web3Modal/Analytics/AnalyticsProvider.swift b/Sources/Web3Modal/Analytics/AnalyticsProvider.swift
new file mode 100644
index 0000000..79abfab
--- /dev/null
+++ b/Sources/Web3Modal/Analytics/AnalyticsProvider.swift
@@ -0,0 +1,3 @@
+protocol AnalyticsProvider {
+ func track(_ event: AnalyticsEvent)
+}
diff --git a/Sources/Web3Modal/Analytics/Convenience/AnalyticsEvent+ResultBuilders.swift b/Sources/Web3Modal/Analytics/Convenience/AnalyticsEvent+ResultBuilders.swift
new file mode 100644
index 0000000..7277f3a
--- /dev/null
+++ b/Sources/Web3Modal/Analytics/Convenience/AnalyticsEvent+ResultBuilders.swift
@@ -0,0 +1,17 @@
+import Foundation
+
+/// A builder resulting in an array of analytics event groups
+@resultBuilder enum AnalyticsEventGroupBuilder {
+ /// Return an array of analytics event groups given a closure containing statements of analytics event groups
+ static func buildBlock(_ eventGroups: AnalyticsEventGroup...) -> [AnalyticsEventGroup] {
+ eventGroups
+ }
+}
+
+/// A builder resulting in an array of analytics events
+@resultBuilder enum AnalyticsEventBuilder {
+ /// Return an array of analytics events given a closure containing statements of analytics events.
+ static func buildBlock(_ events: AnalyticsEvent...) -> [AnalyticsEvent] {
+ events
+ }
+}
diff --git a/Sources/Web3Modal/Analytics/Convenience/AnalyticsEventGroup.swift b/Sources/Web3Modal/Analytics/Convenience/AnalyticsEventGroup.swift
new file mode 100644
index 0000000..7eab387
--- /dev/null
+++ b/Sources/Web3Modal/Analytics/Convenience/AnalyticsEventGroup.swift
@@ -0,0 +1,24 @@
+/// A group of analytics events tracked together in response to a common trigger
+struct AnalyticsEventGroup {
+ // MARK: Properties
+
+ /// The trigger causing the analytics events to be tracked
+ let trigger: AnalyticsEventTrigger
+
+ /// The events being tracked
+ let events: [AnalyticsEvent]
+
+ // MARK: Initializers
+
+ init(_ trigger: AnalyticsEventTrigger, events: [AnalyticsEvent]) {
+ self.trigger = trigger
+ self.events = events
+ }
+}
+
+extension AnalyticsEventGroup {
+ /// Initialize with a trigger and event builder
+ init(_ trigger: AnalyticsEventTrigger, @AnalyticsEventBuilder events: () -> [AnalyticsEvent]) {
+ self.init(trigger, events: events())
+ }
+}
diff --git a/Sources/Web3Modal/Analytics/Convenience/AnalyticsEventTrackingModifier.swift b/Sources/Web3Modal/Analytics/Convenience/AnalyticsEventTrackingModifier.swift
new file mode 100644
index 0000000..ed07560
--- /dev/null
+++ b/Sources/Web3Modal/Analytics/Convenience/AnalyticsEventTrackingModifier.swift
@@ -0,0 +1,39 @@
+import SwiftUI
+
+/// A view modifier that tracks analytics events
+struct AnalyticsEventTrackingModifier: ViewModifier {
+
+ @EnvironmentObject var analyticsService: AnalyticsService
+
+ /// The groups of analytics events to track
+ let groups: [AnalyticsEventGroup]
+
+ func body(content: Content) -> some View {
+ content
+ .onAppear {
+ trackAll(in: groups(for: .onAppear))
+ }
+ .onDisappear {
+ trackAll(in: groups(for: .onDisappear))
+ }
+ .onTapGesture {
+ trackAll(in: groups(for: .onTapGesture))
+ }
+ }
+
+ // MARK: Helpers
+
+ /// Returns the group for the given trigger
+ private func groups(for trigger: AnalyticsEventTrigger) -> [AnalyticsEventGroup] {
+ groups.filter { $0.trigger == trigger }
+ }
+
+ /// Track all events in the given group
+ private func trackAll(in group: [AnalyticsEventGroup]) {
+ groups
+ .flatMap { $0.events }
+ .forEach { event in
+ analyticsService.track(event)
+ }
+ }
+}
diff --git a/Sources/Web3Modal/Analytics/Convenience/AnalyticsEventTrigger.swift b/Sources/Web3Modal/Analytics/Convenience/AnalyticsEventTrigger.swift
new file mode 100644
index 0000000..79346da
--- /dev/null
+++ b/Sources/Web3Modal/Analytics/Convenience/AnalyticsEventTrigger.swift
@@ -0,0 +1,6 @@
+/// A trigger that causes analytics events to be tracked
+enum AnalyticsEventTrigger {
+ case onAppear
+ case onDisappear
+ case onTapGesture
+}
diff --git a/Sources/Web3Modal/Analytics/Convenience/View+Track.swift b/Sources/Web3Modal/Analytics/Convenience/View+Track.swift
new file mode 100644
index 0000000..5e90a40
--- /dev/null
+++ b/Sources/Web3Modal/Analytics/Convenience/View+Track.swift
@@ -0,0 +1,30 @@
+import SwiftUI
+
+extension View {
+
+ func track(@AnalyticsEventGroupBuilder _ groups: () -> [AnalyticsEventGroup]) -> some View {
+ let groups = groups()
+ let modifier = AnalyticsEventTrackingModifier(groups: groups)
+ return self.modifier(modifier)
+ }
+
+ func track(_ event: AnalyticsEvent) {
+ let service: AnalyticsService = Environment(\.analyticsService).wrappedValue
+ service.track(event)
+ }
+
+ func track(@AnalyticsEventBuilder _ events: () -> [AnalyticsEvent]) {
+ let service: AnalyticsService = Environment(\.analyticsService).wrappedValue
+ let events = events()
+ events.forEach { event in
+ service.track(event)
+ }
+ }
+
+ /// Track a group of events in response to the trigger with the provided service.
+ func track(_ trigger: AnalyticsEventTrigger, @AnalyticsEventBuilder _ events: () -> [AnalyticsEvent]) -> some View {
+ let eventsArray = events()
+ let group = AnalyticsEventGroup(trigger, events: eventsArray)
+ return track { group }
+ }
+}
diff --git a/Sources/Web3Modal/Analytics/Private/AnalyticsService.swift b/Sources/Web3Modal/Analytics/Private/AnalyticsService.swift
new file mode 100644
index 0000000..520beec
--- /dev/null
+++ b/Sources/Web3Modal/Analytics/Private/AnalyticsService.swift
@@ -0,0 +1,58 @@
+import Foundation
+
+class AnalyticsService: AnalyticsProvider, ObservableObject {
+ private(set) static var shared = AnalyticsService(providers: [
+// LoggingAnalyticsProvider(),
+ ClickstreamAnalyticsProvider()
+ ])
+
+ private let providers: [AnalyticsProvider]
+ var method: AnalyticsEvent.Method = .mobile
+
+ var isAnalyticsEnabled: Bool {
+ return UserDefaults.standard.bool(forKey: analyticsEnabledKey)
+ }
+
+ // Key to store the state of analytics
+ private let analyticsEnabledKey = "com.walletconnect.w3m.analyticsEnabled"
+
+ init(providers: [AnalyticsProvider]) {
+ self.providers = providers
+ // Set default value for analytics enabled if it's not already set
+ if UserDefaults.standard.object(forKey: analyticsEnabledKey) == nil {
+ UserDefaults.standard.set(true, forKey: analyticsEnabledKey)
+ }
+ }
+
+ func track(_ event: AnalyticsEvent) {
+ guard isAnalyticsEnabled else { return }
+
+ providers.forEach {
+ $0.track(event)
+ }
+ if case .SELECT_WALLET(_, let platform) = event {
+ self.method = platform
+ }
+ }
+
+ func disable() {
+ UserDefaults.standard.set(false, forKey: analyticsEnabledKey)
+ }
+
+ func enable() {
+ UserDefaults.standard.set(true, forKey: analyticsEnabledKey)
+ }
+}
+
+import SwiftUI
+
+struct AnalyticsServiceKey: EnvironmentKey {
+ static var defaultValue: AnalyticsService = .shared
+}
+
+extension EnvironmentValues {
+ var analyticsService: AnalyticsService {
+ get { self[AnalyticsServiceKey.self] }
+ set { self[AnalyticsServiceKey.self] = newValue }
+ }
+}
diff --git a/Sources/Web3Modal/Analytics/Private/ClickstreamAnalyticsProvider.swift b/Sources/Web3Modal/Analytics/Private/ClickstreamAnalyticsProvider.swift
new file mode 100644
index 0000000..32ed0b0
--- /dev/null
+++ b/Sources/Web3Modal/Analytics/Private/ClickstreamAnalyticsProvider.swift
@@ -0,0 +1,124 @@
+import Foundation
+
+class ClickstreamAnalyticsProvider: AnalyticsProvider {
+ private let eventMapper = DefaultAnalyticsEventMapper()
+
+ func track(_ event: AnalyticsEvent) {
+ let urlString = analyticsApiUrl()
+ let name = eventMapper.eventName(for: event)
+ let properties = eventMapper.parameters(for: event)
+ let payload = EventPayload(for: name, properties: properties)
+
+ guard
+ let url = URL(string: "\(urlString)/e")
+ else {
+ return
+ }
+
+ Task {
+ do {
+ let encodedPayload = try JSONEncoder().encode(payload)
+
+ var request = URLRequest(url: url)
+ request.httpMethod = "POST"
+ request.httpBody = encodedPayload
+ request.setW3MHeaders()
+// request.setValue("com.walletconnect.web3modal.sample", forHTTPHeaderField: "Origin")
+ request.setValue("localhost", forHTTPHeaderField: "Origin") // Localhost temporarily
+ request.setValue("application/json", forHTTPHeaderField: "Content-Type")
+
+ let (_, _) = try await URLSession.shared.dataWithRetry(for: request, retryPolicy: .init(
+ maxAttempts: 1,
+ initialDelay: 3,
+ multiplier: 3
+ ))
+ } catch {
+ print("Failed posting event \(error)")
+ }
+ }
+
+ }
+
+ private func analyticsApiUrl() -> String {
+// #if DEBUG
+// return "https://analytics-api-cf-workers-staging.walletconnect-v1-bridge.workers.dev"
+// #else
+ return "https://pulse.walletconnect.com"
+// #endif
+ }
+}
+
+struct EventPayload: Codable {
+ struct Props: Codable {
+ let type: String
+ let event: String
+ let properties: [String: String]
+ }
+ let eventId: String
+ let url: String
+ let domain: String
+ let timestamp: UInt64
+ let props: Props
+
+ init(for name: String, properties: [String: String]) {
+ self.eventId = UUID().uuidString
+ self.url = "https://lab.web3modal.com/"
+ self.domain = "lab.web3modal.com"
+ self.timestamp = UInt64(Date().timeIntervalSince1970)
+
+ self.props = Props(
+ type: "track",
+ event: name,
+ properties: properties
+ )
+ }
+}
+
+private extension URLSession {
+
+ struct RetryPolicy {
+ let maxAttempts: Int
+ let initialDelay: TimeInterval
+ let multiplier: Double
+ }
+
+ enum NetworkError: Error {
+ case tooManyAttempts
+ case networkFailure(Error)
+ case invalidStatusCode
+ }
+
+ func dataWithRetry(for request: URLRequest, retryPolicy: RetryPolicy) async throws -> (Data, URLResponse) {
+ var attempts = 0
+ var delay = retryPolicy.initialDelay
+
+ while attempts < retryPolicy.maxAttempts {
+ do {
+ // Attempt the network request
+ let (data, response) = try await URLSession.shared.data(for: request)
+ // If the request is successful, return the data and response
+
+ guard
+ let httpResponse = response as? HTTPURLResponse,
+ (200..<300).contains(httpResponse.statusCode)
+ else {
+ throw NetworkError.invalidStatusCode
+ }
+
+ return (data, response)
+ } catch {
+ attempts += 1
+ if attempts >= retryPolicy.maxAttempts {
+ // If we've reached the max attempts, throw a tooManyAttempts error
+ throw NetworkError.tooManyAttempts
+ } else {
+ // If the request fails, wait for the delay before retrying
+ try await Task.sleep(nanoseconds: UInt64(delay * 1_000_000_000))
+ delay *= retryPolicy.multiplier // Increase the delay for the next attempt
+ }
+ }
+ }
+ // Fallback error, though we should never reach here due to the throw in the loop
+ throw NetworkError.tooManyAttempts
+ }
+}
diff --git a/Sources/Web3Modal/Analytics/Private/DefaultAnalyticsEventMapper.swift b/Sources/Web3Modal/Analytics/Private/DefaultAnalyticsEventMapper.swift
new file mode 100644
index 0000000..c62d4bd
--- /dev/null
+++ b/Sources/Web3Modal/Analytics/Private/DefaultAnalyticsEventMapper.swift
@@ -0,0 +1,71 @@
+class DefaultAnalyticsEventMapper: AnalyticsEventMapper {
+ func eventName(for event: AnalyticsEvent) -> String {
+ switch event {
+ case .MODAL_LOADED:
+ return "MODAL_LOADED"
+ case .MODAL_OPEN:
+ return "MODAL_OPEN"
+ case .MODAL_CLOSE:
+ return "MODAL_CLOSE"
+ case .CLICK_ALL_WALLETS:
+ return "CLICK_ALL_WALLETS"
+ case .SELECT_WALLET:
+ return "SELECT_WALLET"
+ case .CLICK_NETWORKS:
+ return "CLICK_NETWORKS"
+// case .OPEN_ACTIVITY_VIEW:
+// return "OPEN_ACTIVITY_VIEW"
+ case .SWITCH_NETWORK:
+ return "SWITCH_NETWORK"
+ case .CONNECT_SUCCESS:
+ return "CONNECT_SUCCESS"
+ case .CONNECT_ERROR:
+ return "CONNECT_ERROR"
+ case .DISCONNECT_SUCCESS:
+ return "DISCONNECT_SUCCESS"
+ case .DISCONNECT_ERROR:
+ return "DISCONNECT_ERROR"
+ case .CLICK_WALLET_HELP:
+ return "CLICK_WALLET_HELP"
+ case .CLICK_NETWORK_HELP:
+ return "CLICK_NETWORK_HELP"
+ case .CLICK_GET_WALLET:
+ return "CLICK_GET_WALLET"
+ }
+ }
+
+ func parameters(for event: AnalyticsEvent) -> [String: String] {
+ switch event {
+ case .MODAL_LOADED:
+ return [:]
+ case let .MODAL_OPEN(connected):
+ return ["connected": connected.description]
+ case let .MODAL_CLOSE(connected):
+ return ["connected": connected.description]
+ case .CLICK_ALL_WALLETS:
+ return [:]
+ case let .SELECT_WALLET(name, platform):
+ return ["wallet": name, "platform": platform.rawValue]
+ case .CLICK_NETWORKS:
+ return [:]
+// case .OPEN_ACTIVITY_VIEW:
+// return [:]
+ case let .SWITCH_NETWORK(network):
+ return ["network": network.id]
+ case let .CONNECT_SUCCESS(method, name):
+ return ["method": method.rawValue, "name": name]
+ case let .CONNECT_ERROR(message):
+ return ["message": message]
+ case .DISCONNECT_SUCCESS:
+ return [:]
+ case .DISCONNECT_ERROR:
+ return [:]
+ case .CLICK_WALLET_HELP:
+ return [:]
+ case .CLICK_NETWORK_HELP:
+ return [:]
+ case .CLICK_GET_WALLET:
+ return [:]
+ }
+ }
+}
diff --git a/Sources/Web3Modal/Analytics/Private/LoggingAnalyticsProvider.swift b/Sources/Web3Modal/Analytics/Private/LoggingAnalyticsProvider.swift
new file mode 100644
index 0000000..43db57c
--- /dev/null
+++ b/Sources/Web3Modal/Analytics/Private/LoggingAnalyticsProvider.swift
@@ -0,0 +1,9 @@
+class LoggingAnalyticsProvider: AnalyticsProvider {
+ private let eventMapper = DefaultAnalyticsEventMapper()
+
+ func track(_ event: AnalyticsEvent) {
+ let name = eventMapper.eventName(for: event)
+ let properties = eventMapper.parameters(for: event)
+ print("📊 Event reported: \(name), properties: \(properties)")
+ }
+}
diff --git a/Sources/Web3Modal/Components/AccountButton.swift b/Sources/Web3Modal/Components/AccountButton.swift
new file mode 100644
index 0000000..83f8098
--- /dev/null
+++ b/Sources/Web3Modal/Components/AccountButton.swift
@@ -0,0 +1,267 @@
+import SwiftUI
+
+struct AccountButtonStyle: ButtonStyle {
+ @ObservedObject var store: Store
+
+ public init() {
+ self.store = .shared
+ }
+
+ init(
+ store: Store = .shared,
+ isPressedOverride: Bool? = nil
+ ) {
+ self.store = store
+ self.isPressedOverride = isPressedOverride
+ }
+
+ @Environment(\.isEnabled) var isEnabled
+
+ var isPressedOverride: Bool?
+
+ var addressFormatted: String? {
+ guard let address = store.account?.address else {
+ return nil
+ }
+
+ return String(address.prefix(4)) + "..." + String(address.suffix(4))
+ }
+
+ var selectedChain: Chain {
+ return store.selectedChain ?? ChainPresets.ethChains.first!
+ }
+
+ func makeBody(configuration: Configuration) -> some View {
+ var backgroundColor: Color = .GrayGlass002
+ let pressedColor: Color = .GrayGlass010
+ backgroundColor = (isPressedOverride ?? configuration.isPressed) ? pressedColor : backgroundColor
+ backgroundColor = isEnabled ? backgroundColor : .Overgray010
+
+ let verticalPadding = Spacing.xxxs
+ let leadingPadding = Spacing.xxs
+ let trailingPadding = Spacing.xxxs
+
+ return Group {
+ if store.balance != nil {
+ mixedVariant()
+ } else {
+ accountVariant()
+ }
+ }
+ .padding(.vertical, verticalPadding)
+ .padding(.leading, leadingPadding)
+ .padding(.trailing, trailingPadding)
+ .background(backgroundColor)
+ .cornerRadius(Radius.m)
+ .overlay(
+ RoundedRectangle(cornerRadius: Radius.m)
+ .stroke(Color.Overgray010, lineWidth: 1)
+ )
+ }
+
+ func accountVariant() -> some View {
+ var textColor: Color = .Foreground100
+ textColor = isEnabled ? textColor : .Overgray015
+
+ return HStack(spacing: Spacing.xxs) {
+ avatar()
+
+ Text(addressFormatted ?? "")
+ .font(.paragraph500)
+ .foregroundColor(textColor)
+ }
+ .padding(Spacing.xs)
+ .cornerRadius(Radius.m)
+ }
+
+ func mixedVariant() -> some View {
+ var textColor: Color = .Foreground100
+ textColor = isEnabled ? textColor : .Overgray015
+
+ var textColorInner: Color = .Foreground200
+ textColorInner = isEnabled ? textColorInner : .Overgray010
+
+ return HStack(spacing: Spacing.xs) {
+ HStack(spacing: Spacing.xxs) {
+ networkImage()
+
+ let balance = store.balance?.roundedDecimal(to: 4, mode: .down) ?? 0
+
+ Text(balance == 0 ? "0 \(selectedChain.token.symbol)" : "\(balance, specifier: "%.3f") \(selectedChain.token.symbol)")
+ .font(.paragraph600)
+ .foregroundColor(textColor)
+ .lineLimit(1)
+ }
+
+ HStack(spacing: Spacing.xxs) {
+ avatar()
+
+ Text(addressFormatted ?? "")
+ .font(.paragraph500)
+ .foregroundColor(textColorInner)
+ }
+ .padding(Spacing.xs)
+ .background(Color.GrayGlass005)
+ .cornerRadius(Radius.m)
+ .overlay(
+ RoundedRectangle(cornerRadius: Radius.m)
+ .stroke(Color.Overgray010, lineWidth: 1)
+ )
+ }
+ }
+
+ @ViewBuilder
+ func networkImage() -> some View {
+ Group {
+ if let storedImage = store.chainImages[selectedChain.imageId] {
+ Image(uiImage: storedImage)
+ .resizable()
+ } else {
+ Image.Regular.network
+ .resizable()
+ .padding(Spacing.xxs)
+ }
+ }
+ .saturation(isEnabled ? 1 : 0)
+ .opacity(isEnabled ? 1 : 0.5)
+ .frame(width: 24, height: 24)
+ .clipShape(Circle())
+ .overlay(Circle().stroke(.Overgray005, lineWidth: 2))
+ }
+
+ @ViewBuilder
+ func avatar() -> some View {
+ Group {
+ if let avatarUrlString = store.identity?.avatar, let url = URL(string: avatarUrlString) {
+ Backport.AsyncImage(url: url)
+ } else if let address = store.account?.address {
+ W3MAvatarGradient(address: address)
+ }
+ }
+ .saturation(isEnabled ? 1 : 0)
+ .opacity(isEnabled ? 1 : 0.5)
+ .frame(width: 20, height: 20)
+ .clipShape(Circle())
+ .overlay(Circle().stroke(.GrayGlass010, lineWidth: 3))
+ }
+}
+
+public struct AccountButton: View {
+ let store: Store
+ let blockchainApiInteractor: BlockchainAPIInteractor
+
+ public init() {
+ self.store = .shared
+ self.blockchainApiInteractor = BlockchainAPIInteractor(store: .shared)
+ }
+
+ init(store: Store = .shared, blockchainApiInteractor: BlockchainAPIInteractor) {
+ self.store = store
+ self.blockchainApiInteractor = blockchainApiInteractor
+ }
+
+ public var body: some View {
+ Button(action: {
+ Web3Modal.present()
+ }, label: {})
+ .buttonStyle(AccountButtonStyle(store: store))
+ .onAppear {
+ fetchIdentity()
+ fetchBalance()
+ }
+ }
+
+ func fetchIdentity() {
+ Task { @MainActor in
+ do {
+ try await blockchainApiInteractor.getIdentity()
+ } catch {
+ store.toast = .init(style: .error, message: "Network error")
+ Web3Modal.config.onError(error)
+ }
+ }
+ }
+
+ func fetchBalance() {
+ Task { @MainActor in
+ do {
+ try await blockchainApiInteractor.getBalance()
+ } catch {
+ store.toast = .init(style: .error, message: "Network error")
+ Web3Modal.config.onError(error)
+ }
+ }
+ }
+}
+
+#if DEBUG
+
+public struct AccountButtonPreviewView: View {
+ public init() {}
+
+ static let store = { (balance: Double?) -> Store in
+ let store = Store()
+ store.balance = balance
+ store.session = .stub
+ store.account = W3MAccount(
+ address: Session.stub.accounts.first!.address,
+ chain: Session.stub.accounts.first!.blockchain
+ )
+
+ return store
+ }
+
+ static let blockchainInteractor = { () -> BlockchainAPIInteractor in
+ MockBlockchainAPIInteractor()
+ }
+
+ public var body: some View {
+ VStack {
+ AccountButton(
+ store: AccountButtonPreviewView.store(1.23),
+ blockchainApiInteractor: MockBlockchainAPIInteractor()
+ )
+
+ AccountButton(
+ store: AccountButtonPreviewView.store(nil),
+ blockchainApiInteractor: MockBlockchainAPIInteractor()
+ )
+
+ AccountButton(
+ store: AccountButtonPreviewView.store(1.23),
+ blockchainApiInteractor: MockBlockchainAPIInteractor()
+ )
+ .disabled(true)
+
+ AccountButton(
+ store: AccountButtonPreviewView.store(nil),
+ blockchainApiInteractor: MockBlockchainAPIInteractor()
+ )
+ .disabled(true)
+
+ Button(action: {}, label: {})
+ .buttonStyle(
+ AccountButtonStyle(
+ store: AccountButtonPreviewView.store(1.23),
+ isPressedOverride: true
+ )
+ )
+
+ Button(action: {}, label: {})
+ .buttonStyle(
+ AccountButtonStyle(
+ store: AccountButtonPreviewView.store(nil),
+ isPressedOverride: true
+ )
+ )
+ }
+ }
+}
+
+struct AccountButton_Preview: PreviewProvider {
+ static var previews: some View {
+ AccountButtonPreviewView()
+ }
+}
+
+#endif
diff --git a/Sources/Web3Modal/Components/ConnectButton.swift b/Sources/Web3Modal/Components/ConnectButton.swift
new file mode 100644
index 0000000..81db537
--- /dev/null
+++ b/Sources/Web3Modal/Components/ConnectButton.swift
@@ -0,0 +1,49 @@
+import SwiftUI
+
+
+public struct ConnectButton: View {
+ @ObservedObject var store: Store
+
+ public init() {
+ self.store = .shared
+ }
+
+ init(store: Store = .shared) {
+ self.store = store
+ }
+
+ public var body: some View {
+ Button {
+ Web3Modal.present()
+ } label: {
+ if store.connecting {
+ HStack {
+ DrawingProgressView(
+ shape: .circle,
+ color: .white,
+ lineWidth: 2,
+ duration: 1,
+ isAnimating: .constant(true)
+ )
+ .frame(width: 20, height: 20)
+
+ Text("Connecting...")
+ }
+ } else {
+ Text("Connect wallet")
+ }
+ }
+ .buttonStyle(W3MChipButtonStyle())
+ }
+}
+
+struct ConnectButton_Preview: PreviewProvider {
+ static var previews: some View {
+ VStack {
+ ConnectButton()
+
+ ConnectButton()
+ .disabled(true)
+ }
+ }
+}
diff --git a/Sources/Web3Modal/Components/Web3ModalButton.swift b/Sources/Web3Modal/Components/Web3ModalButton.swift
new file mode 100644
index 0000000..e435e4a
--- /dev/null
+++ b/Sources/Web3Modal/Components/Web3ModalButton.swift
@@ -0,0 +1,47 @@
+import SwiftUI
+
+public struct Web3ModalButton: View {
+ @ObservedObject var store: Store
+
+ public init() {
+ self.store = .shared
+ }
+
+ init(store: Store = .shared) {
+ self.store = store
+ }
+
+ public var body: some View {
+ Group {
+ if let _ = store.account {
+ AccountButton()
+ } else {
+ ConnectButton()
+ }
+ }
+ }
+}
+
+#if DEBUG
+
+struct Web3Button_Preview: PreviewProvider {
+ static let store = { () -> Store in
+ let store = Store()
+ store.balance = 1.23
+ store.account = .stub
+ return store
+ }()
+
+ static var previews: some View {
+ VStack {
+ Web3ModalButton(store: Store())
+
+ Web3ModalButton(store: Web3Button_Preview.store)
+
+ Web3ModalButton(store: Web3Button_Preview.store)
+ .disabled(true)
+ }
+ }
+}
+
+#endif
diff --git a/Sources/Web3Modal/Components/Web3ModalNetworkButton.swift b/Sources/Web3Modal/Components/Web3ModalNetworkButton.swift
new file mode 100644
index 0000000..cb4eca3
--- /dev/null
+++ b/Sources/Web3Modal/Components/Web3ModalNetworkButton.swift
@@ -0,0 +1,110 @@
+import SwiftUI
+
+
+public struct Web3ModalNetworkButton: View {
+ @ObservedObject var store: Store
+
+ @Environment(\.analyticsService) var analyticsService
+
+ public init() {
+ self.store = .shared
+ }
+
+ init(store: Store = .shared) {
+ self.store = store
+ }
+
+ public var body: some View {
+ if let selectedChain = store.selectedChain {
+ Button(selectedChain.chainName) {
+ Web3Modal.selectChain()
+ }
+ .buttonStyle(
+ W3MChipButtonStyle(
+ variant: .shade,
+ leadingImage: {
+ if let storedImage = store.chainImages[selectedChain.imageId] {
+ Circle()
+ .fill(.GrayGlass005)
+ .backport.overlay {
+ Image(uiImage: storedImage)
+ .resizable()
+ .frame(width: 22, height: 22)
+ .clipShape(Circle())
+ }
+ .frame(width: 26, height: 26)
+ } else {
+ networkImagePlaceholder()
+ }
+ }
+ )
+ )
+ } else {
+ Button {
+ analyticsService.track(.CLICK_NETWORKS)
+ Web3Modal.selectChain()
+ } label: {
+ Text("Select network").foregroundColor(.Foreground100)
+ }
+ .buttonStyle(
+ W3MChipButtonStyle(
+ variant: .shade,
+ leadingImage: {
+ networkImagePlaceholder()
+ }
+ )
+ )
+ }
+ }
+
+ private func networkImagePlaceholder() -> some View {
+ Circle().fill(.GrayGlass010, strokeBorder: .GrayGlass005, lineWidth: 2)
+ .backport.overlay {
+ Image.Bold.network
+ .foregroundColor(.Foreground200)
+ .padding(Spacing.xs)
+ }
+ .frame(width: 24, height: 24)
+ }
+}
+
+#if DEBUG
+
+public struct NetworkButtonPreviewView: View {
+ public init() {}
+
+ static let store = { (chain: Chain?) -> Store in
+ let store = Store()
+ store.balance = 1.23
+ store.selectedChain = chain
+ store.chainImages[ChainPresets.ethChains[0].imageId] = UIImage(
+ named: "MockWalletImage", in: .coreModule, compatibleWith: nil
+ )
+
+ return store
+ }
+
+ public var body: some View {
+ VStack {
+ Web3ModalNetworkButton(store: NetworkButtonPreviewView.store(nil))
+
+ Web3ModalNetworkButton(store: NetworkButtonPreviewView.store(ChainPresets.ethChains[0]))
+
+ Web3ModalNetworkButton(store: NetworkButtonPreviewView.store(ChainPresets.ethChains[1]))
+
+ Web3ModalNetworkButton(store: NetworkButtonPreviewView.store(ChainPresets.ethChains[0]))
+ .disabled(true)
+
+ Web3ModalNetworkButton(store: NetworkButtonPreviewView.store(nil))
+ .disabled(true)
+ }
+ }
+}
+
+struct NetworkButton_Preview: PreviewProvider {
+ static var previews: some View {
+ NetworkButtonPreviewView()
+ }
+}
+
+#endif
diff --git a/Sources/Web3Modal/Core/BlockchainAPIInteractor.swift b/Sources/Web3Modal/Core/BlockchainAPIInteractor.swift
new file mode 100644
index 0000000..2ed3266
--- /dev/null
+++ b/Sources/Web3Modal/Core/BlockchainAPIInteractor.swift
@@ -0,0 +1,138 @@
+import Foundation
+
+class BlockchainAPIInteractor: ObservableObject {
+ let store: Store
+
+ init(store: Store = .shared) {
+ self.store = store
+ }
+
+ func getIdentity() async throws {
+ guard
+ let account = store.account,
+ store.connectedWith == .wc
+ else { return }
+
+ let address = account.address
+ let chainId = account.chain.absoluteString
+
+ let httpClient = HTTPNetworkClient(host: "rpc.walletconnect.com")
+ let response = try await httpClient.request(
+ Identity.self,
+ at: BlockchainAPI.getIdentity(
+ params: .init(
+ address: address,
+ chainId: chainId,
+ projectId: Web3Modal.config.projectId
+ )
+ )
+ )
+
+ DispatchQueue.main.async { [self] in
+ self.store.identity = response
+ }
+ }
+
+ func getBalance() async throws {
+ enum GetBalanceError: Error {
+ case noAddress, invalidValue, noChain
+ }
+
+ guard let address = store.account?.address else {
+ throw GetBalanceError.noAddress
+ }
+
+ let request = RPCRequest(
+ method: "eth_getBalance", params: [
+ address, "latest"
+ ]
+ )
+
+ guard let chain = store.selectedChain else {
+ throw GetBalanceError.noChain
+ }
+
+ var urlRequest = URLRequest(url: URL(string: chain.rpcUrl)!)
+ urlRequest.httpMethod = "POST"
+ urlRequest.httpBody = try JSONEncoder().encode(request)
+ urlRequest.setValue("application/json", forHTTPHeaderField: "Content-Type")
+
+ let (data, _) = try await URLSession.shared.data(for: urlRequest)
+ let decodedResponse = try JSONDecoder().decode(RPCResponse.self, from: data)
+ let weiFactor = pow(10, chain.token.decimal)
+
+ guard let decimalValue = try decodedResponse.result?
+ .get(String.self)
+ .convertBalanceHexToBigDecimal()?
+ .toWei(weiFactor: weiFactor)
+ else {
+ throw GetBalanceError.invalidValue
+ }
+
+ let doubleValue = Double(truncating: decimalValue as NSNumber)
+
+ DispatchQueue.main.async {
+ self.store.balance = doubleValue
+ }
+ }
+}
+
+struct Identity: Codable {
+ let name: String?
+ let avatar: String?
+}
+
+struct BalanceRequest: Encodable {
+ init(address: String) {
+ self.address = address
+
+ self.id = RPCID()
+ self.params = [
+ address, "latest"
+ ]
+ }
+
+ let address: String
+ let id: RPCID
+ let jsonrpc: String = "2.0"
+ let method: String = "eth_getBalance"
+ let params: [String]
+}
+
+struct BalanceRpcResponse: Codable {
+ let id: RPCID
+ let jsonrpc: String
+ let result: String?
+ let error: RpcError?
+
+ struct RpcError: Codable {
+ let code: Int
+ let message: String
+ }
+}
+
+extension String {
+ func convertBalanceHexToBigDecimal() -> Decimal? {
+ let substring = dropFirst(2)
+ guard let longValue = UInt64(substring, radix: 16) else { return nil }
+ return Decimal(string: "\(longValue)")
+ }
+}
+
+extension Decimal {
+ func toWei(weiFactor: Decimal) -> Decimal {
+ return self / weiFactor
+ }
+}
+
+#if DEBUG
+class MockBlockchainAPIInteractor: BlockchainAPIInteractor {
+ override func getIdentity() async throws {
+ // no-op
+ }
+
+ override func getBalance() async throws {
+ // no-op
+ }
+}
+#endif
diff --git a/Sources/Web3Modal/Core/SignInteractor.swift b/Sources/Web3Modal/Core/SignInteractor.swift
new file mode 100644
index 0000000..fb12017
--- /dev/null
+++ b/Sources/Web3Modal/Core/SignInteractor.swift
@@ -0,0 +1,46 @@
+import Foundation
+import Combine
+
+class SignInteractor: ObservableObject {
+
+ private let store: Store
+
+ lazy var sessionsPublisher: AnyPublisher<[Session], Never> = Web3Modal.instance.sessionsPublisher
+ lazy var sessionSettlePublisher: AnyPublisher = Web3Modal.instance.sessionSettlePublisher
+ lazy var sessionResponsePublisher: AnyPublisher = Web3Modal.instance.sessionResponsePublisher
+ lazy var sessionRejectionPublisher: AnyPublisher<(Session.Proposal, Reason), Never> = Web3Modal.instance.sessionRejectionPublisher
+ lazy var sessionDeletePublisher: AnyPublisher<(String, Reason), Never> = Web3Modal.instance.sessionDeletePublisher
+ lazy var sessionEventPublisher: AnyPublisher<(event: Session.Event, sessionTopic: String, chainId: Blockchain?), Never> = Web3Modal.instance.sessionEventPublisher
+
+ init(store: Store = .shared) {
+ self.store = store
+ }
+
+ func createPairingAndConnect() async throws {
+ let uri = try await Web3Modal.instance.connect(topic: nil)
+
+ DispatchQueue.main.async {
+ self.store.uri = uri
+ self.store.retryShown = false
+ }
+ }
+
+ func disconnect() async throws {
+ defer {
+ DispatchQueue.main.async {
+ self.store.session = nil
+ self.store.account = nil
+ }
+ }
+
+ do {
+ try await Web3Modal.instance.disconnect(topic: store.session?.topic ?? "")
+ } catch {
+ DispatchQueue.main.async {
+ self.store.toast = .init(style: .error, message: "Failed to disconnect.")
+ }
+ Web3Modal.config.onError(error)
+ }
+ try await Web3Modal.instance.cleanup()
+ }
+}
diff --git a/Sources/Web3Modal/Core/W3MAPIInteractor.swift b/Sources/Web3Modal/Core/W3MAPIInteractor.swift
new file mode 100644
index 0000000..0ebded1
--- /dev/null
+++ b/Sources/Web3Modal/Core/W3MAPIInteractor.swift
@@ -0,0 +1,247 @@
+import UIKit
+
+final class W3MAPIInteractor: ObservableObject {
+ @Published var isLoading: Bool = false
+
+ private let store: Store
+ private let uiApplicationWrapper: UIApplicationWrapper
+
+ private let entriesPerPage: Int = 40
+
+ var totalEntries: Int = 0
+
+ init(
+ store: Store = .shared,
+ uiApplicationWrapper: UIApplicationWrapper = .live
+ ) {
+ self.store = store
+ self.uiApplicationWrapper = uiApplicationWrapper
+ }
+
+ func fetchWallets(search: String = "") async throws {
+ if search.isEmpty {
+ if store.currentPage + 1 > store.totalPages {
+ return
+ }
+
+ store.currentPage = min(store.currentPage + 1, store.totalPages)
+ }
+
+ DispatchQueue.main.async {
+ self.isLoading = true
+ }
+
+ let params = Web3ModalAPI.GetWalletsParams(
+ page: search.isEmpty ? store.currentPage : 1,
+ entries: search.isEmpty ? entriesPerPage : 100,
+ search: search,
+ projectId: Web3Modal.config.projectId,
+ metadata: Web3Modal.config.metadata,
+ recommendedIds: Web3Modal.config.recommendedWalletIds,
+ excludedIds: Web3Modal.config.excludedWalletIds
+ )
+
+ let httpClient = HTTPNetworkClient(host: "api.web3modal.com")
+ let response = try await httpClient.request(
+ GetWalletsResponse.self,
+ at: Web3ModalAPI.getWallets(
+ params: params
+ )
+ )
+
+ try await fetchWalletImages(for: response.data)
+
+ DispatchQueue.main.async { [self] in
+ var wallets = response.data
+
+ for index in wallets.indices {
+ let contains = store.installedWalletIds.contains(wallets[index].id)
+ wallets[index].isInstalled = contains
+ }
+
+ if !search.isEmpty {
+ let matchingCustomWallets = store.customWallets.filter { wallet in
+ wallet.name.contains(search)
+ }
+
+ self.store.searchedWallets = wallets + matchingCustomWallets
+ } else {
+ self.store.searchedWallets = []
+ self.store.wallets.formUnion(wallets + store.customWallets)
+ self.totalEntries = response.count
+ self.store.totalPages = Int(ceil(Double(response.count) / Double(entriesPerPage)))
+ }
+
+ self.isLoading = false
+ }
+ }
+
+ func fetchAllWalletMetadata() async throws {
+ let httpClient = HTTPNetworkClient(host: "api.web3modal.com")
+ let response = try await httpClient.request(
+ GetIosDataResponse.self,
+ at: Web3ModalAPI.getIosData(
+ params: .init(
+ projectId: Web3Modal.config.projectId,
+ metadata: Web3Modal.config.metadata
+ )
+ )
+ )
+
+ let installedWallets: [String?] = try await response.data.concurrentMap { walletMetadata in
+ guard
+ let nativeUrl = URL(string: walletMetadata.ios_schema),
+ await UIApplication.shared.canOpenURL(nativeUrl)
+ else {
+ return nil
+ }
+
+ return walletMetadata.id
+ }
+
+ store.installedWalletIds = installedWallets.compactMap { $0 }
+ }
+
+ func fetchFeaturedWallets() async throws {
+ let httpClient = HTTPNetworkClient(host: "api.web3modal.com")
+ let response = try await httpClient.request(
+ GetWalletsResponse.self,
+ at: Web3ModalAPI.getWallets(
+ params: .init(
+ page: 1,
+ entries: 4,
+ search: "",
+ projectId: Web3Modal.config.projectId,
+ metadata: Web3Modal.config.metadata,
+ recommendedIds: Web3Modal.config.recommendedWalletIds,
+ excludedIds: Web3Modal.config.excludedWalletIds
+ )
+ )
+ )
+
+ try await fetchWalletImages(for: response.data)
+
+ DispatchQueue.main.async { [self] in
+
+ var wallets = response.data
+
+ for index in wallets.indices {
+ let contains = store.installedWalletIds.contains(wallets[index].id)
+ wallets[index].isInstalled = contains
+ }
+
+ self.store.totalNumberOfWallets = response.count
+ self.store.featuredWallets.append(contentsOf: wallets)
+ }
+ }
+
+ func fetchWalletImages(for wallets: [Wallet]) async throws {
+ var walletImages: [String: UIImage] = [:]
+
+ try await wallets.concurrentMap { wallet in
+
+ // Build URL
+ var imageUrl: URL?
+ if let imageId = wallet.imageId {
+ imageUrl = URL(string: "https://api.web3modal.com/getWalletImage/\(imageId)")
+ } else if let customImageUrl = wallet.imageUrl {
+ imageUrl = URL(string: customImageUrl)
+ }
+
+ // Check whether we have some url and not fetched already
+ guard
+ let imageUrl,
+ !self.store.walletImages.contains(where: { key, _ in key == wallet.id })
+ else {
+ return ("", UIImage?.none)
+ }
+
+ var request = URLRequest(url: imageUrl)
+ request.setW3MHeaders()
+
+ do {
+ let (data, _) = try await URLSession.shared.data(for: request)
+ let image = UIImage(data: data)
+ return (wallet.id, image)
+ } catch {
+ print(error.localizedDescription)
+ }
+
+ return ("", UIImage?.none)
+ }
+ // Assign to outside dictionary
+ .forEach { (key: String, value: UIImage?) in
+ if value == nil || key == "" {
+ return
+ }
+
+ walletImages[key] = value
+ }
+
+ // Update images in Store
+ DispatchQueue.main.async { [walletImages] in
+ self.store.walletImages.merge(walletImages) { _, new in
+ new
+ }
+ }
+ }
+
+ func prefetchChainImages() async throws {
+ var chainImages: [String: UIImage] = [:]
+
+ try await ChainPresets.ethChains.concurrentMap { chain in
+ do {
+ let image = try await self.fetchAssetImage(id: chain.imageId)
+ return (chain.imageId, image)
+ } catch {
+ print(error.localizedDescription)
+ }
+
+ return ("", UIImage?.none)
+ }
+ .forEach { key, value in
+ if value == nil {
+ return
+ }
+
+ chainImages[key] = value
+ }
+
+ DispatchQueue.main.async { [chainImages] in
+ self.store.chainImages.merge(chainImages) { _, new in
+ new
+ }
+ }
+ }
+
+ func fetchAssetImage(id: String) async throws -> UIImage? {
+
+ let url = URL(string: "https://api.web3modal.com/public/getAssetImage/\(id)")!
+ var request = URLRequest(url: url)
+ request.setW3MHeaders()
+
+ let (data, _) = try await URLSession.shared.data(for: request)
+
+ return UIImage(data: data)
+ }
+
+ func fetchWalletImage(id: String) async throws -> UIImage? {
+
+ let url = URL(string: "https://api.web3modal.com/getWalletImage/\(id)")!
+ var request = URLRequest(url: url)
+ request.setW3MHeaders()
+
+ let (data, _) = try await URLSession.shared.data(for: request)
+
+ return UIImage(data: data)
+ }
+}
+
+extension URLRequest {
+ mutating func setW3MHeaders() {
+ setValue(Web3Modal.config.projectId, forHTTPHeaderField: "x-project-id")
+ setValue(Web3Modal.Config.sdkType, forHTTPHeaderField: "x-sdk-type")
+ setValue(Web3Modal.Config.sdkVersion, forHTTPHeaderField: "x-sdk-version")
+ setValue(EnvironmentInfo.sdkVersion, forHTTPHeaderField: "User-Agent")
+ }
+}
diff --git a/Sources/Web3Modal/Core/W3MJSONRPC+Coinbase.swift b/Sources/Web3Modal/Core/W3MJSONRPC+Coinbase.swift
new file mode 100644
index 0000000..8ab70eb
--- /dev/null
+++ b/Sources/Web3Modal/Core/W3MJSONRPC+Coinbase.swift
@@ -0,0 +1,67 @@
+import CoinbaseWalletSDK
+
+extension W3MJSONRPC {
+ func toCbAction() -> Web3JSONRPC? {
+ switch self {
+ case let .personal_sign(address, message):
+ return .personal_sign(
+ address: address,
+ message: message
+ )
+ case .eth_requestAccounts:
+ return .eth_requestAccounts
+ case let .eth_signTransaction(from, to, value, data, nonce, _, gasPrice, maxFeePerGas, maxPriorityFeePerGas, gasLimit, chainId):
+ return .eth_signTransaction(
+ fromAddress: from,
+ toAddress: to,
+ weiValue: value,
+ data: data,
+ nonce: nonce,
+ gasPriceInWei: gasPrice,
+ maxFeePerGas: maxFeePerGas,
+ maxPriorityFeePerGas: maxPriorityFeePerGas,
+ gasLimit: gasLimit,
+ chainId: chainId
+ )
+ case let .eth_sendTransaction(from, to, value, data, nonce, _, gasPrice, maxFeePerGas, maxPriorityFeePerGas, gasLimit, chainId):
+ return .eth_sendTransaction(
+ fromAddress: from,
+ toAddress: to,
+ weiValue: value,
+ data: data,
+ nonce: nonce,
+ gasPriceInWei: gasPrice,
+ maxFeePerGas: maxFeePerGas,
+ maxPriorityFeePerGas: maxPriorityFeePerGas,
+ gasLimit: gasLimit,
+ chainId: chainId,
+ actionSource: nil
+ )
+ case let .wallet_switchEthereumChain(chainId):
+ return .wallet_switchEthereumChain(chainId: chainId)
+ case let .wallet_addEthereumChain(chainId, blockExplorerUrls, chainName, iconUrls, nativeCurrency, rpcUrls):
+ return .wallet_addEthereumChain(
+ chainId: chainId,
+ blockExplorerUrls: blockExplorerUrls,
+ chainName: chainName,
+ iconUrls: iconUrls,
+ nativeCurrency: nativeCurrency != nil ? .init(
+ name: nativeCurrency!.name,
+ symbol: nativeCurrency!.symbol,
+ decimals: nativeCurrency!.decimals
+ ) : nil,
+ rpcUrls: rpcUrls
+ )
+ case let .wallet_watchAsset(type, options):
+ return .wallet_watchAsset(
+ type: type,
+ options: .init(
+ address: options.address,
+ symbol: options.symbol,
+ decimals: options.decimals,
+ image: options.image
+ )
+ )
+ }
+ }
+}
diff --git a/Sources/Web3Modal/Core/W3MJSONRPC.swift b/Sources/Web3Modal/Core/W3MJSONRPC.swift
new file mode 100644
index 0000000..ddbc5a5
--- /dev/null
+++ b/Sources/Web3Modal/Core/W3MJSONRPC.swift
@@ -0,0 +1,90 @@
+import Foundation
+
+public enum W3MJSONRPC: Codable {
+ case eth_requestAccounts
+
+ case personal_sign(
+ address: String,
+ message: String
+ )
+ case eth_signTransaction(
+ from: String,
+ to: String?,
+ value: String,
+ data: String,
+ nonce: Int?,
+ gas: String?,
+ gasPrice: String?,
+ maxFeePerGas: String?,
+ maxPriorityFeePerGas: String?,
+ gasLimit: String?,
+ chainId: String
+ )
+
+ case eth_sendTransaction(
+ from: String,
+ to: String?,
+ value: String,
+ data: String,
+ nonce: Int?,
+ gas: String?,
+ gasPrice: String?,
+ maxFeePerGas: String?,
+ maxPriorityFeePerGas: String?,
+ gasLimit: String?,
+ chainId: String
+ )
+
+ case wallet_switchEthereumChain(
+ chainId: String
+ )
+
+ case wallet_addEthereumChain(
+ chainId: String,
+ blockExplorerUrls: [String]?,
+ chainName: String?,
+ iconUrls: [String]?,
+ nativeCurrency: AddChainNativeCurrency?,
+ rpcUrls: [String]
+ )
+
+ case wallet_watchAsset(
+ type: String,
+ options: WatchAssetOptions
+ )
+
+ var rawValues: (method: String, params: [String: Any]) {
+ let json = try! JSONEncoder().encode(self)
+ let dictionary = try! JSONSerialization.jsonObject(with: json) as! [String: [String: Any]]
+
+ let method = dictionary.keys.first!
+ let params = dictionary[method]!
+ return (method, params)
+ }
+}
+
+public struct AddChainNativeCurrency: Codable {
+ let name: String
+ let symbol: String
+ let decimals: Int
+
+ public init(name: String, symbol: String, decimals: Int) {
+ self.name = name
+ self.symbol = symbol
+ self.decimals = decimals
+ }
+}
+
+public struct WatchAssetOptions: Codable {
+ let address: String
+ let symbol: String?
+ let decimals: Int?
+ let image: String?
+
+ public init(address: String, symbol: String?, decimals: Int?, image: String?) {
+ self.address = address
+ self.symbol = symbol
+ self.decimals = decimals
+ self.image = image
+ }
+}
diff --git a/Sources/Web3Modal/Core/W3MResponse.swift b/Sources/Web3Modal/Core/W3MResponse.swift
new file mode 100644
index 0000000..7f99fcd
--- /dev/null
+++ b/Sources/Web3Modal/Core/W3MResponse.swift
@@ -0,0 +1,15 @@
+import Foundation
+
+public struct W3MResponse: Codable, Equatable {
+ init(id: RPCID? = RPCID(), topic: String? = nil, chainId: String? = nil, result: RPCResult) {
+ self.id = id
+ self.topic = topic
+ self.chainId = chainId
+ self.result = result
+ }
+
+ public let id: RPCID?
+ public let topic: String?
+ public let chainId: String?
+ public let result: RPCResult
+}
diff --git a/Sources/Web3Modal/Core/Web3Modal.swift b/Sources/Web3Modal/Core/Web3Modal.swift
new file mode 100644
index 0000000..fbbb523
--- /dev/null
+++ b/Sources/Web3Modal/Core/Web3Modal.swift
@@ -0,0 +1,336 @@
+import CoinbaseWalletSDK
+import Foundation
+import SwiftUI
+
+#if canImport(UIKit)
+import UIKit
+#endif
+
+/// Web3Modal instance wrapper
+///
+/// ```Swift
+/// let metadata = AppMetadata(
+/// name: "Swift dapp",
+/// description: "dapp",
+/// url: "dapp.wallet.connect",
+/// icons: ["https://my_icon.com/1"]
+/// )
+/// Web3Modal.configure(projectId: PROJECT_ID, metadata: metadata)
+/// Web3Modal.instance.getSessions()
+/// ```
+public class Web3Modal {
+ /// Web3Modalt client instance
+ public static var instance: Web3ModalClient = {
+ guard let config = Web3Modal.config else {
+ fatalError("Error - you must call Web3Modal.configure(_:) before accessing the shared instance.")
+ }
+ let client = Web3ModalClient(
+ logger: ConsoleLogger(prefix: "📜", loggingLevel: .off),
+ signClient: Sign.instance,
+ pairingClient: Pair.instance as! (PairingClientProtocol & PairingInteracting & PairingRegisterer),
+ store: .shared,
+ analyticsService: .shared
+ )
+
+ let store = Store.shared
+
+ if let session = client.getSessions().first {
+ store.session = session
+ store.connectedWith = .wc
+ store.account = .init(from: session)
+ } else if CoinbaseWalletSDK.shared.isConnected() {
+
+ let storedAccount = AccountStorage.read()
+ store.connectedWith = .cb
+ store.account = storedAccount
+ } else {
+ AccountStorage.clear()
+ }
+
+ return client
+ }()
+
+ struct Config {
+ static let sdkVersion: String = {
+ guard
+ let fileURL = Bundle.coreModule.url(forResource: "PackageConfig", withExtension: "json"),
+ let data = try? Data(contentsOf: fileURL),
+ let jsonObject = try? JSONSerialization.jsonObject(with: data, options: []) as? [String: Any],
+ let version = jsonObject["version"] as? String
+ else {
+ return "undefined"
+ }
+
+ return "swift-\(version)"
+ }()
+
+ static let sdkType = "w3m"
+
+ let projectId: String
+ var metadata: AppMetadata
+ var sessionParams: SessionParams
+
+ let includeWebWallets: Bool
+ let recommendedWalletIds: [String]
+ let excludedWalletIds: [String]
+ let customWallets: [Wallet]
+ let coinbaseEnabled: Bool
+
+ let onError: (Error) -> Void
+ }
+
+ private(set) static var config: Config!
+
+ private(set) static var viewModel: Web3ModalViewModel!
+
+ private init() {}
+
+ /// Wallet instance wallet config method.
+ /// - Parameters:
+ /// - metadata: App metadata
+ public static func configure(
+ projectId: String,
+ metadata: AppMetadata,
+ sessionParams: SessionParams = .default,
+ includeWebWallets: Bool = true,
+ recommendedWalletIds: [String] = [],
+ excludedWalletIds: [String] = [],
+ customWallets: [Wallet] = [],
+ coinbaseEnabled: Bool = true,
+ onError: @escaping (Error) -> Void = { _ in }
+ ) {
+ Pair.configure(metadata: metadata)
+
+ Web3Modal.config = Web3Modal.Config(
+ projectId: projectId,
+ metadata: metadata,
+ sessionParams: sessionParams,
+ includeWebWallets: includeWebWallets,
+ recommendedWalletIds: recommendedWalletIds,
+ excludedWalletIds: excludedWalletIds,
+ customWallets: customWallets,
+ coinbaseEnabled: coinbaseEnabled,
+ onError: onError
+ )
+
+ let store = Store.shared
+ let router = Router()
+ let w3mApiInteractor = W3MAPIInteractor(store: store)
+ let signInteractor = SignInteractor(store: store)
+ let blockchainApiInteractor = BlockchainAPIInteractor(store: store)
+
+ store.customWallets = customWallets
+
+ configureCoinbaseIfNeeded(
+ store: store,
+ metadata: metadata,
+ w3mApiInteractor: w3mApiInteractor
+ )
+
+ Web3Modal.viewModel = Web3ModalViewModel(
+ router: router,
+ store: store,
+ w3mApiInteractor: w3mApiInteractor,
+ signInteractor: signInteractor,
+ blockchainApiInteractor: blockchainApiInteractor
+ )
+
+ Task {
+ try? await w3mApiInteractor.fetchWalletImages(for: store.recentWallets + store.customWallets)
+ try? await w3mApiInteractor.fetchAllWalletMetadata()
+ try? await w3mApiInteractor.fetchFeaturedWallets()
+ try? await w3mApiInteractor.prefetchChainImages()
+ }
+ }
+
+ public static func set(sessionParams: SessionParams) {
+ Web3Modal.config.sessionParams = sessionParams
+ }
+
+ private static func configureCoinbaseIfNeeded(
+ store: Store,
+ metadata: AppMetadata,
+ w3mApiInteractor: W3MAPIInteractor
+ ) {
+ guard Web3Modal.config.coinbaseEnabled else { return }
+
+ if let redirectLink = metadata.redirect?.universal ?? metadata.redirect?.native {
+ CoinbaseWalletSDK.configure(callback: URL(string: redirectLink)!)
+ } else {
+ CoinbaseWalletSDK.configure(
+ callback: URL(string: "w3mdapp://")!
+ )
+ }
+
+ var wallet: Wallet = .init(
+ id: "fd20dc426fb37566d803205b19bbc1d4096b248ac04548e3cfb6b3a38bd033aa",
+ name: "Coinbase",
+ homepage: "https://www.coinbase.com/wallet/",
+ imageId: "a5ebc364-8f91-4200-fcc6-be81310a0000",
+ order: 4,
+ mobileLink: nil,
+ desktopLink: nil,
+ webappLink: nil,
+ appStore: "https://apps.apple.com/us/app/coinbase-wallet-nfts-crypto/id1278383455",
+ alternativeConnectionMethod: {
+ CoinbaseWalletSDK.shared.initiateHandshake { result, account in
+ switch result {
+ case .success:
+ guard
+ let account = account,
+ let blockchain = Blockchain(
+ namespace: account.chain == "eth" ? "eip155" : "",
+ reference: String(account.networkId)
+ )
+ else { return }
+
+ store.connectedWith = .cb
+ store.account = .init(
+ address: account.address,
+ chain: blockchain
+ )
+
+ withAnimation {
+ store.isModalShown = false
+ }
+ Web3Modal.viewModel.router.setRoute(Router.AccountSubpage.profile)
+
+ let matchingChain = ChainPresets.ethChains.first(where: {
+ $0.chainNamespace == blockchain.namespace && $0.chainReference == blockchain.reference
+ })
+
+ store.selectedChain = matchingChain
+ case .failure(let error):
+ store.toast = .init(style: .error, message: error.localizedDescription)
+ }
+ }
+ }
+ )
+
+ wallet.isInstalled = CoinbaseWalletSDK.isCoinbaseWalletInstalled()
+
+ store.customWallets.append(wallet)
+
+ Task { [wallet] in
+ try? await w3mApiInteractor.fetchWalletImages(for: [wallet])
+ }
+ }
+}
+
+#if canImport(UIKit)
+
+public extension Web3Modal {
+ static func selectChain(from presentingViewController: UIViewController? = nil) {
+ guard let vc = presentingViewController ?? topViewController() else {
+ assertionFailure("No controller found for presenting modal")
+ return
+ }
+
+ _ = Web3Modal.instance
+
+ Web3Modal.viewModel.router.setRoute(Router.NetworkSwitchSubpage.selectChain)
+
+ Store.shared.connecting = true
+
+ let modal = Web3ModalSheetController(router: Web3Modal.viewModel.router)
+ vc.present(modal, animated: true)
+ }
+
+ static func present(from presentingViewController: UIViewController? = nil) {
+ guard let vc = presentingViewController ?? topViewController() else {
+ assertionFailure("No controller found for presenting modal")
+ return
+ }
+
+ _ = Web3Modal.instance
+
+ Store.shared.connecting = true
+
+ Web3Modal.viewModel.router.setRoute(Store.shared.account != nil ? Router.AccountSubpage.profile : Router.ConnectingSubpage.connectWallet)
+
+ let modal = Web3ModalSheetController(router: Web3Modal.viewModel.router)
+ vc.present(modal, animated: true)
+ }
+
+ private static func topViewController(_ base: UIViewController? = nil) -> UIViewController? {
+ let base = base ?? UIApplication
+ .shared
+ .connectedScenes
+ .flatMap { ($0 as? UIWindowScene)?.windows ?? [] }
+ .last { $0.isKeyWindow }?
+ .rootViewController
+
+ if let nav = base as? UINavigationController {
+ return topViewController(nav.visibleViewController)
+ }
+
+ if let tab = base as? UITabBarController {
+ if let selected = tab.selectedViewController {
+ return topViewController(selected)
+ }
+ }
+
+ if let presented = base?.presentedViewController {
+ return topViewController(presented)
+ }
+
+ return base
+ }
+}
+
+#elseif canImport(AppKit)
+
+import AppKit
+
+public extension Web3Modal {
+ static func present(from presentingViewController: NSViewController? = nil) {
+ let modal = Web3ModalSheetController()
+ presentingViewController!.presentAsModalWindow(modal)
+ }
+}
+
+#endif
+
+public struct SessionParams {
+ public let requiredNamespaces: [String: ProposalNamespace]
+ public let optionalNamespaces: [String: ProposalNamespace]?
+ public let sessionProperties: [String: String]?
+
+ public init(requiredNamespaces: [String: ProposalNamespace], optionalNamespaces: [String: ProposalNamespace]? = nil, sessionProperties: [String: String]? = nil) {
+ self.requiredNamespaces = requiredNamespaces
+ self.optionalNamespaces = optionalNamespaces
+ self.sessionProperties = sessionProperties
+ }
+
+ public static let `default`: Self = {
+ let methods: Set = Set(EthUtils.ethMethods)
+ let events: Set = ["chainChanged", "accountsChanged"]
+ let blockchains: Set = Set(ChainPresets.ethChains.map(\.id).compactMap(Blockchain.init))
+
+ let namespaces: [String: ProposalNamespace] = [
+ "eip155": ProposalNamespace(
+ chains: blockchains,
+ methods: methods,
+ events: events
+ )
+ ]
+
+ let optionalNamespaces: [String: ProposalNamespace] = [
+ "solana": ProposalNamespace(
+ chains: [
+ Blockchain("solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp")!
+ ],
+ methods: [
+ "solana_signMessage",
+ "solana_signTransaction"
+ ], events: []
+ )
+ ]
+
+ return SessionParams(
+ requiredNamespaces: [:],
+ optionalNamespaces: namespaces.merging(optionalNamespaces, uniquingKeysWith: { old, _ in old }),
+ sessionProperties: nil
+ )
+ }()
+}
diff --git a/Sources/Web3Modal/Core/Web3ModalClient.swift b/Sources/Web3Modal/Core/Web3ModalClient.swift
new file mode 100644
index 0000000..aee1f8b
--- /dev/null
+++ b/Sources/Web3Modal/Core/Web3ModalClient.swift
@@ -0,0 +1,392 @@
+import class CoinbaseWalletSDK.CoinbaseWalletSDK
+import struct CoinbaseWalletSDK.Action
+import struct CoinbaseWalletSDK.ActionError
+import Combine
+import Foundation
+import UIKit
+
+// Web3 Modal Client
+///
+/// Cannot be instantiated outside of the SDK
+///
+/// Access via `Web3Modal.instance`
+public class Web3ModalClient {
+ // MARK: - Public Properties
+
+ /// Publisher that sends sessions on every sessions update
+ ///
+ /// Event will be emited on controller and non-controller clients.
+ public var sessionsPublisher: AnyPublisher<[Session], Never> {
+ signClient.sessionsPublisher.eraseToAnyPublisher()
+ }
+
+ /// Publisher that sends session when one is settled
+ ///
+ /// Event is emited on proposer and responder client when both communicating peers have successfully established a session.
+ public var sessionSettlePublisher: AnyPublisher {
+ signClient.sessionSettlePublisher.eraseToAnyPublisher()
+ }
+
+ /// Publisher that sends session proposal that has been rejected
+ ///
+ /// Event will be emited on dApp client only.
+ public var sessionRejectionPublisher: AnyPublisher<(Session.Proposal, Reason), Never> {
+ signClient.sessionRejectionPublisher.eraseToAnyPublisher()
+ }
+
+ /// Publisher that sends deleted session topic
+ ///
+ /// Event can be emited on any type of the client.
+ public var sessionDeletePublisher: AnyPublisher<(String, Reason), Never> {
+ signClient.sessionDeletePublisher.eraseToAnyPublisher()
+ }
+
+ /// Publisher that sends response for session request
+ ///
+ /// In most cases that event will be emited on dApp client.
+ public var sessionResponsePublisher: AnyPublisher {
+ signClient.sessionResponsePublisher
+ .map { response in
+ W3MResponse(
+ id: response.id,
+ topic: response.topic,
+ chainId: response.chainId,
+ result: response.result
+ )
+ }
+ .merge(with: coinbaseResponseSubject)
+ .eraseToAnyPublisher()
+ }
+
+ public var coinbaseResponseSubject = PassthroughSubject()
+
+ /// Publisher that sends web socket connection status
+ public var socketConnectionStatusPublisher: AnyPublisher {
+ signClient.socketConnectionStatusPublisher.eraseToAnyPublisher()
+ }
+
+ /// Publisher that sends session event
+ ///
+ /// Event will be emited on dApp client only
+ public var sessionEventPublisher: AnyPublisher<(event: Session.Event, sessionTopic: String, chainId: Blockchain?), Never> {
+ signClient.sessionEventPublisher.eraseToAnyPublisher()
+ }
+
+ public var isAnalyticsEnabled: Bool {
+ return analyticsService.isAnalyticsEnabled
+ }
+
+ // MARK: - Private Properties
+
+ private let signClient: SignClientProtocol
+ private let pairingClient: PairingClientProtocol & PairingInteracting & PairingRegisterer
+ private let store: Store
+ private let analyticsService: AnalyticsService
+ private var disposeBag = Set()
+ public let logger: ConsoleLogging
+
+ init(
+ logger: ConsoleLogging,
+ signClient: SignClientProtocol,
+ pairingClient: PairingClientProtocol & PairingInteracting & PairingRegisterer,
+ store: Store,
+ analyticsService: AnalyticsService
+ ) {
+ self.logger = logger
+ self.signClient = signClient
+ self.pairingClient = pairingClient
+ self.store = store
+ self.analyticsService = analyticsService
+ setUpConnectionEvents()
+ analyticsService.track(.MODAL_LOADED)
+ }
+
+ /// For creating new pairing
+ public func createPairing() async throws -> WalletConnectURI {
+ logger.debug("Creating new pairing")
+ do {
+ return try await pairingClient.create()
+ } catch {
+ Web3Modal.config.onError(error)
+ throw error
+ }
+ }
+
+ /// For proposing a session to a wallet.
+ /// Function will propose a session on existing pairing or create new one if not specified
+ /// Namespaces from Web3Modal.config will be used
+ /// - Parameters:
+ /// - topic: pairing topic
+ public func connect(
+ topic: String?
+ ) async throws -> WalletConnectURI? {
+ logger.debug("Connecting Application")
+ do {
+ if let topic = topic {
+ try pairingClient.validatePairingExistance(topic)
+ try await signClient.connect(
+ requiredNamespaces: Web3Modal.config.sessionParams.requiredNamespaces,
+ optionalNamespaces: Web3Modal.config.sessionParams.optionalNamespaces,
+ sessionProperties: Web3Modal.config.sessionParams.sessionProperties,
+ topic: topic
+ )
+ return nil
+ } else {
+ let pairingURI = try await pairingClient.create()
+ try await signClient.connect(
+ requiredNamespaces: Web3Modal.config.sessionParams.requiredNamespaces,
+ optionalNamespaces: Web3Modal.config.sessionParams.optionalNamespaces,
+ sessionProperties: Web3Modal.config.sessionParams.sessionProperties,
+ topic: pairingURI.topic
+ )
+ return pairingURI
+ }
+ } catch {
+ Web3Modal.config.onError(error)
+ throw error
+ }
+ }
+
+ /// For proposing a session to a wallet.
+ /// Function will propose a session on existing pairing.
+ /// - Parameters:
+ /// - requiredNamespaces: required namespaces for a session
+ /// - topic: pairing topic
+ public func connect(
+ requiredNamespaces: [String: ProposalNamespace],
+ optionalNamespaces: [String: ProposalNamespace]? = nil,
+ sessionProperties: [String: String]? = nil,
+ topic: String
+ ) async throws {
+ logger.debug("Connecting Application on topic: \(topic)")
+ do {
+ try await signClient.connect(
+ requiredNamespaces: requiredNamespaces,
+ optionalNamespaces: optionalNamespaces,
+ sessionProperties: sessionProperties,
+ topic: topic
+ )
+ } catch {
+ Web3Modal.config.onError(error)
+ throw error
+ }
+ }
+
+ /// Ping method allows to check if peer client is online and is subscribing for given topic
+ ///
+ /// Should Error:
+ /// - When the session topic is not found
+ ///
+ /// - Parameters:
+ /// - topic: Topic of a session
+ public func ping(topic: String) async throws {
+ do {
+ try await pairingClient.ping(topic: topic)
+ } catch {
+ Web3Modal.config.onError(error)
+ throw error
+ }
+ }
+
+ public func request(_ request: W3MJSONRPC) async throws {
+ logger.debug("Requesting: \(request.rawValues.method)")
+ switch store.connectedWith {
+ case .wc:
+ guard
+ let session = getSessions().first,
+ let chain = getSelectedChain(),
+ let blockchain = Blockchain(namespace: chain.chainNamespace, reference: chain.chainReference)
+ else { return }
+
+ if case let .personal_sign(address, message) = request {
+ try await signClient.request(
+ params: .init(
+ topic: session.topic,
+ method: request.rawValues.method,
+ params: AnyCodable(any: [message, address]),
+ chainId: blockchain
+ )
+ )
+ } else {
+ try await signClient.request(
+ params: .init(
+ topic: session.topic,
+ method: request.rawValues.method,
+ params: AnyCodable(any: request.rawValues.params),
+ chainId: blockchain
+ )
+ )
+ }
+ case .cb:
+
+ guard let jsonRpc = request.toCbAction() else { return }
+
+ // Execute on main as Coinbase SDK is not dispatching on main when calling UIApplication.openUrl()
+ DispatchQueue.main.async {
+ CoinbaseWalletSDK.shared.makeRequest(
+ .init(
+ actions: [
+ Action(jsonRpc: jsonRpc)
+ ]
+ )
+ ) { result in
+ let response: W3MResponse
+ switch result {
+ case let .success(payload):
+
+ switch payload.content.first {
+ case let .success(JSONString):
+ response = .init(result: .response(AnyCodable(JSONString)))
+ case let .failure(error):
+ response = .init(result: .error(.init(code: error.code, message: error.message)))
+ case .none:
+ response = .init(result: .error(.init(code: -1, message: "Empty response")))
+ }
+ case let .failure(error):
+ Web3Modal.config.onError(error)
+
+ if let cbError = error as? ActionError {
+ response = .init(result: .error(.init(code: cbError.code, message: cbError.message)))
+ } else {
+ response = .init(result: .error(.init(code: -1, message: error.localizedDescription)))
+ }
+ }
+
+ self.coinbaseResponseSubject.send(response)
+ }
+ }
+ case .none:
+ break
+ }
+ }
+
+ /// For sending JSON-RPC requests to wallet.
+ /// - Parameters:
+ /// - params: Parameters defining request and related session
+ public func request(params: Request) async throws {
+ do {
+ try await signClient.request(params: params)
+ } catch {
+ Web3Modal.config.onError(error)
+ throw error
+ }
+ }
+
+ /// For a terminating a session
+ ///
+ /// Should Error:
+ /// - When the session topic is not found
+ /// - Parameters:
+ /// - topic: Session topic that you want to delete
+ public func disconnect(topic: String) async throws {
+ switch store.connectedWith {
+ case .wc:
+ do {
+ try await signClient.disconnect(topic: topic)
+ analyticsService.track(.DISCONNECT_SUCCESS)
+ } catch {
+ Web3Modal.config.onError(error)
+ analyticsService.track(.DISCONNECT_ERROR)
+ throw error
+ }
+ case .cb:
+ if case let .failure(error) = CoinbaseWalletSDK.shared.resetSession() {
+ analyticsService.track(.DISCONNECT_ERROR)
+ throw error
+ } else {
+ analyticsService.track(.DISCONNECT_SUCCESS)
+ }
+ case .none:
+ break
+ }
+ }
+
+ /// Query sessions
+ /// - Returns: All sessions
+ public func getSessions() -> [Session] {
+ signClient.getSessions()
+ }
+
+ /// Query pairings
+ /// - Returns: All pairings
+ public func getPairings() -> [Pairing] {
+ pairingClient.getPairings()
+ }
+
+ /// Delete all stored data such as: pairings, sessions, keys
+ ///
+ /// - Note: Will unsubscribe from all topics
+ public func cleanup() async throws {
+ do {
+ try await signClient.cleanup()
+ } catch {
+ Web3Modal.config.onError(error)
+ throw error
+ }
+ }
+
+ public func getAddress() -> String? {
+ guard let account = store.account else { return nil }
+
+ return account.address
+ }
+
+ public func getSelectedChain() -> Chain? {
+ guard let chain = store.selectedChain else {
+ return nil
+ }
+
+ return chain
+ }
+
+ public func addChainPreset(_ chain: Chain) {
+ ChainPresets.ethChains.append(chain)
+ }
+
+ public func selectChain(_ chain: Chain) {
+ store.selectedChain = chain
+ }
+
+ public func launchCurrentWallet() {
+ guard
+ let session = store.session,
+ let urlString = session.peer.redirect?.native ?? session.peer.redirect?.universal,
+ let url = URL(string: urlString)
+ else { return }
+
+ DispatchQueue.main.async {
+ UIApplication.shared.open(url, completionHandler: nil)
+ }
+ }
+
+ @discardableResult
+ public func handleDeeplink(_ url: URL) -> Bool {
+ do {
+ return try CoinbaseWalletSDK.shared.handleResponse(url)
+ } catch {
+ store.toast = .init(style: .error, message: error.localizedDescription)
+ return false
+ }
+ }
+
+ private func setUpConnectionEvents() {
+ analyticsService.track(.MODAL_LOADED)
+
+ signClient.sessionSettlePublisher.sink { [unowned self] session in
+ self.analyticsService.track(.CONNECT_SUCCESS(method: analyticsService.method, name: session.peer.name))
+ }.store(in: &disposeBag)
+
+
+ signClient.sessionRejectionPublisher.sink { [unowned self] (_, reason) in
+ self.analyticsService.track(.CONNECT_ERROR(message: reason.message))
+ }.store(in: &disposeBag)
+ }
+
+ public func enableAnalytics() {
+ analyticsService.enable()
+ }
+
+ public func disableAnalytics() {
+ analyticsService.disable()
+ }
+}
diff --git a/Sources/Web3Modal/Extensions/Collection.swift b/Sources/Web3Modal/Extensions/Collection.swift
new file mode 100644
index 0000000..fbf2875
--- /dev/null
+++ b/Sources/Web3Modal/Extensions/Collection.swift
@@ -0,0 +1,2 @@
+import Foundation
+
diff --git a/Sources/Web3Modal/Extensions/Sequence.swift b/Sources/Web3Modal/Extensions/Sequence.swift
new file mode 100644
index 0000000..7a9047e
--- /dev/null
+++ b/Sources/Web3Modal/Extensions/Sequence.swift
@@ -0,0 +1,29 @@
+import Foundation
+
+extension Sequence {
+ func asyncMap(
+ _ transform: (Element) async throws -> T
+ ) async rethrows -> [T] {
+ var values = [T]()
+
+ for element in self {
+ try await values.append(transform(element))
+ }
+
+ return values
+ }
+
+ func concurrentMap(
+ _ transform: @escaping (Element) async throws -> T
+ ) async throws -> [T] {
+ let tasks = map { element in
+ Task {
+ try await transform(element)
+ }
+ }
+
+ return try await tasks.asyncMap { task in
+ try await task.value
+ }
+ }
+}
diff --git a/Sources/Web3Modal/Extensions/View+RoundedCorners.swift b/Sources/Web3Modal/Extensions/View+RoundedCorners.swift
new file mode 100644
index 0000000..8cd2d1e
--- /dev/null
+++ b/Sources/Web3Modal/Extensions/View+RoundedCorners.swift
@@ -0,0 +1,96 @@
+import SwiftUI
+
+#if canImport(UIKit)
+
+extension View {
+ func cornerRadius(_ radius: CGFloat, corners: UIRectCorner) -> some View {
+ clipShape( RoundedCorner(radius: radius, corners: corners) )
+ }
+}
+
+struct RoundedCorner: Shape {
+
+ var insetAmount = 0.0
+ var radius: CGFloat = .infinity
+ var corners: UIRectCorner = .allCorners
+
+ func path(in rect: CGRect) -> Path {
+ let path = UIBezierPath(roundedRect: rect.inset(by: .init(top: 0, left: insetAmount, bottom: 0, right: insetAmount)), byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
+ return Path(path.cgPath)
+ }
+}
+
+extension RoundedCorner: InsettableShape {
+ func inset(by amount: CGFloat) -> some InsettableShape {
+ var roundedCorner = self
+ roundedCorner.insetAmount += amount
+ return roundedCorner
+ }
+}
+
+#elseif canImport(AppKit)
+
+struct RectCorner: OptionSet {
+
+ let rawValue: Int
+
+ static let topLeft = RectCorner(rawValue: 1 << 0)
+ static let topRight = RectCorner(rawValue: 1 << 1)
+ static let bottomRight = RectCorner(rawValue: 1 << 2)
+ static let bottomLeft = RectCorner(rawValue: 1 << 3)
+
+ static let allCorners: RectCorner = [.topLeft, topRight, .bottomLeft, .bottomRight]
+}
+
+
+// draws shape with specified rounded corners applying corner radius
+struct RoundedCorner: Shape {
+
+ var radius: CGFloat = .zero
+ var corners: RectCorner = .allCorners
+
+ func path(in rect: CGRect) -> Path {
+ var path = Path()
+
+ let p1 = CGPoint(x: rect.minX, y: corners.contains(.topLeft) ? rect.minY + radius : rect.minY )
+ let p2 = CGPoint(x: corners.contains(.topLeft) ? rect.minX + radius : rect.minX, y: rect.minY )
+
+ let p3 = CGPoint(x: corners.contains(.topRight) ? rect.maxX - radius : rect.maxX, y: rect.minY )
+ let p4 = CGPoint(x: rect.maxX, y: corners.contains(.topRight) ? rect.minY + radius : rect.minY )
+
+ let p5 = CGPoint(x: rect.maxX, y: corners.contains(.bottomRight) ? rect.maxY - radius : rect.maxY )
+ let p6 = CGPoint(x: corners.contains(.bottomRight) ? rect.maxX - radius : rect.maxX, y: rect.maxY )
+
+ let p7 = CGPoint(x: corners.contains(.bottomLeft) ? rect.minX + radius : rect.minX, y: rect.maxY )
+ let p8 = CGPoint(x: rect.minX, y: corners.contains(.bottomLeft) ? rect.maxY - radius : rect.maxY )
+
+
+ path.move(to: p1)
+ path.addArc(tangent1End: CGPoint(x: rect.minX, y: rect.minY),
+ tangent2End: p2,
+ radius: radius)
+ path.addLine(to: p3)
+ path.addArc(tangent1End: CGPoint(x: rect.maxX, y: rect.minY),
+ tangent2End: p4,
+ radius: radius)
+ path.addLine(to: p5)
+ path.addArc(tangent1End: CGPoint(x: rect.maxX, y: rect.maxY),
+ tangent2End: p6,
+ radius: radius)
+ path.addLine(to: p7)
+ path.addArc(tangent1End: CGPoint(x: rect.minX, y: rect.maxY),
+ tangent2End: p8,
+ radius: radius)
+ path.closeSubpath()
+
+ return path
+ }
+}
+
+extension View {
+ func cornerRadius(_ radius: CGFloat, corners: RectCorner) -> some View {
+ clipShape( RoundedCorner(radius: radius, corners: corners) )
+ }
+}
+
+#endif
diff --git a/Sources/Web3Modal/Helpers/EnvironmentInfo.swift b/Sources/Web3Modal/Helpers/EnvironmentInfo.swift
new file mode 100644
index 0000000..83669b6
--- /dev/null
+++ b/Sources/Web3Modal/Helpers/EnvironmentInfo.swift
@@ -0,0 +1,34 @@
+#if os(iOS)
+import UIKit
+#endif
+import Foundation
+
+enum EnvironmentInfo {
+
+ static var sdkVersion: String {
+ "swift-\(packageVersion)/\(operatingSystem)"
+ }
+
+ static var packageVersion: String {
+ guard
+ let fileURL = Bundle.coreModule.url(forResource: "PackageConfig", withExtension: "json"),
+ let data = try? Data(contentsOf: fileURL),
+ let jsonObject = try? JSONSerialization.jsonObject(with: data, options: []) as? [String: Any],
+ let version = jsonObject["version"] as? String
+ else {
+ return "undefined"
+ }
+
+ return version
+ }
+
+ public static var operatingSystem: String {
+#if os(iOS)
+ return "\(UIDevice.current.systemName)-\(UIDevice.current.systemVersion)"
+#elseif os(macOS)
+ return "macOS-\(ProcessInfo.processInfo.operatingSystemVersion)"
+#elseif os(tvOS)
+ return "tvOS-\(ProcessInfo.processInfo.operatingSystemVersion)"
+#endif
+ }
+}
diff --git a/Sources/Web3Modal/Models/Chain.swift b/Sources/Web3Modal/Models/Chain.swift
new file mode 100644
index 0000000..73a6ea2
--- /dev/null
+++ b/Sources/Web3Modal/Models/Chain.swift
@@ -0,0 +1,214 @@
+import Foundation
+
+public struct Chain: Identifiable, Hashable {
+
+ public var id: String {
+ "\(chainNamespace):\(chainReference)"
+ }
+
+ public var chainName: String
+ public var chainNamespace: String
+ public var chainReference: String
+ public var requiredMethods: [String]
+ public var optionalMethods: [String]
+ public var events: [String]
+ public var token: Token
+ public var rpcUrl: String
+ public var blockExplorerUrl: String
+ public var imageId: String
+
+ public struct Token: Hashable {
+ public var name: String
+ public var symbol: String
+ public var decimal: Int
+
+ public init(name: String, symbol: String, decimal: Int) {
+ self.name = name
+ self.symbol = symbol
+ self.decimal = decimal
+ }
+ }
+
+ public init(chainName: String, chainNamespace: String, chainReference: String, requiredMethods: [String], optionalMethods: [String], events: [String], token: Chain.Token, rpcUrl: String, blockExplorerUrl: String, imageId: String) {
+ self.chainName = chainName
+ self.chainNamespace = chainNamespace
+ self.chainReference = chainReference
+ self.requiredMethods = requiredMethods
+ self.optionalMethods = optionalMethods
+ self.events = events
+ self.token = token
+ self.rpcUrl = rpcUrl
+ self.blockExplorerUrl = blockExplorerUrl
+ self.imageId = imageId
+ }
+}
+
+enum EthUtils {
+
+ static let walletSwitchEthChain = "wallet_switchEthereumChain"
+ static let walletAddEthChain = "wallet_addEthereumChain"
+
+ static let ethRequiredMethods = [
+ "personal_sign",
+ "eth_signTypedData",
+ "eth_sendTransaction",
+ ]
+ static let ethOptionalMethods = [walletSwitchEthChain, walletAddEthChain]
+ static let ethMethods = ethRequiredMethods + ethOptionalMethods
+
+ static let chainChanged = "chainChanged"
+ static let accountsChanged = "accountsChanged"
+
+ static let ethEvents = [chainChanged, accountsChanged]
+}
+
+enum ChainPresets {
+ static let ethToken = Chain.Token(name: "Ether", symbol: "ETH", decimal: 18)
+
+ static var ethChains: [Chain] = [
+ Chain(
+ chainName: "Ethereum",
+ chainNamespace: "eip155",
+ chainReference: "1",
+ requiredMethods: [],
+ optionalMethods: [],
+ events: [],
+ token: ethToken,
+ rpcUrl: "https://cloudflare-eth.com",
+ blockExplorerUrl: "https://etherscan.io",
+ imageId: "692ed6ba-e569-459a-556a-776476829e00"
+ ),
+ Chain(
+ chainName: "Arbitrum One",
+ chainNamespace: "eip155",
+ chainReference: "42161",
+ requiredMethods: [],
+ optionalMethods: [],
+ events: [],
+ token: ethToken,
+ rpcUrl: "https://arb1.arbitrum.io/rpc",
+ blockExplorerUrl: "https://arbiscan.io",
+ imageId: "600a9a04-c1b9-42ca-6785-9b4b6ff85200"
+ ),
+ Chain(
+ chainName: "Polygon",
+ chainNamespace: "eip155",
+ chainReference: "137",
+ requiredMethods: [],
+ optionalMethods: [],
+ events: [],
+ token: .init(name: "MATIC", symbol: "MATIC", decimal: 18),
+ rpcUrl: "https://polygon-rpc.com",
+ blockExplorerUrl: "https://polygonscan.com",
+ imageId: "41d04d42-da3b-4453-8506-668cc0727900"
+ ),
+ Chain(
+ chainName: "Avalanche",
+ chainNamespace: "eip155",
+ chainReference: "43114",
+ requiredMethods: [],
+ optionalMethods: [],
+ events: [],
+ token: .init(name: "Avalanche", symbol: "AVAX", decimal: 18),
+ rpcUrl: "https://api.avax.network/ext/bc/C/rpc",
+ blockExplorerUrl: "https://snowtrace.io",
+ imageId: "30c46e53-e989-45fb-4549-be3bd4eb3b00"
+ ),
+ Chain(
+ chainName: "BNB Smart Chain",
+ chainNamespace: "eip155",
+ chainReference: "56",
+ requiredMethods: EthUtils.ethRequiredMethods,
+ optionalMethods: EthUtils.ethOptionalMethods,
+ events: EthUtils.ethEvents,
+ token: .init(name: "BNB",symbol: "BNB",decimal: 18),
+ rpcUrl: "https://rpc.ankr.com/bsc",
+ blockExplorerUrl: "https://bscscan.com",
+ imageId: "93564157-2e8e-4ce7-81df-b264dbee9b00"
+ ),
+ Chain(
+ chainName: "OP Mainnet",
+ chainNamespace: "eip155",
+ chainReference: "10",
+ requiredMethods: EthUtils.ethRequiredMethods,
+ optionalMethods: EthUtils.ethOptionalMethods,
+ events: EthUtils.ethEvents,
+ token: ethToken,
+ rpcUrl: "https://mainnet.optimism.io",
+ blockExplorerUrl: "https://explorer.optimism.io",
+ imageId: "ab9c186a-c52f-464b-2906-ca59d760a400"
+ ),
+ Chain(
+ chainName: "Gnosis",
+ chainNamespace: "eip155",
+ chainReference: "100",
+ requiredMethods: EthUtils.ethRequiredMethods,
+ optionalMethods: EthUtils.ethOptionalMethods,
+ events: EthUtils.ethEvents,
+ token: .init(name: "Gnosis",symbol: "xDAI",decimal: 18),
+ rpcUrl: "https://rpc.gnosischain.com",
+ blockExplorerUrl: "https://blockscout.com/xdai/mainnet",
+ imageId: "02b53f6a-e3d4-479e-1cb4-21178987d100"
+ ),
+ Chain(
+ chainName: "zkSync Era",
+ chainNamespace: "eip155",
+ chainReference: "324",
+ requiredMethods: EthUtils.ethRequiredMethods,
+ optionalMethods: EthUtils.ethOptionalMethods,
+ events: EthUtils.ethEvents,
+ token: ethToken,
+ rpcUrl: "https://mainnet.era.zksync.io",
+ blockExplorerUrl: "https://explorer.zksync.io",
+ imageId: "b310f07f-4ef7-49f3-7073-2a0a39685800"
+ ),
+ Chain(
+ chainName: "Zora",
+ chainNamespace: "eip155",
+ chainReference: "7777777",
+ requiredMethods: EthUtils.ethRequiredMethods,
+ optionalMethods: EthUtils.ethOptionalMethods,
+ events: EthUtils.ethEvents,
+ token: ethToken,
+ rpcUrl: "https://rpc.zora.energy",
+ blockExplorerUrl: "https://explorer.zora.energy",
+ imageId: "845c60df-d429-4991-e687-91ae45791600"
+ ),
+ Chain(
+ chainName: "Base",
+ chainNamespace: "eip155",
+ chainReference: "8453",
+ requiredMethods: EthUtils.ethRequiredMethods,
+ optionalMethods: EthUtils.ethOptionalMethods,
+ events: EthUtils.ethEvents,
+ token: ethToken,
+ rpcUrl: "https://mainnet.base.org",
+ blockExplorerUrl: "https://basescan.org",
+ imageId: "7289c336-3981-4081-c5f4-efc26ac64a00"
+ ),
+ Chain(
+ chainName: "Celo",
+ chainNamespace: "eip155",
+ chainReference: "42220",
+ requiredMethods: EthUtils.ethRequiredMethods,
+ optionalMethods: EthUtils.ethOptionalMethods,
+ events: EthUtils.ethEvents,
+ token: .init(name: "CELO",symbol: "CELO",decimal: 18),
+ rpcUrl: "https://forno.celo.org",
+ blockExplorerUrl: "https://explorer.celo.org/mainnet",
+ imageId: "ab781bbc-ccc6-418d-d32d-789b15da1f00"
+ ),
+ Chain(
+ chainName: "Aurora",
+ chainNamespace: "eip155",
+ chainReference: "1313161554",
+ requiredMethods: [],
+ optionalMethods: [],
+ events: [],
+ token: ethToken,
+ rpcUrl: "https://mainnet.aurora.dev",
+ blockExplorerUrl: "https://aurorascan.dev",
+ imageId: "3ff73439-a619-4894-9262-4470c773a100"
+ )
+ ]
+}
diff --git a/Sources/Web3Modal/Models/Helpers/AccountStorage.swift b/Sources/Web3Modal/Models/Helpers/AccountStorage.swift
new file mode 100644
index 0000000..efeb540
--- /dev/null
+++ b/Sources/Web3Modal/Models/Helpers/AccountStorage.swift
@@ -0,0 +1,28 @@
+import Foundation
+
+class AccountStorage {
+ enum Keys: String {
+ case storeAccount
+ }
+
+ static func read(defaults: UserDefaults = .standard) -> W3MAccount? {
+ guard
+ let data = defaults.data(forKey: Keys.storeAccount.rawValue),
+ let account = try? JSONDecoder().decode(W3MAccount.self, from: data)
+ else {
+ return nil
+ }
+
+ return account
+ }
+
+ static func save(defaults: UserDefaults = .standard, _ account: W3MAccount?) {
+ guard let accountData = try? JSONEncoder().encode(account) else { return }
+
+ defaults.set(accountData, forKey: Keys.storeAccount.rawValue)
+ }
+
+ static func clear(defaults: UserDefaults = .standard) {
+ defaults.set(nil, forKey: Keys.storeAccount.rawValue)
+ }
+}
diff --git a/Sources/Web3Modal/Models/Helpers/AsyncSemaphore.swift b/Sources/Web3Modal/Models/Helpers/AsyncSemaphore.swift
new file mode 100644
index 0000000..d25aa18
--- /dev/null
+++ b/Sources/Web3Modal/Models/Helpers/AsyncSemaphore.swift
@@ -0,0 +1,31 @@
+import Foundation
+
+// Simple implementation of semaphore using continuations. Please revise before using for anything else.
+actor AsyncSemaphore {
+ private var count = 0
+ private var waiters = [UnsafeContinuation]()
+
+ public init(count: Int) {
+ self.count = count
+ }
+
+ private func wait() async {
+ count -= 1
+ if count >= 0 { return }
+ await withUnsafeContinuation {
+ waiters.append($0)
+ }
+ }
+
+ private func signal() {
+ count += 1
+ if waiters.isEmpty { return }
+ waiters.removeFirst().resume()
+ }
+
+ public func withTurn(_ procedure: @Sendable () async throws -> Void) async rethrows {
+ await wait()
+ defer { signal() }
+ try await procedure()
+ }
+}
diff --git a/Sources/Web3Modal/Models/Helpers/Bundle+extension.swift b/Sources/Web3Modal/Models/Helpers/Bundle+extension.swift
new file mode 100644
index 0000000..efd1d42
--- /dev/null
+++ b/Sources/Web3Modal/Models/Helpers/Bundle+extension.swift
@@ -0,0 +1,17 @@
+import Foundation
+
+#if CocoaPods
+public extension Foundation.Bundle {
+ private class CocoapodsBundle {}
+
+ static var coreModule: Bundle {
+ let bundle = Bundle(for: CocoapodsBundle.self)
+ let frameworkBundlePath = bundle.path(forResource: "Web3Modal", ofType: "bundle")!
+ return Bundle(path: frameworkBundlePath) ?? bundle
+ }
+}
+#else
+public extension Foundation.Bundle {
+ static var coreModule: Bundle { Bundle.module }
+}
+#endif
diff --git a/Sources/Web3Modal/Models/Helpers/RecentWalletStorage.swift b/Sources/Web3Modal/Models/Helpers/RecentWalletStorage.swift
new file mode 100644
index 0000000..794028d
--- /dev/null
+++ b/Sources/Web3Modal/Models/Helpers/RecentWalletStorage.swift
@@ -0,0 +1,53 @@
+import Foundation
+
+class RecentWalletsStorage {
+
+ static func loadRecentWallets(defaults: UserDefaults = .standard) -> [Wallet] {
+ guard
+ let data = defaults.data(forKey: "recentWallets"),
+ let wallets = try? JSONDecoder().decode([Wallet].self, from: data)
+ else {
+ return []
+ }
+
+ return wallets.filter { wallet in
+ guard let lastTimeUsed = wallet.lastTimeUsed else {
+ assertionFailure("Shouldn't happen we stored wallet without `lastTimeUsed`")
+ return false
+ }
+
+ // Consider Recent only for 3 days
+ return abs(lastTimeUsed.timeIntervalSinceNow) < (24 * 60 * 60 * 3)
+ }
+ }
+
+ static func saveRecentWallets(defaults: UserDefaults = .standard, _ wallets: [Wallet]) {
+
+ let subset = Array(
+ wallets
+ .filter {
+ $0.lastTimeUsed != nil
+ }
+ .sorted(by: { lhs, rhs in
+ lhs.lastTimeUsed! > rhs.lastTimeUsed!
+ })
+ .prefix(2)
+ )
+
+ var uniqueValues: [Wallet] = []
+ subset.forEach { item in
+ guard !uniqueValues.contains(where: { wallet in
+ item.id == wallet.id
+ }) else { return }
+ uniqueValues.append(item)
+ }
+
+ guard
+ let walletsData = try? JSONEncoder().encode(uniqueValues)
+ else {
+ return
+ }
+
+ defaults.set(walletsData, forKey: "recentWallets")
+ }
+}
diff --git a/Sources/Web3Modal/Models/Helpers/Session+Stub.swift b/Sources/Web3Modal/Models/Helpers/Session+Stub.swift
new file mode 100644
index 0000000..3ba2f15
--- /dev/null
+++ b/Sources/Web3Modal/Models/Helpers/Session+Stub.swift
@@ -0,0 +1,50 @@
+import Foundation
+
+#if DEBUG
+extension Session {
+ static let stubJson: Data = """
+ {
+ "peer": {
+ "name": "MetaMask Wallet",
+ "url": "https://metamask.io/",
+ "icons": [],
+ "redirect": {
+ "native": "metamask://",
+ "universal": "https://metamask.app.link/"
+ },
+ "description": "MetaMask Wallet Integration"
+ },
+ "namespaces": {
+ "eip155": {
+ "chains": [
+ "eip155:56"
+ ],
+ "accounts": [
+ "eip155:56:0x5c8877144d858e41d8c33f5baa7e67a5e0027e37"
+ ],
+ "events": [
+ "chainChanged",
+ "accountsChanged"
+ ],
+ "methods": [
+ "wallet_addEthereumChain",
+ "personal_sign",
+ "eth_sendTransaction",
+ "eth_signTypedData",
+ "wallet_switchEthereumChain"
+ ]
+ }
+ },
+ "pairingTopic": "08698f505aa6f677823953cbe3d5f34e4f098635f2444096d88977c1850267bb",
+ "requiredNamespaces": {},
+ "expiryDate": 720702756,
+ "topic": "34afbcab97c8b9105f66ea3770cb540d59085c6f0996b4170cb163fee2558f59"
+ }
+ """.data(using: .utf8)!
+
+ static let stub: Session! = {
+ try! JSONDecoder().decode(Session.self, from: Session.stubJson)
+ }()
+}
+
+#endif
diff --git a/Sources/Web3Modal/Models/Wallet.swift b/Sources/Web3Modal/Models/Wallet.swift
new file mode 100644
index 0000000..b9179aa
--- /dev/null
+++ b/Sources/Web3Modal/Models/Wallet.swift
@@ -0,0 +1,135 @@
+import Foundation
+
+public struct Wallet: Codable, Identifiable {
+ public let id: String
+ let name: String
+ let homepage: String
+ let imageId: String?
+ let imageUrl: String?
+ let order: Int
+ let mobileLink: String?
+ let desktopLink: String?
+ let webappLink: String?
+ let appStore: String?
+
+ var lastTimeUsed: Date?
+ var isInstalled: Bool = false
+ var alternativeConnectionMethod: (() -> Void)? = nil
+
+ enum CodingKeys: String, CodingKey {
+ case id
+ case name
+ case homepage
+ case imageId = "image_id"
+ case imageUrl = "image_url"
+ case order
+ case mobileLink = "mobile_link"
+ case desktopLink = "desktop_link"
+ case webappLink = "webapp_link"
+ case appStore = "app_store"
+
+ // Decorated
+ case lastTimeUsed
+ case isInstalled
+ }
+
+ public init(
+ id: String,
+ name: String,
+ homepage: String,
+ imageId: String? = nil,
+ imageUrl: String? = nil,
+ order: Int,
+ mobileLink: String?,
+ desktopLink: String? = nil,
+ webappLink: String? = nil,
+ appStore: String? = nil,
+ lastTimeUsed: Date? = nil,
+ isInstalled: Bool = false,
+ alternativeConnectionMethod: (() -> Void)? = nil
+ ) {
+ self.id = id
+ self.name = name
+ self.homepage = homepage
+ self.imageId = imageId
+ self.imageUrl = imageUrl
+ self.order = order
+ self.mobileLink = mobileLink
+ self.desktopLink = desktopLink
+ self.webappLink = webappLink
+ self.appStore = appStore
+ self.lastTimeUsed = lastTimeUsed
+ self.isInstalled = isInstalled
+ self.alternativeConnectionMethod = alternativeConnectionMethod
+ }
+
+ public init(from decoder: Decoder) throws {
+ let container = try decoder.container(keyedBy: CodingKeys.self)
+ self.id = try container.decode(String.self, forKey: .id)
+ self.name = try container.decode(String.self, forKey: .name)
+ self.homepage = try container.decode(String.self, forKey: .homepage)
+ self.imageUrl = try container.decodeIfPresent(String.self, forKey: .imageUrl)
+ self.imageId = try container.decodeIfPresent(String.self, forKey: .imageId)
+ self.order = try container.decode(Int.self, forKey: .order)
+ self.mobileLink = try container.decodeIfPresent(String.self, forKey: .mobileLink)
+ self.desktopLink = try container.decodeIfPresent(String.self, forKey: .desktopLink)
+ self.webappLink = try container.decodeIfPresent(String.self, forKey: .webappLink)
+ self.appStore = try container.decodeIfPresent(String.self, forKey: .appStore)
+ self.lastTimeUsed = try container.decodeIfPresent(Date.self, forKey: .lastTimeUsed)
+ self.isInstalled = try container.decodeIfPresent(Bool.self, forKey: .isInstalled) ?? false
+ }
+}
+
+extension Wallet: Equatable {
+ public static func == (lhs: Wallet, rhs: Wallet) -> Bool {
+ return lhs.id == rhs.id
+ }
+}
+
+extension Wallet: Hashable {
+ public func hash(into hasher: inout Hasher) {
+ hasher.combine(id)
+ }
+}
+
+#if DEBUG
+
+extension Wallet {
+ static let stubList: [Wallet] = [
+ Wallet(
+ id: UUID().uuidString,
+ name: "Sample Wallet",
+ homepage: "https://example.com/cool",
+ imageId: "0528ee7e-16d1-4089-21e3-bbfb41933100",
+ order: 1,
+ mobileLink: "https://sample.com/foo/universal",
+ desktopLink: "sampleapp://deeplink",
+ webappLink: "https://sample.com/foo/webapp",
+ appStore: ""
+ ),
+ Wallet(
+ id: UUID().uuidString,
+ name: "Cool Wallet",
+ homepage: "https://example.com/cool",
+ imageId: "5195e9db-94d8-4579-6f11-ef553be95100",
+ order: 2,
+ mobileLink: "awsomeapp://",
+ desktopLink: "awsomeapp://deeplink",
+ webappLink: "https://awesome.com/foo/webapp",
+ appStore: ""
+ ),
+ Wallet(
+ id: UUID().uuidString,
+ name: "Cool Wallet",
+ homepage: "https://example.com/cool",
+ imageId: "3913df81-63c2-4413-d60b-8ff83cbed500",
+ order: 3,
+ mobileLink: "https://cool.com/foo/universal",
+ desktopLink: "coolapp://deeplink",
+ webappLink: "https://cool.com/foo/webapp",
+ appStore: ""
+ )
+ ]
+}
+
+#endif
diff --git a/Sources/Web3Modal/Networking/BlockchainAPI.swift b/Sources/Web3Modal/Networking/BlockchainAPI.swift
new file mode 100644
index 0000000..5ce48a6
--- /dev/null
+++ b/Sources/Web3Modal/Networking/BlockchainAPI.swift
@@ -0,0 +1,45 @@
+import Foundation
+
+enum BlockchainAPI: HTTPService {
+ struct GetIdentityParams {
+ let address: String
+ let chainId: String
+ let projectId: String
+ }
+
+ case getIdentity(params: GetIdentityParams)
+
+ var path: String {
+ switch self {
+ case let .getIdentity(params): return "/v1/identity/\(params.address)"
+ }
+ }
+
+ var method: HTTPMethod {
+ switch self {
+ case .getIdentity: return .get
+ }
+ }
+
+ var body: Data? {
+ nil
+ }
+
+ var queryParameters: [String: String]? {
+ switch self {
+ case let .getIdentity(params):
+ return [
+ "projectId": params.projectId,
+ "chainId": params.chainId,
+ ]
+ }
+ }
+
+ var scheme: String {
+ return "https"
+ }
+
+ var additionalHeaderFields: [String: String]? {
+ nil
+ }
+}
diff --git a/Sources/Web3Modal/Networking/GetWalletsResponse.swift b/Sources/Web3Modal/Networking/GetWalletsResponse.swift
new file mode 100644
index 0000000..3a3edfa
--- /dev/null
+++ b/Sources/Web3Modal/Networking/GetWalletsResponse.swift
@@ -0,0 +1,16 @@
+import Foundation
+
+struct GetWalletsResponse: Codable {
+ let count: Int
+ let data: [Wallet]
+}
+
+struct GetIosDataResponse: Codable {
+ let count: Int
+ let data: [WalletMetadata]
+
+ struct WalletMetadata: Codable {
+ let id: String
+ let ios_schema: String
+ }
+}
diff --git a/Sources/Web3Modal/Networking/Web3ModalAPI.swift b/Sources/Web3Modal/Networking/Web3ModalAPI.swift
new file mode 100644
index 0000000..eb835d8
--- /dev/null
+++ b/Sources/Web3Modal/Networking/Web3ModalAPI.swift
@@ -0,0 +1,84 @@
+import Foundation
+
+enum Web3ModalAPI: HTTPService {
+ struct GetWalletsParams {
+ let page: Int
+ let entries: Int
+ let search: String?
+ let projectId: String
+ let metadata: AppMetadata
+ let recommendedIds: [String]
+ let excludedIds: [String]
+ }
+
+ struct GetIosDataParams {
+ let projectId: String
+ let metadata: AppMetadata
+ }
+
+ case getWallets(params: GetWalletsParams)
+ case getIosData(params: GetIosDataParams)
+
+ var path: String {
+ switch self {
+ case .getWallets: return "/getWallets"
+ case .getIosData: return "/getIosData"
+ }
+ }
+
+ var method: HTTPMethod {
+ switch self {
+ case .getWallets: return .get
+ case .getIosData: return .get
+ }
+ }
+
+ var body: Data? {
+ nil
+ }
+
+ var queryParameters: [String: String]? {
+ switch self {
+ case let .getWallets(params):
+ return [
+ "page": "\(params.page)",
+ "entries": "\(params.entries)",
+ "search": params.search ?? "",
+ "recommendedIds": params.recommendedIds.joined(separator: ","),
+ "excludedIds": params.excludedIds.joined(separator: ","),
+ "platform": "ios",
+ ]
+ .compactMapValues { value in
+ value.isEmpty ? nil : value
+ }
+ case let .getIosData(params):
+ return [
+ "projectId": params.projectId,
+ "metadata": params.metadata.name
+ ]
+ }
+ }
+
+ var scheme: String {
+ return "https"
+ }
+
+ var additionalHeaderFields: [String: String]? {
+ switch self {
+ case let .getWallets(params):
+ return [
+ "x-project-id": params.projectId,
+ "x-sdk-version": Web3Modal.Config.sdkVersion,
+ "x-sdk-type": Web3Modal.Config.sdkType,
+ "Referer": params.metadata.name
+ ]
+ case let .getIosData(params):
+ return [
+ "x-project-id": params.projectId,
+ "x-sdk-version": Web3Modal.Config.sdkVersion,
+ "x-sdk-type": Web3Modal.Config.sdkType,
+ "Referer": params.metadata.name
+ ]
+ }
+ }
+}
diff --git a/Sources/Web3Modal/PackageConfig.json b/Sources/Web3Modal/PackageConfig.json
new file mode 100644
index 0000000..695c896
--- /dev/null
+++ b/Sources/Web3Modal/PackageConfig.json
@@ -0,0 +1,3 @@
+{
+"version": "1.1.0"
+}
diff --git a/Sources/Web3Modal/Resources/Assets.xcassets/Contents.json b/Sources/Web3Modal/Resources/Assets.xcassets/Contents.json
new file mode 100644
index 0000000..73c0059
--- /dev/null
+++ b/Sources/Web3Modal/Resources/Assets.xcassets/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3Modal/Resources/Assets.xcassets/Mocks/Contents.json b/Sources/Web3Modal/Resources/Assets.xcassets/Mocks/Contents.json
new file mode 100644
index 0000000..73c0059
--- /dev/null
+++ b/Sources/Web3Modal/Resources/Assets.xcassets/Mocks/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3Modal/Resources/Assets.xcassets/Mocks/MockChainImage.imageset/Contents.json b/Sources/Web3Modal/Resources/Assets.xcassets/Mocks/MockChainImage.imageset/Contents.json
new file mode 100644
index 0000000..1777a61
--- /dev/null
+++ b/Sources/Web3Modal/Resources/Assets.xcassets/Mocks/MockChainImage.imageset/Contents.json
@@ -0,0 +1,21 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "filename" : "Polygon.png",
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3Modal/Resources/Assets.xcassets/Mocks/MockChainImage.imageset/Polygon.png b/Sources/Web3Modal/Resources/Assets.xcassets/Mocks/MockChainImage.imageset/Polygon.png
new file mode 100644
index 0000000..47e3458
Binary files /dev/null and b/Sources/Web3Modal/Resources/Assets.xcassets/Mocks/MockChainImage.imageset/Polygon.png differ
diff --git a/Sources/Web3Modal/Resources/Assets.xcassets/Mocks/MockWalletImage.imageset/Contents.json b/Sources/Web3Modal/Resources/Assets.xcassets/Mocks/MockWalletImage.imageset/Contents.json
new file mode 100644
index 0000000..3929e95
--- /dev/null
+++ b/Sources/Web3Modal/Resources/Assets.xcassets/Mocks/MockWalletImage.imageset/Contents.json
@@ -0,0 +1,21 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "filename" : "Rainbow.png",
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3Modal/Resources/Assets.xcassets/Mocks/MockWalletImage.imageset/Rainbow.png b/Sources/Web3Modal/Resources/Assets.xcassets/Mocks/MockWalletImage.imageset/Rainbow.png
new file mode 100644
index 0000000..b4be2ec
Binary files /dev/null and b/Sources/Web3Modal/Resources/Assets.xcassets/Mocks/MockWalletImage.imageset/Rainbow.png differ
diff --git a/Sources/Web3Modal/Resources/Assets.xcassets/imageLogo.imageset/Contents.json b/Sources/Web3Modal/Resources/Assets.xcassets/imageLogo.imageset/Contents.json
new file mode 100644
index 0000000..f87704b
--- /dev/null
+++ b/Sources/Web3Modal/Resources/Assets.xcassets/imageLogo.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Square Image Editor.png",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3Modal/Resources/Assets.xcassets/imageLogo.imageset/Square Image Editor.png b/Sources/Web3Modal/Resources/Assets.xcassets/imageLogo.imageset/Square Image Editor.png
new file mode 100644
index 0000000..8fd49e6
Binary files /dev/null and b/Sources/Web3Modal/Resources/Assets.xcassets/imageLogo.imageset/Square Image Editor.png differ
diff --git a/Sources/Web3Modal/Router.swift b/Sources/Web3Modal/Router.swift
new file mode 100644
index 0000000..ef021b8
--- /dev/null
+++ b/Sources/Web3Modal/Router.swift
@@ -0,0 +1,65 @@
+import Combine
+import Foundation
+import SwiftUI
+
+class Router: ObservableObject {
+ @Published private(set) var currentRoute: any SubPage = Router.ConnectingSubpage.connectWallet
+ private(set) var previousRoute: (any SubPage)?
+
+ private let uiApplicationWrapper: UIApplicationWrapper
+
+ init(uiApplicationWrapper: UIApplicationWrapper = .live) {
+ self.uiApplicationWrapper = uiApplicationWrapper
+ }
+
+ func openURL(_ url: URL, completionHandler: ((Bool) -> Void)? = nil) {
+ uiApplicationWrapper.openURL(url, completionHandler)
+ }
+
+ func canOpenURL(_ url: URL) -> Bool {
+ uiApplicationWrapper.canOpenURL(url)
+ }
+
+ func setRoute(_ route: any SubPage) {
+ previousRoute = currentRoute
+ withAnimation {
+ currentRoute = route
+ }
+ }
+
+ func goBack() {
+ let prev = previousRoute ?? Router.ConnectingSubpage.connectWallet
+ withAnimation {
+ currentRoute = prev
+ }
+ previousRoute = nil
+ }
+
+ func resetRoute() {
+ withAnimation {
+ currentRoute = ConnectingSubpage.connectWallet
+ }
+ }
+
+ enum AccountSubpage: SubPage {
+ case transactions
+ case profile
+ }
+
+ enum ConnectingSubpage: SubPage {
+ case connectWallet
+ case qr
+ case allWallets
+ case whatIsAWallet
+ case walletDetail(Wallet)
+ case getWallet
+ }
+
+ enum NetworkSwitchSubpage: SubPage {
+ case selectChain
+ case networkDetail(Chain)
+ case whatIsANetwork
+ }
+}
+
+protocol SubPage: Equatable {}
diff --git a/Sources/Web3Modal/Screens/.DS_Store b/Sources/Web3Modal/Screens/.DS_Store
new file mode 100644
index 0000000..2304a10
Binary files /dev/null and b/Sources/Web3Modal/Screens/.DS_Store differ
diff --git a/Sources/Web3Modal/Screens/AccountView.swift b/Sources/Web3Modal/Screens/AccountView.swift
new file mode 100644
index 0000000..e062f58
--- /dev/null
+++ b/Sources/Web3Modal/Screens/AccountView.swift
@@ -0,0 +1,198 @@
+import SwiftUI
+
+
+struct AccountView: View {
+ @EnvironmentObject var router: Router
+ @EnvironmentObject var blockchainApiInteractor: BlockchainAPIInteractor
+ @EnvironmentObject var signInteractor: SignInteractor
+ @EnvironmentObject var store: Store
+
+ var addressFormatted: String? {
+ guard let address = store.account?.address else {
+ return nil
+ }
+
+ return String(address.prefix(4)) + "..." + String(address.suffix(4))
+ }
+
+ var selectedChain: Chain {
+ return store.selectedChain ?? ChainPresets.ethChains.first!
+ }
+
+ var body: some View {
+ VStack(spacing: 0) {
+ VStack(spacing: 0) {
+ avatar()
+
+ Spacer()
+ .frame(height: Spacing.xl)
+
+ HStack {
+ (store.identity?.name ?? addressFormatted).map {
+ Text($0)
+ .font(.title600)
+ .foregroundColor(.Foreground100)
+ }
+
+ Button {
+ UIPasteboard.general.string = store.session?.accounts.first?.address
+ store.toast = .init(style: .success, message: "Address copied")
+ } label: {
+ Image.Medium.copy
+ .resizable()
+ .frame(width: 12, height: 12)
+ .foregroundColor(.Foreground250)
+ }
+ }
+
+ Spacer()
+ .frame(height: Spacing.xxxxs)
+
+ if store.balance != nil {
+ let balance = store.balance?.roundedDecimal(to: 4, mode: .down) ?? 0
+
+ Text(balance == 0 ? "0 \(selectedChain.token.symbol)" : "\(balance, specifier: "%.4f") \(selectedChain.token.symbol)")
+ .font(.paragraph500)
+ .foregroundColor(.Foreground200)
+ }
+
+ Spacer()
+ .frame(height: Spacing.s)
+
+ Button {
+ guard let chain = store.selectedChain else { return }
+
+ router.openURL(URL(string: chain.blockExplorerUrl)!)
+ } label: {
+ Text("Block Explorer")
+ }
+ .buttonStyle(W3MChipButtonStyle(
+ variant: .transparent,
+ size: .s,
+ leadingImage: {
+ Image.Medium.compass
+ .resizable()
+ },
+ trailingImage: {
+ Image.Bold.externalLink
+ .resizable()
+ }
+ ))
+
+ }
+
+ Spacer()
+ .frame(height: Spacing.xl)
+
+ Button {
+ router.setRoute(Router.NetworkSwitchSubpage.selectChain)
+ } label: {
+ Text(selectedChain.chainName)
+ }
+ .buttonStyle(W3MListSelectStyle(imageContent: { _ in
+ Image(
+ uiImage: store.chainImages[selectedChain.imageId] ?? UIImage()
+ )
+ .resizable()
+ .frame(width: 32, height: 32)
+ .clipShape(Circle())
+ }))
+
+ Spacer()
+ .frame(height: Spacing.xs)
+
+ Button {
+ disconnect()
+ } label: {
+ Text("Disconnect")
+ }
+ .buttonStyle(W3MListSelectStyle(imageContent: { _ in
+ Image.Medium.disconnect
+ .resizable()
+ .frame(width: 14, height: 14)
+ .padding(Spacing.xxxs)
+ .frame(width: 32, height: 32)
+ .background(Color.GrayGlass010)
+ .clipShape(Circle())
+ }))
+
+ Spacer()
+ .frame(height: Spacing.m)
+ }
+ .padding(.horizontal, Spacing.s)
+ .padding(.top, 40)
+ .padding(.bottom)
+ .onAppear {
+ Task {
+ do {
+ try await blockchainApiInteractor.getBalance()
+ } catch {
+ store.toast = .init(style: .error, message: "Network error")
+ Web3Modal.config.onError(error)
+ }
+ }
+
+ guard store.identity == nil else {
+ return
+ }
+
+ Task {
+ do {
+ try await blockchainApiInteractor.getIdentity()
+ } catch {
+ store.toast = .init(style: .error, message: "Network error")
+ Web3Modal.config.onError(error)
+ }
+ }
+ }
+ .frame(maxWidth: .infinity)
+ .background(Color.Background125)
+ .overlay(closeButton().padding().foregroundColor(.Foreground100), alignment: .topTrailing)
+ .cornerRadius(30, corners: [.topLeft, .topRight])
+ }
+
+ @ViewBuilder
+ func avatar() -> some View {
+ if let avatarUrlString = store.identity?.avatar, let url = URL(string: avatarUrlString) {
+ Backport.AsyncImage(url: url)
+ .frame(width: 64, height: 64)
+ .clipShape(Circle())
+ .overlay(Circle().stroke(.GrayGlass010, lineWidth: 8))
+ } else if let address = store.account?.address {
+ W3MAvatarGradient(address: address)
+ .frame(width: 64, height: 64)
+ .overlay(Circle().stroke(.GrayGlass010, lineWidth: 8))
+ }
+ }
+
+ func disconnect() {
+ Task {
+ do {
+ router.setRoute(Router.ConnectingSubpage.connectWallet)
+ try await signInteractor.disconnect()
+ } catch {
+ store.toast = .init(style: .error, message: "Network error")
+ }
+ }
+ }
+
+ private func closeButton() -> some View {
+ Button {
+ withAnimation {
+ store.isModalShown = false
+ }
+ } label: {
+ Image.Medium.xMark
+ }
+ }
+}
+
+extension Double {
+ func roundedDecimal(to scale: Int = 0, mode: NSDecimalNumber.RoundingMode = .plain) -> Double {
+ var decimalValue = Decimal(self)
+ var result = Decimal()
+ NSDecimalRound(&result, &decimalValue, scale, mode)
+ return Double(truncating: result as NSNumber)
+ }
+}
+
diff --git a/Sources/Web3Modal/Screens/ChainSwitch/ChainSelectView.swift b/Sources/Web3Modal/Screens/ChainSwitch/ChainSelectView.swift
new file mode 100644
index 0000000..04c4fcf
--- /dev/null
+++ b/Sources/Web3Modal/Screens/ChainSwitch/ChainSelectView.swift
@@ -0,0 +1,220 @@
+import SwiftUI
+
+struct ChainSelectView: View {
+ @EnvironmentObject var router: Router
+ @EnvironmentObject var store: Store
+
+ @ObservedObject var viewModel: Web3ModalViewModel
+
+ @Environment(\.analyticsService) var analyticsService: AnalyticsService
+
+ var body: some View {
+ VStack(spacing: 0) {
+ modalHeader()
+ routes()
+ }
+ .background(Color.Background125)
+ .cornerRadius(30, corners: [.topLeft, .topRight])
+ }
+
+ @ViewBuilder
+ private func routes() -> some View {
+ switch router.currentRoute as? Router.NetworkSwitchSubpage {
+ case .none:
+ EmptyView()
+ case .selectChain:
+ if #available(iOS 14.0, *) {
+ grid()
+ } else {
+ Text("Please upgrade to iOS 14 to use this feature")
+ }
+ case .whatIsANetwork:
+ WhatIsNetworkView()
+ case let .networkDetail(chain):
+ NetworkDetailView(viewModel: .init(chain: chain, router: router))
+ }
+ }
+
+ @available(iOS 14.0, *)
+ @ViewBuilder
+ private func grid() -> some View {
+ let numberOfColumns = calculateNumberOfColumns()
+ let columns = Array(repeating: GridItem(.flexible()), count: numberOfColumns)
+ let maxNumberOfRows = ceil(Double(ChainPresets.ethChains.count) / Double(numberOfColumns))
+ let numberOfRows = min(4, maxNumberOfRows)
+
+ VStack {
+ ScrollView {
+ LazyVGrid(columns: columns, spacing: Spacing.l) {
+ ForEach(ChainPresets.ethChains, id: \.self) { chain in
+ gridElement(for: chain)
+ }
+ }
+ }
+ .frame(height: numberOfRows * 96 + (numberOfRows - 1) * Spacing.l)
+ .padding(Spacing.s)
+
+ Divider()
+ .background(Color.GrayGlass005)
+
+ VStack(spacing: 0) {
+ Text("Your connected wallet may not support some of the networks available for this dApp")
+ .fixedSize(horizontal: false, vertical: true)
+ .font(.small400)
+ .foregroundColor(.Foreground300)
+ .multilineTextAlignment(.center)
+
+ Button {
+ router.setRoute(Router.NetworkSwitchSubpage.whatIsANetwork)
+ analyticsService.track(.CLICK_NETWORK_HELP)
+ } label: {
+ HStack(spacing: Spacing.xxs) {
+ Image.Bold.questionMarkCircle
+ .resizable()
+ .frame(width: 12, height: 12)
+
+ Text("What is a network")
+ }
+ .foregroundColor(.Blue100)
+ .font(.small600)
+ }
+ .padding(.vertical, Spacing.s)
+ .background(Color.clear)
+ .contentShape(Rectangle())
+ }
+ .padding(.horizontal)
+ .padding(.top, Spacing.xs)
+ .padding(.bottom, Spacing.xl)
+ }
+ }
+
+ private func gridElement(for chain: Chain) -> some View {
+ let isSelected = chain.id == store.selectedChain?.id
+ let currentChains = viewModel.getChains()
+ let currentMethods = viewModel.getMethods()
+ let needToSendSwitchRequest = currentMethods.contains("wallet_switchEthereumChain")
+ let isChainApproved = store.account != nil ? currentChains.contains(chain) : true
+
+ return Button(action: {
+ analyticsService.track(.SWITCH_NETWORK(network: chain))
+ if store.account == nil {
+ store.selectedChain = chain
+ router.setRoute(Router.ConnectingSubpage.connectWallet)
+ } else if isChainApproved, !needToSendSwitchRequest {
+ store.selectedChain = chain
+ router.setRoute(Router.AccountSubpage.profile)
+ } else {
+ router.setRoute(Router.NetworkSwitchSubpage.networkDetail(chain))
+ }
+ }, label: {
+ Text(chain.chainName)
+ })
+ .buttonStyle(W3MCardSelectStyle(
+ variant: .network,
+ imageContent: {
+ Image(
+ uiImage: store.chainImages[chain.imageId] ?? UIImage()
+ )
+ .resizable()
+ },
+ isSelected: isSelected
+ ))
+ .disabled({
+ if isSelected {
+ return true
+ }
+
+ if store.session == nil {
+ return false
+ }
+
+ if needToSendSwitchRequest {
+ return false
+ }
+
+ if !currentChains.contains(chain) {
+ return true
+ }
+
+ return false
+ }())
+ }
+
+ private func modalHeader() -> some View {
+ HStack(spacing: 0) {
+ switch router.currentRoute as? Router.NetworkSwitchSubpage {
+ case .none:
+ EmptyView()
+ case .selectChain:
+ if router.previousRoute as? Router.AccountSubpage == .profile {
+ backButton()
+ }
+ default:
+ backButton()
+ }
+
+ Spacer()
+
+ (router.currentRoute as? Router.NetworkSwitchSubpage)?.title.map { title in
+ Text(title)
+ .font(.paragraph700)
+ }
+
+ Spacer()
+
+ closeButton()
+ }
+ .padding()
+ .frame(height: 64)
+ .frame(maxWidth: .infinity)
+ .foregroundColor(.Foreground100)
+ .overlay(
+ RoundedCorner(radius: 30, corners: [.topLeft, .topRight])
+ .stroke(Color.GrayGlass005, lineWidth: 1)
+ )
+ .cornerRadius(30, corners: [.topLeft, .topRight])
+ }
+
+ private func backButton() -> some View {
+ Button {
+ router.goBack()
+ } label: {
+ Image.Medium.chevronLeft
+ }
+ }
+
+ private func closeButton() -> some View {
+ Button {
+ withAnimation {
+ store.isModalShown = false
+ }
+ } label: {
+ Image.Medium.xMark
+ }
+ }
+
+ private func calculateNumberOfColumns() -> Int {
+ let itemWidth: CGFloat = 76
+
+ let screenWidth = UIScreen.main.bounds.width
+ let count = floor(screenWidth / itemWidth)
+ let spaceLeft = screenWidth.truncatingRemainder(dividingBy: itemWidth)
+ let spacing = spaceLeft / (count - 1)
+ let updatedCount = spacing < 4 ? count - 1 : count
+
+ return Int(updatedCount)
+ }
+}
+
+extension Router.NetworkSwitchSubpage {
+ var title: String? {
+ switch self {
+ case .selectChain:
+ return "Select network"
+ case .whatIsANetwork:
+ return "What is a network?"
+ case let .networkDetail(chain):
+ return chain.chainName
+ }
+ }
+}
diff --git a/Sources/Web3Modal/Screens/ChainSwitch/NetworkDetail/NetworkDetailView.swift b/Sources/Web3Modal/Screens/ChainSwitch/NetworkDetail/NetworkDetailView.swift
new file mode 100644
index 0000000..af43a51
--- /dev/null
+++ b/Sources/Web3Modal/Screens/ChainSwitch/NetworkDetail/NetworkDetailView.swift
@@ -0,0 +1,84 @@
+import SwiftUI
+
+
+struct NetworkDetailView: View {
+ @EnvironmentObject var store: Store
+
+ @ObservedObject var viewModel: NetworkDetailViewModel
+
+
+ var body: some View {
+ VStack {
+ content()
+ .onAppear {
+ viewModel.handle(.onAppear)
+ }
+ }
+ }
+
+ @ViewBuilder
+ func content() -> some View {
+ VStack(spacing: 0) {
+ chainImage()
+ .padding(.top, 20)
+ .padding(.bottom, Spacing.l)
+ }
+ .padding(.horizontal)
+ .padding(.bottom, Spacing.xl * 2)
+ }
+
+ func chainImage() -> some View {
+ VStack(spacing: Spacing.xs) {
+ ZStack {
+ Image(
+ uiImage: store.chainImages[viewModel.chain.imageId] ?? UIImage()
+ )
+ .resizable()
+ .frame(width: 80, height: 80)
+ .clipShape(Polygon(count: 6, relativeCornerRadius: 0.25))
+ .cornerRadius(Radius.m)
+ .backport.overlay(alignment: .bottomTrailing) {
+ Image.Bold.xMark
+ .resizable()
+ .foregroundColor(.Error100)
+ .frame(width: 10, height: 10)
+ .padding(5)
+ .background(Color.Error100.opacity(0.15))
+ .clipShape(Circle())
+ .padding(2)
+ .background(Color.Background125)
+ .clipShape(Circle())
+ .opacity(viewModel.switchFailed ? 1 : 0)
+ .offset(x: 5, y: 5)
+ }
+
+ if !viewModel.switchFailed {
+ DrawingProgressView(shape: .hexagon, color: .Blue100, lineWidth: 3, isAnimating: .constant(true))
+ .frame(width: 90, height: 90)
+ }
+ }
+ .padding(.bottom, Spacing.s)
+
+ Text(!viewModel.switchFailed ? "Approve in wallet" : "Switch declined")
+ .font(.paragraph500)
+ .foregroundColor(.Foreground100)
+
+ Text(!viewModel.switchFailed ? "Accept connection request in your wallet" : "Switch can be declined if chain is not supported by a wallet or previous request is still active")
+ .font(.small500)
+ .foregroundColor(.Foreground200)
+ .multilineTextAlignment(.center)
+
+ if viewModel.switchFailed {
+ Button {
+ viewModel.handle(.didTapRetry)
+ } label: {
+ Text("Try again")
+ .font(.small600)
+ .foregroundColor(.Blue100)
+ }
+ .padding(Spacing.xl)
+ .buttonStyle(W3MButtonStyle(size: .m, variant: .accent, leftIcon: Image.Bold.refresh))
+ }
+ }
+ }
+}
diff --git a/Sources/Web3Modal/Screens/ChainSwitch/NetworkDetail/NetworkDetailViewModel.swift b/Sources/Web3Modal/Screens/ChainSwitch/NetworkDetail/NetworkDetailViewModel.swift
new file mode 100644
index 0000000..e52911d
--- /dev/null
+++ b/Sources/Web3Modal/Screens/ChainSwitch/NetworkDetail/NetworkDetailViewModel.swift
@@ -0,0 +1,243 @@
+import Combine
+import SwiftUI
+
+final class NetworkDetailViewModel: ObservableObject {
+ enum Event {
+ case onAppear
+ case didTapRetry
+ }
+
+ @Published var switchFailed: Bool = false
+ var triedAddingChain: Bool = false
+
+ private var disposeBag = Set()
+
+ var chain: Chain
+ let router: Router
+ let store: Store
+
+
+ init(
+ chain: Chain,
+ router: Router,
+ store: Store = .shared
+ ) {
+
+ self.chain = chain
+ self.router = router
+ self.store = store
+
+ Web3Modal.instance.sessionEventPublisher
+ .receive(on: DispatchQueue.main)
+ .sink { [unowned self] event, _, _ in
+ switch event.name {
+ case "chainChanged":
+ guard let chainReference = try? event.data.get(Int.self) else {
+ return
+ }
+
+ self.store.selectedChain = ChainPresets.ethChains.first(where: { $0.chainReference == String(chainReference) })
+ self.router.setRoute(Router.AccountSubpage.profile)
+
+ case "accountsChanged":
+
+ guard let account = try? event.data.get([String].self) else {
+ return
+ }
+
+ let chainReference = account[0].split(separator: ":")[1]
+
+ self.store.selectedChain = ChainPresets.ethChains.first(where: { $0.chainReference == String(chainReference) })
+ self.router.setRoute(Router.AccountSubpage.profile)
+ default:
+ break
+ }
+ }
+ .store(in: &disposeBag)
+
+ Web3Modal.instance.sessionResponsePublisher
+ .receive(on: DispatchQueue.main)
+ .sink { [unowned self] response in
+
+ switch response.result {
+ case .response:
+
+ print("Switch/Add chain success switching to: \(chain.chainName)")
+
+ self.store.selectedChain = chain
+ self.router.setRoute(Router.AccountSubpage.profile)
+ case let .error(error):
+
+ if error.message.contains("4001") {
+ // User declined
+ self.switchFailed = true
+ return
+ }
+
+ if !self.triedAddingChain {
+ guard let from = store.selectedChain else {
+ return
+ }
+
+ self.triedAddingChain = true
+ Task {
+ try? await self.addEthChain(from: from, to: chain)
+ }
+ } else {
+ self.switchFailed = true
+ }
+ }
+ }
+ .store(in: &disposeBag)
+ }
+
+ func handle(_ event: Event) {
+ switch event {
+ case .onAppear, .didTapRetry:
+ triedAddingChain = false
+ switchFailed = false
+
+ Task { @MainActor in
+ // Switch chain
+ await switchChain(chain)
+ }
+ }
+ }
+
+ @MainActor
+ func switchChain(_ to: Chain) async {
+ guard let from = store.selectedChain else { return }
+
+ do {
+ try await switchEthChain(from: from, to: to)
+ } catch {
+ Web3Modal.config.onError(error)
+ }
+
+ guard let session = store.session else { return }
+
+ if
+ let urlString = session.peer.redirect?.native ?? session.peer.redirect?.universal,
+ let url = URL(string: urlString)
+ {
+ DispatchQueue.main.async {
+ self.router.openURL(url)
+ }
+ }
+ }
+
+ @MainActor
+ private func switchEthChain(
+ from: Chain,
+ to: Chain
+ ) async throws {
+ guard let chainIdNumber = Int(to.chainReference) else { return }
+
+ switch store.connectedWith {
+ case .wc:
+
+ let chainHex = String(format: "%X", chainIdNumber)
+
+ guard let session = store.session else { return }
+
+ try await Web3Modal.instance.request(params:
+ .init(
+ topic: session.topic,
+ method: EthUtils.walletSwitchEthChain,
+ params: AnyCodable([AnyCodable(ChainSwitchParams(chainId: "0x\(chainHex)"))]),
+ chainId: .init(from.id)!
+ )
+ )
+ case .cb:
+ try await Web3Modal.instance.request(.wallet_switchEthereumChain(chainId: to.chainReference))
+ case .none:
+ break
+ }
+ }
+
+ @MainActor
+ private func addEthChain(
+ from: Chain,
+ to: Chain
+ ) async throws {
+
+ guard let addChainParams = createAddEthChainParams(chain: to) else {
+ return
+ }
+
+ switch store.connectedWith {
+ case .wc:
+
+ guard let session = store.session else { return }
+
+ try await Web3Modal.instance.request(params:
+ .init(
+ topic: session.topic,
+ method: EthUtils.walletAddEthChain,
+ params: AnyCodable([AnyCodable(addChainParams)]),
+ chainId: .init(from.id)!
+ )
+ )
+ case .cb:
+ try await Web3Modal.instance.request(
+ .wallet_addEthereumChain(
+ chainId: addChainParams.chainId,
+ blockExplorerUrls: addChainParams.blockExplorerUrls,
+ chainName: addChainParams.chainName,
+ iconUrls: addChainParams.iconUrls,
+ nativeCurrency: .init(
+ name: addChainParams.nativeCurrency.name,
+ symbol: addChainParams.nativeCurrency.symbol,
+ decimals: addChainParams.nativeCurrency.decimals
+ ),
+ rpcUrls: addChainParams.rpcUrls
+ ))
+ case .none:
+ break
+ }
+ }
+
+ func createAddEthChainParams(chain: Chain) -> ChainAddParams? {
+ guard let chainIdNumber = Int(chain.chainReference) else { return nil }
+
+ let chainHex = String(format: "%X", chainIdNumber)
+
+ return ChainAddParams(
+ chainId: "0x\(chainHex)",
+ blockExplorerUrls: [
+ chain.blockExplorerUrl
+ ],
+ chainName: chain.chainName,
+ nativeCurrency: .init(
+ name: chain.token.name,
+ symbol: chain.token.symbol,
+ decimals: chain.token.decimal
+ ),
+ rpcUrls: [
+ chain.rpcUrl
+ ],
+ iconUrls: [
+ chain.imageId
+ ]
+ )
+ }
+
+ struct ChainAddParams: Codable {
+ let chainId: String
+ let blockExplorerUrls: [String]
+ let chainName: String
+ let nativeCurrency: NativeCurrency
+ let rpcUrls: [String]
+ let iconUrls: [String]
+
+ struct NativeCurrency: Codable {
+ let name: String
+ let symbol: String
+ let decimals: Int
+ }
+ }
+
+ struct ChainSwitchParams: Codable {
+ let chainId: String
+ }
+}
diff --git a/Sources/Web3Modal/Screens/ChainSwitch/WhatIsNetworkView.swift b/Sources/Web3Modal/Screens/ChainSwitch/WhatIsNetworkView.swift
new file mode 100644
index 0000000..7107001
--- /dev/null
+++ b/Sources/Web3Modal/Screens/ChainSwitch/WhatIsNetworkView.swift
@@ -0,0 +1,78 @@
+import SwiftUI
+
+struct WhatIsNetworkView: View {
+ @Environment(\.verticalSizeClass) var verticalSizeClass
+
+ @EnvironmentObject var router: Router
+
+ var body: some View {
+ content()
+ .onAppear {
+ UIPageControl.appearance().currentPageIndicatorTintColor = UIColor.Foreground100
+ UIPageControl.appearance().pageIndicatorTintColor = UIColor.Foreground100.withAlphaComponent(0.2)
+ }
+ }
+
+ func content() -> some View {
+ VStack(spacing: 0) {
+ if verticalSizeClass == .compact {
+ TabView {
+ ForEach(sections(), id: \.title) { section in
+ section
+ .padding(.bottom, 40)
+ }
+ }
+ .transform {
+ #if os(iOS)
+ if #available(iOS 14.0, *) {
+ $0.tabViewStyle(.page(indexDisplayMode: .always))
+ }
+ #endif
+ }
+ .scaledToFill()
+ .layoutPriority(1)
+
+ } else {
+ ForEach(sections(), id: \.title) { section in
+ section
+ .padding(.bottom, Spacing.s)
+ }
+ }
+
+ Button(action: {
+ router.openURL(URL(string: "https://ethereum.org/en/developers/docs/networks/")!)
+ }) {
+ HStack {
+ Text("Learn More")
+ Image.Bold.externalLink
+ }
+ }
+ .buttonStyle(W3MButtonStyle(size: .s))
+ }
+ .padding(.vertical, Spacing.xxl)
+ .padding(.horizontal, Spacing.xl)
+ }
+
+ func sections() -> [HelpSection] {
+ [
+ HelpSection(
+ title: "The system’s nuts and bolts",
+ description: "A network is what brings the blockchain to life, as this technical infrastructure allows apps to access the ledger and smart contract services.",
+ assets: [.imageNetwork, .imageLayers, .imageSystem]
+ ),
+ HelpSection(
+ title: "Designed for different uses",
+ description: "Each network is designed differently, and may therefore suit certain apps and experiences.",
+ assets: [.imageNoun, .imageDefiAlt, .imageDao]
+ ),
+ ]
+ }
+}
+
+#if DEBUG
+struct WhatIsNetworkView_Previews: PreviewProvider {
+ static var previews: some View {
+ WhatIsNetworkView()
+ }
+}
+#endif
diff --git a/Sources/Web3Modal/Screens/ConnectWallet/AllWalletsView.swift b/Sources/Web3Modal/Screens/ConnectWallet/AllWalletsView.swift
new file mode 100644
index 0000000..3beea23
--- /dev/null
+++ b/Sources/Web3Modal/Screens/ConnectWallet/AllWalletsView.swift
@@ -0,0 +1,201 @@
+import Combine
+import SwiftUI
+import UIKit
+
+
+@available(iOS 14.0, *)
+struct AllWalletsView: View {
+ @EnvironmentObject var router: Router
+ @EnvironmentObject var store: Store
+ @EnvironmentObject var interactor: W3MAPIInteractor
+
+ @Environment(\.analyticsService) var analyticsService: AnalyticsService
+
+ @EnvironmentObject var signInteractor: SignInteractor
+
+ @State var searchTerm: String = ""
+ let searchTermPublisher = PassthroughSubject()
+
+ private let semaphore = AsyncSemaphore(count: 1)
+
+ var isSearching: Bool {
+ searchTerm.count >= 2
+ }
+
+ var body: some View {
+ content()
+ }
+
+ @ViewBuilder
+ private func content() -> some View {
+ VStack(spacing: 0) {
+ HStack {
+ W3MTextField("Search wallet", text: $searchTerm)
+ .ignoresSafeArea(.keyboard, edges: .bottom)
+
+ qrButton()
+ }
+ .padding(.horizontal)
+ .padding(.vertical, Spacing.xs)
+
+ if isSearching {
+ searchGrid()
+ } else {
+ regularGrid()
+ }
+ }
+ .onAppear {
+ fetchWallets()
+ }
+ .animation(.default, value: isSearching)
+ .frame(maxHeight: UIScreen.main.bounds.height - 240)
+ .backport.onChange(of: searchTerm) { searchTerm in
+ searchTermPublisher.send(searchTerm)
+ }
+ .onReceive(
+ searchTermPublisher
+ .debounce(for: .milliseconds(500), scheduler: DispatchQueue.main)
+ .filter { string in
+ string.count >= 2
+ }
+ .removeDuplicates()
+ ) { debouncedSearchTerm in
+ fetchWallets(search: debouncedSearchTerm)
+ }
+ .onReceive(
+ searchTermPublisher
+ .receive(on: DispatchQueue.main)
+ .removeDuplicates()
+ ) { searchTerm in
+ if searchTerm.count < 2 {
+ store.searchedWallets = []
+ }
+ }
+ }
+
+ @ViewBuilder
+ private func regularGrid() -> some View {
+ ScrollView {
+ LazyVGrid(
+ columns: Array(
+ repeating: GridItem(.flexible()),
+ count: calculateNumberOfColumns()
+ ),
+ spacing: Spacing.l
+ ) {
+ ForEach(store.wallets.sorted(by: { $0.order < $1.order }), id: \.self) { wallet in
+ gridElement(for: wallet)
+ }
+
+ if interactor.isLoading || store.currentPage < store.totalPages {
+ ForEach(1 ... calculateNumberOfColumns() * 4, id: \.self) { _ in
+ Button(action: {}, label: { Text("Loading") })
+ .buttonStyle(W3MCardSelectStyle(
+ variant: .wallet,
+ imageContent: {
+ Color.Overgray005.modifier(ShimmerBackground())
+ },
+ isLoading: .constant(true)
+ ))
+ }
+ .onAppear {
+ fetchWallets()
+ }
+ }
+ }
+ .padding(.horizontal, 12)
+ .padding(.bottom, 60)
+ }
+ }
+
+ @ViewBuilder
+ private func searchGrid() -> some View {
+ Group {
+ ZStack(alignment: .center) {
+ Spacer().frame(maxWidth: .infinity, maxHeight: .infinity)
+
+ ProgressView()
+ .opacity(interactor.isLoading ? 1 : 0)
+
+ let columns = Array(
+ repeating: GridItem(.flexible()),
+ count: calculateNumberOfColumns()
+ )
+
+ ScrollView {
+ LazyVGrid(columns: columns, spacing: Spacing.l) {
+ ForEach(store.searchedWallets, id: \.self) { wallet in
+ gridElement(for: wallet)
+ }
+ }
+ .padding(.horizontal)
+ .padding(.bottom, 30)
+ }
+ }
+ }
+ .animation(.default, value: interactor.isLoading)
+ }
+
+ private func gridElement(for wallet: Wallet) -> some View {
+ Button(action: {
+ Task {
+ do {
+ try await signInteractor.createPairingAndConnect()
+ analyticsService.track(.SELECT_WALLET(name: wallet.name, platform: .mobile))
+ router.setRoute(Router.ConnectingSubpage.walletDetail(wallet))
+ } catch {
+ store.toast = .init(style: .error, message: error.localizedDescription)
+ }
+ }
+ }, label: {
+ Text(wallet.name)
+ })
+ .buttonStyle(W3MCardSelectStyle(
+ variant: .wallet,
+ imageContent: {
+ if let storedImage = store.walletImages[wallet.id] {
+ Image(uiImage: storedImage)
+ .resizable()
+ } else {
+ Image.Regular.wallet
+ .resizable()
+ }
+ },
+ isLoading: .constant(false)
+ ))
+ .id(wallet.id)
+ }
+
+ private func fetchWallets(search: String = "") {
+ Task {
+ do {
+ try await semaphore.withTurn {
+ try await interactor.fetchWallets(search: search)
+ }
+ } catch {
+ store.toast = .init(style: .error, message: "Network error")
+ }
+ }
+ }
+
+ private func qrButton() -> some View {
+ Button {
+ router.setRoute(Router.ConnectingSubpage.qr)
+ analyticsService.track(.SELECT_WALLET(name: "Unknown", platform: .qrcode))
+ } label: {
+ Image.optionQrCode
+ }
+ }
+
+ private func calculateNumberOfColumns() -> Int {
+ let itemWidth: CGFloat = 76
+
+ let screenWidth = UIScreen.main.bounds.width
+ let count = floor(screenWidth / itemWidth)
+ let spaceLeft = screenWidth.truncatingRemainder(dividingBy: itemWidth)
+ let spacing = spaceLeft / (count - 1)
+ let updatedCount = spacing < 4 ? count - 1 : count
+
+ return Int(updatedCount)
+ }
+}
diff --git a/Sources/Web3Modal/Screens/ConnectWallet/ConnectWalletView.swift b/Sources/Web3Modal/Screens/ConnectWallet/ConnectWalletView.swift
new file mode 100644
index 0000000..599f600
--- /dev/null
+++ b/Sources/Web3Modal/Screens/ConnectWallet/ConnectWalletView.swift
@@ -0,0 +1,130 @@
+import SwiftUI
+
+struct ConnectWalletView: View {
+ @EnvironmentObject var store: Store
+ @EnvironmentObject var router: Router
+
+ @Environment(\.analyticsService) var analyticsService: AnalyticsService
+
+ @EnvironmentObject var signInteractor: SignInteractor
+
+ let displayWCConnection = false
+
+ var wallets: [Wallet] {
+ var recentWallets = store.recentWallets
+
+ let result = (store.featuredWallets + store.customWallets).map { featuredWallet in
+ var featuredWallet = featuredWallet
+ let (index, matchingRecentWallet) = recentWallets.enumerated().first { (index, recentWallet) in
+ featuredWallet.id == recentWallet.id
+ } ?? (nil, nil)
+
+
+ if let match = matchingRecentWallet, let matchingIndex = index {
+ featuredWallet.lastTimeUsed = match.lastTimeUsed
+ recentWallets.remove(at: matchingIndex)
+ }
+
+ return featuredWallet
+ }
+
+ return (recentWallets + result)
+ }
+
+ var body: some View {
+ VStack {
+ wcConnection()
+
+ featuredWallets()
+
+ Button(action: {
+ router.setRoute(Router.ConnectingSubpage.allWallets)
+ analyticsService.track(.CLICK_ALL_WALLETS)
+ }, label: {
+ Text("All wallets")
+ })
+ .buttonStyle(W3MListSelectStyle(
+ imageContent: { _ in
+ Image.optionAll
+ },
+ tag: store.totalNumberOfWallets != 0 ? W3MTag(title: "\(store.totalNumberOfWallets)+", variant: .info) : nil
+ ))
+ }
+ .padding(Spacing.s)
+ .padding(.bottom)
+ }
+
+ @ViewBuilder
+ private func featuredWallets() -> some View {
+ ForEach(wallets, id: \.self) { wallet in
+ Group {
+ let isRecent: Bool = wallet.lastTimeUsed != nil
+ let tagTitle: String? = isRecent ? "RECENT" : nil
+
+ Button(action: {
+ Task {
+ do {
+ try await signInteractor.createPairingAndConnect()
+ router.setRoute(Router.ConnectingSubpage.walletDetail(wallet))
+ analyticsService.track(.SELECT_WALLET(name: wallet.name, platform: .mobile))
+ } catch {
+ store.toast = .init(style: .error, message: error.localizedDescription)
+ }
+ }
+ }, label: {
+ Text(wallet.name)
+ })
+ .buttonStyle(W3MListSelectStyle(
+ imageContent: { _ in
+ Group {
+ if let storedImage = store.walletImages[wallet.id] {
+ Image(uiImage: storedImage)
+ .resizable()
+ } else {
+ Image.Regular.wallet
+ .resizable()
+ .padding(Spacing.xxs)
+ }
+ }
+ .background(Color.Overgray005)
+ .backport.overlay {
+ RoundedRectangle(cornerRadius: Radius.xxxs)
+ .stroke(.Overgray010, lineWidth: 1)
+ }
+ },
+ tag: tagTitle != nil ? .init(title: tagTitle!, variant: .info) : nil
+ ))
+ }
+ }
+ }
+
+ @ViewBuilder
+ private func wcConnection() -> some View {
+ if displayWCConnection {
+ Button(action: {
+ router.setRoute(Router.ConnectingSubpage.qr)
+ }, label: {
+ Text("WalletConnect")
+ })
+ .buttonStyle(W3MListSelectStyle(
+ imageContent: { _ in
+ ZStack {
+ Color.Blue100
+
+ Image.imageLogo
+ .resizable()
+ .aspectRatio(contentMode: .fit)
+ .foregroundColor(.white)
+ }
+ },
+ tag: W3MTag(title: "QR CODE", variant: .main)
+ ))
+ }
+ }
+}
+
+struct ConnectWalletView_Previews: PreviewProvider {
+ static var previews: some View {
+ ConnectWalletView()
+ }
+}
diff --git a/Sources/Web3Modal/Screens/ConnectWallet/ConnectWithQRCode.swift b/Sources/Web3Modal/Screens/ConnectWallet/ConnectWithQRCode.swift
new file mode 100644
index 0000000..44f6c74
--- /dev/null
+++ b/Sources/Web3Modal/Screens/ConnectWallet/ConnectWithQRCode.swift
@@ -0,0 +1,89 @@
+import SwiftUI
+
+
+struct ConnectWithQRCode: View {
+
+ @EnvironmentObject var store: Store
+ @EnvironmentObject var signInteractor: SignInteractor
+
+ var body: some View {
+
+ VStack(spacing: Spacing.xl) {
+ if let uri = store.uri?.absoluteString {
+
+ QRCodeView(uri: uri)
+ } else {
+ RoundedRectangle(cornerRadius: Radius.l)
+ .fill(.Overgray015)
+ .aspectRatio(1, contentMode: .fit)
+ .modifier(ShimmerBackground())
+ }
+
+ Text("Scan this QR code with your phone")
+ .font(.paragraph500)
+ .foregroundColor(.Foreground100)
+
+ Button(action: {
+ UIPasteboard.general.string = store.uri?.absoluteString ?? ""
+ store.toast = .init(style: .success, message: "Link copied")
+ }, label: {
+ Text("Copy Link")
+ })
+ .buttonStyle(W3MActionEntryStyle(leftIcon: .Bold.copy))
+ .disabled(store.uri == nil)
+ }
+ .padding([.top, .horizontal], Spacing.xl)
+ .padding(.bottom, Spacing.l)
+ .padding(.bottom)
+ .background(Color.Background125)
+ .onAppear {
+ connect()
+ }
+ }
+
+ private func connect() {
+ Task {
+ do {
+ try await signInteractor.createPairingAndConnect()
+ } catch {
+ store.toast = .init(style: .error, message: "Failed to create connection URI.")
+ }
+ }
+ }
+}
+
+struct ConnectWithQRCode_Previews: PreviewProvider {
+ static let stubUri: String = Array(repeating: ["a", "b", "c", "1", "2", "3"], count: 30)
+ .flatMap { $0 }
+ .shuffled()
+ .joined()
+
+ static let store: Store = {
+
+ let store = Store()
+ store.uri = WalletConnectURI(
+ string: "wc:de631d0009368177ec5b7dd26b5614536f6117c83236c15452f01f0f1c877529@2?symKey=61ee028ff757f897597cc367a4c2f359b34ec615764cae4dea6f41cdff53bf66&relay-protocol=irn"
+ )
+
+ return store
+ }()
+
+ static var previews: some View {
+ VStack {
+ ConnectWithQRCode()
+ .environmentObject(store)
+ .environmentObject(MockSignInteractor(store: store))
+
+ ConnectWithQRCode()
+ .environmentObject(Store())
+ .environmentObject(MockSignInteractor(store: Store()))
+ }
+ }
+
+ class MockSignInteractor: SignInteractor {
+
+ override func createPairingAndConnect() async throws {
+ // no-op
+ }
+ }
+}
diff --git a/Sources/Web3Modal/Screens/ConnectWallet/GetAWalletView.swift b/Sources/Web3Modal/Screens/ConnectWallet/GetAWalletView.swift
new file mode 100644
index 0000000..085a072
--- /dev/null
+++ b/Sources/Web3Modal/Screens/ConnectWallet/GetAWalletView.swift
@@ -0,0 +1,87 @@
+import SwiftUI
+
+
+struct GetAWalletView: View {
+ @EnvironmentObject var router: Router
+ @EnvironmentObject var store: Store
+
+ var body: some View {
+ VStack {
+ ForEach(store.featuredWallets.prefix(4), id: \.self) { wallet in
+ Button(action: {
+ if let appstoreLink = wallet.appStore {
+ router.openURL(URL(string: appstoreLink)!)
+ }
+ }, label: {
+ Text(wallet.name)
+ })
+ .buttonStyle(W3MListSelectStyle(
+ imageContent: { _ in
+ Group {
+ if let storedImage = store.walletImages[wallet.id] {
+ Image(uiImage: storedImage)
+ .resizable()
+ } else {
+ Image.Regular.wallet
+ .resizable()
+ .padding(Spacing.xxs)
+ }
+ }
+ .background(
+ RoundedRectangle(cornerRadius: Radius.xxxs)
+ .fill(.Overgray005)
+ )
+ .backport.overlay {
+ RoundedRectangle(cornerRadius: Radius.xxxs)
+ .stroke(.Overgray010, lineWidth: 1)
+ }
+ }
+ ))
+ }
+
+ Button(action: {
+ router.openURL(URL(string: "https://walletconnect.com/explorer?type=wallet")!)
+ }, label: {
+ Text("Explore all")
+ })
+ .buttonStyle(W3MListSelectStyle(
+ imageContent: { _ in
+ Image.optionAll
+ }
+ ))
+ .backport.overlay(alignment: .trailing) {
+ Image.Bold.externalLink
+ .resizable()
+ .frame(width: 14, height: 14)
+ .foregroundColor(.Foreground200)
+ .padding(.trailing, Spacing.l)
+ }
+ }
+ .padding(Spacing.s)
+ .padding(.bottom)
+ }
+}
+
+#if DEBUG
+
+struct GetAWalletView_Previews: PreviewProvider {
+ static let store = {
+ let store = Store()
+ store.featuredWallets = Wallet.stubList
+
+ for id in Wallet.stubList.map(\.imageId).compactMap({ $0 }).prefix(2) {
+ store.walletImages[id] = UIImage(
+ named: "MockWalletImage", in: .coreModule, compatibleWith: nil
+ )
+ }
+
+ return store
+ }()
+
+ static var previews: some View {
+ GetAWalletView()
+ .environmentObject(GetAWalletView_Previews.store)
+ }
+}
+
+#endif
diff --git a/Sources/Web3Modal/Screens/ConnectWallet/QRCodeView.swift b/Sources/Web3Modal/Screens/ConnectWallet/QRCodeView.swift
new file mode 100644
index 0000000..169792f
--- /dev/null
+++ b/Sources/Web3Modal/Screens/ConnectWallet/QRCodeView.swift
@@ -0,0 +1,187 @@
+import QRCode
+import SwiftUI
+
+struct QRCodeView: View {
+ let uri: String
+ var imageData: Data? = nil
+
+ @Environment(\.colorScheme) var colorScheme
+
+ var body: some View {
+ let size: CGSize = .init(
+ width: UIScreen.main.bounds.width - Spacing.xl * 2,
+ height: UIScreen.main.bounds.height * 0.4
+ )
+
+ VStack(alignment: .center) {
+ render(
+ content: uri,
+ size: .init(width: size.width, height: size.width)
+ )
+ .id(colorScheme)
+ .colorScheme(.light)
+ .cornerRadius(Radius.l)
+ }
+ }
+
+ @MainActor private func render(content: String, size: CGSize) -> Image {
+ let doc = QRCode.Document(
+ utf8String: content,
+ errorCorrection: .quantize
+ )
+ doc.design.shape.eye = QRCode.EyeShape.Squircle2()
+ doc.design.shape.onPixels = QRCode.PixelShape.Vertical(
+ insetFraction: 0.15,
+ cornerRadiusFraction: 1
+ )
+
+ doc.design.additionalQuietZonePixels = 2
+
+ doc.design.style.eye = QRCode.FillStyle.Solid(UIColor.Foreground100.cgColor)
+ doc.design.style.pupil = QRCode.FillStyle.Solid(UIColor.Foreground100.cgColor)
+ doc.design.style.onPixels = QRCode.FillStyle.Solid(UIColor.Foreground100.cgColor)
+ doc.design.style.background = QRCode.FillStyle.Solid(UIColor.Background125.cgColor)
+
+ let uiImage = imageData != nil ?
+ UIImage(data: imageData!) :
+ UIImage(named: "imageLogo", in: .coreModule, compatibleWith: nil)?.withColor(UIColor.Blue100)
+
+ if let uiImage = uiImage {
+ let cgImage = uiImage.cgImage!
+
+ let logoSize = 0.25
+ let pathWidth = logoSize * (uiImage.size.width / uiImage.size.height)
+ let pathHeight = logoSize
+
+ doc.logoTemplate = QRCode.LogoTemplate(
+ image: cgImage,
+ path: CGPath(
+ rect: CGRect(x: (1 - pathWidth) / 2, y: (1 - pathHeight) / 2, width: pathWidth, height: pathHeight),
+ transform: nil
+ ),
+ inset: 20
+ )
+ }
+ return doc.imageUI(
+ size.applying(.init(scaleX: 3, y: 3)),
+ dpi: 72 * 3,
+ label: Text("QR code with URI")
+ )!
+ }
+}
+
+private extension UIImage {
+ func withColor(_ color: UIColor) -> UIImage? {
+ UIGraphicsBeginImageContextWithOptions(size, false, scale)
+ let drawRect = CGRect(x: 0, y: 0, width: size.width, height: size.height)
+ color.setFill()
+ UIRectFill(drawRect)
+ draw(in: drawRect, blendMode: .destinationIn, alpha: 1)
+ let tintedImage = UIGraphicsGetImageFromCurrentImageContext()
+ UIGraphicsEndImageContext()
+ return tintedImage!
+ }
+}
+
+#if DEBUG
+public struct QRCodeViewPreviewView: View {
+ public init() {}
+
+ static let stubUri: String = Array(repeating: ["a", "b", "c", "1", "2", "3"], count: 10)
+ .flatMap { $0 }
+ .joined()
+
+ public var body: some View {
+ VStack {
+ QRCodeView(
+ uri: QRCodeViewPreviewView.stubUri,
+ imageData: UIImage(named: "MockWalletImage", in: .coreModule, compatibleWith: nil)?.pngData()
+ )
+ .previewLayout(.sizeThatFits)
+
+ QRCodeView(uri: QRCodeViewPreviewView.stubUri)
+ }
+ }
+}
+
+struct QRCodeView_Previews: PreviewProvider {
+ static var previews: some View {
+ QRCodeViewPreviewView()
+ .previewLayout(.sizeThatFits)
+ }
+}
+#endif
+
+extension QRCode.EyeShape {
+ /// A 'squircle' eye style
+ @objc(QRCodeEyeShapeSquircle2) class Squircle2: NSObject, QRCodeEyeShapeGenerator {
+ @objc public static let Name = "squircle"
+ @objc public static var Title: String { "Squircle2" }
+ @objc public static func Create(_ settings: [String: Any]?) -> QRCodeEyeShapeGenerator {
+ return QRCode.EyeShape.Squircle2()
+ }
+
+ @objc public func settings() -> [String: Any] { return [:] }
+ @objc public func supportsSettingValue(forKey key: String) -> Bool { false }
+ @objc public func setSettingValue(_ value: Any?, forKey key: String) -> Bool { false }
+
+ /// Make a copy of the object
+ @objc public func copyShape() -> QRCodeEyeShapeGenerator {
+ return Self.Create(settings())
+ }
+
+ public func eyePath() -> CGPath {
+
+ let strokeWidth: CGFloat = 10
+ let size: CGFloat = 65
+ let cornerRadius: CGFloat = min(25, size/2)
+ let offset: CGFloat = (90 - size) / 2
+
+ let path = CGMutablePath()
+ path.addRoundedRect(in: CGRect(x: offset, y: offset, width: size, height: size), cornerWidth: cornerRadius, cornerHeight: cornerRadius)
+
+ return path.copy(strokingWithWidth: strokeWidth, lineCap: .round, lineJoin: .round, miterLimit: 1)
+ }
+
+ @objc public func eyeBackgroundPath() -> CGPath {
+ CGPath(rect: CGRect(origin: .zero, size: CGSize(width: 90, height: 90)), transform: nil)
+ }
+
+ private static let _defaultPupil = QRCode.PupilShape.Squircle2()
+ public func defaultPupil() -> QRCodePupilShapeGenerator { Self._defaultPupil }
+ }
+}
+
+
+extension QRCode.PupilShape {
+ /// A 'squircle' pupil style
+ @objc(QRCodePupilShapeSquircle2) class Squircle2: NSObject, QRCodePupilShapeGenerator {
+ @objc public static var Name: String { "squircle2" }
+ /// The generator title
+ @objc public static var Title: String { "Squircle2" }
+
+ @objc public static func Create(_ settings: [String : Any]?) -> QRCodePupilShapeGenerator {
+ Squircle2()
+ }
+
+ /// Make a copy of the object
+ @objc public func copyShape() -> QRCodePupilShapeGenerator { Squircle2() }
+
+ @objc public func settings() -> [String : Any] { [:] }
+ @objc public func supportsSettingValue(forKey key: String) -> Bool { false }
+ @objc public func setSettingValue(_ value: Any?, forKey key: String) -> Bool { false }
+
+ /// The pupil centered in the 90x90 square
+ @objc public func pupilPath() -> CGPath {
+
+ let size: CGFloat = 35
+ let cornerRadius: CGFloat = min(12, size/2)
+ let offset: CGFloat = (90 - size) / 2
+
+ let path = CGMutablePath()
+ path.addRoundedRect(in: CGRect(x: offset, y: offset, width: size, height: size), cornerWidth: cornerRadius, cornerHeight: cornerRadius)
+
+ return path
+ }
+ }
+}
diff --git a/Sources/Web3Modal/Screens/ConnectWallet/WalletDetail/WalletDetailView.swift b/Sources/Web3Modal/Screens/ConnectWallet/WalletDetail/WalletDetailView.swift
new file mode 100644
index 0000000..8372ddb
--- /dev/null
+++ b/Sources/Web3Modal/Screens/ConnectWallet/WalletDetail/WalletDetailView.swift
@@ -0,0 +1,309 @@
+import SwiftUI
+
+struct WalletDetailView: View {
+ @Environment(\.verticalSizeClass) var verticalSizeClass
+
+ @EnvironmentObject var store: Store
+
+ @ObservedObject var viewModel: WalletDetailViewModel
+
+ var body: some View {
+ content()
+ .onAppear {
+ DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
+ viewModel.handle(.onAppear)
+ }
+ }
+ }
+
+ @ViewBuilder
+ func content() -> some View {
+ VStack(spacing: 0) {
+ if viewModel.showToggle {
+ picker()
+ }
+
+ walletInfo()
+
+ if viewModel.wallet.isInstalled == true {
+ copyLink()
+ }
+
+ if
+ viewModel.preferredPlatform == .mobile,
+ viewModel.wallet.isInstalled != true,
+ viewModel.wallet.appStore != nil
+ {
+ appStoreRow()
+ }
+ }
+ .padding(.horizontal, Spacing.s)
+ .padding(.bottom, Spacing.xl + 17)
+ }
+
+ private func picker() -> some View {
+ W3MPicker(
+ WalletDetailViewModel.Platform.allCases,
+ selection: viewModel.preferredPlatform
+ ) { item in
+
+ HStack {
+ switch item {
+ case .mobile:
+ Image.Bold.mobile
+ case .browser:
+ Image.Bold.browser
+ }
+
+ Text(item.rawValue.capitalized)
+ }
+ .font(.small500)
+ .multilineTextAlignment(.center)
+ .foregroundColor(viewModel.preferredPlatform == item ? .Foreground100 : .Foreground200)
+ .frame(maxWidth: .infinity)
+ .contentShape(Rectangle())
+ .onTapGesture {
+ withAnimation(.easeInOut(duration: 0.15)) {
+ viewModel.preferredPlatform = item
+ }
+ }
+ }
+ .frame(maxWidth: 200)
+ .padding(.top, Spacing.l)
+ }
+
+ private func copyLink() -> some View {
+ Button {
+ viewModel.handle(.didTapCopy)
+ } label: {
+ HStack(spacing: Spacing.xxxs) {
+ Image.Bold.copy
+ .resizable()
+ .frame(width: 12, height: 12)
+ Text("Copy link")
+ }
+ .font(.small600)
+ .foregroundColor(.Foreground200)
+ .padding(Spacing.xs)
+ }
+ .padding(.bottom, Spacing.xl)
+ }
+
+ private func walletImage() -> some View {
+ return ZStack {
+ Image(
+ uiImage: store.walletImages[viewModel.wallet.id] ?? UIImage()
+ )
+ .resizable()
+ .frame(width: 80, height: 80)
+ .cornerRadius(Radius.m)
+ .backport.overlay(alignment: .bottomTrailing) {
+ Image.Bold.xMark
+ .resizable()
+ .foregroundColor(.Error100)
+ .frame(width: 10, height: 10)
+ .padding(5)
+ .background(Color.Error100.opacity(0.15))
+ .clipShape(Circle())
+ .padding(2)
+ .background(Color.Background125)
+ .clipShape(Circle())
+ .opacity(store.retryShown ? 1 : 0)
+ .offset(x: 5, y: 5)
+ }
+
+ if !store.retryShown {
+ DrawingProgressView(
+ shape: .roundedRectangleRelative(relativeCornerRadius: Radius.m / 80),
+ color: .Blue100,
+ lineWidth: 3,
+ isAnimating: .constant(true)
+ )
+ .frame(width: 90, height: 90)
+ }
+ }
+ }
+
+ private func retryButton() -> some View {
+ return Button {
+ viewModel.handle(.didTapOpen)
+ } label: {
+ HStack {
+ Text(!store.retryShown ? "Open" : "Try again")
+ }
+ .font(.small600)
+ .foregroundColor(.Blue100)
+ }
+ .buttonStyle(
+ W3MButtonStyle(
+ size: .m,
+ variant: .accent,
+ leftIcon: store.retryShown ? Image.Bold.refresh : nil,
+ rightIcon: store.retryShown ? nil : Image.Bold.externalLink
+ )
+ )
+ }
+
+ private func walletInfo() -> some View {
+ VStack(spacing: 0) {
+ walletImage()
+ .padding(.top, 40)
+ .padding(.bottom, Spacing.xl)
+
+ Text(store.retryShown ? "Connection declined" : "Continue in \(viewModel.wallet.name)")
+ .font(.paragraph600)
+ .foregroundColor(store.retryShown ? .Error100 : .Foreground100)
+ .padding(.bottom, Spacing.xs)
+
+ Text(
+ store.retryShown
+ ? "Connection can be declined if a previous request is still active"
+ : viewModel.preferredPlatform == .browser ? "Open and continue in a new browser tab" : "Accept connection request in the wallet"
+ )
+ .font(.small500)
+ .foregroundColor(.Foreground200)
+ .multilineTextAlignment(.center)
+ .padding(.bottom, Spacing.l)
+
+ if store.retryShown || viewModel.preferredPlatform == .browser {
+ retryButton()
+ }
+ }
+ }
+
+ func appStoreRow() -> some View {
+ HStack(spacing: 0) {
+ Text("Don't have \(viewModel.wallet.name)?")
+ .font(.paragraph500)
+ .foregroundColor(.Foreground200)
+
+ Spacer()
+
+ Button {
+ viewModel.handle(.didTapAppStore)
+ } label: {
+ Text("Get")
+ }
+ .buttonStyle(GetWalletButtonStyle())
+ }
+ .padding()
+ .frame(height: 56)
+ .background(Color.GrayGlass002)
+ .cornerRadius(Radius.xs)
+ }
+
+ struct GetWalletButtonStyle: ButtonStyle {
+ func makeBody(configuration: Configuration) -> some View {
+ HStack(spacing: Spacing.xxxs) {
+ configuration.label
+ Image.Bold.chevronRight
+ .resizable()
+ .frame(width: 12, height: 12)
+ }
+ .font(.small600)
+ .foregroundColor(.Blue100)
+ .padding([.vertical, .trailing], Spacing.xs)
+ .padding(.leading, Spacing.s)
+ .background(configuration.isPressed ? Color.GrayGlass010 : Color.clear)
+ .backport.overlay {
+ Capsule()
+ .stroke(.GrayGlass010, lineWidth: 1)
+ }
+ .clipShape(Capsule())
+ }
+ }
+}
+
+#if DEBUG
+
+class MockSignInteractor: SignInteractor {
+ override func createPairingAndConnect() async throws {
+ // no-op
+ }
+
+ override func disconnect() async throws {
+ // no-op
+ }
+}
+
+class MockWalletDetailViewModel: WalletDetailViewModel {
+ convenience init(retryShown: Bool, isInstalled: Bool, store: Store) {
+ var wallet = Wallet.stubList.first!
+ wallet.isInstalled = isInstalled
+
+ self.init(
+ wallet: wallet,
+ router: Router(),
+ signInteractor: MockSignInteractor(store: store),
+ store: store
+ )
+
+// self.retryShown = retryShown
+ }
+
+ override func startObserving() {
+ // no-op
+ }
+
+ override func handle(_ event: Event) {
+ // no-op
+ }
+}
+
+struct WalletDetailView_Preview: PreviewProvider {
+ static let store = {
+ let store = Store()
+ store.walletImages["0528ee7e-16d1-4089-21e3-bbfb41933100"] = UIImage(
+ named: "MockWalletImage", in: .coreModule, compatibleWith: nil
+ )
+
+ return store
+ }()
+
+ static var previews: some View {
+ ScrollView {
+ WalletDetailView(
+ viewModel: MockWalletDetailViewModel(
+ retryShown: false,
+ isInstalled: false,
+ store: WalletDetailView_Preview.store
+ )
+ )
+
+ Divider()
+
+ WalletDetailView(
+ viewModel: MockWalletDetailViewModel(
+ retryShown: true,
+ isInstalled: false,
+ store: WalletDetailView_Preview.store
+ )
+ )
+
+ Divider()
+
+ WalletDetailView(
+ viewModel: MockWalletDetailViewModel(
+ retryShown: true,
+ isInstalled: true,
+ store: WalletDetailView_Preview.store
+ )
+ )
+
+ Divider()
+
+ WalletDetailView(
+ viewModel: MockWalletDetailViewModel(
+ retryShown: false,
+ isInstalled: true,
+ store: WalletDetailView_Preview.store
+ )
+ )
+
+ Divider()
+ }
+ .environmentObject(WalletDetailView_Preview.store)
+ }
+}
+
+#endif
diff --git a/Sources/Web3Modal/Screens/ConnectWallet/WalletDetail/WalletDetailViewModel.swift b/Sources/Web3Modal/Screens/ConnectWallet/WalletDetail/WalletDetailViewModel.swift
new file mode 100644
index 0000000..6d30424
--- /dev/null
+++ b/Sources/Web3Modal/Screens/ConnectWallet/WalletDetail/WalletDetailViewModel.swift
@@ -0,0 +1,189 @@
+import SwiftUI
+import Combine
+
+class WalletDetailViewModel: ObservableObject {
+ enum Platform: String, CaseIterable, Identifiable {
+ case mobile
+ case browser
+
+ var id: Self { self }
+ }
+
+ enum Event {
+ case onAppear
+ case didTapOpen
+ case didTapAppStore
+ case didTapCopy
+ }
+
+ let wallet: Wallet
+ let router: Router
+ let store: Store
+ let signInteractor: SignInteractor
+
+ @Published var preferredPlatform: Platform = .mobile
+
+ private var disposeBag = Set()
+
+ var showToggle: Bool {
+ hasWebAppLink && hasMobileLink && wallet.isInstalled != true
+ }
+
+ var hasWebAppLink: Bool { wallet.webappLink?.isEmpty == false }
+ var hasMobileLink: Bool { wallet.mobileLink?.isEmpty == false }
+
+ init(
+ wallet: Wallet,
+ router: Router,
+ signInteractor: SignInteractor,
+ store: Store = .shared
+ ) {
+ self.wallet = wallet
+ self.router = router
+ self.store = store
+ self.signInteractor = signInteractor
+ preferredPlatform = wallet.mobileLink != nil ? .mobile : .browser
+
+ startObserving()
+ }
+
+ func startObserving() {
+ Web3Modal.instance.sessionRejectionPublisher
+ .receive(on: DispatchQueue.main)
+ .sink { [weak self] _, _ in
+ self?.store.retryShown = true
+ }
+ .store(in: &disposeBag)
+ }
+
+ func handle(_ event: Event) {
+ switch event {
+ case .didTapCopy:
+ UIPasteboard.general.string = store.uri?.absoluteString ?? ""
+ store.toast = .init(style: .success, message: "Link copied")
+ case .onAppear:
+
+ if wallet.alternativeConnectionMethod == nil {
+
+ navigateToDeepLink(
+ wallet: wallet,
+ preferBrowser: preferredPlatform == .browser
+ )
+ } else {
+ wallet.alternativeConnectionMethod?()
+ }
+
+ var wallet = wallet
+ wallet.lastTimeUsed = Date()
+
+ store.recentWallets.append(wallet)
+ case .didTapOpen:
+ store.retryShown = false
+
+ if wallet.alternativeConnectionMethod == nil {
+ navigateToDeepLink(
+ wallet: wallet,
+ preferBrowser: preferredPlatform == .browser
+ )
+ } else {
+ wallet.alternativeConnectionMethod?()
+ }
+
+ case .didTapAppStore:
+ openAppstore(wallet: wallet)
+ }
+ }
+
+ private func openAppstore(wallet: Wallet) {
+ guard
+ let storeLinkString = wallet.appStore,
+ let storeLink = URL(string: storeLinkString)
+ else { return }
+
+ router.openURL(storeLink)
+ }
+
+ private func navigateToDeepLink(wallet: Wallet, preferBrowser: Bool) {
+ do {
+ let link = preferBrowser ? wallet.webappLink : wallet.mobileLink
+
+ let urlString = try formatNativeUrlString(link)
+ if let url = urlString?.toURL() {
+ router.openURL(url) { success in
+ self.store.toast = .init(style: .error, message: DeeplinkErrors.failedToOpen.localizedDescription)
+ }
+ } else {
+ throw DeeplinkErrors.noWalletLinkFound
+ }
+ } catch {
+ store.toast = .init(style: .error, message: error.localizedDescription)
+ Web3Modal.config.onError(error)
+ }
+ }
+
+ enum DeeplinkErrors: LocalizedError {
+ case noWalletLinkFound
+ case uriNotCreated
+ case failedToOpen
+
+ var errorDescription: String? {
+ switch self {
+ case .noWalletLinkFound:
+ return NSLocalizedString("No valid link for opening given wallet found", comment: "")
+ case .uriNotCreated:
+ return NSLocalizedString("Couldn't generate link due to missing connection URI", comment: "")
+ case .failedToOpen:
+ return NSLocalizedString("Given link couldn't be opened", comment: "")
+ }
+ }
+ }
+
+ private func isHttpUrl(url: String) -> Bool {
+ return url.hasPrefix("http://") || url.hasPrefix("https://")
+ }
+
+ private func formatNativeUrlString(_ string: String?) throws -> String? {
+ guard let string = string, !string.isEmpty else { return nil }
+
+ if isHttpUrl(url: string) {
+ return try formatUniversalUrlString(string)
+ }
+
+ var safeAppUrl = string
+ if !safeAppUrl.contains("://") {
+ safeAppUrl = safeAppUrl.replacingOccurrences(of: "/", with: "").replacingOccurrences(of: ":", with: "")
+ safeAppUrl = "\(safeAppUrl)://"
+ }
+
+ guard let deeplinkUri = store.uri?.deeplinkUri else {
+ throw DeeplinkErrors.uriNotCreated
+ }
+
+ return "\(safeAppUrl)wc?uri=\(deeplinkUri)"
+ }
+
+ private func formatUniversalUrlString(_ string: String?) throws -> String? {
+ guard let string = string, !string.isEmpty else { return nil }
+
+ if !isHttpUrl(url: string) {
+ return try formatNativeUrlString(string)
+ }
+
+ var plainAppUrl = string
+ if plainAppUrl.hasSuffix("/") {
+ plainAppUrl = String(plainAppUrl.dropLast())
+ }
+
+ guard let deeplinkUri = store.uri?.deeplinkUri else {
+ throw DeeplinkErrors.uriNotCreated
+ }
+
+ return "\(plainAppUrl)/wc?uri=\(deeplinkUri)"
+ }
+}
+
+private extension String {
+ func toURL() -> URL? {
+ URL(string: self)
+ }
+}
diff --git a/Sources/Web3Modal/Screens/ConnectWallet/WhatIsWalletView.swift b/Sources/Web3Modal/Screens/ConnectWallet/WhatIsWalletView.swift
new file mode 100644
index 0000000..2906901
--- /dev/null
+++ b/Sources/Web3Modal/Screens/ConnectWallet/WhatIsWalletView.swift
@@ -0,0 +1,116 @@
+import SwiftUI
+
+struct WhatIsWalletView: View {
+ @Environment(\.verticalSizeClass) var verticalSizeClass
+
+ @EnvironmentObject var router: Router
+ @Environment(\.analyticsService) var analyticsService: AnalyticsService
+
+ var body: some View {
+ content()
+ .onAppear {
+ UIPageControl.appearance().currentPageIndicatorTintColor = UIColor.Foreground100
+ UIPageControl.appearance().pageIndicatorTintColor = UIColor.Foreground100.withAlphaComponent(0.2)
+ }
+ }
+
+ func content() -> some View {
+ VStack(spacing: 0) {
+ if verticalSizeClass == .compact {
+ TabView {
+ ForEach(sections(), id: \.title) { section in
+ section
+ .padding(.bottom, 40)
+ }
+ }
+ .transform {
+ #if os(iOS)
+ if #available(iOS 14.0, *) {
+ $0.tabViewStyle(.page(indexDisplayMode: .always))
+ }
+ #endif
+ }
+ .scaledToFill()
+ .layoutPriority(1)
+
+ } else {
+ ForEach(sections(), id: \.title) { section in
+ section
+ .padding(.bottom, Spacing.xxl)
+ }
+ }
+
+ HStack {
+ Button(action: {
+ router.setRoute(Router.ConnectingSubpage.getWallet)
+ analyticsService.track(.CLICK_GET_WALLET)
+ }) {
+ HStack {
+ Image.Bold.wallet
+ Text("Get a wallet")
+ }
+ }
+ }
+ .buttonStyle(W3MButtonStyle(size: .s))
+ }
+ .padding(.vertical, 40)
+ .padding(.horizontal, 40)
+ }
+
+ func sections() -> [HelpSection] {
+ [
+ HelpSection(
+ title: "One login for all of web3",
+ description: "Log in to any app by connecting your wallet. Say goodbye to countless passwords!",
+ assets: [.imageLogin, .imageProfile, .imageLock]
+ ),
+ HelpSection(
+ title: "A home for your digital assets",
+ description: "A wallet lets you store, send and receive digital assets like cryptocurrencies and NFTs.",
+ assets: [.imageDeFi, .imageNft, .imageEth]
+ ),
+ HelpSection(
+ title: "Your gateway to a new web",
+ description: "With your wallet, you can explore and interact with DeFi, NFTs, DAOs, and much more.",
+ assets: [.imageBrowser, .imageNoun, .imageDao]
+ )
+ ]
+ }
+}
+
+struct HelpSection: View {
+ let title: String
+ let description: String
+ let assets: [Image]
+
+ var body: some View {
+ VStack(spacing: Spacing.zero) {
+ HStack(spacing: Spacing.s) {
+ ForEach(assets.indices, id: \.self) { index in
+ assets[index]
+ }
+ }
+ .padding(.bottom, Spacing.xl)
+
+ Text(title)
+ .font(.paragraph500)
+ .foregroundColor(.Foreground100)
+ .multilineTextAlignment(.center)
+ .padding(.bottom, Spacing.xs)
+ Text(description)
+ .font(.small500)
+ .foregroundColor(.Foreground200)
+ .multilineTextAlignment(.center)
+ .fixedSize(horizontal: false, vertical: true)
+ .padding(.bottom, Spacing.s)
+ }
+ }
+}
+
+#if DEBUG
+struct WhatIsWalletView_Previews: PreviewProvider {
+ static var previews: some View {
+ WhatIsWalletView()
+ }
+}
+#endif
diff --git a/Sources/Web3Modal/Sheets/ModalContainerView.swift b/Sources/Web3Modal/Sheets/ModalContainerView.swift
new file mode 100644
index 0000000..1724bad
--- /dev/null
+++ b/Sources/Web3Modal/Sheets/ModalContainerView.swift
@@ -0,0 +1,105 @@
+import SwiftUI
+
+struct ModalContainerView: View {
+ @Environment(\.presentationMode) var presentationMode
+
+ @Environment(\.analyticsService) var analyticsService
+
+ @ObservedObject var store: Store
+ @Backport.StateObject var router: Router
+ @Backport.StateObject var web3modalViewModel: Web3ModalViewModel
+
+ init(store: Store = .shared, router: Router) {
+ self.store = store
+ _router = Backport.StateObject(wrappedValue: router)
+ _web3modalViewModel = Backport.StateObject(
+ wrappedValue: Web3Modal.viewModel
+ )
+ }
+
+ var body: some View {
+ ZStack {
+ Color.Overgray020
+ .colorScheme(.light)
+ .opacity(store.isModalShown ? 1 : 0)
+ .transform {
+ #if os(iOS)
+ $0.onTapGesture {
+ withAnimation {
+ store.isModalShown = false
+ store.connecting = false
+ }
+ }
+ #endif
+ }
+
+ VStack(spacing: 0) {
+ Spacer()
+ .background(Color.clear)
+
+ if store.isModalShown {
+ Group {
+ switch router.currentRoute {
+ case _ where router.currentRoute as? Router.AccountSubpage != nil:
+ AccountView()
+ case _ where router.currentRoute as? Router.ConnectingSubpage != nil:
+ Web3ModalView(
+ viewModel: web3modalViewModel
+ )
+ case _ where router.currentRoute as? Router.NetworkSwitchSubpage != nil:
+ ChainSelectView(
+ viewModel: web3modalViewModel
+ )
+ default:
+ EmptyView()
+ }
+ }
+ .toastView(toast: $store.toast)
+ .transition(.move(edge: .bottom))
+ .animation(.spring(), value: store.isModalShown)
+ .environmentObject(web3modalViewModel.router)
+ .environmentObject(web3modalViewModel.store)
+ .environmentObject(web3modalViewModel.w3mApiInteractor)
+ .environmentObject(web3modalViewModel.signInteractor)
+ .environmentObject(web3modalViewModel.blockchainApiInteractor)
+ }
+ }
+ }
+ .edgesIgnoringSafeArea(.all)
+ .backport.onChange(of: store.isModalShown, perform: { newValue in
+ if newValue {
+ let connected = store.account != nil
+
+ analyticsService.track(.MODAL_OPEN(connected: connected))
+ } else {
+ withAnimation {
+ self.dismiss()
+ store.connecting = false
+ }
+ }
+ })
+ .onAppear {
+ withAnimation {
+ store.isModalShown = true
+ }
+ }
+ }
+
+ private func dismiss() {
+
+ let connected = store.account != nil
+ analyticsService.track(.MODAL_CLOSE(connected: connected))
+
+ // Small delay so the sliding transition can happen before cross disolve starts
+ DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
+ self.presentationMode.wrappedValue.dismiss()
+ }
+ }
+}
+
+@available(iOS 14.0, *)
+struct ModalContainerView_Previews: PreviewProvider {
+ static var previews: some View {
+ ModalContainerView(router: Router())
+ }
+}
diff --git a/Sources/Web3Modal/Sheets/Web3ModalSheetController.swift b/Sources/Web3Modal/Sheets/Web3ModalSheetController.swift
new file mode 100644
index 0000000..7ecd9f3
--- /dev/null
+++ b/Sources/Web3Modal/Sheets/Web3ModalSheetController.swift
@@ -0,0 +1,20 @@
+import SwiftUI
+import UIKit
+
+class Web3ModalSheetController: UIHostingController {
+ @available(*, unavailable)
+ @MainActor dynamic required init?(coder aDecoder: NSCoder) {
+ fatalError("init(coder:) has not been implemented")
+ }
+
+ init(router: Router) {
+ super.init(rootView: ModalContainerView(router: router))
+ self.modalTransitionStyle = .crossDissolve
+ self.modalPresentationStyle = .overFullScreen
+ }
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+ self.view.backgroundColor = .clear
+ }
+}
diff --git a/Sources/Web3Modal/Sheets/Web3ModalView.swift b/Sources/Web3Modal/Sheets/Web3ModalView.swift
new file mode 100644
index 0000000..6822ac9
--- /dev/null
+++ b/Sources/Web3Modal/Sheets/Web3ModalView.swift
@@ -0,0 +1,144 @@
+import SwiftUI
+
+struct Web3ModalView: View {
+ @ObservedObject var viewModel: Web3ModalViewModel
+
+ @EnvironmentObject var signInteractor: SignInteractor
+ @EnvironmentObject var store: Store
+ @EnvironmentObject var router: Router
+
+ @Environment(\.analyticsService) var analyticsService: AnalyticsService
+
+ var body: some View {
+ VStack(spacing: 0) {
+ modalHeader()
+ routes()
+ }
+ .background(Color.Background125)
+ .cornerRadius(30, corners: [.topLeft, .topRight])
+ }
+
+ @ViewBuilder
+ private func routes() -> some View {
+ switch router.currentRoute as? Router.ConnectingSubpage {
+ case .none:
+ EmptyView()
+ case .connectWallet:
+ ConnectWalletView()
+ case .allWallets:
+ if #available(iOS 14.0, *) {
+ AllWalletsView()
+ } else {
+ Text("Please upgrade to iOS 14 to use this feature")
+ }
+ case .qr:
+ ConnectWithQRCode()
+ case .whatIsAWallet:
+ WhatIsWalletView()
+ case let .walletDetail(wallet):
+ WalletDetailView(
+ viewModel: .init(
+ wallet: wallet,
+ router: router,
+ signInteractor: signInteractor,
+ store: store
+ )
+ )
+ case .getWallet:
+ GetAWalletView()
+ }
+ }
+
+ private func modalHeader() -> some View {
+ HStack(spacing: 0) {
+ switch router.currentRoute as? Router.ConnectingSubpage {
+ case .none:
+ EmptyView()
+ case .connectWallet:
+ helpButton()
+ default:
+ backButton()
+ }
+
+ Spacer()
+
+ (router.currentRoute as? Router.ConnectingSubpage)?.title.map { title in
+ Text(title)
+ .font(.paragraph700)
+ }
+
+ Spacer()
+
+ closeButton()
+ }
+ .padding()
+ .frame(height: 64)
+ .frame(maxWidth: .infinity)
+ .foregroundColor(.Foreground100)
+ .overlay(
+ RoundedCorner(radius: 30, corners: [.topLeft, .topRight])
+ .stroke(Color.GrayGlass005, lineWidth: 1)
+ )
+ .cornerRadius(30, corners: [.topLeft, .topRight])
+ }
+
+ private func helpButton() -> some View {
+ Button(action: {
+ router.setRoute(Router.ConnectingSubpage.whatIsAWallet)
+ analyticsService.track(.CLICK_WALLET_HELP)
+ }, label: {
+ Image.Medium.questionMarkCircle
+ })
+ }
+
+ private func backButton() -> some View {
+ Button {
+ router.goBack()
+ } label: {
+ Image.Medium.chevronLeft
+ }
+ }
+
+ private func closeButton() -> some View {
+ Button {
+ withAnimation {
+ store.isModalShown = false
+ }
+ } label: {
+ Image.Medium.xMark
+ }
+ }
+}
+
+extension Router.ConnectingSubpage {
+ var title: String? {
+ switch self {
+ case .connectWallet:
+ return "Connect wallet"
+ case .qr:
+ return "WalletConnect"
+ case .allWallets:
+ return "All wallets"
+ case .whatIsAWallet:
+ return "What is a wallet?"
+ case let .walletDetail(wallet):
+ return "\(wallet.name)"
+ case .getWallet:
+ return "Get wallet"
+ }
+ }
+}
+
+struct Web3ModalView_Previews: PreviewProvider {
+ static var previews: some View {
+ Web3ModalView(
+ viewModel: .init(
+ router: Router(),
+ store: Store(),
+ w3mApiInteractor: W3MAPIInteractor(store: Store()),
+ signInteractor: SignInteractor(store: Store()),
+ blockchainApiInteractor: BlockchainAPIInteractor(store: Store())
+ ))
+ .previewLayout(.sizeThatFits)
+ }
+}
diff --git a/Sources/Web3Modal/Sheets/Web3ModalViewModel.swift b/Sources/Web3Modal/Sheets/Web3ModalViewModel.swift
new file mode 100644
index 0000000..b6bb74f
--- /dev/null
+++ b/Sources/Web3Modal/Sheets/Web3ModalViewModel.swift
@@ -0,0 +1,191 @@
+import Combine
+import SwiftUI
+
+class Web3ModalViewModel: ObservableObject {
+ private(set) var router: Router
+ private(set) var store: Store
+ private(set) var w3mApiInteractor: W3MAPIInteractor
+ private(set) var signInteractor: SignInteractor
+ private(set) var blockchainApiInteractor: BlockchainAPIInteractor
+
+ private var disposeBag = Set()
+
+ init(
+ router: Router,
+ store: Store,
+ w3mApiInteractor: W3MAPIInteractor,
+ signInteractor: SignInteractor,
+ blockchainApiInteractor: BlockchainAPIInteractor
+ ) {
+ self.router = router
+ self.store = store
+ self.w3mApiInteractor = w3mApiInteractor
+ self.signInteractor = signInteractor
+ self.blockchainApiInteractor = blockchainApiInteractor
+
+ Web3Modal.instance.sessionEventPublisher
+ .receive(on: DispatchQueue.main)
+ .sink { event, _, _ in
+ switch event.name {
+ case "chainChanged":
+ guard let chainReference = try? event.data.get(Int.self) else {
+ return
+ }
+
+ Store.shared.selectedChain = ChainPresets.ethChains.first(where: { $0.chainReference == String(chainReference) })
+
+ case "accountsChanged":
+
+ guard let account = try? event.data.get([String].self) else {
+ return
+ }
+
+ let chainReference = account[0].split(separator: ":")[1]
+
+ Store.shared.selectedChain = ChainPresets.ethChains.first(where: { $0.chainReference == String(chainReference) })
+ default:
+ break
+ }
+ }
+ .store(in: &disposeBag)
+
+ signInteractor.sessionSettlePublisher
+ .receive(on: DispatchQueue.main)
+ .sink { session in
+ router.setRoute(Router.AccountSubpage.profile)
+ store.connectedWith = .wc
+ store.account = .init(from: session)
+ store.session = session
+
+ if
+ let blockchain = session.accounts.first?.blockchain,
+ let matchingChain = ChainPresets.ethChains.first(where: { $0.chainNamespace == blockchain.namespace && $0.chainReference == blockchain.reference })
+ {
+ store.selectedChain = matchingChain
+ }
+
+ self.fetchIdentity()
+
+ withAnimation {
+ store.isModalShown = false
+ }
+ }
+ .store(in: &disposeBag)
+
+ signInteractor.sessionDeletePublisher
+ .receive(on: DispatchQueue.main)
+ .sink { topic, _ in
+
+ if store.session?.topic == topic {
+ store.session = nil
+ store.account = nil
+ }
+ router.setRoute(Router.ConnectingSubpage.connectWallet)
+ }
+ .store(in: &disposeBag)
+
+ signInteractor.sessionsPublisher
+ .receive(on: DispatchQueue.main)
+ .sink { sessions in
+
+ if sessions.isEmpty {
+ DispatchQueue.main.async {
+ store.session = nil
+ store.account = nil
+ router.setRoute(Router.ConnectingSubpage.connectWallet)
+ }
+ }
+ }
+ .store(in: &disposeBag)
+
+ Task {
+ try? await signInteractor.createPairingAndConnect()
+ }
+ }
+
+ func fetchIdentity() {
+ Task { @MainActor in
+ do {
+ try await blockchainApiInteractor.getIdentity()
+ } catch {
+ store.toast = .init(style: .error, message: "Network error")
+ Web3Modal.config.onError(error)
+ }
+ }
+ }
+
+ func fetchBalance() {
+ Task { @MainActor in
+ do {
+ try await blockchainApiInteractor.getBalance()
+ } catch {
+ store.toast = .init(style: .error, message: "Network error")
+ Web3Modal.config.onError(error)
+ }
+ }
+ }
+
+ func getChains() -> [Chain] {
+ guard let namespaces = store.session?.namespaces.values else {
+ return []
+ }
+
+ var chains = namespaces
+ .compactMap { $0.chains }
+ .flatMap { $0 }
+ .filter { chain in
+ isChainIdCAIP2Compliant(chainId: chain.absoluteString)
+ }
+
+ if let requiredNamespaces = store.session?.requiredNamespaces.values {
+ let requiredChains = requiredNamespaces
+ .compactMap { $0.chains }
+ .flatMap { $0 }
+ .filter { chain in
+ isChainIdCAIP2Compliant(chainId: chain.absoluteString)
+ }
+
+ chains.append(contentsOf: requiredChains)
+ }
+
+ return chains
+ .compactMap { chain in
+ ChainPresets.ethChains.first(where: { chain.reference == $0.chainReference && chain.namespace == $0.chainNamespace })
+ }
+ }
+
+ func getMethods() -> [String] {
+ guard let session = store.session else {
+ return []
+ }
+
+ let methods = session.namespaces.values
+ .compactMap { $0.methods }
+ .flatMap { $0 }
+
+ let requiredMethods = session.requiredNamespaces.values
+ .compactMap { $0.methods }
+ .flatMap { $0 }
+
+ return (methods + requiredMethods)
+ }
+
+ func isChainIdCAIP2Compliant(chainId: String) -> Bool {
+ let elements = chainId.split(separator: ":")
+ guard elements.count == 2 else { return false }
+
+ let namespace = String(elements[0])
+ let reference = String(elements[1])
+
+ return isNamespaceRegexCompliant(key: namespace) && referenceRegex.matches(in: reference, options: [], range: NSRange(location: 0, length: reference.utf16.count)).count > 0
+ }
+
+ private let referenceRegex = try! NSRegularExpression(pattern: "^[-_a-zA-Z0-9]{1,32}$")
+
+ // For namespace key validation reference check CAIP-2: https://github.com/ChainAgnostic/CAIPs/blob/master/CAIPs/caip-2.md#syntax
+ func isNamespaceRegexCompliant(key: String) -> Bool {
+ return namespaceRegex.matches(in: key, options: [], range: NSRange(location: 0, length: key.utf16.count)).count > 0
+ }
+
+ private let namespaceRegex = try! NSRegularExpression(pattern: "^[-a-z0-9]{3,8}$")
+}
diff --git a/Sources/Web3Modal/Store.swift b/Sources/Web3Modal/Store.swift
new file mode 100644
index 0000000..5dfbf07
--- /dev/null
+++ b/Sources/Web3Modal/Store.swift
@@ -0,0 +1,91 @@
+import Combine
+import SwiftUI
+
+enum ConnectionProviderType {
+ case wc
+ case cb
+}
+
+class Store: ObservableObject {
+ static var shared: Store = .init()
+
+ @Published var isModalShown: Bool = false
+ @Published var retryShown = false
+
+ @Published var identity: Identity?
+ @Published var balance: Double?
+
+ @Published var connectedWith: ConnectionProviderType?
+ @Published var connecting: Bool = false
+ @Published var account: W3MAccount? {
+ didSet {
+ let matchingChain = ChainPresets.ethChains.first(where: {
+ $0.chainNamespace == account?.chain.namespace && $0.chainReference == account?.chain.reference
+ })
+
+ Store.shared.selectedChain = matchingChain
+
+ AccountStorage.save(account)
+ }
+ }
+
+ // WalletConnect specific
+ @Published var session: Session? {
+ didSet {
+ if let blockchain = session?.accounts.first?.blockchain {
+ let matchingChain = ChainPresets.ethChains.first(where: {
+ $0.chainNamespace == blockchain.namespace && $0.chainReference == blockchain.reference
+ })
+
+ Store.shared.selectedChain = matchingChain
+ }
+ }
+ }
+ @Published var uri: WalletConnectURI?
+
+ @Published var wallets: Set = []
+ @Published var featuredWallets: [Wallet] = []
+ @Published var searchedWallets: [Wallet] = []
+ @Published var customWallets: [Wallet] = []
+
+ var totalNumberOfWallets: Int = 0
+ var currentPage: Int = 0
+ var totalPages: Int = .max
+ var walletImages: [String: UIImage] = [:]
+ var installedWalletIds: [String] = []
+
+ var recentWallets: [Wallet] {
+ get {
+ RecentWalletsStorage.loadRecentWallets()
+ }
+ set(newValue) {
+ RecentWalletsStorage.saveRecentWallets(newValue)
+ }
+ }
+
+ @Published public var selectedChain: Chain?
+ @Published var chainImages: [String: UIImage] = [:]
+
+ @Published var toast: Toast? = nil
+}
+
+struct W3MAccount: Codable {
+ let address: String
+ let chain: Blockchain
+}
+
+extension W3MAccount {
+
+ init?(from session: Session) {
+ guard let account = session.accounts.first else {
+ return nil
+ }
+
+ self.init(address: account.address, chain: account.blockchain)
+ }
+
+ static let stub: Self = .init(
+ address: "0x5c8877144d858e41d8c33f5baa7e67a5e0027e37",
+ chain: Blockchain(namespace: "eip155", reference: "56")!
+ )
+}
diff --git a/Sources/Web3Modal/Web3ModalImports.swift b/Sources/Web3Modal/Web3ModalImports.swift
new file mode 100644
index 0000000..e0cc083
--- /dev/null
+++ b/Sources/Web3Modal/Web3ModalImports.swift
@@ -0,0 +1,7 @@
+#if !CocoaPods
+@_exported import Web3ModalUI
+@_exported import Web3ModalBackport
+@_exported import WalletConnectSign
+#else
+@_exported import WalletConnectSwiftV2
+#endif
diff --git a/Sources/Web3Modal/Wrappers/UIApplicationWrapper.swift b/Sources/Web3Modal/Wrappers/UIApplicationWrapper.swift
new file mode 100644
index 0000000..3017191
--- /dev/null
+++ b/Sources/Web3Modal/Wrappers/UIApplicationWrapper.swift
@@ -0,0 +1,18 @@
+import Foundation
+import UIKit
+
+struct UIApplicationWrapper {
+ let openURL: (URL, _ completionHandler: ((Bool) -> Void)?) -> Void
+ let canOpenURL: (URL) -> Bool
+}
+
+extension UIApplicationWrapper {
+ static let live = Self(
+ openURL: { url, completion in
+ UIApplication.shared.open(url, completionHandler: completion)
+ },
+ canOpenURL: { url in
+ UIApplication.shared.canOpenURL(url)
+ }
+ )
+}
diff --git a/Sources/Web3ModalBackport/AsyncImage.swift b/Sources/Web3ModalBackport/AsyncImage.swift
new file mode 100644
index 0000000..5069d75
--- /dev/null
+++ b/Sources/Web3ModalBackport/AsyncImage.swift
@@ -0,0 +1,171 @@
+import SwiftUI
+
+@available(iOS, deprecated: 15.0)
+public extension Backport where Wrapped == Any {
+
+ @ViewBuilder
+ static func AsyncImage(url: URL?, scale: CGFloat = 1) -> some View {
+ _AsyncImage(url: url, scale: scale)
+ }
+
+ @ViewBuilder
+ static func AsyncImage(url: URL?, scale: CGFloat = 1, @ViewBuilder content: @escaping (Image) -> I, @ViewBuilder placeholder: @escaping () -> P) -> some View {
+ _AsyncImage(url: url, scale: scale, content: content, placeholder: placeholder)
+ }
+
+ @ViewBuilder
+ static func AsyncImage(url: URL?, scale: CGFloat = 1, transaction: Transaction = Transaction(), @ViewBuilder content: @escaping (AsyncImagePhase) -> Content) -> some View {
+ _AsyncImage(url: url, scale: scale, transaction: transaction, content: content)
+ }
+
+ enum AsyncImagePhase {
+ case empty
+ case success(Image)
+ case failure(Error)
+
+ public var image: Image? {
+ guard case let .success(image) = self else { return nil }
+ return image
+ }
+
+ public var error: Error? {
+ guard case let .failure(error) = self else { return nil }
+ return error
+ }
+ }
+
+ // An iOS 13+ async/await backport implementation
+ private struct _AsyncImage: View {
+ @State private var phase: AsyncImagePhase = .empty
+
+ var url: URL?
+ var scale: CGFloat = 1
+ var transaction: Transaction = .init()
+ var content: (Backport.AsyncImagePhase) -> Content
+
+ public var body: some View {
+ ZStack {
+ content(phase)
+ }
+ .backport.task(id: url) {
+ do {
+ guard !Task.isCancelled, let url = url else { return }
+ let (data, _) = try await URLSession.shared.data(from: url)
+ guard !Task.isCancelled else { return }
+
+ #if os(macOS)
+ if let image = NSImage(data: data) {
+ withTransaction(transaction) {
+ phase = .success(Image(nsImage: image))
+ }
+ }
+ #else
+ if let image = UIImage(data: data, scale: scale) {
+ withTransaction(transaction) {
+ phase = .success(Image(uiImage: image))
+ }
+ }
+ #endif
+ } catch {
+ phase = .failure(error)
+ }
+ }
+ }
+
+ init(url: URL?, scale: CGFloat = 1) where Content == AnyView {
+ self.url = url
+ self.scale = scale
+ self.content = { AnyView($0.image) }
+ }
+
+ init(url: URL?, scale: CGFloat = 1, @ViewBuilder content: @escaping (Image) -> I, @ViewBuilder placeholder: @escaping () -> P) where Content == _ConditionalContent {
+ self.url = url
+ self.scale = scale
+ self.transaction = Transaction()
+ self.content = { phase -> _ConditionalContent in
+ if let image = phase.image {
+ return ViewBuilder.buildEither(first: content(image))
+ } else {
+ return ViewBuilder.buildEither(second: placeholder())
+ }
+ }
+ }
+
+ init(url: URL?, scale: CGFloat = 1, transaction: Transaction = Transaction(), @ViewBuilder content: @escaping (Backport.AsyncImagePhase) -> Content) {
+ self.url = url
+ self.scale = scale
+ self.transaction = transaction
+ self.content = content
+ }
+ }
+
+}
+
+import SwiftUI
+import Combine
+
+@available(iOS, deprecated: 15.0)
+@available(macOS, deprecated: 12.0)
+@available(tvOS, deprecated: 15.0)
+@available(watchOS, deprecated: 8.0)
+extension Backport where Wrapped: View {
+
+ @ViewBuilder
+ func task(priority: TaskPriority = .userInitiated, @_inheritActorContext _ action: @escaping @Sendable () async -> Void) -> some View {
+ wrapped.modifier(
+ TaskModifier(
+ id: 0,
+ priority: priority,
+ action: action
+ )
+ )
+ }
+
+ @ViewBuilder
+ func task(id: T, priority: TaskPriority = .userInitiated, @_inheritActorContext _ action: @escaping @Sendable () async -> Void) -> some View {
+ wrapped.modifier(
+ TaskModifier(
+ id: id,
+ priority: priority,
+ action: action
+ )
+ )
+ }
+
+}
+
+private struct TaskModifier: ViewModifier {
+
+ var id: ID
+ var priority: TaskPriority
+ var action: @Sendable () async -> Void
+
+ @State private var task: Task?
+ @State private var publisher = PassthroughSubject<(), Never>()
+
+ init(id: ID, priority: TaskPriority, action: @Sendable @escaping () async -> Void) {
+ self.id = id
+ self.priority = priority
+ self.action = action
+ }
+
+ func body(content: Content) -> some View {
+ content
+ .backport.onChange(of: id) { _ in
+ publisher.send()
+ }
+ .onReceive(publisher) { _ in
+ task?.cancel()
+ task = Task(priority: priority, operation: action)
+ }
+ .onAppear {
+ task?.cancel()
+ task = Task(priority: priority, operation: action)
+ }
+ .onDisappear {
+ task?.cancel()
+ task = nil
+ }
+ }
+
+}
diff --git a/Sources/Web3ModalBackport/Background.swift b/Sources/Web3ModalBackport/Background.swift
new file mode 100644
index 0000000..2327d55
--- /dev/null
+++ b/Sources/Web3ModalBackport/Background.swift
@@ -0,0 +1,7 @@
+import SwiftUI
+
+extension Backport where Wrapped: View {
+ public func background(alignment: Alignment = .center, @ViewBuilder _ content: () -> Content) -> some View {
+ wrapped.background(content(), alignment: alignment)
+ }
+}
diff --git a/Sources/Web3ModalBackport/Backport.swift b/Sources/Web3ModalBackport/Backport.swift
new file mode 100644
index 0000000..cf03a50
--- /dev/null
+++ b/Sources/Web3ModalBackport/Backport.swift
@@ -0,0 +1,14 @@
+import SwiftUI
+
+public struct Backport {
+ let wrapped: Wrapped
+
+ public init(_ wrapped: Wrapped) {
+ self.wrapped = wrapped
+ }
+}
+
+public extension View {
+ /// Wraps a SwiftUI `View` that can be extended to provide backport functionality.
+ var backport: Backport { .init(self) }
+}
diff --git a/Sources/Web3ModalBackport/ContentSizeCategory.swift b/Sources/Web3ModalBackport/ContentSizeCategory.swift
new file mode 100644
index 0000000..4b36c2d
--- /dev/null
+++ b/Sources/Web3ModalBackport/ContentSizeCategory.swift
@@ -0,0 +1,27 @@
+import SwiftUI
+
+extension ContentSizeCategory {
+ var order: Int {
+ switch self {
+ case .extraSmall: return 0
+ case .small: return 1
+ case .medium: return 2
+ case .large: return 3
+ case .extraLarge: return 4
+ case .extraExtraLarge: return 5
+ case .extraExtraExtraLarge: return 6
+ case .accessibilityMedium: return 7
+ case .accessibilityLarge: return 8
+ case .accessibilityExtraLarge: return 9
+ case .accessibilityExtraExtraLarge: return 10
+ case .accessibilityExtraExtraExtraLarge: return 11
+ @unknown default: fatalError("Unknown content size category")
+ }
+ }
+}
+
+extension ContentSizeCategory: Comparable {
+ public static func < (lhs: ContentSizeCategory, rhs: ContentSizeCategory) -> Bool {
+ lhs.order < rhs.order
+ }
+}
diff --git a/Sources/Web3ModalBackport/OnChange.swift b/Sources/Web3ModalBackport/OnChange.swift
new file mode 100644
index 0000000..d050cfe
--- /dev/null
+++ b/Sources/Web3ModalBackport/OnChange.swift
@@ -0,0 +1,41 @@
+import SwiftUI
+import Combine
+
+@available(iOS, deprecated: 14.0)
+@available(macOS, deprecated: 11.0)
+@available(tvOS, deprecated: 14.0)
+@available(watchOS, deprecated: 7.0)
+extension Backport where Wrapped: View {
+
+ @ViewBuilder
+ public func onChange(of value: Value, perform action: @escaping (Value) -> Void) -> some View {
+ if #available(iOS 14, tvOS 14, macOS 11, watchOS 7, *) {
+ wrapped.onChange(of: value, perform: action)
+ } else {
+ wrapped.modifier(ChangeModifier(value: value, action: action))
+ }
+ }
+
+}
+
+private struct ChangeModifier: ViewModifier {
+ let value: Value
+ let action: (Value) -> Void
+
+ @State var oldValue: Value?
+
+ init(value: Value, action: @escaping (Value) -> Void) {
+ self.value = value
+ self.action = action
+ _oldValue = .init(initialValue: value)
+ }
+
+ func body(content: Content) -> some View {
+ content
+ .onReceive(Just(value)) { newValue in
+ guard newValue != oldValue else { return }
+ action(newValue)
+ oldValue = newValue
+ }
+ }
+}
diff --git a/Sources/Web3ModalBackport/Overlay.swift b/Sources/Web3ModalBackport/Overlay.swift
new file mode 100644
index 0000000..054ba74
--- /dev/null
+++ b/Sources/Web3ModalBackport/Overlay.swift
@@ -0,0 +1,7 @@
+import SwiftUI
+
+extension Backport where Wrapped: View {
+ public func overlay(alignment: Alignment = .center, @ViewBuilder _ content: () -> Content) -> some View {
+ self.wrapped.overlay(content(), alignment: alignment)
+ }
+}
diff --git a/Sources/Web3ModalBackport/ScaledMetric.swift b/Sources/Web3ModalBackport/ScaledMetric.swift
new file mode 100644
index 0000000..b223ecc
--- /dev/null
+++ b/Sources/Web3ModalBackport/ScaledMetric.swift
@@ -0,0 +1,80 @@
+import SwiftUI
+
+@available(iOS, deprecated: 14)
+@available(macOS, deprecated: 11)
+@available(tvOS, deprecated: 14)
+@available(watchOS, deprecated: 7)
+public extension Backport where Wrapped == Any {
+
+ /// A dynamic property that scales a numeric value.
+ @propertyWrapper
+ struct ScaledMetric: DynamicProperty where Value: BinaryFloatingPoint {
+
+ @Environment(\.sizeCategory) var sizeCategory
+
+ private let baseValue: Value
+
+ #if os(iOS) || os(tvOS)
+ private let metrics: UIFontMetrics
+ #endif
+
+ public var wrappedValue: Value {
+ #if os(iOS) || os(tvOS)
+ let traits = UITraitCollection(traitsFrom: [
+ UITraitCollection(preferredContentSizeCategory: UIContentSizeCategory(sizeCategory: sizeCategory))
+ ])
+
+ return Value(metrics.scaledValue(for: CGFloat(baseValue), compatibleWith: traits))
+ #else
+ return baseValue
+ #endif
+ }
+
+ #if os(iOS) || os(tvOS)
+ /// Creates the scaled metric with an unscaled value using the default scaling.
+ public init(baseValue: Value, metrics: UIFontMetrics) {
+ self.baseValue = baseValue
+ self.metrics = metrics
+ }
+
+ /// Creates the scaled metric with an unscaled value using the default scaling.
+ public init(wrappedValue: Value) {
+ self.init(baseValue: wrappedValue, metrics: UIFontMetrics(forTextStyle: .body))
+ }
+
+ /// Creates the scaled metric with an unscaled value and a text style to scale relative to.
+ public init(wrappedValue: Value, relativeTo textStyle: UIFont.TextStyle) {
+ self.init(baseValue: wrappedValue, metrics: UIFontMetrics(forTextStyle: textStyle))
+ }
+ #else
+ /// Creates the scaled metric with an unscaled value using the default scaling.
+ public init(wrappedValue: Value) {
+ self.baseValue = wrappedValue
+ }
+ #endif
+
+ }
+
+}
+
+#if os(iOS) || os(tvOS)
+private extension UIContentSizeCategory {
+ init(sizeCategory: ContentSizeCategory?) {
+ switch sizeCategory {
+ case .accessibilityExtraExtraExtraLarge: self = .accessibilityExtraExtraExtraLarge
+ case .accessibilityExtraExtraLarge: self = .accessibilityExtraExtraLarge
+ case .accessibilityExtraLarge: self = .accessibilityExtraLarge
+ case .accessibilityLarge: self = .accessibilityLarge
+ case .accessibilityMedium: self = .accessibilityMedium
+ case .extraExtraExtraLarge: self = .extraExtraExtraLarge
+ case .extraExtraLarge: self = .extraExtraLarge
+ case .extraLarge: self = .extraLarge
+ case .extraSmall: self = .extraSmall
+ case .large: self = .large
+ case .medium: self = .medium
+ case .small: self = .small
+ default: self = .unspecified
+ }
+ }
+}
+#endif
diff --git a/Sources/Web3ModalBackport/StateObject.swift b/Sources/Web3ModalBackport/StateObject.swift
new file mode 100644
index 0000000..bcd347c
--- /dev/null
+++ b/Sources/Web3ModalBackport/StateObject.swift
@@ -0,0 +1,63 @@
+import Combine
+import SwiftUI
+
+@available(iOS, deprecated: 14.0)
+@available(macOS, deprecated: 11.0)
+@available(tvOS, deprecated: 14.0)
+@available(watchOS, deprecated: 7.0)
+extension Backport where Wrapped: ObservableObject {
+
+ @propertyWrapper public struct StateObject: DynamicProperty {
+ private final class Wrapper: ObservableObject {
+ private var subject = PassthroughSubject()
+
+ var value: Wrapped? {
+ didSet {
+ cancellable = nil
+ cancellable = value?.objectWillChange
+ .sink { [subject] _ in subject.send() }
+ }
+ }
+
+ private var cancellable: AnyCancellable?
+
+ var objectWillChange: AnyPublisher {
+ subject.eraseToAnyPublisher()
+ }
+ }
+
+ @State private var state = Wrapper()
+
+ @ObservedObject private var observedObject = Wrapper()
+
+ private var thunk: () -> Wrapped
+
+ public var wrappedValue: Wrapped {
+ if let object = state.value {
+ return object
+ } else {
+ let object = thunk()
+ state.value = object
+ return object
+ }
+ }
+
+ public var projectedValue: ObservedObject.Wrapper {
+ ObservedObject(wrappedValue: wrappedValue).projectedValue
+ }
+
+ public init(wrappedValue thunk: @autoclosure @escaping () -> Wrapped) {
+ self.thunk = thunk
+ }
+
+ public mutating func update() {
+ if state.value == nil {
+ state.value = thunk()
+ }
+ if observedObject.value !== state.value {
+ observedObject.value = state.value
+ }
+ }
+ }
+
+}
diff --git a/Sources/Web3ModalUI/Components/W3MActionEntryStyle.swift b/Sources/Web3ModalUI/Components/W3MActionEntryStyle.swift
new file mode 100644
index 0000000..d023d8b
--- /dev/null
+++ b/Sources/Web3ModalUI/Components/W3MActionEntryStyle.swift
@@ -0,0 +1,106 @@
+import SwiftUI
+
+public struct W3MActionEntryStyle: ButtonStyle {
+ @Environment(\.isEnabled) var isEnabled
+
+ @Backport.ScaledMetric var scale: CGFloat = 1
+
+ var leftIcon: Image?
+ var rightIcon: Image?
+
+ var isPressedOverride: Bool?
+
+ public init(
+ leftIcon: Image? = nil,
+ rightIcon: Image? = nil
+ ) {
+ self.leftIcon = leftIcon
+ self.rightIcon = rightIcon
+ }
+
+ #if DEBUG
+ init(
+ leftIcon: Image? = nil,
+ rightIcon: Image? = nil,
+ isPressedOverride: Bool?
+ ) {
+ self.leftIcon = leftIcon
+ self.rightIcon = rightIcon
+ self.isPressedOverride = isPressedOverride
+ }
+ #endif
+
+ public func makeBody(configuration: Configuration) -> some View {
+ HStack(spacing: Spacing.xs) {
+ if let leftIcon {
+ leftIcon
+ .resizable()
+ .frame(width: 14 * scale, height: 14 * scale)
+ }
+
+ configuration.label
+
+ if let rightIcon {
+ rightIcon
+ .resizable()
+ .frame(width: 14 * scale, height: 14 * scale)
+ }
+ }
+ .font(.paragraph600)
+ .foregroundColor((isPressedOverride ?? configuration.isPressed) ? .Foreground150 : .Foreground200)
+ .frame(maxWidth: .infinity)
+ .frame(height: 56)
+ .opacity(isEnabled ? 1 : 0.5)
+ .padding(.vertical, Spacing.xs * scale)
+ .padding(.leading, Spacing.xs * scale)
+ .padding(.trailing, Spacing.xs * scale)
+ .backport
+ .background { (isPressedOverride ?? configuration.isPressed) ? Color.GrayGlass010 : Color.GrayGlass002 }
+ .cornerRadius(Radius.xs * scale)
+ }
+}
+
+#if DEBUG
+ public struct W3MActionEntryStylePreviewView: View {
+ public init() {}
+
+ public var body: some View {
+ ScrollView {
+ VStack {
+ Button(action: {}, label: {
+ Text("Copy link")
+ })
+ .buttonStyle(W3MActionEntryStyle(
+ leftIcon: Image.Medium.desktop
+ ))
+
+ Button(action: {}, label: {
+ Text("Copy link")
+ })
+ .buttonStyle(W3MActionEntryStyle(
+ leftIcon: Image.Regular.copy,
+ isPressedOverride: true
+ ))
+
+ Button(action: {}, label: {
+ Text("Copy link")
+ })
+ .buttonStyle(W3MActionEntryStyle(
+ leftIcon: Image.Regular.copy
+ ))
+ .disabled(true)
+ }
+ .padding()
+
+ }
+ }
+ }
+
+ struct W3MActionEntry_Preview: PreviewProvider {
+ static var previews: some View {
+ W3MActionEntryStylePreviewView()
+ .previewLayout(.sizeThatFits)
+ }
+ }
+
+#endif
diff --git a/Sources/Web3ModalUI/Components/W3MAvatarGradient.swift b/Sources/Web3ModalUI/Components/W3MAvatarGradient.swift
new file mode 100644
index 0000000..112b6eb
--- /dev/null
+++ b/Sources/Web3ModalUI/Components/W3MAvatarGradient.swift
@@ -0,0 +1,83 @@
+import SwiftUI
+
+public struct W3MAvatarGradient: View {
+ let address: String
+
+ public init(address: String) {
+ self.address = address
+ }
+
+ public var body: some View {
+ let colors = generateAvatarColors(address: address)
+
+ GeometryReader { proxy in
+ // Create Orb like gradient
+ RadialGradient(
+ gradient: Gradient(stops: [
+ .init(color: .white, location: 0.0052),
+ .init(color: colors[4], location: 0.3125),
+ .init(color: colors[2], location: 0.5156),
+ .init(color: colors[1], location: 0.6563),
+ .init(color: colors[0], location: 0.8229),
+ .init(color: colors[3], location: 1.0)
+ ]),
+ center: UnitPoint(x: 0.6496, y: 0.2436),
+ startRadius: 0,
+ endRadius: proxy.frame(in: .local).height * 0.8
+ )
+ }
+ .clipShape(Circle())
+ }
+
+ func generateAvatarColors(address: String) -> [Color] {
+ let hash = address.lowercased().replacingOccurrences(of: "0x", with: "")
+ let baseColor = String(hash.prefix(6))
+ let rgbColor = hexToRgb(hex: baseColor)
+ var colors: [Color] = []
+ for i in 0 ..< 5 {
+ let tintedColor = tintColor(rgb: rgbColor, tint: 0.15 * Double(i))
+ colors.append(
+ Color(
+ red: CGFloat(tintedColor.0)/255.0,
+ green: CGFloat(tintedColor.1)/255.0,
+ blue: CGFloat(tintedColor.2)/255.0,
+ opacity: 1.0
+ )
+ )
+ }
+
+ return colors
+ }
+
+ func hexToRgb(hex: String) -> (Int, Int, Int) {
+ guard let bigint = Int64(hex, radix: 16) else { return (0, 0, 0) }
+
+ let r = Int((bigint >> 16) & 255)
+ let g = Int((bigint >> 8) & 255)
+ let b = Int(bigint & 255)
+ return (r, g, b)
+ }
+
+ func tintColor(rgb: (Int, Int, Int), tint: Double) -> (Int, Int, Int) {
+ let (r, g, b) = rgb
+ let tintedR = Int(round(Double(r) + (255.0 - Double(r)) * tint))
+ let tintedG = Int(round(Double(g) + (255.0 - Double(g)) * tint))
+ let tintedB = Int(round(Double(b) + (255.0 - Double(b)) * tint))
+ return (tintedR, tintedG, tintedB)
+ }
+}
+
+struct W3MAvatarGradient_Preview: PreviewProvider {
+ static var previews: some View {
+ VStack {
+ W3MAvatarGradient(address: "0x5C8877144D858E41D8C33F5BAA7E67A5E0027E37")
+ .frame(width: 128, height: 128)
+ W3MAvatarGradient(address: "0x6E7E5B77B0EE215E6471713EF7EB1F69982A0603")
+ .frame(width: 16, height: 16)
+ W3MAvatarGradient(address: "0x7542D32A86402165DD13E09360A01DF0662401E9")
+ .frame(width: 32, height: 32)
+ W3MAvatarGradient(address: "0xEF56528723AA4ECC52E115DCF18628ADB773658B")
+ .frame(width: 64, height: 64)
+ }
+ }
+}
diff --git a/Sources/Web3ModalUI/Components/W3MButtonStyle.swift b/Sources/Web3ModalUI/Components/W3MButtonStyle.swift
new file mode 100644
index 0000000..3116356
--- /dev/null
+++ b/Sources/Web3ModalUI/Components/W3MButtonStyle.swift
@@ -0,0 +1,284 @@
+import SwiftUI
+
+public struct W3MButtonStyle: ButtonStyle {
+ public enum Size {
+ case s, m
+ }
+
+ public enum Variant {
+ case accent
+ case main
+ }
+
+ @Environment(\.isEnabled) var isEnabled
+
+ let size: Size
+ let variant: Variant
+ var leftIcon: Image?
+ var rightIcon: Image?
+
+ var isPressedOverride: Bool?
+
+ public init(
+ size: Size = .m,
+ variant: Variant = .main,
+ leftIcon: Image? = nil,
+ rightIcon: Image? = nil
+ ) {
+ self.size = size
+ self.variant = variant
+ self.leftIcon = leftIcon
+ self.rightIcon = rightIcon
+ }
+
+ fileprivate init(
+ size: Size = .m,
+ variant: Variant = .main,
+ leftIcon: Image? = nil,
+ rightIcon: Image? = nil,
+ isPressedOverride: Bool?
+ ) {
+ self.size = size
+ self.variant = variant
+ self.leftIcon = leftIcon
+ self.rightIcon = rightIcon
+ self.isPressedOverride = isPressedOverride
+ }
+
+ public func makeBody(configuration: Configuration) -> some View {
+ var textColor: Color = variant == .accent ? .Blue100 : .Inverse100
+ textColor = isEnabled ? textColor : .Overgray015
+
+ var backgroundColor: Color = variant == .accent ? .clear : .Blue100
+ let pressedColor: Color = variant == .accent ? .Overgray010 : .Blue080
+ backgroundColor = (isPressedOverride ?? configuration.isPressed) ? pressedColor : backgroundColor
+ backgroundColor = isEnabled ? backgroundColor : .Overgray010
+
+ let verticalPadding = size == .m ? Spacing.xs : Spacing.xxs
+ let horizontalPadding = size == .m ? Spacing.l : Spacing.s
+ let leadingPadding = horizontalPadding - (leftIcon == nil ? 0 : Spacing.xxxs)
+ let trailingPadding = horizontalPadding - (rightIcon == nil ? 0 : Spacing.xxxs)
+ let iconSize: CGFloat = size == .m ? 16 : 14
+
+ return HStack(spacing: size == .m ? Spacing.xxs : Spacing.xxxs) {
+ if let leftIcon {
+ leftIcon
+ .resizable()
+ .frame(width: iconSize, height: iconSize)
+ .foregroundColor(textColor)
+ }
+
+ configuration
+ .label
+ .lineLimit(1)
+ .font(size == .m ? .paragraph600 : .small600)
+ .foregroundColor(textColor)
+
+ if let rightIcon {
+ rightIcon
+ .resizable()
+ .frame(width: iconSize, height: iconSize)
+ .foregroundColor(textColor)
+ }
+ }
+ .padding(.vertical, verticalPadding)
+ .padding(.leading, leadingPadding)
+ .padding(.trailing, trailingPadding)
+ .frame(height: size == .m ? 40 : 32)
+ .background(backgroundColor)
+ .cornerRadius(Radius.m)
+ .overlay(
+ RoundedRectangle(cornerRadius: Radius.m)
+ .stroke(Color.Overgray010, lineWidth: 1)
+ )
+ }
+}
+
+#if DEBUG
+ public struct W3MButtonStylePreviewView: View {
+ public init() {}
+
+ public var body: some View {
+ VStack(alignment: .leading) {
+ Text("S")
+ .font(.title700)
+
+ Text("Main")
+ .font(.large500)
+
+ VStack(alignment: .leading) {
+ HStack {
+ Button(action: {}) {
+ Text("Button")
+ }
+ .buttonStyle(W3MButtonStyle(size: .s))
+
+ Button(action: {}) {
+ Text("Button")
+ }
+ .buttonStyle(W3MButtonStyle(size: .s, leftIcon: .Medium.desktop))
+
+ Button(action: {}) {
+ Text("Button")
+ }
+ .buttonStyle(W3MButtonStyle(size: .s, rightIcon: .Medium.mobile, isPressedOverride: true))
+ }
+
+ HStack {
+ Button(action: {}) {
+ Text("Button")
+ }
+ .buttonStyle(W3MButtonStyle(size: .s, leftIcon: .Medium.desktop, rightIcon: .Medium.mobile))
+
+ Button(action: {}) {
+ Text("Button")
+ }
+ .buttonStyle(W3MButtonStyle(size: .s, leftIcon: .Medium.desktop, rightIcon: .Medium.mobile))
+ .disabled(true)
+
+ Button(action: {}) {
+ Text("Button")
+ }
+ .buttonStyle(W3MButtonStyle(size: .s))
+ .disabled(true)
+ }
+ }
+
+ Text("Accent")
+ .font(.large500)
+
+ VStack(alignment: .leading) {
+ HStack {
+ Button(action: {}) {
+ Text("Button")
+ }
+ .buttonStyle(W3MButtonStyle(size: .s, variant: .accent))
+
+ Button(action: {}) {
+ Text("Button")
+ }
+ .buttonStyle(W3MButtonStyle(size: .s, variant: .accent, leftIcon: .Medium.desktop))
+
+ Button(action: {}) {
+ Text("Button")
+ }
+ .buttonStyle(W3MButtonStyle(size: .s, variant: .accent, rightIcon: .Medium.mobile, isPressedOverride: true))
+ }
+
+ HStack {
+ Button(action: {}) {
+ Text("Button")
+ }
+ .buttonStyle(W3MButtonStyle(size: .s, variant: .accent, leftIcon: .Medium.desktop, rightIcon: .Medium.mobile))
+
+ Button(action: {}) {
+ Text("Button")
+ }
+ .buttonStyle(W3MButtonStyle(size: .s, variant: .accent, leftIcon: .Medium.desktop, rightIcon: .Medium.mobile))
+ .disabled(true)
+
+ Button(action: {}) {
+ Text("Button")
+ }
+ .buttonStyle(W3MButtonStyle(size: .s, variant: .accent))
+ .disabled(true)
+ }
+ }
+
+ Text("M")
+ .font(.title700)
+
+ Text("Main")
+ .font(.large500)
+
+ VStack(alignment: .leading) {
+ HStack {
+ Button(action: {}) {
+ Text("Button")
+ }
+ .buttonStyle(W3MButtonStyle())
+
+ Button(action: {}) {
+ Text("Button")
+ }
+ .buttonStyle(W3MButtonStyle(leftIcon: .Medium.desktop))
+
+ Button(action: {}) {
+ Text("Button")
+ }
+ .buttonStyle(W3MButtonStyle(rightIcon: .Medium.mobile, isPressedOverride: true))
+ }
+
+ HStack {
+ Button(action: {}) {
+ Text("Button")
+ }
+ .buttonStyle(W3MButtonStyle(leftIcon: .Medium.desktop, rightIcon: .Medium.mobile))
+
+ Button(action: {}) {
+ Text("Button")
+ }
+ .buttonStyle(W3MButtonStyle(leftIcon: .Medium.desktop, rightIcon: .Medium.mobile))
+ .disabled(true)
+
+ Button(action: {}) {
+ Text("Button")
+ }
+ .buttonStyle(W3MButtonStyle())
+ .disabled(true)
+ }
+ }
+
+ Text("Accent")
+ .font(.large500)
+
+ VStack(alignment: .leading) {
+ HStack {
+ Button(action: {}) {
+ Text("Button")
+ }
+ .buttonStyle(W3MButtonStyle(variant: .accent))
+
+ Button(action: {}) {
+ Text("Button")
+ }
+ .buttonStyle(W3MButtonStyle(variant: .accent, leftIcon: .Medium.desktop))
+
+ Button(action: {}) {
+ Text("Button")
+ }
+ .buttonStyle(W3MButtonStyle(variant: .accent, rightIcon: .Medium.mobile, isPressedOverride: true))
+ }
+
+ HStack {
+ Button(action: {}) {
+ Text("Button")
+ }
+ .buttonStyle(W3MButtonStyle(variant: .accent, leftIcon: .Medium.desktop, rightIcon: .Medium.mobile))
+
+ Button(action: {}) {
+ Text("Button")
+ }
+ .buttonStyle(W3MButtonStyle(variant: .accent, leftIcon: .Medium.desktop, rightIcon: .Medium.mobile))
+ .disabled(true)
+
+ Button(action: {}) {
+ Text("Button")
+ }
+ .buttonStyle(W3MButtonStyle(variant: .accent))
+ .disabled(true)
+ }
+ }
+ }
+ .padding()
+ .background(Color.Overgray002)
+ }
+ }
+
+ struct W3MButtonStyle_Preview: PreviewProvider {
+ static var previews: some View {
+ W3MButtonStylePreviewView()
+ }
+ }
+
+#endif
diff --git a/Sources/Web3ModalUI/Components/W3MCardSelectButtonStyle.swift b/Sources/Web3ModalUI/Components/W3MCardSelectButtonStyle.swift
new file mode 100644
index 0000000..50f1ac5
--- /dev/null
+++ b/Sources/Web3ModalUI/Components/W3MCardSelectButtonStyle.swift
@@ -0,0 +1,232 @@
+import SwiftUI
+
+public struct W3MCardSelectStyle: ButtonStyle {
+ public enum Variant {
+ case wallet
+ case network
+ }
+
+ @Environment(\.isEnabled) var isEnabled
+
+ let variant: Variant
+
+ var imageContent: () -> ImageContent
+ var isPressedOverride: Bool?
+ var isSelected: Bool
+
+ @Binding var isLoading: Bool
+
+ public init(
+ variant: Variant,
+ @ViewBuilder imageContent: @escaping () -> ImageContent,
+ isLoading: Binding = .constant(false),
+ isSelected: Bool = false
+ ) {
+ self.variant = variant
+ self.imageContent = imageContent
+ self._isLoading = isLoading
+ self.isSelected = isSelected
+ }
+
+ #if DEBUG
+ init(
+ variant: Variant,
+ @ViewBuilder imageContent: @escaping () -> ImageContent,
+ isPressedOverride: Bool? = nil,
+ isLoading: Binding,
+ isSelected: Bool = false
+ ) {
+ self.variant = variant
+ self.imageContent = imageContent
+ self.isPressedOverride = isPressedOverride
+ self._isLoading = isLoading
+ self.isSelected = isSelected
+ }
+ #endif
+
+ public func makeBody(configuration: Configuration) -> some View {
+
+ var backgroundColor: Color = (isPressedOverride ?? configuration.isPressed) ? .Overgray010 : .Overgray005
+ backgroundColor = isSelected ? Color.Blue100.opacity(0.2) : backgroundColor
+
+ var foregroundColor: Color = .Foreground100
+ foregroundColor = isSelected ? .Blue100 : foregroundColor
+
+ return VStack(spacing: Spacing.xs) {
+ imageComponent()
+
+ configuration.label
+ .font(.tiny500)
+ .foregroundColor(foregroundColor)
+ .frame(maxWidth: .infinity)
+ .opacity(isLoading ? 0 : 1)
+ .backport
+ .overlay {
+ RoundedRectangle(cornerRadius: Radius.xs)
+ .stroke(.Overgray010, lineWidth: 1)
+ .background(RoundedRectangle(cornerRadius: Radius.xs).fill(.Overgray005))
+ .opacity(isLoading ? 1 : 0)
+ }
+ .padding(.horizontal, Spacing.xs)
+ }
+ .if(isLoading) {
+ $0.modifier(ShimmerBackground())
+ }
+ .opacity(isEnabled || isSelected ? 1 : 0.5)
+ .padding(.top, Spacing.xs)
+ .padding(.bottom, Spacing.xxs)
+ .background(backgroundColor)
+ .cornerRadius(Radius.xs)
+ .frame(minWidth: 76, maxWidth: 76, minHeight: 96, maxHeight: 96)
+ }
+
+ @ViewBuilder
+ func imageComponent() -> some View {
+ imageContent()
+ .frame(width: 56, height: 56)
+ .saturation(isEnabled || isSelected ? 1 : 0)
+ .opacity(isEnabled || isSelected ? 1 : 0.5)
+ .transform {
+ switch variant {
+ case .network:
+ $0.clipShape(Polygon(count: 6, relativeCornerRadius: 0.25))
+ case .wallet:
+ $0.clipShape(RoundedRectangle(cornerRadius: Radius.xs))
+ }
+ }
+ .backport
+ .overlay {
+ switch variant {
+ case .network:
+ Polygon(count: 6, relativeCornerRadius: 0.25)
+ .stroke(isSelected ? .Blue100 : .Overgray010, lineWidth: 1)
+ .background(Polygon(count: 6, relativeCornerRadius: 0.25).fill(.Overgray005).opacity(isLoading ? 1 : 0))
+ case .wallet:
+ RoundedRectangle(cornerRadius: Radius.xs)
+ .strokeBorder(isSelected ? .Blue100 : .Overgray010, lineWidth: 1)
+ .background(RoundedRectangle(cornerRadius: Radius.xs).fill(.Overgray005).opacity(isLoading ? 1 : 0))
+ }
+ }
+ }
+}
+
+#if DEBUG
+ public struct W3MCardSelectStylePreviewView: View {
+ public init() {}
+
+ public var body: some View {
+ VStack {
+ HStack {
+ Button(action: {}, label: {
+ Text("Rainbow")
+ })
+ .buttonStyle(W3MCardSelectStyle(
+ variant: .wallet,
+ imageContent: { Image.mockWallet.resizable() },
+ isLoading: .constant(false)
+ ))
+
+ Button(action: {}, label: {
+ Text("Rainbow")
+ })
+ .buttonStyle(W3MCardSelectStyle(
+ variant: .wallet,
+ imageContent: { Image.mockWallet.resizable() },
+ isLoading: .constant(false)
+ ))
+ .disabled(true)
+
+ Button(action: {}, label: {
+ Text("Rainbow")
+ })
+ .buttonStyle(W3MCardSelectStyle(
+ variant: .wallet,
+ imageContent: { Image.mockWallet.resizable() },
+ isLoading: .constant(false),
+ isSelected: true
+ ))
+
+ Button(action: {}, label: {
+ Text("Rainbow")
+ })
+ .buttonStyle(W3MCardSelectStyle(
+ variant: .wallet,
+ imageContent: { Image.mockWallet.resizable() },
+ isPressedOverride: true,
+ isLoading: .constant(false)
+ ))
+
+ Button(action: {}, label: {
+ Text("Rainbow")
+ })
+ .buttonStyle(W3MCardSelectStyle(
+ variant: .wallet,
+ imageContent: { Color.Overgray005 },
+ isPressedOverride: false,
+ isLoading: .constant(true)
+ ))
+ }
+
+ HStack {
+ Button(action: {}, label: {
+ Text("Polygon")
+ })
+ .buttonStyle(W3MCardSelectStyle(
+ variant: .network,
+ imageContent: { Image("MockChainImage", bundle: .module).resizable() },
+ isLoading: .constant(false)
+ ))
+ Button(action: {}, label: {
+ Text("Polygon")
+ })
+ .buttonStyle(W3MCardSelectStyle(
+ variant: .network,
+ imageContent: { Image("MockChainImage", bundle: .module).resizable() },
+ isLoading: .constant(false)
+ ))
+ .disabled(true)
+
+ Button(action: {}, label: {
+ Text("Polygon")
+ })
+ .buttonStyle(W3MCardSelectStyle(
+ variant: .network,
+ imageContent: { Image("MockChainImage", bundle: .module).resizable() },
+ isLoading: .constant(false),
+ isSelected: true
+ ))
+
+ Button(action: {}, label: {
+ Text("Polygon")
+ })
+ .buttonStyle(W3MCardSelectStyle(
+ variant: .network,
+ imageContent: { Image("MockChainImage", bundle: .module).resizable() },
+ isPressedOverride: true,
+ isLoading: .constant(false)
+ ))
+
+ Button(action: {}, label: {
+ Text("Polygon")
+ })
+ .buttonStyle(W3MCardSelectStyle(
+ variant: .network,
+ imageContent: { Color.Overgray005 },
+ isPressedOverride: false,
+ isLoading: .constant(true)
+ ))
+ }
+ }
+ .padding()
+ .background(Color.Overgray002)
+ }
+ }
+
+ struct W3MCardSelect_Preview: PreviewProvider {
+ static var previews: some View {
+ W3MCardSelectStylePreviewView()
+ .previewLayout(.sizeThatFits)
+ }
+ }
+
+#endif
diff --git a/Sources/Web3ModalUI/Components/W3MChipButtonStyle.swift b/Sources/Web3ModalUI/Components/W3MChipButtonStyle.swift
new file mode 100644
index 0000000..84c8a40
--- /dev/null
+++ b/Sources/Web3ModalUI/Components/W3MChipButtonStyle.swift
@@ -0,0 +1,539 @@
+import SwiftUI
+
+public struct W3MChipButtonStyle: ButtonStyle {
+ public enum Variant {
+ case fill
+ case shade
+ case transparent
+
+ var textColor: Color {
+ switch self {
+ case .fill:
+ return Color.Inverse100
+ case .shade:
+ return Color.Foreground200
+ case .transparent:
+ return Color.Foreground150
+ }
+ }
+
+ var backgroundColor: Color {
+ switch self {
+ case .fill:
+ return Color.Blue100
+ case .shade:
+ return Color.GrayGlass010
+ case .transparent:
+ return Color.clear
+ }
+ }
+
+ var pressedColor: Color {
+ switch self {
+ case .fill:
+ return Color.Blue080
+ case .shade:
+ return Color.GrayGlass020
+ case .transparent:
+ return Color.GrayGlass010
+ }
+ }
+ }
+
+ public enum Size {
+ case s, m
+ }
+
+ @Environment(\.isEnabled) var isEnabled
+
+ let variant: Variant
+ let size: Size
+ var leadingImage: () -> LeadingImageContent
+ var trailingImage: () -> TrailingImageContent
+
+ var isPressedOverride: Bool?
+
+ public init(
+ variant: Variant = .fill,
+ size: Size = .m,
+ @ViewBuilder leadingImage: @escaping () -> LeadingImageContent,
+ @ViewBuilder trailingImage: @escaping () -> TrailingImageContent
+ ) {
+ self.variant = variant
+ self.size = size
+ self.leadingImage = leadingImage
+ self.trailingImage = trailingImage
+ }
+
+ fileprivate init(
+ variant: Variant,
+ size: Size = .m,
+ @ViewBuilder leadingImage: @escaping () -> LeadingImageContent,
+ @ViewBuilder trailingImage: @escaping () -> TrailingImageContent,
+ isPressedOverride: Bool?
+ ) {
+ self.variant = variant
+ self.size = size
+ self.leadingImage = leadingImage
+ self.trailingImage = trailingImage
+ self.isPressedOverride = isPressedOverride
+ }
+
+ public func makeBody(configuration: Configuration) -> some View {
+ var textColor: Color = variant.textColor
+ textColor = isEnabled ? textColor : .Overgray015
+
+ var backgroundColor: Color = variant.backgroundColor
+ let pressedColor: Color = variant.pressedColor
+ backgroundColor = (isPressedOverride ?? configuration.isPressed) ? pressedColor : backgroundColor
+ backgroundColor = isEnabled ? backgroundColor : .Overgray010
+
+ let verticalPadding = size == .m ? Spacing.xxs : Spacing.xxs
+ let horizontalPadding = size == .m ? Spacing.m : Spacing.s
+ let leadingPadding = horizontalPadding - (LeadingImageContent.self == EmptyView.self ? 0 : Spacing.xxxs)
+ let trailingPadding = horizontalPadding - (TrailingImageContent.self == EmptyView.self ? 0 : Spacing.xxxs)
+
+ return HStack(spacing: size == .m ? Spacing.xxs : Spacing.xxxs) {
+ leadingImage()
+ .clipShape(Circle())
+ .saturation(isEnabled ? 1 : 0)
+ .opacity(isEnabled ? 1 : 0.5)
+ .frame(width: size == .m ? 24 : 16, height: size == .m ? 24 : 16)
+
+ configuration
+ .label
+ .font(.paragraph600)
+ .lineLimit(1)
+
+ trailingImage()
+ .saturation(isEnabled ? 1 : 0)
+ .opacity(isEnabled ? 1 : 0.5)
+ .frame(width: size == .m ? 14 : 12, height: size == .m ? 14 : 12)
+ }
+ .foregroundColor(textColor)
+ .padding(.vertical, verticalPadding)
+ .padding(.leading, leadingPadding)
+ .padding(.trailing, trailingPadding)
+ .frame(minHeight: size == .m ? 36 : 32)
+ .background(backgroundColor)
+ .cornerRadius(Radius.m)
+ .overlay(
+ RoundedRectangle(cornerRadius: Radius.m)
+ .stroke(Color.Overgray010, lineWidth: 1)
+ )
+ }
+}
+
+public extension W3MChipButtonStyle where LeadingImageContent == EmptyView, TrailingImageContent == EmptyView {
+ init(
+ variant: Variant = .fill,
+ size: Size = .m
+ ) {
+ self.variant = variant
+ self.size = size
+ self.leadingImage = { EmptyView() }
+ self.trailingImage = { EmptyView() }
+ }
+}
+
+public extension W3MChipButtonStyle where LeadingImageContent == EmptyView {
+ init(
+ variant: Variant = .fill,
+ size: Size = .m,
+ @ViewBuilder trailingImage: @escaping () -> TrailingImageContent
+ ) {
+ self.variant = variant
+ self.size = size
+ self.leadingImage = { EmptyView() }
+ self.trailingImage = trailingImage
+ }
+}
+
+public extension W3MChipButtonStyle where TrailingImageContent == EmptyView {
+ init(
+ variant: Variant = .fill,
+ size: Size = .m,
+ @ViewBuilder leadingImage: @escaping () -> LeadingImageContent
+ ) {
+ self.variant = variant
+ self.size = size
+ self.leadingImage = leadingImage
+ self.trailingImage = { EmptyView() }
+ }
+}
+
+#if DEBUG
+ public struct W3MChipButtonStylePreviewView: View {
+ public init() {}
+
+ public var body: some View {
+ ScrollView([.horizontal, .vertical]) {
+ VStack(alignment: .leading, spacing: 15) {
+ Group {
+ Text("Fill")
+ .font(.large600)
+
+ HStack {
+ Button(action: {}) {
+ Text("Button")
+ }
+ .buttonStyle(
+ W3MChipButtonStyle()
+ )
+
+ Button(action: {}) {
+ Text("Button")
+ }
+ .buttonStyle(
+ W3MChipButtonStyle(leadingImage: { Image.imageEth.resizable() })
+ )
+
+ Button(action: {}) {
+ Text("Button")
+ }
+ .buttonStyle(
+ W3MChipButtonStyle(
+ variant: .fill,
+ leadingImage: { Image.imageEth.resizable() },
+ trailingImage: { Image.Medium.externalLink.resizable() },
+ isPressedOverride: nil
+ )
+ )
+
+ Button(action: {}) {
+ Text("Button")
+ }
+ .buttonStyle(
+ W3MChipButtonStyle(
+ variant: .fill,
+ leadingImage: { Image.imageEth.resizable() },
+ trailingImage: { Image.Medium.externalLink.resizable() },
+ isPressedOverride: true
+ )
+ )
+
+ Button(action: {}) {
+ Text("Button")
+ }
+ .buttonStyle(
+ W3MChipButtonStyle(
+ variant: .fill,
+ leadingImage: { Image.imageEth.resizable() },
+ trailingImage: { Image.Medium.externalLink.resizable() },
+ isPressedOverride: nil
+ )
+ )
+ .disabled(true)
+ }
+
+ Text("Shade")
+ .font(.large600)
+
+ HStack {
+ Button(action: {}) {
+ Text("Button")
+ }
+ .buttonStyle(
+ W3MChipButtonStyle(variant: .shade)
+ )
+
+ Button(action: {}) {
+ Text("Button")
+ }
+ .buttonStyle(
+ W3MChipButtonStyle(variant: .shade, leadingImage: { Image.imageEth.resizable() })
+ )
+
+ Button(action: {}) {
+ Text("Button")
+ }
+ .buttonStyle(
+ W3MChipButtonStyle(
+ variant: .shade,
+ leadingImage: { Image.imageEth.resizable() },
+ trailingImage: { Image.Medium.externalLink.resizable() },
+ isPressedOverride: nil
+ )
+ )
+
+ Button(action: {}) {
+ Text("Button")
+ }
+ .buttonStyle(
+ W3MChipButtonStyle(
+ variant: .shade,
+ leadingImage: { Image.imageEth.resizable() },
+ trailingImage: { Image.Medium.externalLink.resizable() },
+ isPressedOverride: true
+ )
+ )
+
+ Button(action: {}) {
+ Text("Button")
+ }
+ .buttonStyle(
+ W3MChipButtonStyle(
+ variant: .shade,
+ leadingImage: { Image.imageEth.resizable() },
+ trailingImage: { Image.Medium.externalLink.resizable() },
+ isPressedOverride: nil
+ )
+ )
+ .disabled(true)
+ }
+
+ Text("Transparent")
+ .font(.large600)
+
+ HStack {
+
+ Button(action: {}) {
+ Text("Button")
+ }
+ .buttonStyle(
+ W3MChipButtonStyle(variant: .transparent)
+ )
+
+ Button(action: {}) {
+ Text("Button")
+ }
+ .buttonStyle(
+ W3MChipButtonStyle(variant: .transparent, leadingImage: { Image.imageEth.resizable() })
+ )
+
+ Button(action: {}) {
+ Text("Button")
+ }
+ .buttonStyle(
+ W3MChipButtonStyle(
+ variant: .transparent,
+ leadingImage: { Image.imageEth.resizable() },
+ trailingImage: { Image.Medium.externalLink.resizable() },
+ isPressedOverride: nil
+ )
+ )
+
+ Button(action: {}) {
+ Text("Button")
+ }
+ .buttonStyle(
+ W3MChipButtonStyle(
+ variant: .transparent,
+ leadingImage: { Image.imageEth.resizable() },
+ trailingImage: { Image.Medium.externalLink.resizable() },
+ isPressedOverride: true
+ )
+ )
+
+ Button(action: {}) {
+ Text("Button")
+ }
+ .buttonStyle(
+ W3MChipButtonStyle(
+ variant: .transparent,
+ leadingImage: { Image.imageEth.resizable() },
+ trailingImage: { Image.Medium.externalLink.resizable() },
+ isPressedOverride: nil
+ )
+ )
+ .disabled(true)
+ }
+ }
+
+ Divider()
+ .padding(.vertical, 24)
+
+ Group {
+
+ Text("Fill S")
+ .font(.large600)
+
+ HStack {
+ Button(action: {}) {
+ Text("Button")
+ }
+ .buttonStyle(
+ W3MChipButtonStyle(size: .s)
+ )
+
+ Button(action: {}) {
+ Text("Button")
+ }
+ .buttonStyle(
+ W3MChipButtonStyle(size: .s, leadingImage: { Image.imageEth.resizable() })
+ )
+
+ Button(action: {}) {
+ Text("Button")
+ }
+ .buttonStyle(
+ W3MChipButtonStyle(
+ variant: .fill,
+ size: .s,
+ leadingImage: { Image.imageEth.resizable() },
+ trailingImage: { Image.Medium.externalLink.resizable() },
+ isPressedOverride: nil
+ )
+ )
+
+ Button(action: {}) {
+ Text("Button")
+ }
+ .buttonStyle(
+ W3MChipButtonStyle(
+ variant: .fill,
+ size: .s,
+ leadingImage: { Image.imageEth.resizable() },
+ trailingImage: { Image.Medium.externalLink.resizable() },
+ isPressedOverride: true
+ )
+ )
+
+ Button(action: {}) {
+ Text("Button")
+ }
+ .buttonStyle(
+ W3MChipButtonStyle(
+ variant: .fill,
+ size: .s,
+ leadingImage: { Image.imageEth.resizable() },
+ trailingImage: { Image.Medium.externalLink.resizable() },
+ isPressedOverride: nil
+ )
+ )
+ .disabled(true)
+ }
+
+ Text("Shade S")
+ .font(.large600)
+
+ HStack {
+
+ Button(action: {}) {
+ Text("Button")
+ }
+ .buttonStyle(
+ W3MChipButtonStyle(variant: .shade, size: .s)
+ )
+
+ Button(action: {}) {
+ Text("Button")
+ }
+ .buttonStyle(
+ W3MChipButtonStyle(variant: .shade, size: .s, leadingImage: { Image.imageEth.resizable() })
+ )
+
+ Button(action: {}) {
+ Text("Button")
+ }
+ .buttonStyle(
+ W3MChipButtonStyle(
+ variant: .shade,
+ size: .s,
+ leadingImage: { Image.imageEth.resizable() },
+ trailingImage: { Image.Medium.externalLink.resizable() },
+ isPressedOverride: nil
+ )
+ )
+
+ Button(action: {}) {
+ Text("Button")
+ }
+ .buttonStyle(
+ W3MChipButtonStyle(
+ variant: .shade,
+ size: .s,
+ leadingImage: { Image.imageEth.resizable() },
+ trailingImage: { Image.Medium.externalLink.resizable() },
+ isPressedOverride: true
+ )
+ )
+
+ Button(action: {}) {
+ Text("Button")
+ }
+ .buttonStyle(
+ W3MChipButtonStyle(
+ variant: .shade,
+ size: .s,
+ leadingImage: { Image.imageEth.resizable() },
+ trailingImage: { Image.Medium.externalLink.resizable() },
+ isPressedOverride: nil
+ )
+ )
+ .disabled(true)
+ }
+
+ Text("Transparent S")
+ .font(.large600)
+
+ HStack {
+ Button(action: {}) {
+ Text("Button")
+ }
+ .buttonStyle(
+ W3MChipButtonStyle(variant: .transparent, size: .s)
+ )
+
+ Button(action: {}) {
+ Text("Button")
+ }
+ .buttonStyle(
+ W3MChipButtonStyle(variant: .transparent, size: .s, leadingImage: { Image.imageEth.resizable() })
+ )
+
+ Button(action: {}) {
+ Text("Button")
+ }
+ .buttonStyle(
+ W3MChipButtonStyle(
+ variant: .transparent,
+ size: .s,
+ leadingImage: { Image.imageEth.resizable() },
+ trailingImage: { Image.Medium.externalLink.resizable() },
+ isPressedOverride: nil
+ )
+ )
+
+ Button(action: {}) {
+ Text("Button")
+ }
+ .buttonStyle(
+ W3MChipButtonStyle(
+ variant: .transparent,
+ size: .s,
+ leadingImage: { Image.imageEth.resizable() },
+ trailingImage: { Image.Medium.externalLink.resizable() },
+ isPressedOverride: true
+ )
+ )
+
+ Button(action: {}) {
+ Text("Button")
+ }
+ .buttonStyle(
+ W3MChipButtonStyle(
+ variant: .transparent,
+ size: .s,
+ leadingImage: { Image.imageEth.resizable() },
+ trailingImage: { Image.Medium.externalLink.resizable() },
+ isPressedOverride: nil
+ )
+ )
+ .disabled(true)
+ }
+ }
+ }
+ .padding()
+ .background(Color.Overgray002)
+ }
+ }
+ }
+
+ struct W3MChipButtonStyle_Preview: PreviewProvider {
+ static var previews: some View {
+ W3MChipButtonStylePreviewView()
+ }
+ }
+
+#endif
diff --git a/Sources/Web3ModalUI/Components/W3MListItemButtonStyle.swift b/Sources/Web3ModalUI/Components/W3MListItemButtonStyle.swift
new file mode 100644
index 0000000..953d421
--- /dev/null
+++ b/Sources/Web3ModalUI/Components/W3MListItemButtonStyle.swift
@@ -0,0 +1,224 @@
+import SwiftUI
+
+public struct W3MListItemButtonStyle: ButtonStyle {
+ @Environment(\.sizeCategory) var sizeCategory
+ @Environment(\.isEnabled) var isEnabled
+
+ @Backport.ScaledMetric var scale: CGFloat = 1
+
+ var imageContent: () -> ImageContent
+ var showChevron: Bool = false
+ @Binding var isLoading: Bool
+
+ var isPressedOverride: Bool?
+
+ #if DEBUG
+ init(
+ @ViewBuilder imageContent: @escaping () -> ImageContent,
+ showChevron: Bool,
+ isLoading: Binding,
+ isPressedOverride: Bool? = nil
+ ) {
+ self.imageContent = imageContent
+ _isLoading = isLoading
+ self.showChevron = showChevron
+ self.isPressedOverride = isPressedOverride
+ }
+ #endif
+
+ public func makeBody(configuration: Configuration) -> some View {
+ AdaptiveStack(
+ condition: sizeCategory >= .accessibilityMedium,
+ horizontalAlignment: .center,
+ spacing: Spacing.s
+
+ ) {
+ imageComponent()
+
+ configuration.label
+
+ if !(sizeCategory >= .accessibilityMedium) {
+ Spacer()
+ }
+
+ Group {
+ if isLoading {
+ DrawingProgressView(
+ shape: .circle,
+ color: .Blue100,
+ lineWidth: 2 * scale,
+ duration: 1,
+ isAnimating: $isLoading
+ )
+ .frame(width: 15 * scale, height: 15 * scale)
+ } else if showChevron {
+ Image(systemName: "chevron.right")
+ .foregroundColor(.Foreground200)
+ }
+
+ }
+ }
+ .font(.paragraph600)
+ .foregroundColor(.Foreground100)
+ .frame(maxWidth: .infinity)
+ .frame(minHeight: 56)
+ .opacity(isEnabled ? 1 : 0.5)
+ .padding(.vertical, Spacing.xs * scale)
+ .padding(.leading, Spacing.s * scale)
+ .padding(.trailing, Spacing.l * scale)
+ .backport
+ .background { (isPressedOverride ?? configuration.isPressed) ? Color.Overgray010 : Color.Overgray005 }
+ .cornerRadius(Radius.s * scale)
+ .allowsHitTesting(!isLoading)
+ }
+
+ @ViewBuilder
+ func imageComponent() -> some View {
+ imageContent()
+ .frame(maxWidth: 32 * scale, maxHeight: 32 * scale)
+ .aspectRatio(contentMode: .fit)
+ .saturation(isEnabled ? 1 : 0)
+ .opacity(isEnabled ? 1 : 0.5)
+ .cornerRadius(Radius.xxxs * scale)
+ }
+}
+
+#if DEBUG
+ public struct W3MListItemButtonStylePreviewView: View {
+
+ @Environment(\.sizeCategory) var sizeCategory
+
+ public init() {}
+
+ public var body: some View {
+ ScrollView {
+ VStack {
+ Button(action: {}, label: {
+ AdaptiveStack(condition: sizeCategory >= .accessibilityMedium, spacing: 5) {
+ Text("0.527 ETH")
+
+ Text("607.38 USD")
+ .foregroundColor(.Foreground200)
+ }
+ })
+ .buttonStyle(W3MListItemButtonStyle(
+ imageContent: {
+ Image.imageEth
+ .resizable()
+ .clipShape(Circle())
+ },
+ showChevron: true,
+ isLoading: .constant(false),
+ isPressedOverride: nil
+ ))
+
+ Button(action: {}, label: {
+ AdaptiveStack(condition: sizeCategory >= .accessibilityMedium, spacing: 5) {
+ Text("W/ CHEVRON")
+
+ Text("607.38 USD")
+ .foregroundColor(.Foreground200)
+ }
+ })
+ .buttonStyle(W3MListItemButtonStyle(
+ imageContent: {
+ Image.imageEth
+ .resizable()
+ .clipShape(Circle())
+ },
+ showChevron: true,
+ isLoading: .constant(false),
+ isPressedOverride: nil
+ ))
+
+ Button(action: {}, label: {
+ HStack(spacing: 5) {
+ Text("W/O CHEVRON")
+
+ Text("607.38 USD")
+ .foregroundColor(.Foreground200)
+ }
+ })
+ .buttonStyle(W3MListItemButtonStyle(
+ imageContent: {
+ Image.imageEth
+ .resizable()
+ .clipShape(Circle())
+ },
+ showChevron: false,
+ isLoading: .constant(false),
+ isPressedOverride: nil
+ ))
+
+ Button(action: {}, label: {
+ HStack(spacing: 5) {
+ Text("LOADING")
+
+ Text("607.38 USD")
+ .foregroundColor(.Foreground200)
+ }
+ })
+ .buttonStyle(W3MListItemButtonStyle(
+ imageContent: {
+ Image.imageEth
+ .resizable()
+ .clipShape(Circle())
+ },
+ showChevron: true,
+ isLoading: .constant(true),
+ isPressedOverride: nil
+ ))
+
+ Button(action: {}, label: {
+ HStack(spacing: 5) {
+ Text("DISABLED")
+
+ Text("607.38 USD")
+ .foregroundColor(.Foreground200)
+ }
+ })
+ .buttonStyle(W3MListItemButtonStyle(
+ imageContent: {
+ Image.imageEth
+ .resizable()
+ .clipShape(Circle())
+ },
+ showChevron: true,
+ isLoading: .constant(false),
+ isPressedOverride: nil
+ ))
+ .disabled(true)
+
+ Button(action: {}, label: {
+ HStack(spacing: 5) {
+ Text("PRESSED")
+
+ Text("607.38 USD")
+ .foregroundColor(.Foreground200)
+ }
+ })
+ .buttonStyle(W3MListItemButtonStyle(
+ imageContent: {
+ Image.imageEth
+ .resizable()
+ .clipShape(Circle())
+ },
+ showChevron: true,
+ isLoading: .constant(false),
+ isPressedOverride: true
+ ))
+ }
+ .padding()
+ .background(Color.Overgray002)
+ }
+ }
+ }
+
+ struct W3MListItem_Preview: PreviewProvider {
+ static var previews: some View {
+ W3MListItemButtonStylePreviewView()
+ .previewLayout(.sizeThatFits)
+ }
+ }
+
+#endif
diff --git a/Sources/Web3ModalUI/Components/W3MListSelectButtonStyle.swift b/Sources/Web3ModalUI/Components/W3MListSelectButtonStyle.swift
new file mode 100644
index 0000000..6b38822
--- /dev/null
+++ b/Sources/Web3ModalUI/Components/W3MListSelectButtonStyle.swift
@@ -0,0 +1,183 @@
+import SwiftUI
+
+public struct W3MListSelectStyle: ButtonStyle {
+ @Environment(\.isEnabled) var isEnabled
+ @Environment(\.sizeCategory) var sizeCategory
+
+ @Backport.ScaledMetric var scale: CGFloat = 1
+
+ var imageContent: (CGFloat) -> ImageContent
+ var tag: W3MTag?
+ var showChevron: Bool
+
+ var isPressedOverride: Bool?
+
+ public init(
+ @ViewBuilder imageContent: @escaping (CGFloat) -> ImageContent,
+ tag: W3MTag? = nil,
+ showChevron: Bool = false
+ ) {
+ self.imageContent = imageContent
+ self.tag = tag
+ self.showChevron = showChevron
+ }
+
+ #if DEBUG
+ init(
+ @ViewBuilder imageContent: @escaping (CGFloat) -> ImageContent,
+ tag: W3MTag? = nil,
+ isPressedOverride: Bool? = nil,
+ showChevron: Bool = false
+ ) {
+ self.imageContent = imageContent
+ self.tag = tag
+ self.isPressedOverride = isPressedOverride
+ self.showChevron = showChevron
+ }
+ #endif
+
+ public func makeBody(configuration: Configuration) -> some View {
+ let layoutBreakCondition = sizeCategory >= .accessibilityMedium
+
+ AdaptiveStack(
+ condition: layoutBreakCondition,
+ horizontalAlignment: .center,
+ spacing: 10 * scale
+ ) {
+ Group {
+ imageComponent()
+ .scaledToFill()
+ .foregroundColor(.Foreground100)
+ .layoutPriority(3)
+
+ configuration.label
+ .lineLimit(1)
+ .scaledToFill()
+ .font(.paragraph500)
+ .foregroundColor(.Foreground100)
+ .layoutPriority(5)
+
+ if !layoutBreakCondition {
+ Spacer()
+ }
+
+ if let tag {
+ tag
+ .saturation(isEnabled ? 1 : 0)
+ .layoutPriority(3)
+ } else if showChevron {
+ Image.Bold.chevronRight
+ .foregroundColor(.Foreground200)
+ } else if !layoutBreakCondition {
+ Spacer()
+ .layoutPriority(3)
+ }
+ }
+ }
+ .frame(maxWidth: .infinity)
+ .opacity(isEnabled ? 1 : 0.5)
+ .padding(.vertical, Spacing.xs * scale)
+ .padding(.leading, Spacing.xs * scale)
+ .padding(.trailing, Spacing.l * scale)
+ .backport
+ .background { (isPressedOverride ?? configuration.isPressed) ? Color.Overgray010 : Color.Overgray002 }
+ .cornerRadius(Radius.xs * scale)
+ }
+
+ @ViewBuilder
+ func imageComponent() -> some View {
+ imageContent(scale)
+ .frame(maxWidth: 40 * scale, maxHeight: 40 * scale)
+ .aspectRatio(contentMode: .fit)
+ .saturation(isEnabled ? 1 : 0)
+ .opacity(isEnabled ? 1 : 0.5)
+ .cornerRadius(Radius.xxs * scale)
+ }
+}
+
+#if DEBUG
+ public struct W3MListSelectStylePreviewView: View {
+ public init() {}
+
+ public var body: some View {
+ ScrollView {
+ VStack {
+ Button(action: {}, label: {
+ Text("Rainbow")
+ })
+ .buttonStyle(W3MListSelectStyle(
+ imageContent: { _ in Image.mockWallet.resizable() },
+ tag: W3MTag(title: "QR CODE", variant: .main)
+ ))
+
+ Button(action: {}, label: {
+ Text("Rainbow")
+ })
+ .buttonStyle(W3MListSelectStyle(
+ imageContent: { scale in
+ ZStack {
+ Color.Overgray005
+ RoundedRectangle(cornerRadius: Radius.xxxs * scale).stroke(.Overgray010, lineWidth: 1 * scale)
+ Image.Medium.wallet
+ }
+ },
+ tag: W3MTag(title: "INSTALLED", variant: .success),
+ isPressedOverride: true
+ ))
+
+ Button(action: {}, label: {
+ Text("Rainbow")
+ })
+ .buttonStyle(W3MListSelectStyle(
+ imageContent: { _ in Image.mockWallet.resizable() }
+ ))
+
+ Button(action: {}, label: {
+ Text("All wallets")
+ })
+ .buttonStyle(W3MListSelectStyle(
+ imageContent: { _ in
+ Image.optionAll
+ }
+ ))
+
+ Button(action: {}, label: {
+ Text("Rainbow")
+ })
+ .buttonStyle(W3MListSelectStyle(
+ imageContent: { _ in Image.mockWallet.resizable() },
+ tag: W3MTag(title: "QR CODE", variant: .main)
+ ))
+ .disabled(true)
+
+ Button(action: {}, label: {
+ Text("Rainbow")
+ })
+ .buttonStyle(W3MListSelectStyle(
+ imageContent: { _ in Image.mockWallet.resizable() },
+ showChevron: true
+ ))
+
+ Button(action: {}, label: {
+ Text("Rainbow")
+ })
+ .buttonStyle(W3MListSelectStyle(
+ imageContent: { _ in Image.mockWallet.resizable() },
+ showChevron: true
+ ))
+ .disabled(true)
+ }
+ .padding()
+ .background(Color.Overgray002)
+ }
+ }
+ }
+
+ struct W3MListSelect_Preview: PreviewProvider {
+ static var previews: some View {
+ W3MListSelectStylePreviewView()
+ .previewLayout(.sizeThatFits)
+ }
+ }
+
+#endif
diff --git a/Sources/Web3ModalUI/Components/W3MPicker.swift b/Sources/Web3ModalUI/Components/W3MPicker.swift
new file mode 100644
index 0000000..845b93e
--- /dev/null
+++ b/Sources/Web3ModalUI/Components/W3MPicker.swift
@@ -0,0 +1,87 @@
+import SwiftUI
+
+public struct W3MPicker: View where Data: Hashable, Content: View {
+ let sources: [Data]
+ let selection: Data?
+ let itemBuilder: (Data) -> Content
+
+ private var customIndicator: AnyView?
+
+ public init(
+ _ sources: [Data],
+ selection: Data?,
+ @ViewBuilder itemBuilder: @escaping (Data) -> Content
+ ) {
+ self.sources = sources
+ self.selection = selection
+ self.itemBuilder = itemBuilder
+ }
+
+ public var body: some View {
+ ZStack(alignment: .center) {
+ if let selection = selection, let selectedIdx = sources.firstIndex(of: selection) {
+
+ GeometryReader { geo in
+ RoundedRectangle(cornerRadius: Radius.s)
+ .fill(.GrayGlass002, strokeBorder: .GrayGlass002, lineWidth: 1)
+ .frame(width: geo.size.width / CGFloat(sources.count))
+ .animation(.spring().speed(1.5), value: selection)
+ .offset(x: geo.size.width / CGFloat(sources.count) * CGFloat(selectedIdx), y: 0)
+ }.frame(height: 28)
+ }
+
+ HStack(spacing: 0) {
+ ForEach(sources, id: \.self) { item in
+ itemBuilder(item)
+ }
+ }
+ }
+ .background(
+ RoundedRectangle(cornerRadius: Radius.s)
+ .fill(.GrayGlass002)
+ .padding(-3)
+ )
+ }
+}
+
+struct PreviewWeb3ModalPicker: View {
+
+ enum Platform: String, CaseIterable {
+ case native
+ case browser
+ }
+
+ @State private var selectedItem: Platform? = .native
+
+ var body: some View {
+ W3MPicker(
+ Platform.allCases,
+ selection: selectedItem
+ ) { item in
+
+ HStack {
+ item == .native ? Image.Bold.mobile : Image.Bold.browser
+ Text(item.rawValue.capitalized)
+ }
+ .font(.small600)
+ .multilineTextAlignment(.center)
+ .foregroundColor(selectedItem == item ? .Foreground100 : .Foreground200)
+ .frame(maxWidth: .infinity)
+ .contentShape(Rectangle())
+ .onTapGesture {
+ withAnimation(.easeInOut(duration: 0.15)) {
+ selectedItem = item
+ }
+ }
+ }
+ .accentColor(Color.Overgray005)
+ .frame(maxWidth: 200)
+ .padding()
+ }
+}
+
+struct Web3ModalPicker_Previews: PreviewProvider {
+ static var previews: some View {
+ PreviewWeb3ModalPicker()
+ }
+}
diff --git a/Sources/Web3ModalUI/Components/W3MTag.swift b/Sources/Web3ModalUI/Components/W3MTag.swift
new file mode 100644
index 0000000..1f7b04a
--- /dev/null
+++ b/Sources/Web3ModalUI/Components/W3MTag.swift
@@ -0,0 +1,99 @@
+import SwiftUI
+
+public struct W3MTag: View {
+ public enum Variant: String, CaseIterable, Identifiable {
+ case main = "MAIN"
+ case info = "INFO"
+ case success = "SUCCESS"
+ case error = "ERROR"
+ case inProgress = "IN PROGRESS"
+ case warning = "WARNING"
+ case disabled = "DISABLED"
+
+ var backgroundColor: Color {
+ switch self {
+ case .main:
+ return Color.Overblue015
+ case .info:
+ return Color.Overgray010
+ case .success:
+ return Color.Success100.opacity(0.15)
+ case .error:
+ return Color.Error100.opacity(0.15)
+ case .inProgress:
+ return Color(red: 0.84, green: 0.85, blue: 0.09).opacity(0.15)
+ case .warning:
+ return Color.Orange100.opacity(0.15)
+ case .disabled:
+ return Color.Overgray015.opacity(0.15)
+ }
+ }
+
+ var textColor: Color {
+ switch self {
+ case .main:
+ return Color.Blue100
+ case .info:
+ return Color.Foreground150
+ case .success:
+ return Color.Success100
+ case .error:
+ return Color.Error100
+ case .inProgress:
+ return Color(red: 0.84, green: 0.85, blue: 0.09)
+ case .warning:
+ return Color.Orange100
+ case .disabled:
+ return Color.Overgray015
+ }
+ }
+
+ public var id: Self {
+ return self
+ }
+ }
+
+ let title: String
+ let variant: Variant
+
+ @Backport.ScaledMetric var scale: CGFloat = 1
+
+ public init(title: String, variant: Variant) {
+ self.title = title
+ self.variant = variant
+ }
+
+ public var body: some View {
+ Text(title)
+ .font(.micro700)
+ .lineLimit(1)
+ .foregroundColor(variant.textColor)
+ .padding(Spacing.xxxs * scale)
+ .background(variant.backgroundColor)
+ .cornerRadius(Radius.xxxxxs * scale)
+ }
+}
+
+#if DEBUG
+ public struct W3MTagPreviewView: View {
+ public init() {}
+
+ public var body: some View {
+ VStack {
+ ForEach(W3MTag.Variant.allCases) {
+ W3MTag(title: $0.rawValue, variant: $0)
+ }
+ }
+ .padding()
+ .background(Color.Overgray002)
+ }
+ }
+
+ struct W3MTag_Preview: PreviewProvider {
+ static var previews: some View {
+ W3MTagPreviewView()
+ .previewLayout(.sizeThatFits)
+ }
+ }
+
+#endif
diff --git a/Sources/Web3ModalUI/Components/W3MTextField.swift b/Sources/Web3ModalUI/Components/W3MTextField.swift
new file mode 100644
index 0000000..945d97d
--- /dev/null
+++ b/Sources/Web3ModalUI/Components/W3MTextField.swift
@@ -0,0 +1,86 @@
+import SwiftUI
+
+public struct W3MTextField: View {
+ var titleKey: LocalizedStringKey
+ @Binding var text: String
+
+ /// Whether the user is focused on this `TextField`.
+ @State var isEditing: Bool = false
+
+ public init(
+ _ titleKey: LocalizedStringKey,
+ text: Binding
+ ) {
+ self.titleKey = titleKey
+ self._text = text
+ }
+
+ public var body: some View {
+ TextField(self.titleKey, text: self.$text, onEditingChanged: { self.isEditing = $0 })
+ .padding(.horizontal, Spacing.xxl)
+ .padding(.vertical, Spacing.xxxxs)
+ .backport.overlay(alignment: .leading) {
+ Image.Medium.magnifier
+ .foregroundColor(.Foreground275)
+ }
+ .backport.overlay(alignment: .trailing) {
+ if !self.text.isEmpty {
+ Button(action: {
+ self.text = ""
+ }) {
+ ZStack {
+ RoundedRectangle(cornerRadius: Radius.xxxxs)
+ .fill(.GrayGlass020)
+ .frame(width: 18, height: 18)
+ .padding(.vertical, Spacing.xxxs)
+
+ Image.Medium.xMark
+ .resizable()
+ .frame(width: 10, height: 10)
+ .foregroundColor(.Background250)
+ .blendMode(.destinationOut)
+ }
+ .compositingGroup()
+ }
+ }
+ }
+ .foregroundColor(.Foreground100)
+ .font(.paragraph500)
+ .padding(.vertical, Spacing.xs)
+ .padding(.horizontal, Spacing.s)
+ .background(
+ RoundedRectangle(cornerRadius: Radius.xxs)
+ .fill(self.isEditing ? .GrayGlass010 : .GrayGlass005)
+ )
+ .background(
+ RoundedRectangle(cornerRadius: Radius.xxs)
+ .stroke(.GrayGlass005, lineWidth: 1)
+ )
+ .backport.background {
+ if self.isEditing {
+ ZStack {
+ RoundedRectangle(cornerRadius: Radius.xxs)
+ .fill(Color(red: 0.2, green: 0.59, blue: 1).opacity(0.2))
+
+ RoundedRectangle(cornerRadius: Radius.xxs)
+ .inset(by: 4)
+ .blendMode(.destinationOut)
+
+ RoundedRectangle(cornerRadius: Radius.xxs)
+ .inset(by: 4)
+ .stroke(Color.Blue100, lineWidth: 1)
+ }
+ .compositingGroup()
+ }
+ }
+ }
+}
+
+struct W3MTextFieldStylePreview: PreviewProvider {
+ static var previews: some View {
+ VStack {
+ W3MTextField("FOoo", text: .constant(""))
+ }
+ .padding()
+ }
+}
diff --git a/Sources/Web3ModalUI/Helpers/Bundle.swift b/Sources/Web3ModalUI/Helpers/Bundle.swift
new file mode 100644
index 0000000..6262ba0
--- /dev/null
+++ b/Sources/Web3ModalUI/Helpers/Bundle.swift
@@ -0,0 +1,15 @@
+import Foundation
+
+
+#if CocoaPods
+public extension Foundation.Bundle {
+ private class CocoapodsBundle {}
+
+ static var module: Bundle {
+ let bundle = Bundle(for: CocoapodsBundle.self)
+ let frameworkBundlePath = bundle.path(forResource: "Web3ModalUI", ofType: "bundle")!
+ return Bundle(path: frameworkBundlePath) ?? bundle
+ }
+}
+
+#endif
diff --git a/Sources/Web3ModalUI/Helpers/Extensions/Color+extension.swift b/Sources/Web3ModalUI/Helpers/Extensions/Color+extension.swift
new file mode 100644
index 0000000..12d4291
--- /dev/null
+++ b/Sources/Web3ModalUI/Helpers/Extensions/Color+extension.swift
@@ -0,0 +1,66 @@
+import SwiftUI
+
+public extension ShapeStyle where Self == Color {
+ static var Background100: Color { Color(#function, bundle: .module) }
+ static var Background125: Color { Color(#function, bundle: .module) }
+ static var Background150: Color { Color(#function, bundle: .module) }
+ static var Background175: Color { Color(#function, bundle: .module) }
+ static var Background200: Color { Color(#function, bundle: .module) }
+ static var Background225: Color { Color(#function, bundle: .module) }
+ static var Background250: Color { Color(#function, bundle: .module) }
+ static var Background275: Color { Color(#function, bundle: .module) }
+ static var Background300: Color { Color(#function, bundle: .module) }
+ static var BlackAndWhite100: Color { Color(#function, bundle: .module) }
+ static var Blue080: Color { Color(#function, bundle: .module) }
+ static var Blue090: Color { Color(#function, bundle: .module) }
+ static var Blue100: Color { Color(#function, bundle: .module) }
+ static var Error100: Color { Color(#function, bundle: .module) }
+ static var Foreground100: Color { Color(#function, bundle: .module) }
+ static var Foreground125: Color { Color(#function, bundle: .module) }
+ static var Foreground150: Color { Color(#function, bundle: .module) }
+ static var Foreground175: Color { Color(#function, bundle: .module) }
+ static var Foreground200: Color { Color(#function, bundle: .module) }
+ static var Foreground225: Color { Color(#function, bundle: .module) }
+ static var Foreground250: Color { Color(#function, bundle: .module) }
+ static var Foreground275: Color { Color(#function, bundle: .module) }
+ static var Foreground300: Color { Color(#function, bundle: .module) }
+ static var Glass75: Color { Color(#function, bundle: .module) }
+ static var Glass88: Color { Color(#function, bundle: .module) }
+ static var Indigo100: Color { Color(#function, bundle: .module) }
+ static var Inverse000: Color { Color(#function, bundle: .module) }
+ static var Inverse100: Color { Color(#function, bundle: .module) }
+ static var Magenta100: Color { Color(#function, bundle: .module) }
+ static var Orange100: Color { Color(#function, bundle: .module) }
+ static var Overblue002: Color { Color(#function, bundle: .module) }
+ static var Overblue005: Color { Color(#function, bundle: .module) }
+ static var Overblue010: Color { Color(#function, bundle: .module) }
+ static var Overblue015: Color { Color(#function, bundle: .module) }
+ static var Overblue020: Color { Color(#function, bundle: .module) }
+ static var Overblue080: Color { Color(#function, bundle: .module) }
+ static var Overblue090: Color { Color(#function, bundle: .module) }
+ static var Overgray001: Color { Color(#function, bundle: .module) }
+ static var Overgray002: Color { Color(#function, bundle: .module) }
+ static var Overgray005: Color { Color(#function, bundle: .module) }
+ static var Overgray010: Color { Color(#function, bundle: .module) }
+ static var Overgray015: Color { Color(#function, bundle: .module) }
+ static var Overgray020: Color { Color(#function, bundle: .module) }
+ static var Overgray025: Color { Color(#function, bundle: .module) }
+ static var Overgray030: Color { Color(#function, bundle: .module) }
+ static var Purple100: Color { Color(#function, bundle: .module) }
+ static var Success100: Color { Color(#function, bundle: .module) }
+ static var Teal100: Color { Color(#function, bundle: .module) }
+ static var Yellow100: Color { Color(#function, bundle: .module) }
+ static var Grey18: Color { Color(#function, bundle: .module) }
+ static var Grey20: Color { Color(#function, bundle: .module) }
+ static var Grey22: Color { Color(#function, bundle: .module) }
+ static var GrayGlass002: Color { Color(#function, bundle: .module) }
+ static var GrayGlass005: Color { Color(#function, bundle: .module) }
+ static var GrayGlass010: Color { Color(#function, bundle: .module) }
+ static var GrayGlass020: Color { Color(#function, bundle: .module) }
+}
+
+public extension UIColor {
+ static var Blue100: UIColor { UIColor(named: #function, in: .module, compatibleWith: nil) ?? .blue }
+ static var Background125: UIColor { UIColor(named: #function, in: .module, compatibleWith: nil) ?? .blue }
+ static var Foreground100: UIColor { UIColor(named: #function, in: .module, compatibleWith: nil) ?? .blue }
+}
diff --git a/Sources/Web3ModalUI/Helpers/Extensions/Font+extension.swift b/Sources/Web3ModalUI/Helpers/Extensions/Font+extension.swift
new file mode 100644
index 0000000..35ab48a
--- /dev/null
+++ b/Sources/Web3ModalUI/Helpers/Extensions/Font+extension.swift
@@ -0,0 +1,120 @@
+import SwiftUI
+
+public enum W3MFont {
+ case large500
+ case large600
+ case large700
+ case micro600
+ case micro700
+ case paragraph500
+ case paragraph600
+ case paragraph700
+ case small400
+ case small500
+ case small600
+ case tiny500
+ case tiny600
+ case title500
+ case title600
+ case title700
+
+ var weight: Font.Weight {
+ switch self {
+ case .large500: return .medium
+ case .large600: return .semibold
+ case .large700: return .bold
+ case .micro600: return .semibold
+ case .micro700: return .bold
+ case .paragraph500: return .medium
+ case .paragraph600: return .semibold
+ case .paragraph700: return .bold
+ case .small400: return .regular
+ case .small500: return .medium
+ case .small600: return .semibold
+ case .tiny500: return .medium
+ case .tiny600: return .semibold
+ case .title500: return .medium
+ case .title600: return .semibold
+ case .title700: return .bold
+ }
+ }
+
+ var size: CGFloat {
+ switch self {
+ case .large500: return 20.0
+ case .large600: return 20.0
+ case .large700: return 20.0
+ case .micro600: return 10.0
+ case .micro700: return 10.0
+ case .paragraph500: return 16.0
+ case .paragraph600: return 16.0
+ case .paragraph700: return 16.0
+ case .small400: return 14.0
+ case .small500: return 14.0
+ case .small600: return 14.0
+ case .tiny500: return 12.0
+ case .tiny600: return 12.0
+ case .title500: return 24.0
+ case .title600: return 24.0
+ case .title700: return 24.0
+ }
+ }
+}
+
+struct ScaledFont: ViewModifier {
+ @Environment(\.sizeCategory) var sizeCategory
+
+ var size: Double
+ var weight: Font.Weight
+
+ func body(content: Content) -> some View {
+ let scaledSize = UIFontMetrics.default.scaledValue(for: size)
+ return content.font(.system(size: scaledSize, weight: weight))
+ }
+}
+
+extension View {
+ public func scaledFont(size: Double, weight: Font.Weight) -> some View {
+ return modifier(ScaledFont(size: size, weight: weight))
+ }
+
+ public func font(_ font: W3MFont) -> some View {
+ return modifier(ScaledFont(size: font.size, weight: font.weight))
+ }
+}
+
+struct FontPreviews: PreviewProvider {
+ @Environment(\.sizeCategory) var sizeCategory
+
+ static var previews: some View {
+ VStack(spacing: 10) {
+ Group {
+ Text("large500").font(.large500)
+ Text("large600").font(.large600)
+ Text("large700").font(.large700)
+ }
+ Group {
+ Text("title500").font(.title500)
+ Text("title600").font(.title600)
+ Text("title700").font(.title700)
+ }
+ Group {
+ Text("paragraph500").font(.paragraph500)
+ Text("paragraph600").font(.paragraph600)
+ Text("paragraph700").font(.paragraph700)
+ }
+ Group {
+ Text("micro600").font(.micro600)
+ Text("micro700").font(.micro700)
+ }
+ Group {
+ Text("small500").font(.small500)
+ Text("small600").font(.small600)
+ }
+ Group {
+ Text("tiny500").font(.tiny500)
+ Text("tiny600").font(.tiny600)
+ }
+ }
+ }
+}
diff --git a/Sources/Web3ModalUI/Helpers/Extensions/ImageResource_generated.swift b/Sources/Web3ModalUI/Helpers/Extensions/ImageResource_generated.swift
new file mode 100644
index 0000000..3a3b373
--- /dev/null
+++ b/Sources/Web3ModalUI/Helpers/Extensions/ImageResource_generated.swift
@@ -0,0 +1,675 @@
+import SwiftUI
+
+public extension Image {
+ /// The "Regular" asset catalog resource namespace.
+ enum Regular {
+ /// The "Regular/4 dots" asset catalog image resource.
+ public static let _4Dots = Image("Regular/4 dots", bundle: .module)
+
+ /// The "Regular/App" asset catalog image resource.
+ public static let app = Image("Regular/App", bundle: .module)
+
+ /// The "Regular/Arrow Bottom" asset catalog image resource.
+ public static let arrowBottom = Image("Regular/Arrow Bottom", bundle: .module)
+
+ /// The "Regular/Bars" asset catalog image resource.
+ public static let bars = Image("Regular/Bars", bundle: .module)
+
+ /// The "Regular/Bell" asset catalog image resource.
+ public static let bell = Image("Regular/Bell", bundle: .module)
+
+ /// The "Regular/Browser" asset catalog image resource.
+ public static let browser = Image("Regular/Browser", bundle: .module)
+
+ /// The "Regular/Extension" asset catalog image resource.
+ public static let `extension` = Image("Regular/Extension", bundle: .module)
+
+ /// The "Regular/Chart" asset catalog image resource.
+ public static let chart = Image("Regular/Chart", bundle: .module)
+
+ /// The "Regular/Chat Bubble" asset catalog image resource.
+ public static let chatBubble = Image("Regular/Chat Bubble", bundle: .module)
+
+ /// The "Regular/Check Circle" asset catalog image resource.
+ public static let checkCircle = Image("Regular/Check Circle", bundle: .module)
+
+ /// The "Regular/Checkmark" asset catalog image resource.
+ public static let checkmark = Image("Regular/Checkmark", bundle: .module)
+
+ /// The "Regular/Chevron Left" asset catalog image resource.
+ public static let chevronLeft = Image("Regular/Chevron Left", bundle: .module)
+
+ /// The "Regular/Code" asset catalog image resource.
+ public static let code = Image("Regular/Code", bundle: .module)
+
+ /// The "Regular/Coin" asset catalog image resource.
+ public static let coin = Image("Regular/Coin", bundle: .module)
+
+ /// The "Regular/Compass" asset catalog image resource.
+ public static let compass = Image("Regular/Compass", bundle: .module)
+
+ /// The "Regular/Copy" asset catalog image resource.
+ public static let copy = Image("Regular/Copy", bundle: .module)
+
+ /// The "Regular/Desktop" asset catalog image resource.
+ public static let desktop = Image("Regular/Desktop", bundle: .module)
+
+ /// The "Regular/Double Chevron Right" asset catalog image resource.
+ public static let doubleChevronRight = Image("Regular/Double Chevron Right", bundle: .module)
+
+ /// The "Regular/External Link" asset catalog image resource.
+ public static let externalLink = Image("Regular/External Link", bundle: .module)
+
+ /// The "Regular/Eye" asset catalog image resource.
+ public static let eye = Image("Regular/Eye", bundle: .module)
+
+ /// The "Regular/Eye Crossed" asset catalog image resource.
+ public static let eyeCrossed = Image("Regular/Eye Crossed", bundle: .module)
+
+ /// The "Regular/Filters" asset catalog image resource.
+ public static let filters = Image("Regular/Filters", bundle: .module)
+
+ /// The "Regular/Fingerprint" asset catalog image resource.
+ public static let fingerprint = Image("Regular/Fingerprint", bundle: .module)
+
+ /// The "Regular/Image" asset catalog image resource.
+ public static let image = Image("Regular/Image", bundle: .module)
+
+ /// The "Regular/Info" asset catalog image resource.
+ public static let info = Image("Regular/Info", bundle: .module)
+
+ /// The "Regular/Link" asset catalog image resource.
+ public static let link = Image("Regular/Link", bundle: .module)
+
+ /// The "Regular/Load" asset catalog image resource.
+ public static let load = Image("Regular/Load", bundle: .module)
+
+ /// The "Regular/Locker" asset catalog image resource.
+ public static let locker = Image("Regular/Locker", bundle: .module)
+
+ /// The "Regular/Magnifier" asset catalog image resource.
+ public static let magnifier = Image("Regular/Magnifier", bundle: .module)
+
+ /// The "Regular/Mail" asset catalog image resource.
+ public static let mail = Image("Regular/Mail", bundle: .module)
+
+ /// The "Regular/Mobile" asset catalog image resource.
+ public static let mobile = Image("Regular/Mobile", bundle: .module)
+
+ /// The "Regular/Moon" asset catalog image resource.
+ public static let moon = Image("Regular/Moon", bundle: .module)
+
+ /// The "Regular/Network" asset catalog image resource.
+ public static let network = Image("Regular/Network", bundle: .module)
+
+ /// The "Regular/QR code" asset catalog image resource.
+ public static let qrCode = Image("Regular/QR code", bundle: .module)
+
+ /// The "Regular/Question" asset catalog image resource.
+ public static let question = Image("Regular/Question", bundle: .module)
+
+ /// The "Regular/Question Mark Circle" asset catalog image resource.
+ public static let questionMarkCircle = Image("Regular/Question Mark Circle", bundle: .module)
+
+ /// The "Regular/Sliders" asset catalog image resource.
+ public static let sliders = Image("Regular/Sliders", bundle: .module)
+
+ /// The "Regular/Squares" asset catalog image resource.
+ public static let squares = Image("Regular/Squares", bundle: .module)
+
+ /// The "Regular/Sun" asset catalog image resource.
+ public static let sun = Image("Regular/Sun", bundle: .module)
+
+ /// The "Regular/Swap Horizontal" asset catalog image resource.
+ public static let swapHorizontal = Image("Regular/Swap Horizontal", bundle: .module)
+
+ /// The "Regular/Verif" asset catalog image resource.
+ public static let verif = Image("Regular/Verif", bundle: .module)
+
+ /// The "Regular/Wallet" asset catalog image resource.
+ public static let wallet = Image("Regular/Wallet", bundle: .module)
+
+ /// The "Regular/Warning Circle" asset catalog image resource.
+ public static let warningCircle = Image("Regular/Warning Circle", bundle: .module)
+
+ /// The "Regular/X mark" asset catalog image resource.
+ public static let xMark = Image("Regular/X mark", bundle: .module)
+ }
+
+ /// The "Original" asset catalog resource namespace.
+ enum Original {
+ /// The "Original/Add" asset catalog image resource.
+ public static let add = Image("Original/Add", bundle: .module)
+
+ /// The "Original/Apple" asset catalog image resource.
+ public static let apple = Image("Original/Apple", bundle: .module)
+
+ /// The "Original/ArrowDown" asset catalog image resource.
+ public static let arrowDown = Image("Original/ArrowDown", bundle: .module)
+
+ /// The "Original/ArrowExchange" asset catalog image resource.
+ public static let arrowExchange = Image("Original/ArrowExchange", bundle: .module)
+
+ /// The "Original/ArrowLeft" asset catalog image resource.
+ public static let arrowLeft = Image("Original/ArrowLeft", bundle: .module)
+
+ /// The "Original/ArrowRight" asset catalog image resource.
+ public static let arrowRight = Image("Original/ArrowRight", bundle: .module)
+
+ /// The "Original/ArrowUp" asset catalog image resource.
+ public static let arrowUp = Image("Original/ArrowUp", bundle: .module)
+
+ /// The "Original/BackwardChevron" asset catalog image resource.
+ public static let backwardChevron = Image("Original/BackwardChevron", bundle: .module)
+
+ /// The "Original/Checkmark" asset catalog image resource.
+ public static let checkmark = Image("Original/Checkmark", bundle: .module)
+
+ /// The "Original/Compass" asset catalog image resource.
+ public static let compass = Image("Original/Compass", bundle: .module)
+
+ /// The "Original/Desktop" asset catalog image resource.
+ public static let desktop = Image("Original/Desktop", bundle: .module)
+
+ /// The "Original/Disconnect" asset catalog image resource.
+ public static let disconnect = Image("Original/Disconnect", bundle: .module)
+
+ /// The "Original/Discord" asset catalog image resource.
+ public static let discord = Image("Original/Discord", bundle: .module)
+
+ /// The "Original/DownwardChevron" asset catalog image resource.
+ public static let downwardChevron = Image("Original/DownwardChevron", bundle: .module)
+
+ /// The "Original/Error" asset catalog image resource.
+ public static let error = Image("Original/Error", bundle: .module)
+
+ /// The "Original/Extension" asset catalog image resource.
+ public static let `extension` = Image("Original/Extension", bundle: .module)
+
+ /// The "Original/ExternalLink" asset catalog image resource.
+ public static let externalLink = Image("Original/ExternalLink", bundle: .module)
+
+ /// The "Original/Facebook" asset catalog image resource.
+ public static let facebook = Image("Original/Facebook", bundle: .module)
+
+ /// The "Original/ForwardChevron" asset catalog image resource.
+ public static let forwardChevron = Image("Original/ForwardChevron", bundle: .module)
+
+ /// The "Original/Github" asset catalog image resource.
+ public static let github = Image("Original/Github", bundle: .module)
+
+ /// The "Original/Google" asset catalog image resource.
+ public static let google = Image("Original/Google", bundle: .module)
+
+ /// The "Original/Help" asset catalog image resource.
+ public static let help = Image("Original/Help", bundle: .module)
+
+ /// The "Original/HelpSmall" asset catalog image resource.
+ public static let helpSmall = Image("Original/HelpSmall", bundle: .module)
+
+ /// The "Original/History" asset catalog image resource.
+ public static let history = Image("Original/History", bundle: .module)
+
+ /// The "Original/LargeBackward" asset catalog image resource.
+ public static let largeBackward = Image("Original/LargeBackward", bundle: .module)
+
+ /// The "Original/LargeClose" asset catalog image resource.
+ public static let largeClose = Image("Original/LargeClose", bundle: .module)
+
+ /// The "Original/LargeCopy" asset catalog image resource.
+ public static let largeCopy = Image("Original/LargeCopy", bundle: .module)
+
+ /// The "Original/LargeDesktop" asset catalog image resource.
+ public static let largeDesktop = Image("Original/LargeDesktop", bundle: .module)
+
+ /// The "Original/LargeEmail" asset catalog image resource.
+ public static let largeEmail = Image("Original/LargeEmail", bundle: .module)
+
+ /// The "Original/LargeEmoji" asset catalog image resource.
+ public static let largeEmoji = Image("Original/LargeEmoji", bundle: .module)
+
+ /// The "Original/LargeMoon" asset catalog image resource.
+ public static let largeMoon = Image("Original/LargeMoon", bundle: .module)
+
+ /// The "Original/LargePhone" asset catalog image resource.
+ public static let largePhone = Image("Original/LargePhone", bundle: .module)
+
+ /// The "Original/LargeQrcode" asset catalog image resource.
+ public static let largeQrcode = Image("Original/LargeQrcode", bundle: .module)
+
+ /// The "Original/LargeSun" asset catalog image resource.
+ public static let largeSun = Image("Original/LargeSun", bundle: .module)
+
+ /// The "Original/LargeTwitter" asset catalog image resource.
+ public static let largeTwitter = Image("Original/LargeTwitter", bundle: .module)
+
+ /// The "Original/Mail" asset catalog image resource.
+ public static let mail = Image("Original/Mail", bundle: .module)
+
+ /// The "Original/Off" asset catalog image resource.
+ public static let off = Image("Original/Off", bundle: .module)
+
+ /// The "Original/Pen" asset catalog image resource.
+ public static let pen = Image("Original/Pen", bundle: .module)
+
+ /// The "Original/Phone" asset catalog image resource.
+ public static let phone = Image("Original/Phone", bundle: .module)
+
+ /// The "Original/Popular" asset catalog image resource.
+ public static let popular = Image("Original/Popular", bundle: .module)
+
+ /// The "Original/Qrcode" asset catalog image resource.
+ public static let qrcode = Image("Original/Qrcode", bundle: .module)
+
+ /// The "Original/QuestionMarkCircle" asset catalog image resource.
+ public static let questionMarkCircle = Image("Original/QuestionMarkCircle", bundle: .module)
+
+ /// The "Original/Recent" asset catalog image resource.
+ public static let recent = Image("Original/Recent", bundle: .module)
+
+ /// The "Original/Retry" asset catalog image resource.
+ public static let retry = Image("Original/Retry", bundle: .module)
+
+ /// The "Original/Scan" asset catalog image resource.
+ public static let scan = Image("Original/Scan", bundle: .module)
+
+ /// The "Original/Search" asset catalog image resource.
+ public static let search = Image("Original/Search", bundle: .module)
+
+ /// The "Original/Telegram" asset catalog image resource.
+ public static let telegram = Image("Original/Telegram", bundle: .module)
+
+ /// The "Original/ToastError" asset catalog image resource.
+ public static let toastError = Image("Original/ToastError", bundle: .module)
+
+ /// The "Original/ToastInfo" asset catalog image resource.
+ public static let toastInfo = Image("Original/ToastInfo", bundle: .module)
+
+ /// The "Original/ToastSuccess" asset catalog image resource.
+ public static let toastSuccess = Image("Original/ToastSuccess", bundle: .module)
+
+ /// The "Original/Twitch" asset catalog image resource.
+ public static let twitch = Image("Original/Twitch", bundle: .module)
+
+ /// The "Original/Twitter" asset catalog image resource.
+ public static let twitter = Image("Original/Twitter", bundle: .module)
+
+ /// The "Original/UpwardChevron" asset catalog image resource.
+ public static let upwardChevron = Image("Original/UpwardChevron", bundle: .module)
+
+ /// The "Original/Wallet" asset catalog image resource.
+ public static let wallet = Image("Original/Wallet", bundle: .module)
+
+ /// The "Original/Website" asset catalog image resource.
+ public static let website = Image("Original/Website", bundle: .module)
+ }
+
+ /// The "Medium" asset catalog resource namespace.
+ enum Medium {
+ /// The "Medium/Android" asset catalog image resource.
+ public static let android = Image("Medium/Android", bundle: .module)
+
+ /// The "Medium/App" asset catalog image resource.
+ public static let app = Image("Medium/App", bundle: .module)
+
+ /// The "Medium/Arrow Left" asset catalog image resource.
+ public static let arrowLeft = Image("Medium/Arrow Left", bundle: .module)
+
+ /// The "Medium/Arrow Right" asset catalog image resource.
+ public static let arrowRight = Image("Medium/Arrow Right", bundle: .module)
+
+ /// The "Medium/Auth" asset catalog image resource.
+ public static let auth = Image("Medium/Auth", bundle: .module)
+
+ /// The "Medium/Bell" asset catalog image resource.
+ public static let bell = Image("Medium/Bell", bundle: .module)
+
+ /// The "Medium/Bin" asset catalog image resource.
+ public static let bin = Image("Medium/Bin", bundle: .module)
+
+ /// The "Medium/Checkmark" asset catalog image resource.
+ public static let checkmark = Image("Medium/Checkmark", bundle: .module)
+
+ /// The "Medium/Chevron Bottom" asset catalog image resource.
+ public static let chevronBottom = Image("Medium/Chevron Bottom", bundle: .module)
+
+ /// The "Medium/Chevron Left" asset catalog image resource.
+ public static let chevronLeft = Image("Medium/Chevron Left", bundle: .module)
+
+ /// The "Medium/Chevron Right" asset catalog image resource.
+ public static let chevronRight = Image("Medium/Chevron Right", bundle: .module)
+
+ /// The "Medium/Chevron Top" asset catalog image resource.
+ public static let chevronTop = Image("Medium/Chevron Top", bundle: .module)
+
+ /// The "Medium/Compass" asset catalog image resource.
+ public static let compass = Image("Medium/Compass", bundle: .module)
+
+ /// The "Medium/Copy" asset catalog image resource.
+ public static let copy = Image("Medium/Copy", bundle: .module)
+
+ /// The "Medium/Desktop" asset catalog image resource.
+ public static let desktop = Image("Medium/Desktop", bundle: .module)
+
+ /// The "Medium/Disconnect" asset catalog image resource.
+ public static let disconnect = Image("Medium/Disconnect", bundle: .module)
+
+ /// The "Medium/Doc" asset catalog image resource.
+ public static let doc = Image("Medium/Doc", bundle: .module)
+
+ /// The "Medium/Dots Horizontal" asset catalog image resource.
+ public static let dotsHorizontal = Image("Medium/Dots Horizontal", bundle: .module)
+
+ /// The "Medium/Dots Vertical" asset catalog image resource.
+ public static let dotsVertical = Image("Medium/Dots Vertical", bundle: .module)
+
+ /// The "Medium/Double Chevron Vertical" asset catalog image resource.
+ public static let doubleChevronVertical = Image("Medium/Double Chevron Vertical", bundle: .module)
+
+ /// The "Medium/Etherscan" asset catalog image resource.
+ public static let etherscan = Image("Medium/Etherscan", bundle: .module)
+
+ /// The "Medium/External Link" asset catalog image resource.
+ public static let externalLink = Image("Medium/External Link", bundle: .module)
+
+ /// The "Medium/Eye" asset catalog image resource.
+ public static let eye = Image("Medium/Eye", bundle: .module)
+
+ /// The "Medium/Eye Crossed" asset catalog image resource.
+ public static let eyeCrossed = Image("Medium/Eye Crossed", bundle: .module)
+
+ /// The "Medium/File" asset catalog image resource.
+ public static let file = Image("Medium/File", bundle: .module)
+
+ /// The "Medium/Filters" asset catalog image resource.
+ public static let filters = Image("Medium/Filters", bundle: .module)
+
+ /// The "Medium/Info" asset catalog image resource.
+ public static let info = Image("Medium/Info", bundle: .module)
+
+ /// The "Medium/Info Circle" asset catalog image resource.
+ public static let infoCircle = Image("Medium/Info Circle", bundle: .module)
+
+ /// The "Medium/Light Bulb" asset catalog image resource.
+ public static let lightBulb = Image("Medium/Light Bulb", bundle: .module)
+
+ /// The "Medium/Magnifier" asset catalog image resource.
+ public static let magnifier = Image("Medium/Magnifier", bundle: .module)
+
+ /// The "Medium/Mail" asset catalog image resource.
+ public static let mail = Image("Medium/Mail", bundle: .module)
+
+ /// The "Medium/Mobile" asset catalog image resource.
+ public static let mobile = Image("Medium/Mobile", bundle: .module)
+
+ /// The "Medium/Moon" asset catalog image resource.
+ public static let moon = Image("Medium/Moon", bundle: .module)
+
+ /// The "Medium/Nut" asset catalog image resource.
+ public static let nut = Image("Medium/Nut", bundle: .module)
+
+ /// The "Medium/Off" asset catalog image resource.
+ public static let off = Image("Medium/Off", bundle: .module)
+
+ /// The "Medium/Paste" asset catalog image resource.
+ public static let paste = Image("Medium/Paste", bundle: .module)
+
+ /// The "Medium/Pen" asset catalog image resource.
+ public static let pen = Image("Medium/Pen", bundle: .module)
+
+ /// The "Medium/Plus" asset catalog image resource.
+ public static let plus = Image("Medium/Plus", bundle: .module)
+
+ /// The "Medium/QR code" asset catalog image resource.
+ public static let qrCode = Image("Medium/QR code", bundle: .module)
+
+ /// The "Medium/Question Mark Circle" asset catalog image resource.
+ public static let questionMarkCircle = Image("Medium/Question Mark Circle", bundle: .module)
+
+ /// The "Medium/Refresh" asset catalog image resource.
+ public static let refresh = Image("Medium/Refresh", bundle: .module)
+
+ /// The "Medium/Sliders" asset catalog image resource.
+ public static let sliders = Image("Medium/Sliders", bundle: .module)
+
+ /// The "Medium/Squares" asset catalog image resource.
+ public static let squares = Image("Medium/Squares", bundle: .module)
+
+ /// The "Medium/Sun" asset catalog image resource.
+ public static let sun = Image("Medium/Sun", bundle: .module)
+
+ /// The "Medium/Swap Horizontal" asset catalog image resource.
+ public static let swapHorizontal = Image("Medium/Swap Horizontal", bundle: .module)
+
+ /// The "Medium/Swap Vertical" asset catalog image resource.
+ public static let swapVertical = Image("Medium/Swap Vertical", bundle: .module)
+
+ /// The "Medium/Twitter" asset catalog image resource.
+ public static let twitter = Image("Medium/Twitter", bundle: .module)
+
+ /// The "Medium/Wallet" asset catalog image resource.
+ public static let wallet = Image("Medium/Wallet", bundle: .module)
+
+ /// The "Medium/Warning Circle" asset catalog image resource.
+ public static let warningCircle = Image("Medium/Warning Circle", bundle: .module)
+
+ /// The "Medium/Web" asset catalog image resource.
+ public static let web = Image("Medium/Web", bundle: .module)
+
+ /// The "Medium/X mark" asset catalog image resource.
+ public static let xMark = Image("Medium/X mark", bundle: .module)
+
+ /// The "Medium/iOS" asset catalog image resource.
+ public static let iOS = Image("Medium/iOS", bundle: .module)
+ }
+
+ /// The "Bold" asset catalog resource namespace.
+ enum Bold {
+ /// The "Bold/Arrow Bottom" asset catalog image resource.
+ public static let arrowBottom = Image("Bold/Arrow Bottom", bundle: .module)
+
+ /// The "Bold/Arrow Left" asset catalog image resource.
+ public static let arrowLeft = Image("Bold/Arrow Left", bundle: .module)
+
+ /// The "Bold/Arrow Right" asset catalog image resource.
+ public static let arrowRight = Image("Bold/Arrow Right", bundle: .module)
+
+ /// The "Bold/Arrow Top" asset catalog image resource.
+ public static let arrowTop = Image("Bold/Arrow Top", bundle: .module)
+
+ /// The "Bold/Bars" asset catalog image resource.
+ public static let bars = Image("Bold/Bars", bundle: .module)
+
+ /// The "Bold/Bin" asset catalog image resource.
+ public static let bin = Image("Bold/Bin", bundle: .module)
+
+ /// The "Bold/Browser" asset catalog image resource.
+ public static let browser = Image("Bold/Browser", bundle: .module)
+
+ /// The "Bold/Checkmark" asset catalog image resource.
+ public static let checkmark = Image("Bold/Checkmark", bundle: .module)
+
+ /// The "Bold/Chevron Bottom" asset catalog image resource.
+ public static let chevronBottom = Image("Bold/Chevron Bottom", bundle: .module)
+
+ /// The "Bold/Chevron Left" asset catalog image resource.
+ public static let chevronLeft = Image("Bold/Chevron Left", bundle: .module)
+
+ /// The "Bold/Chevron Right" asset catalog image resource.
+ public static let chevronRight = Image("Bold/Chevron Right", bundle: .module)
+
+ /// The "Bold/Chevron Top" asset catalog image resource.
+ public static let chevronTop = Image("Bold/Chevron Top", bundle: .module)
+
+ /// The "Bold/Clock" asset catalog image resource.
+ public static let clock = Image("Bold/Clock", bundle: .module)
+
+ /// The "Bold/Code" asset catalog image resource.
+ public static let code = Image("Bold/Code", bundle: .module)
+
+ /// The "Bold/Compass" asset catalog image resource.
+ public static let compass = Image("Bold/Compass", bundle: .module)
+
+ /// The "Bold/Copy" asset catalog image resource.
+ public static let copy = Image("Bold/Copy", bundle: .module)
+
+ /// The "Bold/Desktop" asset catalog image resource.
+ public static let desktop = Image("Bold/Desktop", bundle: .module)
+
+ /// The "Bold/Disconnect" asset catalog image resource.
+ public static let disconnect = Image("Bold/Disconnect", bundle: .module)
+
+ /// The "Bold/Doc" asset catalog image resource.
+ public static let doc = Image("Bold/Doc", bundle: .module)
+
+ /// The "Bold/Double Chevron Vertical" asset catalog image resource.
+ public static let doubleChevronVertical = Image("Bold/Double Chevron Vertical", bundle: .module)
+
+ /// The "Bold/External Link" asset catalog image resource.
+ public static let externalLink = Image("Bold/External Link", bundle: .module)
+
+ /// The "Bold/Eye" asset catalog image resource.
+ public static let eye = Image("Bold/Eye", bundle: .module)
+
+ /// The "Bold/Eye Crossed" asset catalog image resource.
+ public static let eyeCrossed = Image("Bold/Eye Crossed", bundle: .module)
+
+ /// The "Bold/Filters" asset catalog image resource.
+ public static let filters = Image("Bold/Filters", bundle: .module)
+
+ /// The "Bold/Image" asset catalog image resource.
+ public static let image = Image("Bold/Image", bundle: .module)
+
+ /// The "Bold/Info" asset catalog image resource.
+ public static let info = Image("Bold/Info", bundle: .module)
+
+ /// The "Bold/Light Bulb" asset catalog image resource.
+ public static let lightBulb = Image("Bold/Light Bulb", bundle: .module)
+
+ /// The "Bold/Link" asset catalog image resource.
+ public static let link = Image("Bold/Link", bundle: .module)
+
+ /// The "Bold/Mail" asset catalog image resource.
+ public static let mail = Image("Bold/Mail", bundle: .module)
+
+ /// The "Bold/Mobile" asset catalog image resource.
+ public static let mobile = Image("Bold/Mobile", bundle: .module)
+
+ /// The "Bold/Moon" asset catalog image resource.
+ public static let moon = Image("Bold/Moon", bundle: .module)
+
+ /// The "Bold/Network" asset catalog image resource.
+ public static let network = Image("Bold/Network", bundle: .module)
+
+ /// The "Bold/Nut" asset catalog image resource.
+ public static let nut = Image("Bold/Nut", bundle: .module)
+
+ /// The "Bold/Off" asset catalog image resource.
+ public static let off = Image("Bold/Off", bundle: .module)
+
+ /// The "Bold/Pen" asset catalog image resource.
+ public static let pen = Image("Bold/Pen", bundle: .module)
+
+ /// The "Bold/Plus" asset catalog image resource.
+ public static let plus = Image("Bold/Plus", bundle: .module)
+
+ /// The "Bold/Question Mark Circle" asset catalog image resource.
+ public static let questionMarkCircle = Image("Bold/Question Mark Circle", bundle: .module)
+
+ /// The "Bold/Refresh" asset catalog image resource.
+ public static let refresh = Image("Bold/Refresh", bundle: .module)
+
+ /// The "Bold/Sliders Horizontal" asset catalog image resource.
+ public static let slidersHorizontal = Image("Bold/Sliders Horizontal", bundle: .module)
+
+ /// The "Bold/Sliders Vertical" asset catalog image resource.
+ public static let slidersVertical = Image("Bold/Sliders Vertical", bundle: .module)
+
+ /// The "Bold/Squares" asset catalog image resource.
+ public static let squares = Image("Bold/Squares", bundle: .module)
+
+ /// The "Bold/Sun" asset catalog image resource.
+ public static let sun = Image("Bold/Sun", bundle: .module)
+
+ /// The "Bold/Swap Horizontal" asset catalog image resource.
+ public static let swapHorizontal = Image("Bold/Swap Horizontal", bundle: .module)
+
+ /// The "Bold/Swap Vertical" asset catalog image resource.
+ public static let swapVertical = Image("Bold/Swap Vertical", bundle: .module)
+
+ /// The "Bold/Users" asset catalog image resource.
+ public static let users = Image("Bold/Users", bundle: .module)
+
+ /// The "Bold/Wallet" asset catalog image resource.
+ public static let wallet = Image("Bold/Wallet", bundle: .module)
+
+ /// The "Bold/Warning Circle" asset catalog image resource.
+ public static let warningCircle = Image("Bold/Warning Circle", bundle: .module)
+
+ /// The "Bold/Web" asset catalog image resource.
+ public static let web = Image("Bold/Web", bundle: .module)
+
+ /// The "Bold/X Mark" asset catalog image resource.
+ public static let xMark = Image("Bold/X Mark", bundle: .module)
+ }
+
+ /// The "MockChainImage" asset catalog image resource.
+ static let mockChain = Image("MockChainImage", bundle: .module)
+
+ /// The "MockWalletImage" asset catalog image resource.
+ static let mockWallet = Image("MockWalletImage", bundle: .module)
+
+ /// The "imageBrowser" asset catalog image resource.
+ static let imageBrowser = Image("imageBrowser", bundle: .module)
+
+ /// The "imageDao" asset catalog image resource.
+ static let imageDao = Image("imageDao", bundle: .module)
+
+ /// The "imageDeFi" asset catalog image resource.
+ static let imageDeFi = Image("imageDeFi", bundle: .module)
+
+ /// The "imageDefiAlt" asset catalog image resource.
+ static let imageDefiAlt = Image("imageDefiAlt", bundle: .module)
+
+ /// The "imageEth" asset catalog image resource.
+ static let imageEth = Image("imageEth", bundle: .module)
+
+ /// The "imageLayers" asset catalog image resource.
+ static let imageLayers = Image("imageLayers", bundle: .module)
+
+ /// The "imageLock" asset catalog image resource.
+ static let imageLock = Image("imageLock", bundle: .module)
+
+ /// The "imageLogin" asset catalog image resource.
+ static let imageLogin = Image("imageLogin", bundle: .module)
+
+ /// The "imageLogo" asset catalog image resource.
+ static let imageLogo = Image("imageLogo", bundle: .module)
+
+ /// The "imageNetwork" asset catalog image resource.
+ static let imageNetwork = Image("imageNetwork", bundle: .module)
+
+ /// The "imageNft" asset catalog image resource.
+ static let imageNft = Image("imageNft", bundle: .module)
+
+ /// The "imageNoun" asset catalog image resource.
+ static let imageNoun = Image("imageNoun", bundle: .module)
+
+ /// The "imageProfile" asset catalog image resource.
+ static let imageProfile = Image("imageProfile", bundle: .module)
+
+ /// The "imageSystem" asset catalog image resource.
+ static let imageSystem = Image("imageSystem", bundle: .module)
+
+ /// The "optionAll" asset catalog image resource.
+ static let optionAll = Image("optionAll", bundle: .module)
+
+ /// The "optionBrowser" asset catalog image resource.
+ static let optionBrowser = Image("optionBrowser", bundle: .module)
+
+ /// The "optionExtension" asset catalog image resource.
+ static let optionExtension = Image("optionExtension", bundle: .module)
+
+ /// The "optionQrCode" asset catalog image resource.
+ static let optionQrCode = Image("optionQrCode", bundle: .module)
+}
diff --git a/Sources/Web3ModalUI/Helpers/Radius.swift b/Sources/Web3ModalUI/Helpers/Radius.swift
new file mode 100644
index 0000000..3e1fbca
--- /dev/null
+++ b/Sources/Web3ModalUI/Helpers/Radius.swift
@@ -0,0 +1,25 @@
+import Foundation
+
+public enum Radius {
+ /// Default 4 points
+ public static var masterRadius: CGFloat = 4
+
+ /// Default 4 points
+ public static var xxxxxs: CGFloat = masterRadius
+ /// Default 6 points
+ public static var xxxxs: CGFloat = masterRadius * 1.5
+ /// Default 8 points
+ public static var xxxs: CGFloat = masterRadius * 2
+ /// Default 12 points
+ public static var xxs: CGFloat = masterRadius * 3
+ /// Default 16 points
+ public static var xs: CGFloat = masterRadius * 4
+ /// Default 20 points
+ public static var s: CGFloat = masterRadius * 5
+ /// Default 28 points
+ public static var m: CGFloat = masterRadius * 7
+ /// Default 36 points
+ public static var l: CGFloat = masterRadius * 9
+ /// Default 80 points
+ public static var xxxl: CGFloat = masterRadius * 20
+}
diff --git a/Sources/Web3ModalUI/Helpers/Spacing.swift b/Sources/Web3ModalUI/Helpers/Spacing.swift
new file mode 100644
index 0000000..4a76b3c
--- /dev/null
+++ b/Sources/Web3ModalUI/Helpers/Spacing.swift
@@ -0,0 +1,26 @@
+import Foundation
+
+public enum Spacing {
+ /// 0 points
+ public static var zero: CGFloat = 0
+ /// 2 points
+ public static var xxxxs: CGFloat = 2
+ /// 4 points
+ public static var xxxs: CGFloat = 4
+ /// 6 points
+ public static var xxs: CGFloat = 6
+ /// 8 points
+ public static var xs: CGFloat = 8
+ /// 12 points
+ public static var s: CGFloat = 12
+ /// 14 points
+ public static var m: CGFloat = 14
+ /// 16 points
+ public static var l: CGFloat = 16
+ /// 20 points
+ public static var xl: CGFloat = 20
+ /// 24 points
+ public static var xxl: CGFloat = 24
+ /// 80 points
+ public static var xxxl: CGFloat = 80
+}
diff --git a/Sources/Web3ModalUI/Miscellaneous/AdaptiveStack.swift b/Sources/Web3ModalUI/Miscellaneous/AdaptiveStack.swift
new file mode 100644
index 0000000..5eeab6a
--- /dev/null
+++ b/Sources/Web3ModalUI/Miscellaneous/AdaptiveStack.swift
@@ -0,0 +1,39 @@
+import SwiftUI
+
+struct AdaptiveStack: View {
+ let horizontalAlignment: HorizontalAlignment
+ let verticalAlignment: VerticalAlignment
+ let spacing: CGFloat?
+ let content: () -> Content
+ let condition: () -> Bool
+
+ init(
+ condition: @autoclosure @escaping () -> Bool,
+ horizontalAlignment: HorizontalAlignment = .center,
+ verticalAlignment: VerticalAlignment = .center,
+ spacing: CGFloat? = nil,
+ @ViewBuilder content: @escaping () -> Content
+ ) {
+ self.condition = condition
+ self.horizontalAlignment = horizontalAlignment
+ self.verticalAlignment = verticalAlignment
+ self.spacing = spacing
+ self.content = content
+ }
+
+ var body: some View {
+ if condition() {
+ VStack(
+ alignment: horizontalAlignment,
+ spacing: spacing,
+ content: content
+ )
+ } else {
+ HStack(
+ alignment: verticalAlignment,
+ spacing: spacing,
+ content: content
+ )
+ }
+ }
+}
diff --git a/Sources/Web3ModalUI/Miscellaneous/Binding+extension.swift b/Sources/Web3ModalUI/Miscellaneous/Binding+extension.swift
new file mode 100644
index 0000000..1d872b6
--- /dev/null
+++ b/Sources/Web3ModalUI/Miscellaneous/Binding+extension.swift
@@ -0,0 +1,9 @@
+import SwiftUI
+
+public extension Binding {
+ /// Shorthand for default binding. Usually handy in View initialisers where outside binding is optional.
+ static func stored(_ value: Value) -> Self {
+ var value = value
+ return .init(get: { value }, set: { value = $0 })
+ }
+}
diff --git a/Sources/Web3ModalUI/Miscellaneous/DrawingProgressView.swift b/Sources/Web3ModalUI/Miscellaneous/DrawingProgressView.swift
new file mode 100644
index 0000000..a8a192e
--- /dev/null
+++ b/Sources/Web3ModalUI/Miscellaneous/DrawingProgressView.swift
@@ -0,0 +1,451 @@
+import SwiftUI
+import UIKit
+
+public struct DrawingProgressView: UIViewRepresentable {
+ var shape: DrawingProgressUIView.ShapePath
+ var color: UIColor
+ var lineWidth: CGFloat
+ var duration: Double
+
+ @Binding var isAnimating: Bool
+
+ public init(
+ shape: DrawingProgressUIView.ShapePath,
+ color: UIColor,
+ lineWidth: CGFloat,
+ duration: Double = 1.5,
+ isAnimating: Binding
+ ) {
+ self.shape = shape
+ self.color = color
+ self.lineWidth = lineWidth
+ self.duration = duration
+ self._isAnimating = isAnimating
+ }
+
+ public func makeUIView(context: Context) -> DrawingProgressUIView {
+ let view = DrawingProgressUIView(
+ shape: shape,
+ colors: [color],
+ lineWidth: lineWidth,
+ duration: duration
+ )
+
+ view.isAnimating = true
+
+ switch self.shape {
+ case .circle, .roundedRectangleRelative, .roundedRectangleAbsolute:
+ view.transform = .identity.rotated(by: -CGFloat.pi / 2)
+ case .hexagon:
+ break
+ }
+
+ return view
+ }
+
+ public func updateUIView(_ uiView: DrawingProgressUIView, context: Context) {
+ uiView.isAnimating = true
+ }
+}
+
+struct DrawingProgressView_Preview: PreviewProvider {
+ static var previews: some View {
+ VStack {
+ DrawingProgressView(
+ shape: .circle,
+ color: .blue,
+ lineWidth: 5,
+ isAnimating: .constant(true)
+ )
+ .frame(width: 100, height: 100)
+
+ DrawingProgressView(
+ shape: .roundedRectangleAbsolute(cornerRadius: 5),
+ color: .blue,
+ lineWidth: 5,
+ isAnimating: .constant(true)
+ )
+ .frame(width: 100, height: 100)
+
+ DrawingProgressView(
+ shape: .roundedRectangleRelative(relativeCornerRadius: 0.25),
+ color: .blue,
+ lineWidth: 5,
+ isAnimating: .constant(true)
+ )
+ .frame(width: 100, height: 100)
+
+ DrawingProgressView(
+ shape: .hexagon,
+ color: .blue,
+ lineWidth: 5,
+ isAnimating: .constant(true)
+ )
+ .frame(width: 100, height: 100)
+ }
+ }
+}
+
+public class DrawingProgressUIView: UIView {
+ public enum ShapePath {
+ case circle
+ case roundedRectangleRelative(relativeCornerRadius: Double)
+ case roundedRectangleAbsolute(cornerRadius: Double)
+ case hexagon
+ }
+
+ // MARK: - Properties
+
+ let shape: ShapePath
+ let colors: [UIColor]
+ let lineWidth: CGFloat
+ let duration: Double
+
+ private lazy var shapeLayer: ProgressShapeLayer = .init(strokeColor: colors.first!, lineWidth: lineWidth)
+
+ var isAnimating: Bool = false {
+ didSet {
+ if self.isAnimating {
+ self.animateStroke()
+ } else {
+ self.shapeLayer.removeFromSuperlayer()
+ self.layer.removeAllAnimations()
+ self.removeFromSuperview()
+ }
+ }
+ }
+
+ // MARK: - Initialization
+
+ init(
+ shape: ShapePath,
+ frame: CGRect,
+ colors: [UIColor],
+ lineWidth: CGFloat,
+ duration: Double
+ ) {
+ self.shape = shape
+ self.colors = colors
+ self.lineWidth = lineWidth
+ self.duration = duration
+
+ super.init(frame: frame)
+
+ self.backgroundColor = .clear
+ }
+
+ convenience init(
+ shape: ShapePath,
+ colors: [UIColor],
+ lineWidth: CGFloat,
+ duration: Double
+ ) {
+ self.init(
+ shape: shape,
+ frame: .zero,
+ colors: colors,
+ lineWidth: lineWidth,
+ duration: duration
+ )
+ }
+
+ @available(*, unavailable)
+ required init?(coder: NSCoder) {
+ fatalError("init(coder:) is not supported")
+ }
+
+ override public func layoutSubviews() {
+ super.layoutSubviews()
+
+ let path: CGPath
+
+ switch self.shape {
+ case .circle:
+ path = UIBezierPath(ovalIn: frame).cgPath
+ case let .roundedRectangleRelative(relativeCornerRadius):
+ path = CGPath(
+ roundedRect: self.frame,
+ cornerWidth: self.frame.width * relativeCornerRadius,
+ cornerHeight: self.frame.height * relativeCornerRadius,
+ transform: nil
+ )
+ case let .roundedRectangleAbsolute(cornerRadius):
+ path = CGPath(
+ roundedRect: self.frame,
+ cornerWidth: cornerRadius,
+ cornerHeight: cornerRadius,
+ transform: nil
+ )
+ case .hexagon:
+ path = Polygon(count: 6, relativeCornerRadius: 0.25).path(in: frame).cgPath
+ }
+
+ self.shapeLayer.path = path
+
+ isAnimating = true
+ }
+
+ // MARK: - Animations
+
+ func animateStroke() {
+ let beginTime = 0.25
+
+ let startAnimation = StrokeAnimation(
+ type: .start,
+ beginTime: beginTime,
+ fromValue: 0.0,
+ toValue: 1.0,
+ duration: duration - beginTime
+ )
+
+ let endAnimation = StrokeAnimation(
+ type: .end,
+ fromValue: 0.0,
+ toValue: 1.0,
+ duration: duration - beginTime
+ )
+
+ let strokeAnimationGroup = CAAnimationGroup()
+ strokeAnimationGroup.duration = self.duration
+ strokeAnimationGroup.repeatDuration = .infinity
+ strokeAnimationGroup.animations = [startAnimation, endAnimation]
+
+ self.shapeLayer.add(strokeAnimationGroup, forKey: "stroke")
+
+ let colorAnimation = StrokeColorAnimation(
+ colors: colors.map { $0.cgColor },
+ duration: strokeAnimationGroup.duration * Double(self.colors.count)
+ )
+
+ self.shapeLayer.add(colorAnimation, forKey: "color")
+
+ self.layer.addSublayer(self.shapeLayer)
+
+ self.shapeLayer.makeAnimationsPersistent()
+ }
+
+ func animateRotation() {
+ let rotationAnimation = RotationAnimation(
+ direction: .z,
+ fromValue: 0,
+ toValue: CGFloat.pi * 2,
+ duration: 2,
+ repeatCount: .greatestFiniteMagnitude
+ )
+
+ self.layer.add(rotationAnimation, forKey: nil)
+ }
+}
+
+class ProgressShapeLayer: CAShapeLayer {
+ public init(strokeColor: UIColor, lineWidth: CGFloat) {
+ super.init()
+
+ self.strokeColor = strokeColor.cgColor
+ self.lineWidth = lineWidth
+ self.fillColor = UIColor.clear.cgColor
+ self.lineCap = .round
+ }
+
+ @available(*, unavailable)
+ required init?(coder: NSCoder) {
+ fatalError("init(coder:) has not been implemented")
+ }
+}
+
+class RotationAnimation: CABasicAnimation {
+ enum Direction: String {
+ case x, y, z
+ }
+
+ override init() {
+ super.init()
+ }
+
+ public init(
+ direction: Direction,
+ fromValue: CGFloat,
+ toValue: CGFloat,
+ duration: Double,
+ repeatCount: Float
+ ) {
+ super.init()
+
+ self.keyPath = "transform.rotation.\(direction.rawValue)"
+
+ self.fromValue = fromValue
+ self.toValue = toValue
+
+ self.duration = duration
+
+ self.repeatCount = repeatCount
+ }
+
+ @available(*, unavailable)
+ required init?(coder: NSCoder) {
+ fatalError("init(coder:) has not been implemented")
+ }
+}
+
+class StrokeAnimation: CABasicAnimation {
+ override init() {
+ super.init()
+ }
+
+ init(
+ type: StrokeType,
+ beginTime: Double = 0.0,
+ fromValue: CGFloat,
+ toValue: CGFloat,
+ duration: Double
+ ) {
+ super.init()
+
+ self.keyPath = type == .start ? "strokeStart" : "strokeEnd"
+
+ self.beginTime = beginTime
+ self.fromValue = fromValue
+ self.toValue = toValue
+ self.duration = duration
+ self.timingFunction = .init(name: .easeInEaseOut)
+ }
+
+ @available(*, unavailable)
+ required init?(coder: NSCoder) {
+ fatalError("init(coder:) has not been implemented")
+ }
+
+ enum StrokeType {
+ case start
+ case end
+ }
+}
+
+class StrokeColorAnimation: CAKeyframeAnimation {
+ override init() {
+ super.init()
+ }
+
+ init(colors: [CGColor], duration: Double) {
+ super.init()
+
+ self.keyPath = "strokeColor"
+ self.values = colors
+ self.duration = duration
+ self.repeatCount = .greatestFiniteMagnitude
+ self.timingFunction = .init(name: .easeInEaseOut)
+ }
+
+ @available(*, unavailable)
+ required init?(coder: NSCoder) {
+ fatalError("init(coder:) has not been implemented")
+ }
+}
+
+public extension CALayer {
+ var isAnimationsPaused: Bool {
+ return speed == 0.0
+ }
+
+ func pauseAnimations() {
+ if !self.isAnimationsPaused {
+ let currentTime = CACurrentMediaTime()
+ let pausedTime = convertTime(currentTime, from: nil)
+ speed = 0.0
+ timeOffset = pausedTime
+ }
+ }
+
+ func resumeAnimations() {
+ let pausedTime = timeOffset
+ speed = 1.0
+ timeOffset = 0.0
+ beginTime = 0.0
+ let currentTime = CACurrentMediaTime()
+ let timeSincePause = convertTime(currentTime, from: nil) - pausedTime
+ beginTime = timeSincePause
+ }
+}
+
+public extension CALayer {
+ private static var persistentHelperKey = "CALayer.LayerPersistentHelper"
+
+ func makeAnimationsPersistent() {
+ withUnsafePointer(to: &CALayer.persistentHelperKey) {
+ var object = objc_getAssociatedObject(self, $0)
+
+ if object == nil {
+ object = LayerPersistentHelper(with: self)
+ let nonatomic = objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC
+ objc_setAssociatedObject(self, $0, object, nonatomic)
+ }
+ }
+ }
+}
+
+public class LayerPersistentHelper {
+ private var persistentAnimations: [String: CAAnimation] = [:]
+ private var persistentSpeed: Float = 0.0
+ private weak var layer: CALayer?
+
+ public init(with layer: CALayer) {
+ self.layer = layer
+ addNotificationObservers()
+ }
+
+ deinit {
+ removeNotificationObservers()
+ }
+}
+
+private extension LayerPersistentHelper {
+ func addNotificationObservers() {
+ let center = NotificationCenter.default
+ let enterForeground = UIApplication.willEnterForegroundNotification
+ let enterBackground = UIApplication.didEnterBackgroundNotification
+ center.addObserver(self, selector: #selector(didBecomeActive), name: enterForeground, object: nil)
+ center.addObserver(self, selector: #selector(willResignActive), name: enterBackground, object: nil)
+ }
+
+ func removeNotificationObservers() {
+ NotificationCenter.default.removeObserver(self)
+ }
+
+ func persistAnimations(with keys: [String]?) {
+ guard let layer = self.layer else { return }
+ keys?.forEach { key in
+ if let animation = layer.animation(forKey: key) {
+ self.persistentAnimations[key] = animation
+ }
+ }
+ }
+
+ func restoreAnimations(with keys: [String]?) {
+ guard let layer = self.layer else { return }
+ keys?.forEach { key in
+ if let animation = persistentAnimations[key] {
+ layer.add(animation, forKey: key)
+ }
+ }
+ }
+}
+
+@objc extension LayerPersistentHelper {
+ func didBecomeActive() {
+ guard let layer = self.layer else { return }
+ self.restoreAnimations(with: Array(self.persistentAnimations.keys))
+ self.persistentAnimations.removeAll()
+ if self.persistentSpeed == 1.0 { // if layer was playing before background, resume it
+ layer.resumeAnimations()
+ }
+ }
+
+ func willResignActive() {
+ guard let layer = self.layer else { return }
+ self.persistentSpeed = layer.speed
+ layer.speed = 1.0 // in case layer was paused from outside, set speed to 1.0 to get all animations
+ self.persistAnimations(with: layer.animationKeys())
+ layer.speed = self.persistentSpeed // restore original speed
+ layer.pauseAnimations()
+ }
+}
diff --git a/Sources/Web3ModalUI/Miscellaneous/Polygon.swift b/Sources/Web3ModalUI/Miscellaneous/Polygon.swift
new file mode 100644
index 0000000..957b8e2
--- /dev/null
+++ b/Sources/Web3ModalUI/Miscellaneous/Polygon.swift
@@ -0,0 +1,242 @@
+import SwiftUI
+
+/// Animatable Polygon
+public struct Polygon: Shape {
+
+ let count: Int
+
+ enum CornerRadius {
+ case relative(CGFloat)
+ case constant(CGFloat)
+ func relativeRadius(maxRadius: CGFloat) -> CGFloat {
+ switch self {
+ case .relative(let relativeRadius):
+ return relativeRadius
+ case .constant(let radius):
+ return radius / maxRadius
+ }
+ }
+ var animatablePair: AnimatablePair {
+ get {
+ switch self {
+ case .relative(let relativeRadius):
+ return AnimatablePair(0.0, relativeRadius)
+ case .constant(let radius):
+ return AnimatablePair(1.0, radius)
+ }
+ }
+ set {
+ if newValue.first == 0.0 {
+ self = .relative(newValue.second)
+ } else {
+ self = .constant(newValue.second)
+ }
+ }
+ }
+ }
+
+ var cornerRadius: CornerRadius
+
+ public var animatableData: AnimatablePair {
+ get {
+ cornerRadius.animatablePair
+ }
+ set {
+ cornerRadius.animatablePair = newValue
+ }
+ }
+
+ public init(count: Int, cornerRadius: CGFloat = 0.0) {
+ self.count = max(count, 3)
+ self.cornerRadius = .constant(max(cornerRadius, 0.0))
+ }
+
+ /// `relativeCornerRadius` is between `0.0` and `1.0`, where `0.0` is a pure polygon and `1.0` is a circle.
+ public init(count: Int, relativeCornerRadius: CGFloat) {
+ self.count = max(count, 3)
+ self.cornerRadius = .relative(min(max(relativeCornerRadius, 0.0), 1.0))
+ }
+
+ public func path(in rect: CGRect) -> Path {
+
+ var path = Path()
+
+ let size: CGSize = rect.size
+
+ let maxRadius = maxRadius(size: size)
+ let relativeCornerRadius = cornerRadius.relativeRadius(maxRadius: maxRadius)
+
+ if relativeCornerRadius == 0.0 {
+
+ for i in 0.. CGFloat {
+ min(size.width, size.height) / 2.0
+ }
+
+ func angle(index: CGFloat) -> CGFloat {
+ index / CGFloat(count) - 0.25
+ }
+
+ func point(angle: CGFloat, size: CGSize) -> CGPoint {
+ let x: CGFloat = size.width / 2.0 + cos(angle * .pi * 2.0) * radius(size: size)
+ let y: CGFloat = size.height / 2.0 + sin(angle * .pi * 2.0) * radius(size: size)
+ return CGPoint(x: x, y: y)
+ }
+
+ func maxRadius(size: CGSize) -> CGFloat {
+
+ let currentPoint: CGPoint = point(angle: angle(index: 0.0), size: size)
+ let nextPoint: CGPoint = point(angle: angle(index: 1.0), size: size)
+
+ let midPoint: CGPoint = CGPoint(x: (currentPoint.x + nextPoint.x) / 2,
+ y: (currentPoint.y + nextPoint.y) / 2)
+
+ let centerPoint: CGPoint = CGPoint(x: size.width / 2,
+ y: size.height / 2)
+
+ let pointDistance: CGPoint = CGPoint(x: abs(midPoint.x - centerPoint.x),
+ y: abs(midPoint.y - centerPoint.y))
+ let distance: CGFloat = hypot(pointDistance.x, pointDistance.y)
+
+ return distance
+
+ }
+
+ struct RounedCornerCircle {
+ let center: CGPoint
+ let leading: CGPoint
+ let trailing: CGPoint
+ }
+
+ func rounedCornerCircle(leading: CGPoint,
+ center: CGPoint,
+ trailing: CGPoint,
+ cornerRadius: CGFloat) -> RounedCornerCircle {
+ rounedCornerCircle(center, leading, trailing, cornerRadius)
+ }
+
+ private func rounedCornerCircle(_ p: CGPoint,
+ _ p1: CGPoint,
+ _ p2: CGPoint,
+ _ r: CGFloat) -> RounedCornerCircle {
+
+ var r: CGFloat = r
+
+ //Vector 1
+ let dx1: CGFloat = p.x - p1.x
+ let dy1: CGFloat = p.y - p1.y
+
+ //Vector 2
+ let dx2: CGFloat = p.x - p2.x
+ let dy2: CGFloat = p.y - p2.y
+
+ //Angle between vector 1 and vector 2 divided by 2
+ let angle: CGFloat = (atan2(dy1, dx1) - atan2(dy2, dx2)) / 2
+
+ // The length of segment between angular point and the
+ // points of intersection with the circle of a given radius
+ let _tan: CGFloat = abs(tan(angle))
+ var segment: CGFloat = r / _tan
+
+ //Check the segment
+ let length1: CGFloat = sqrt(pow(dx1, 2) + pow(dy1, 2))
+ let length2: CGFloat = sqrt(pow(dx2, 2) + pow(dy2, 2))
+
+ let _length: CGFloat = min(length1, length2)
+
+ if segment > _length {
+ segment = _length;
+ r = _length * _tan;
+ }
+
+ // Points of intersection are calculated by the proportion between
+ // the coordinates of the vector, length of vector and the length of the segment.
+ let p1Cross: CGPoint = proportion(p, segment, length1, dx1, dy1)
+ let p2Cross: CGPoint = proportion(p, segment, length2, dx2, dy2)
+
+ // Calculation of the coordinates of the circle
+ // center by the addition of angular vectors.
+ let dx: CGFloat = p.x * 2 - p1Cross.x - p2Cross.x
+ let dy: CGFloat = p.y * 2 - p1Cross.y - p2Cross.y
+
+ let L: CGFloat = sqrt(pow(dx, 2) + pow(dy, 2))
+ let d: CGFloat = sqrt(pow(segment, 2) + pow(r, 2))
+
+ let circlePoint: CGPoint = proportion(p, d, L, dx, dy)
+
+ return RounedCornerCircle(center: circlePoint, leading: p1Cross, trailing: p2Cross)
+
+ }
+
+ private func proportion(_ point: CGPoint,
+ _ segment: CGFloat,
+ _ length: CGFloat,
+ _ dx: CGFloat,
+ _ dy: CGFloat) -> CGPoint {
+ let factor: CGFloat = segment / length
+ return CGPoint(x: point.x - dx * factor,
+ y: point.y - dy * factor)
+ }
+}
+
+struct Polygon_Previews: PreviewProvider {
+ static var previews: some View {
+ Polygon(count: 6, relativeCornerRadius: 0.5)
+ }
+}
diff --git a/Sources/Web3ModalUI/Miscellaneous/Shape+extension.swift b/Sources/Web3ModalUI/Miscellaneous/Shape+extension.swift
new file mode 100644
index 0000000..a28ab44
--- /dev/null
+++ b/Sources/Web3ModalUI/Miscellaneous/Shape+extension.swift
@@ -0,0 +1,17 @@
+import SwiftUI
+
+public extension Shape {
+ func fill(_ fillStyle: Fill, strokeBorder strokeStyle: Stroke, lineWidth: Double = 1) -> some View {
+ self
+ .stroke(strokeStyle, lineWidth: lineWidth)
+ .background(self.fill(fillStyle))
+ }
+}
+
+public extension InsettableShape {
+ func fill(_ fillStyle: Fill, strokeBorder strokeStyle: Stroke, lineWidth: Double = 1) -> some View {
+ self
+ .strokeBorder(strokeStyle, lineWidth: lineWidth)
+ .background(self.fill(fillStyle))
+ }
+}
diff --git a/Sources/Web3ModalUI/Miscellaneous/Toast.swift b/Sources/Web3ModalUI/Miscellaneous/Toast.swift
new file mode 100644
index 0000000..61237fd
--- /dev/null
+++ b/Sources/Web3ModalUI/Miscellaneous/Toast.swift
@@ -0,0 +1,157 @@
+import SwiftUI
+
+public struct Toast: Equatable {
+ let style: ToastStyle
+ let message: String
+ var duration: Double = 1.5
+ var width: Double = .infinity
+
+ public init(style: ToastStyle, message: String, duration: Double = 1.5, width: Double = .infinity) {
+ self.style = style
+ self.message = message
+ self.duration = duration
+ self.width = width
+ }
+}
+
+public enum ToastStyle {
+ case error
+ case success
+ case info
+
+ var icon: Image {
+ switch self {
+ case .info: return Image.Original.toastInfo
+ case .success: return Image.Original.toastSuccess
+ case .error: return Image.Original.toastError
+ }
+ }
+}
+
+struct ToastView: View {
+ var style: ToastStyle
+ var message: String
+
+ var onCancelTapped: () -> Void
+
+ public var body: some View {
+ HStack(alignment: .center, spacing: Spacing.xs) {
+ style.icon
+
+ Text(message.prefix(100))
+ .font(.paragraph600)
+ .foregroundColor(.Foreground100)
+
+ }
+ .onTapGesture {
+ onCancelTapped()
+ }
+ .padding(.leading, Spacing.xs)
+ .padding(.trailing, Spacing.l)
+ .padding(.vertical, Spacing.xs)
+ .background(Color.Background125)
+ .cornerRadius(Radius.l)
+ .backport
+ .overlay {
+ RoundedRectangle(cornerRadius: Radius.l)
+ .stroke(.GrayGlass005, lineWidth: 1)
+ }
+ .shadow(color: .black.opacity(0.12), radius: 32, x: 0, y: 14)
+ .shadow(color: .black.opacity(0.12), radius: 11, x: 0, y: 8)
+ }
+}
+
+public struct ToastModifier: ViewModifier {
+ @Binding var toast: Toast?
+ @State private var workItem: DispatchWorkItem?
+
+ public func body(content: Content) -> some View {
+ content
+ .overlay(
+ ZStack {
+ mainToastView()
+ .padding(Spacing.s)
+ }
+ .animation(.spring(), value: toast)
+ )
+ .backport.onChange(of: toast) { _ in
+ showToast()
+ }
+ }
+
+ @ViewBuilder func mainToastView() -> some View {
+ if let toast = toast {
+ VStack {
+ ToastView(
+ style: toast.style,
+ message: toast.message
+ ) {
+ dismissToast()
+ }
+
+ Spacer()
+ .allowsHitTesting(false)
+ }
+ }
+ }
+
+ private func showToast() {
+ guard let toast = toast else { return }
+
+ #if os(iOS)
+ UIImpactFeedbackGenerator(style: .light)
+ .impactOccurred()
+ #endif
+
+ if toast.duration > 0 {
+ workItem?.cancel()
+
+ let task = DispatchWorkItem {
+ dismissToast()
+ }
+
+ workItem = task
+ DispatchQueue.main.asyncAfter(deadline: .now() + toast.duration, execute: task)
+ }
+ }
+
+ private func dismissToast() {
+ withAnimation {
+ toast = nil
+ }
+
+ workItem?.cancel()
+ workItem = nil
+ }
+}
+
+public extension View {
+ func toastView(toast: Binding) -> some View {
+ modifier(ToastModifier(toast: toast))
+ }
+}
+
+#if DEBUG
+
+public struct ToastViewPreviewView: View {
+ public init() {}
+
+ public var body: some View {
+ VStack {
+ ToastView(style: .info, message: "Hello World", onCancelTapped: {})
+ ToastView(style: .error, message: "Hello World", onCancelTapped: {})
+ ToastView(style: .success, message: "Address copied", onCancelTapped: {})
+ }
+ .padding()
+ .background(Color.Overgray002)
+ }
+}
+
+struct ToastView_Preview: PreviewProvider {
+ static var previews: some View {
+ ToastViewPreviewView()
+ .previewLayout(.sizeThatFits)
+ }
+}
+
+#endif
diff --git a/Sources/Web3ModalUI/Modifiers/Conditional.swift b/Sources/Web3ModalUI/Modifiers/Conditional.swift
new file mode 100644
index 0000000..4a0767f
--- /dev/null
+++ b/Sources/Web3ModalUI/Modifiers/Conditional.swift
@@ -0,0 +1,21 @@
+import SwiftUI
+
+extension View {
+ /// Applies the given transform if the given condition evaluates to `true`.
+ /// - Parameters:
+ /// - condition: The condition to evaluate.
+ /// - transform: The transform to apply to the source `View`.
+ /// - Returns: Either the original `View` or the modified `View` if the condition is `true`.
+ @ViewBuilder public func `if`(_ condition: @autoclosure () -> Bool, transform: (Self) -> Content) -> some View {
+ if condition() {
+ transform(self)
+ } else {
+ self
+ }
+ }
+
+ /// Transforms the source `View` with the given closure giving more flexibility with modifcations.
+ public func transform(@ViewBuilder _ transform: (Self) -> some View) -> some View {
+ transform(self)
+ }
+}
diff --git a/Sources/Web3ModalUI/Modifiers/Shimmer.swift b/Sources/Web3ModalUI/Modifiers/Shimmer.swift
new file mode 100644
index 0000000..2744c92
--- /dev/null
+++ b/Sources/Web3ModalUI/Modifiers/Shimmer.swift
@@ -0,0 +1,75 @@
+import SwiftUI
+
+public struct ShimmerBackground: ViewModifier {
+ private let animation: Animation
+ private let gradient: Gradient
+ private let min, max: CGFloat
+ @State private var isInitialState = true
+ @Environment(\.layoutDirection) private var layoutDirection
+
+ /// Initializes his modifier with a custom animation,
+ /// - Parameters:
+ /// - animation: A custom animation. Defaults to ``Shimmer/defaultAnimation``.
+ /// - gradient: A custom gradient. Defaults to ``Shimmer/defaultGradient``.
+ /// - bandSize: The size of the animated mask's "band". Defaults to 0.3 unit points, which corresponds to
+ /// 30% of the extent of the gradient.
+ public init(
+ animation: Animation = Self.defaultAnimation,
+ gradient: Gradient = Self.defaultGradient,
+ bandSize: CGFloat = 0.3
+ ) {
+ self.animation = animation
+ self.gradient = gradient
+ // Calculate unit point dimensions beyond the gradient's edges by the band size
+ self.min = 0 - bandSize
+ self.max = 1 + bandSize
+ }
+
+ /// The default animation effect.
+ public static let defaultAnimation = Animation.linear(duration: 0.5).delay(0.25).repeatForever(autoreverses: false)
+
+ // A default gradient for the animated mask.
+ public static let defaultGradient = Gradient(colors: [
+ .black.opacity(0.3), // translucent
+ .black, // opaque
+ .black.opacity(0.3) // translucent
+ ])
+
+ /// The start unit point of our gradient, adjusting for layout direction.
+ var startPoint: UnitPoint {
+ return isInitialState ? UnitPoint(x: min, y: min) : UnitPoint(x: 1, y: 1)
+ }
+
+ /// The end unit point of our gradient, adjusting for layout direction.
+ var endPoint: UnitPoint {
+ return isInitialState ? UnitPoint(x: 0, y: 0) : UnitPoint(x: max, y: max)
+ }
+
+ public func body(content: Content) -> some View {
+ content
+ .mask(LinearGradient(gradient: gradient, startPoint: startPoint, endPoint: endPoint))
+ .onAppear {
+ withAnimation(animation) {
+ isInitialState = false
+ }
+ }
+ }
+}
+
+struct Shimmer_Preview: PreviewProvider {
+ static var previews: some View {
+ VStack {
+ RoundedRectangle(cornerRadius: Radius.xs)
+ .stroke(.Overgray010, lineWidth: 1)
+ .background(RoundedRectangle(cornerRadius: Radius.xs).fill(.red))
+ .frame(width: 100, height: 100)
+ .modifier(ShimmerBackground())
+
+ RoundedRectangle(cornerRadius: Radius.xs)
+ .stroke(.Overgray010, lineWidth: 1)
+ .background(RoundedRectangle(cornerRadius: Radius.xs).fill(.Overgray005))
+ .frame(width: 100, height: 100)
+ .modifier(ShimmerBackground())
+ }
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Background100.colorset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Background100.colorset/Contents.json
new file mode 100644
index 0000000..ee2f44f
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Background100.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0xFF",
+ "green" : "0xFF",
+ "red" : "0xFF"
+ }
+ },
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0x14",
+ "green" : "0x14",
+ "red" : "0x14"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Background125.colorset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Background125.colorset/Contents.json
new file mode 100644
index 0000000..dc512cd
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Background125.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0xFF",
+ "green" : "0xFF",
+ "red" : "0xFF"
+ }
+ },
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0x1A",
+ "green" : "0x1A",
+ "red" : "0x19"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Background150.colorset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Background150.colorset/Contents.json
new file mode 100644
index 0000000..b18b8b1
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Background150.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0xF8",
+ "green" : "0xF8",
+ "red" : "0xF3"
+ }
+ },
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0x1F",
+ "green" : "0x1F",
+ "red" : "0x1E"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Background175.colorset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Background175.colorset/Contents.json
new file mode 100644
index 0000000..3e3ea01
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Background175.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0xF4",
+ "green" : "0xF4",
+ "red" : "0xEE"
+ }
+ },
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0x25",
+ "green" : "0x25",
+ "red" : "0x22"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Background200.colorset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Background200.colorset/Contents.json
new file mode 100644
index 0000000..eb34a3f
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Background200.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0xF1",
+ "green" : "0xF1",
+ "red" : "0xEA"
+ }
+ },
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0x2A",
+ "green" : "0x2A",
+ "red" : "0x27"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Background225.colorset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Background225.colorset/Contents.json
new file mode 100644
index 0000000..53d70f3
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Background225.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0xED",
+ "green" : "0xED",
+ "red" : "0xE5"
+ }
+ },
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0x30",
+ "green" : "0x30",
+ "red" : "0x2C"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Background250.colorset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Background250.colorset/Contents.json
new file mode 100644
index 0000000..ea77cf3
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Background250.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0x97",
+ "green" : "0x97",
+ "red" : "0x8B"
+ }
+ },
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0x35",
+ "green" : "0x35",
+ "red" : "0x31"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Background275.colorset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Background275.colorset/Contents.json
new file mode 100644
index 0000000..496ec20
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Background275.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0xE7",
+ "green" : "0xE7",
+ "red" : "0xDC"
+ }
+ },
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0x3B",
+ "green" : "0x3B",
+ "red" : "0x36"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Background300.colorset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Background300.colorset/Contents.json
new file mode 100644
index 0000000..0e42e8d
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Background300.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0xE3",
+ "green" : "0xE3",
+ "red" : "0xD8"
+ }
+ },
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0x40",
+ "green" : "0x40",
+ "red" : "0x3B"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/BlackAndWhite100.colorset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/BlackAndWhite100.colorset/Contents.json
new file mode 100644
index 0000000..8f066e4
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/BlackAndWhite100.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0x14",
+ "green" : "0x14",
+ "red" : "0x14"
+ }
+ },
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0xFF",
+ "green" : "0xFF",
+ "red" : "0xFF"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Blue080.colorset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Blue080.colorset/Contents.json
new file mode 100644
index 0000000..a940fe0
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Blue080.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0xCC",
+ "green" : "0x78",
+ "red" : "0x29"
+ }
+ },
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0xFF",
+ "green" : "0xB4",
+ "red" : "0x6C"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Blue090.colorset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Blue090.colorset/Contents.json
new file mode 100644
index 0000000..8f757b4
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Blue090.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0xD2",
+ "green" : "0x7D",
+ "red" : "0x2D"
+ }
+ },
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0xFF",
+ "green" : "0xAA",
+ "red" : "0x59"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Blue100.colorset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Blue100.colorset/Contents.json
new file mode 100644
index 0000000..099cb90
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Blue100.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0xFF",
+ "green" : "0x96",
+ "red" : "0x33"
+ }
+ },
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0xFF",
+ "green" : "0xA1",
+ "red" : "0x47"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Contents.json
new file mode 100644
index 0000000..73c0059
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Error100.colorset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Error100.colorset/Contents.json
new file mode 100644
index 0000000..6e9d7d9
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Error100.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0x42",
+ "green" : "0x51",
+ "red" : "0xF0"
+ }
+ },
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0x67",
+ "green" : "0x5A",
+ "red" : "0xF2"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Foreground100.colorset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Foreground100.colorset/Contents.json
new file mode 100644
index 0000000..3142df2
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Foreground100.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0x14",
+ "green" : "0x14",
+ "red" : "0x14"
+ }
+ },
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0xE7",
+ "green" : "0xE7",
+ "red" : "0xE4"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Foreground125.colorset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Foreground125.colorset/Contents.json
new file mode 100644
index 0000000..217e7e0
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Foreground125.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0x31",
+ "green" : "0x31",
+ "red" : "0x2D"
+ }
+ },
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0xD5",
+ "green" : "0xD5",
+ "red" : "0xD0"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Foreground150.colorset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Foreground150.colorset/Contents.json
new file mode 100644
index 0000000..84b6d48
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Foreground150.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0x4D",
+ "green" : "0x4D",
+ "red" : "0x47"
+ }
+ },
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0xB1",
+ "green" : "0xB1",
+ "red" : "0xA8"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Foreground175.colorset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Foreground175.colorset/Contents.json
new file mode 100644
index 0000000..a360598
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Foreground175.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0x6D",
+ "green" : "0x6D",
+ "red" : "0x63"
+ }
+ },
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0xB0",
+ "green" : "0xB0",
+ "red" : "0xA8"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Foreground200.colorset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Foreground200.colorset/Contents.json
new file mode 100644
index 0000000..530bc2c
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Foreground200.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0x86",
+ "green" : "0x86",
+ "red" : "0x79"
+ }
+ },
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0x9E",
+ "green" : "0x9E",
+ "red" : "0x94"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Foreground225.colorset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Foreground225.colorset/Contents.json
new file mode 100644
index 0000000..cf83163
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Foreground225.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0x8F",
+ "green" : "0x8F",
+ "red" : "0x82"
+ }
+ },
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0x8F",
+ "green" : "0x8F",
+ "red" : "0x86"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Foreground250.colorset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Foreground250.colorset/Contents.json
new file mode 100644
index 0000000..a9fbbd1
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Foreground250.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0x80",
+ "green" : "0x80",
+ "red" : "0x78"
+ }
+ },
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0x80",
+ "green" : "0x80",
+ "red" : "0x78"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Foreground275.colorset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Foreground275.colorset/Contents.json
new file mode 100644
index 0000000..79bd67f
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Foreground275.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0xA0",
+ "green" : "0xA0",
+ "red" : "0x95"
+ }
+ },
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0x81",
+ "green" : "0x81",
+ "red" : "0x78"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Foreground300.colorset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Foreground300.colorset/Contents.json
new file mode 100644
index 0000000..93ad845
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Foreground300.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0xA9",
+ "green" : "0xA9",
+ "red" : "0x9E"
+ }
+ },
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0x77",
+ "green" : "0x77",
+ "red" : "0x6E"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Glass75.colorset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Glass75.colorset/Contents.json
new file mode 100644
index 0000000..f9ca6ba
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Glass75.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "0.750",
+ "blue" : "0xF5",
+ "green" : "0xF5",
+ "red" : "0xF4"
+ }
+ },
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "0.660",
+ "blue" : "0x2A",
+ "green" : "0x2A",
+ "red" : "0x27"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Glass88.colorset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Glass88.colorset/Contents.json
new file mode 100644
index 0000000..c11a888
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Glass88.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "0.880",
+ "blue" : "0xF5",
+ "green" : "0xF5",
+ "red" : "0xF4"
+ }
+ },
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "0.880",
+ "blue" : "0x2A",
+ "green" : "0x2A",
+ "red" : "0x27"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/GrayGlass002.colorset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/GrayGlass002.colorset/Contents.json
new file mode 100644
index 0000000..70b997b
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/GrayGlass002.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "0.020",
+ "blue" : "0x14",
+ "green" : "0x14",
+ "red" : "0x14"
+ }
+ },
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "0.020",
+ "blue" : "0xFF",
+ "green" : "0xFF",
+ "red" : "0xFF"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/GrayGlass005.colorset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/GrayGlass005.colorset/Contents.json
new file mode 100644
index 0000000..607c3d2
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/GrayGlass005.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "0.050",
+ "blue" : "0x14",
+ "green" : "0x14",
+ "red" : "0x14"
+ }
+ },
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "0.050",
+ "blue" : "0xFF",
+ "green" : "0xFF",
+ "red" : "0xFF"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/GrayGlass010.colorset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/GrayGlass010.colorset/Contents.json
new file mode 100644
index 0000000..9bab670
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/GrayGlass010.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "0.100",
+ "blue" : "0x14",
+ "green" : "0x14",
+ "red" : "0x14"
+ }
+ },
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "0.100",
+ "blue" : "0xFF",
+ "green" : "0xFF",
+ "red" : "0xFF"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/GrayGlass020.colorset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/GrayGlass020.colorset/Contents.json
new file mode 100644
index 0000000..75ce91d
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/GrayGlass020.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "0.200",
+ "blue" : "0x14",
+ "green" : "0x14",
+ "red" : "0x14"
+ }
+ },
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "0.200",
+ "blue" : "0xFF",
+ "green" : "0xFF",
+ "red" : "0xFF"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Grey18.colorset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Grey18.colorset/Contents.json
new file mode 100644
index 0000000..e8641bc
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Grey18.colorset/Contents.json
@@ -0,0 +1,20 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0x34",
+ "green" : "0x34",
+ "red" : "0x30"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Grey20.colorset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Grey20.colorset/Contents.json
new file mode 100644
index 0000000..2985886
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Grey20.colorset/Contents.json
@@ -0,0 +1,20 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0x3B",
+ "green" : "0x3B",
+ "red" : "0x36"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Grey22.colorset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Grey22.colorset/Contents.json
new file mode 100644
index 0000000..6371178
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Grey22.colorset/Contents.json
@@ -0,0 +1,20 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0x3F",
+ "green" : "0x3F",
+ "red" : "0x3A"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Indigo100.colorset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Indigo100.colorset/Contents.json
new file mode 100644
index 0000000..c593b1c
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Indigo100.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0xF5",
+ "green" : "0x5C",
+ "red" : "0x3D"
+ }
+ },
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0xFB",
+ "green" : "0x6D",
+ "red" : "0x51"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Inverse000.colorset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Inverse000.colorset/Contents.json
new file mode 100644
index 0000000..be9d677
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Inverse000.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0x00",
+ "green" : "0x00",
+ "red" : "0x00"
+ }
+ },
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0x00",
+ "green" : "0x00",
+ "red" : "0x00"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Inverse100.colorset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Inverse100.colorset/Contents.json
new file mode 100644
index 0000000..2536dc2
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Inverse100.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0xFF",
+ "green" : "0xFF",
+ "red" : "0xFF"
+ }
+ },
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0xFF",
+ "green" : "0xFF",
+ "red" : "0xFF"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Magenta100.colorset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Magenta100.colorset/Contents.json
new file mode 100644
index 0000000..24458dc
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Magenta100.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0x80",
+ "green" : "0x53",
+ "red" : "0xC6"
+ }
+ },
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0x8C",
+ "green" : "0x4D",
+ "red" : "0xCB"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Orange100.colorset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Orange100.colorset/Contents.json
new file mode 100644
index 0000000..e0d30b9
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Orange100.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0x2E",
+ "green" : "0x8C",
+ "red" : "0xEA"
+ }
+ },
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0x4C",
+ "green" : "0xA6",
+ "red" : "0xFF"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Overblue002.colorset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Overblue002.colorset/Contents.json
new file mode 100644
index 0000000..494cdad
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Overblue002.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "0.020",
+ "blue" : "0xFF",
+ "green" : "0x96",
+ "red" : "0x33"
+ }
+ },
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "0.020",
+ "blue" : "0xFF",
+ "green" : "0xA1",
+ "red" : "0x47"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Overblue005.colorset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Overblue005.colorset/Contents.json
new file mode 100644
index 0000000..8d76ed1
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Overblue005.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "0.050",
+ "blue" : "0xFF",
+ "green" : "0x96",
+ "red" : "0x33"
+ }
+ },
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "0.050",
+ "blue" : "0xFF",
+ "green" : "0xA1",
+ "red" : "0x47"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Overblue010.colorset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Overblue010.colorset/Contents.json
new file mode 100644
index 0000000..42ec524
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Overblue010.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "0.100",
+ "blue" : "0xFF",
+ "green" : "0x96",
+ "red" : "0x33"
+ }
+ },
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "0.100",
+ "blue" : "0xFF",
+ "green" : "0xA1",
+ "red" : "0x47"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Overblue015.colorset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Overblue015.colorset/Contents.json
new file mode 100644
index 0000000..2fae9a8
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Overblue015.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "0.150",
+ "blue" : "0xFF",
+ "green" : "0x96",
+ "red" : "0x33"
+ }
+ },
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "0.150",
+ "blue" : "0xFF",
+ "green" : "0xA1",
+ "red" : "0x47"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Overblue020.colorset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Overblue020.colorset/Contents.json
new file mode 100644
index 0000000..7bf35a8
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Overblue020.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "0.200",
+ "blue" : "0xFF",
+ "green" : "0x96",
+ "red" : "0x33"
+ }
+ },
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "0.200",
+ "blue" : "0xFF",
+ "green" : "0xA1",
+ "red" : "0x47"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Overblue080.colorset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Overblue080.colorset/Contents.json
new file mode 100644
index 0000000..8a630db
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Overblue080.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "0.800",
+ "blue" : "0xFF",
+ "green" : "0x96",
+ "red" : "0x33"
+ }
+ },
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "0.800",
+ "blue" : "0xFF",
+ "green" : "0xA1",
+ "red" : "0x47"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Overblue090.colorset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Overblue090.colorset/Contents.json
new file mode 100644
index 0000000..22ff9d6
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Overblue090.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "0.900",
+ "blue" : "0xFF",
+ "green" : "0x96",
+ "red" : "0x33"
+ }
+ },
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "0.900",
+ "blue" : "0xFF",
+ "green" : "0xA1",
+ "red" : "0x47"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Overgray001.colorset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Overgray001.colorset/Contents.json
new file mode 100644
index 0000000..7a5a199
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Overgray001.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "0.010",
+ "blue" : "0x00",
+ "green" : "0x00",
+ "red" : "0x00"
+ }
+ },
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "0.010",
+ "blue" : "0xFF",
+ "green" : "0xFF",
+ "red" : "0xFF"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Overgray002.colorset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Overgray002.colorset/Contents.json
new file mode 100644
index 0000000..cd2c284
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Overgray002.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "0.020",
+ "blue" : "0x00",
+ "green" : "0x00",
+ "red" : "0x00"
+ }
+ },
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "0.020",
+ "blue" : "0xFF",
+ "green" : "0xFF",
+ "red" : "0xFF"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Overgray005.colorset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Overgray005.colorset/Contents.json
new file mode 100644
index 0000000..ed54576
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Overgray005.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "0.050",
+ "blue" : "0x00",
+ "green" : "0x00",
+ "red" : "0x00"
+ }
+ },
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "0.050",
+ "blue" : "0xFF",
+ "green" : "0xFF",
+ "red" : "0xFF"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Overgray010.colorset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Overgray010.colorset/Contents.json
new file mode 100644
index 0000000..250f2d9
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Overgray010.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "0.100",
+ "blue" : "0x00",
+ "green" : "0x00",
+ "red" : "0x00"
+ }
+ },
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "0.100",
+ "blue" : "0xFF",
+ "green" : "0xFF",
+ "red" : "0xFF"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Overgray015.colorset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Overgray015.colorset/Contents.json
new file mode 100644
index 0000000..12aca6f
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Overgray015.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "0.150",
+ "blue" : "0x00",
+ "green" : "0x00",
+ "red" : "0x00"
+ }
+ },
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "0.150",
+ "blue" : "0xFF",
+ "green" : "0xFF",
+ "red" : "0xFF"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Overgray020.colorset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Overgray020.colorset/Contents.json
new file mode 100644
index 0000000..2fdf102
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Overgray020.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "0.200",
+ "blue" : "0x00",
+ "green" : "0x00",
+ "red" : "0x00"
+ }
+ },
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "0.200",
+ "blue" : "0xFF",
+ "green" : "0xFF",
+ "red" : "0xFF"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Overgray025.colorset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Overgray025.colorset/Contents.json
new file mode 100644
index 0000000..a2bdd9c
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Overgray025.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "0.250",
+ "blue" : "0x00",
+ "green" : "0x00",
+ "red" : "0x00"
+ }
+ },
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "0.250",
+ "blue" : "0xFF",
+ "green" : "0xFF",
+ "red" : "0xFF"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Overgray030.colorset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Overgray030.colorset/Contents.json
new file mode 100644
index 0000000..5d5e58c
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Overgray030.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "0.300",
+ "blue" : "0x00",
+ "green" : "0x00",
+ "red" : "0x00"
+ }
+ },
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "0.300",
+ "blue" : "0xFF",
+ "green" : "0xFF",
+ "red" : "0xFF"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Purple100.colorset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Purple100.colorset/Contents.json
new file mode 100644
index 0000000..3c591e5
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Purple100.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0xFF",
+ "green" : "0x4C",
+ "red" : "0x79"
+ }
+ },
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0xF7",
+ "green" : "0x6E",
+ "red" : "0x90"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Success100.colorset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Success100.colorset/Contents.json
new file mode 100644
index 0000000..68259fb
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Success100.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0x62",
+ "green" : "0xB5",
+ "red" : "0x26"
+ }
+ },
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0x62",
+ "green" : "0xD9",
+ "red" : "0x26"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Teal100.colorset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Teal100.colorset/Contents.json
new file mode 100644
index 0000000..d694a42
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Teal100.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0xB6",
+ "green" : "0xB6",
+ "red" : "0x2B"
+ }
+ },
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0xE2",
+ "green" : "0xE2",
+ "red" : "0x36"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Yellow100.colorset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Yellow100.colorset/Contents.json
new file mode 100644
index 0000000..7b82ea9
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Colors/Yellow100.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0x1C",
+ "green" : "0xCC",
+ "red" : "0xEE"
+ }
+ },
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0x00",
+ "green" : "0xFF",
+ "red" : "0xFA"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Contents.json
new file mode 100644
index 0000000..73c0059
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Arrow Bottom.imageset/Arrow Bottom.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Arrow Bottom.imageset/Arrow Bottom.pdf
new file mode 100644
index 0000000..0a66ca1
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Arrow Bottom.imageset/Arrow Bottom.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Arrow Bottom.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Arrow Bottom.imageset/Contents.json
new file mode 100644
index 0000000..cce0756
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Arrow Bottom.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Arrow Bottom.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Arrow Left.imageset/Arrow Left.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Arrow Left.imageset/Arrow Left.pdf
new file mode 100644
index 0000000..608ff24
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Arrow Left.imageset/Arrow Left.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Arrow Left.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Arrow Left.imageset/Contents.json
new file mode 100644
index 0000000..2c3eac9
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Arrow Left.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Arrow Left.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Arrow Right.imageset/Arrow Right.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Arrow Right.imageset/Arrow Right.pdf
new file mode 100644
index 0000000..ea748e6
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Arrow Right.imageset/Arrow Right.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Arrow Right.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Arrow Right.imageset/Contents.json
new file mode 100644
index 0000000..5d97a0c
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Arrow Right.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Arrow Right.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Arrow Top.imageset/Arrow Top.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Arrow Top.imageset/Arrow Top.pdf
new file mode 100644
index 0000000..5b65890
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Arrow Top.imageset/Arrow Top.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Arrow Top.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Arrow Top.imageset/Contents.json
new file mode 100644
index 0000000..56450d4
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Arrow Top.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Arrow Top.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Bars.imageset/Bars.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Bars.imageset/Bars.pdf
new file mode 100644
index 0000000..a73617f
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Bars.imageset/Bars.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Bars.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Bars.imageset/Contents.json
new file mode 100644
index 0000000..f6402c7
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Bars.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Bars.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Bin.imageset/Bin.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Bin.imageset/Bin.pdf
new file mode 100644
index 0000000..7a4876c
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Bin.imageset/Bin.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Bin.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Bin.imageset/Contents.json
new file mode 100644
index 0000000..a2fd38f
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Bin.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Bin.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Browser.imageset/Browser.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Browser.imageset/Browser.pdf
new file mode 100644
index 0000000..74e2d3c
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Browser.imageset/Browser.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Browser.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Browser.imageset/Contents.json
new file mode 100644
index 0000000..3f27bd6
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Browser.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Browser.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Checkmark.imageset/Checkmark.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Checkmark.imageset/Checkmark.pdf
new file mode 100644
index 0000000..f616b52
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Checkmark.imageset/Checkmark.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Checkmark.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Checkmark.imageset/Contents.json
new file mode 100644
index 0000000..63f424b
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Checkmark.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Checkmark.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Chevron Bottom.imageset/Chevron Bottom.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Chevron Bottom.imageset/Chevron Bottom.pdf
new file mode 100644
index 0000000..7e86e63
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Chevron Bottom.imageset/Chevron Bottom.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Chevron Bottom.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Chevron Bottom.imageset/Contents.json
new file mode 100644
index 0000000..f664dce
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Chevron Bottom.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Chevron Bottom.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Chevron Left.imageset/Chevron Left.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Chevron Left.imageset/Chevron Left.pdf
new file mode 100644
index 0000000..56c69d7
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Chevron Left.imageset/Chevron Left.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Chevron Left.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Chevron Left.imageset/Contents.json
new file mode 100644
index 0000000..80250da
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Chevron Left.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Chevron Left.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Chevron Right.imageset/Chevron Right.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Chevron Right.imageset/Chevron Right.pdf
new file mode 100644
index 0000000..84cd330
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Chevron Right.imageset/Chevron Right.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Chevron Right.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Chevron Right.imageset/Contents.json
new file mode 100644
index 0000000..4163df7
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Chevron Right.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Chevron Right.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Chevron Top.imageset/Chevron Top.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Chevron Top.imageset/Chevron Top.pdf
new file mode 100644
index 0000000..da41ee9
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Chevron Top.imageset/Chevron Top.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Chevron Top.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Chevron Top.imageset/Contents.json
new file mode 100644
index 0000000..e18a8d9
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Chevron Top.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Chevron Top.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Clock.imageset/Clock.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Clock.imageset/Clock.pdf
new file mode 100644
index 0000000..bc571c2
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Clock.imageset/Clock.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Clock.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Clock.imageset/Contents.json
new file mode 100644
index 0000000..79d4586
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Clock.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Clock.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Code.imageset/Code.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Code.imageset/Code.pdf
new file mode 100644
index 0000000..7490dbe
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Code.imageset/Code.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Code.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Code.imageset/Contents.json
new file mode 100644
index 0000000..882467e
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Code.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Code.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Compass.imageset/Compass.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Compass.imageset/Compass.pdf
new file mode 100644
index 0000000..b80697c
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Compass.imageset/Compass.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Compass.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Compass.imageset/Contents.json
new file mode 100644
index 0000000..7eb503e
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Compass.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Compass.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Contents.json
new file mode 100644
index 0000000..6e96565
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Contents.json
@@ -0,0 +1,9 @@
+{
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "provides-namespace" : true
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Copy.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Copy.imageset/Contents.json
new file mode 100644
index 0000000..7cd8eaf
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Copy.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Copy.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Copy.imageset/Copy.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Copy.imageset/Copy.pdf
new file mode 100644
index 0000000..d737c9f
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Copy.imageset/Copy.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Desktop.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Desktop.imageset/Contents.json
new file mode 100644
index 0000000..6c3a2a4
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Desktop.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Desktop.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Desktop.imageset/Desktop.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Desktop.imageset/Desktop.pdf
new file mode 100644
index 0000000..b0a5f5f
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Desktop.imageset/Desktop.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Disconnect.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Disconnect.imageset/Contents.json
new file mode 100644
index 0000000..0635154
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Disconnect.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Disconnect.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Disconnect.imageset/Disconnect.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Disconnect.imageset/Disconnect.pdf
new file mode 100644
index 0000000..2d745ad
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Disconnect.imageset/Disconnect.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Doc.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Doc.imageset/Contents.json
new file mode 100644
index 0000000..1d93e4d
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Doc.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Doc.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Doc.imageset/Doc.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Doc.imageset/Doc.pdf
new file mode 100644
index 0000000..c310219
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Doc.imageset/Doc.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Double Chevron Vertical.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Double Chevron Vertical.imageset/Contents.json
new file mode 100644
index 0000000..90f2f94
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Double Chevron Vertical.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Double Chevron Vertical.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Double Chevron Vertical.imageset/Double Chevron Vertical.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Double Chevron Vertical.imageset/Double Chevron Vertical.pdf
new file mode 100644
index 0000000..7a29e36
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Double Chevron Vertical.imageset/Double Chevron Vertical.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/External Link.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/External Link.imageset/Contents.json
new file mode 100644
index 0000000..be6a2f0
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/External Link.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "External Link.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/External Link.imageset/External Link.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/External Link.imageset/External Link.pdf
new file mode 100644
index 0000000..02ed310
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/External Link.imageset/External Link.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Eye Crossed.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Eye Crossed.imageset/Contents.json
new file mode 100644
index 0000000..db1c070
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Eye Crossed.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Eye Crossed.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Eye Crossed.imageset/Eye Crossed.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Eye Crossed.imageset/Eye Crossed.pdf
new file mode 100644
index 0000000..65019e4
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Eye Crossed.imageset/Eye Crossed.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Eye.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Eye.imageset/Contents.json
new file mode 100644
index 0000000..a2a6cb4
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Eye.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Eye.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Eye.imageset/Eye.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Eye.imageset/Eye.pdf
new file mode 100644
index 0000000..db18bb8
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Eye.imageset/Eye.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Filters.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Filters.imageset/Contents.json
new file mode 100644
index 0000000..fe1cdfc
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Filters.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Filters.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Filters.imageset/Filters.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Filters.imageset/Filters.pdf
new file mode 100644
index 0000000..3414f65
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Filters.imageset/Filters.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Image.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Image.imageset/Contents.json
new file mode 100644
index 0000000..55c299b
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Image.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Image.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Image.imageset/Image.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Image.imageset/Image.pdf
new file mode 100644
index 0000000..bce9d8d
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Image.imageset/Image.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Info.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Info.imageset/Contents.json
new file mode 100644
index 0000000..e809e27
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Info.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Info.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Info.imageset/Info.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Info.imageset/Info.pdf
new file mode 100644
index 0000000..cc0ee84
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Info.imageset/Info.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Light Bulb.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Light Bulb.imageset/Contents.json
new file mode 100644
index 0000000..984e68d
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Light Bulb.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Light Bulb.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Light Bulb.imageset/Light Bulb.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Light Bulb.imageset/Light Bulb.pdf
new file mode 100644
index 0000000..9b9f790
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Light Bulb.imageset/Light Bulb.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Link.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Link.imageset/Contents.json
new file mode 100644
index 0000000..b9a9ca0
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Link.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Link.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Link.imageset/Link.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Link.imageset/Link.pdf
new file mode 100644
index 0000000..18b2342
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Link.imageset/Link.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Mail.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Mail.imageset/Contents.json
new file mode 100644
index 0000000..7787fa7
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Mail.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Mail.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Mail.imageset/Mail.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Mail.imageset/Mail.pdf
new file mode 100644
index 0000000..12d6be0
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Mail.imageset/Mail.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Mobile.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Mobile.imageset/Contents.json
new file mode 100644
index 0000000..9cba2f2
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Mobile.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Mobile.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Mobile.imageset/Mobile.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Mobile.imageset/Mobile.pdf
new file mode 100644
index 0000000..0dba3d4
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Mobile.imageset/Mobile.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Moon.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Moon.imageset/Contents.json
new file mode 100644
index 0000000..1513a9c
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Moon.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Moon.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Moon.imageset/Moon.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Moon.imageset/Moon.pdf
new file mode 100644
index 0000000..e67c5f6
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Moon.imageset/Moon.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Network.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Network.imageset/Contents.json
new file mode 100644
index 0000000..b058983
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Network.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Network.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Network.imageset/Network.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Network.imageset/Network.pdf
new file mode 100644
index 0000000..1fdf1de
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Network.imageset/Network.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Nut.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Nut.imageset/Contents.json
new file mode 100644
index 0000000..960b99c
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Nut.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Nut.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Nut.imageset/Nut.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Nut.imageset/Nut.pdf
new file mode 100644
index 0000000..c2f9ad5
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Nut.imageset/Nut.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Off.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Off.imageset/Contents.json
new file mode 100644
index 0000000..2c3a3e7
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Off.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Off.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Off.imageset/Off.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Off.imageset/Off.pdf
new file mode 100644
index 0000000..6081932
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Off.imageset/Off.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Pen.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Pen.imageset/Contents.json
new file mode 100644
index 0000000..093dd4c
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Pen.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Pen.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Pen.imageset/Pen.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Pen.imageset/Pen.pdf
new file mode 100644
index 0000000..71a98d6
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Pen.imageset/Pen.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Plus.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Plus.imageset/Contents.json
new file mode 100644
index 0000000..74c8966
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Plus.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Plus.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Plus.imageset/Plus.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Plus.imageset/Plus.pdf
new file mode 100644
index 0000000..39150b6
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Plus.imageset/Plus.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Question Mark Circle.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Question Mark Circle.imageset/Contents.json
new file mode 100644
index 0000000..1ccdc2f
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Question Mark Circle.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Question Mark Circle.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Question Mark Circle.imageset/Question Mark Circle.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Question Mark Circle.imageset/Question Mark Circle.pdf
new file mode 100644
index 0000000..17cbea6
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Question Mark Circle.imageset/Question Mark Circle.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Refresh.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Refresh.imageset/Contents.json
new file mode 100644
index 0000000..8a4468b
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Refresh.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Refresh.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Refresh.imageset/Refresh.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Refresh.imageset/Refresh.pdf
new file mode 100644
index 0000000..41267e8
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Refresh.imageset/Refresh.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Sliders Horizontal.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Sliders Horizontal.imageset/Contents.json
new file mode 100644
index 0000000..89fec90
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Sliders Horizontal.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Sliders Horizontal.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Sliders Horizontal.imageset/Sliders Horizontal.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Sliders Horizontal.imageset/Sliders Horizontal.pdf
new file mode 100644
index 0000000..5faea4f
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Sliders Horizontal.imageset/Sliders Horizontal.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Sliders Vertical.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Sliders Vertical.imageset/Contents.json
new file mode 100644
index 0000000..663d947
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Sliders Vertical.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Sliders Vertical.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Sliders Vertical.imageset/Sliders Vertical.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Sliders Vertical.imageset/Sliders Vertical.pdf
new file mode 100644
index 0000000..4f7d740
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Sliders Vertical.imageset/Sliders Vertical.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Squares.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Squares.imageset/Contents.json
new file mode 100644
index 0000000..0019864
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Squares.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Squares.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Squares.imageset/Squares.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Squares.imageset/Squares.pdf
new file mode 100644
index 0000000..a2031c7
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Squares.imageset/Squares.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Sun.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Sun.imageset/Contents.json
new file mode 100644
index 0000000..3b849e2
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Sun.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Sun.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Sun.imageset/Sun.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Sun.imageset/Sun.pdf
new file mode 100644
index 0000000..ef173df
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Sun.imageset/Sun.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Swap Horizontal.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Swap Horizontal.imageset/Contents.json
new file mode 100644
index 0000000..a6e0cd8
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Swap Horizontal.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Swap Horizontal.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Swap Horizontal.imageset/Swap Horizontal.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Swap Horizontal.imageset/Swap Horizontal.pdf
new file mode 100644
index 0000000..1063e07
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Swap Horizontal.imageset/Swap Horizontal.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Swap Vertical.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Swap Vertical.imageset/Contents.json
new file mode 100644
index 0000000..097be5b
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Swap Vertical.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Swap Vertical.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Swap Vertical.imageset/Swap Vertical.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Swap Vertical.imageset/Swap Vertical.pdf
new file mode 100644
index 0000000..1954cb2
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Swap Vertical.imageset/Swap Vertical.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Users.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Users.imageset/Contents.json
new file mode 100644
index 0000000..caacfa5
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Users.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Users.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Users.imageset/Users.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Users.imageset/Users.pdf
new file mode 100644
index 0000000..68ae786
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Users.imageset/Users.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Wallet.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Wallet.imageset/Contents.json
new file mode 100644
index 0000000..5e974e1
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Wallet.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Wallet.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Wallet.imageset/Wallet.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Wallet.imageset/Wallet.pdf
new file mode 100644
index 0000000..6afccea
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Wallet.imageset/Wallet.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Warning Circle.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Warning Circle.imageset/Contents.json
new file mode 100644
index 0000000..aab64b2
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Warning Circle.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Warning Circle.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Warning Circle.imageset/Warning Circle.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Warning Circle.imageset/Warning Circle.pdf
new file mode 100644
index 0000000..b051ede
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Warning Circle.imageset/Warning Circle.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Web.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Web.imageset/Contents.json
new file mode 100644
index 0000000..3cdb76c
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Web.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Web.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Web.imageset/Web.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Web.imageset/Web.pdf
new file mode 100644
index 0000000..64fb66d
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/Web.imageset/Web.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/X Mark.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/X Mark.imageset/Contents.json
new file mode 100644
index 0000000..26183ce
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/X Mark.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "X Mark.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/X Mark.imageset/X Mark.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/X Mark.imageset/X Mark.pdf
new file mode 100644
index 0000000..970d6fb
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Bold/X Mark.imageset/X Mark.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Contents.json
new file mode 100644
index 0000000..73c0059
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Error.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Error.imageset/Contents.json
new file mode 100644
index 0000000..2f044cb
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Error.imageset/Contents.json
@@ -0,0 +1,22 @@
+{
+ "images" : [
+ {
+ "filename" : "error_light.pdf",
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "filename" : "error.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Error.imageset/error.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Error.imageset/error.pdf
new file mode 100644
index 0000000..eee3f6c
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Error.imageset/error.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Error.imageset/error_light.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Error.imageset/error_light.pdf
new file mode 100644
index 0000000..c1ec9fa
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Error.imageset/error_light.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Android.imageset/Android.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Android.imageset/Android.pdf
new file mode 100644
index 0000000..6eb8003
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Android.imageset/Android.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Android.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Android.imageset/Contents.json
new file mode 100644
index 0000000..e5fa454
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Android.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Android.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/App.imageset/App.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/App.imageset/App.pdf
new file mode 100644
index 0000000..aa5158e
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/App.imageset/App.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/App.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/App.imageset/Contents.json
new file mode 100644
index 0000000..55da715
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/App.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "App.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Arrow Left.imageset/Arrow Left.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Arrow Left.imageset/Arrow Left.pdf
new file mode 100644
index 0000000..996370c
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Arrow Left.imageset/Arrow Left.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Arrow Left.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Arrow Left.imageset/Contents.json
new file mode 100644
index 0000000..2c3eac9
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Arrow Left.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Arrow Left.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Arrow Right.imageset/Arrow Right.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Arrow Right.imageset/Arrow Right.pdf
new file mode 100644
index 0000000..70a9fe5
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Arrow Right.imageset/Arrow Right.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Arrow Right.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Arrow Right.imageset/Contents.json
new file mode 100644
index 0000000..5d97a0c
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Arrow Right.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Arrow Right.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Auth.imageset/Auth.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Auth.imageset/Auth.pdf
new file mode 100644
index 0000000..2d11a20
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Auth.imageset/Auth.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Auth.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Auth.imageset/Contents.json
new file mode 100644
index 0000000..4bcbff9
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Auth.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Auth.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Bell.imageset/Bell.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Bell.imageset/Bell.pdf
new file mode 100644
index 0000000..91fa7f1
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Bell.imageset/Bell.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Bell.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Bell.imageset/Contents.json
new file mode 100644
index 0000000..c0a52e8
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Bell.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Bell.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Bin.imageset/Bin.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Bin.imageset/Bin.pdf
new file mode 100644
index 0000000..300582f
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Bin.imageset/Bin.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Bin.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Bin.imageset/Contents.json
new file mode 100644
index 0000000..a2fd38f
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Bin.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Bin.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Checkmark.imageset/Checkmark.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Checkmark.imageset/Checkmark.pdf
new file mode 100644
index 0000000..c1fc642
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Checkmark.imageset/Checkmark.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Checkmark.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Checkmark.imageset/Contents.json
new file mode 100644
index 0000000..63f424b
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Checkmark.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Checkmark.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Chevron Bottom.imageset/Chevron Bottom.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Chevron Bottom.imageset/Chevron Bottom.pdf
new file mode 100644
index 0000000..3950172
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Chevron Bottom.imageset/Chevron Bottom.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Chevron Bottom.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Chevron Bottom.imageset/Contents.json
new file mode 100644
index 0000000..f664dce
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Chevron Bottom.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Chevron Bottom.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Chevron Left.imageset/Chevron Left.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Chevron Left.imageset/Chevron Left.pdf
new file mode 100644
index 0000000..41658c2
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Chevron Left.imageset/Chevron Left.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Chevron Left.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Chevron Left.imageset/Contents.json
new file mode 100644
index 0000000..80250da
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Chevron Left.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Chevron Left.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Chevron Right.imageset/Chevron Right.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Chevron Right.imageset/Chevron Right.pdf
new file mode 100644
index 0000000..0b945ae
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Chevron Right.imageset/Chevron Right.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Chevron Right.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Chevron Right.imageset/Contents.json
new file mode 100644
index 0000000..4163df7
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Chevron Right.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Chevron Right.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Chevron Top.imageset/Chevron Top.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Chevron Top.imageset/Chevron Top.pdf
new file mode 100644
index 0000000..929d3c3
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Chevron Top.imageset/Chevron Top.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Chevron Top.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Chevron Top.imageset/Contents.json
new file mode 100644
index 0000000..e18a8d9
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Chevron Top.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Chevron Top.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Compass.imageset/Compass.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Compass.imageset/Compass.pdf
new file mode 100644
index 0000000..e06fd2d
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Compass.imageset/Compass.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Compass.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Compass.imageset/Contents.json
new file mode 100644
index 0000000..7eb503e
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Compass.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Compass.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Contents.json
new file mode 100644
index 0000000..6e96565
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Contents.json
@@ -0,0 +1,9 @@
+{
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "provides-namespace" : true
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Copy.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Copy.imageset/Contents.json
new file mode 100644
index 0000000..7cd8eaf
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Copy.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Copy.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Copy.imageset/Copy.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Copy.imageset/Copy.pdf
new file mode 100644
index 0000000..76321bd
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Copy.imageset/Copy.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Desktop.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Desktop.imageset/Contents.json
new file mode 100644
index 0000000..6c3a2a4
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Desktop.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Desktop.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Desktop.imageset/Desktop.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Desktop.imageset/Desktop.pdf
new file mode 100644
index 0000000..70974bc
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Desktop.imageset/Desktop.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Disconnect.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Disconnect.imageset/Contents.json
new file mode 100644
index 0000000..0635154
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Disconnect.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Disconnect.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Disconnect.imageset/Disconnect.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Disconnect.imageset/Disconnect.pdf
new file mode 100644
index 0000000..d1f54c6
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Disconnect.imageset/Disconnect.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Doc.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Doc.imageset/Contents.json
new file mode 100644
index 0000000..1d93e4d
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Doc.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Doc.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Doc.imageset/Doc.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Doc.imageset/Doc.pdf
new file mode 100644
index 0000000..f64f541
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Doc.imageset/Doc.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Dots Horizontal.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Dots Horizontal.imageset/Contents.json
new file mode 100644
index 0000000..971c509
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Dots Horizontal.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Dots Horizontal.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Dots Horizontal.imageset/Dots Horizontal.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Dots Horizontal.imageset/Dots Horizontal.pdf
new file mode 100644
index 0000000..c005c38
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Dots Horizontal.imageset/Dots Horizontal.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Dots Vertical.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Dots Vertical.imageset/Contents.json
new file mode 100644
index 0000000..c011cf9
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Dots Vertical.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Dots Vertical.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Dots Vertical.imageset/Dots Vertical.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Dots Vertical.imageset/Dots Vertical.pdf
new file mode 100644
index 0000000..f6ec10f
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Dots Vertical.imageset/Dots Vertical.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Double Chevron Vertical.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Double Chevron Vertical.imageset/Contents.json
new file mode 100644
index 0000000..90f2f94
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Double Chevron Vertical.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Double Chevron Vertical.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Double Chevron Vertical.imageset/Double Chevron Vertical.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Double Chevron Vertical.imageset/Double Chevron Vertical.pdf
new file mode 100644
index 0000000..fccc08e
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Double Chevron Vertical.imageset/Double Chevron Vertical.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Etherscan.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Etherscan.imageset/Contents.json
new file mode 100644
index 0000000..2fa01f9
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Etherscan.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Etherscan.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Etherscan.imageset/Etherscan.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Etherscan.imageset/Etherscan.pdf
new file mode 100644
index 0000000..796280b
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Etherscan.imageset/Etherscan.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/External Link.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/External Link.imageset/Contents.json
new file mode 100644
index 0000000..be6a2f0
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/External Link.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "External Link.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/External Link.imageset/External Link.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/External Link.imageset/External Link.pdf
new file mode 100644
index 0000000..8b12b0c
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/External Link.imageset/External Link.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Eye Crossed.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Eye Crossed.imageset/Contents.json
new file mode 100644
index 0000000..db1c070
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Eye Crossed.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Eye Crossed.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Eye Crossed.imageset/Eye Crossed.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Eye Crossed.imageset/Eye Crossed.pdf
new file mode 100644
index 0000000..dfa4d72
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Eye Crossed.imageset/Eye Crossed.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Eye.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Eye.imageset/Contents.json
new file mode 100644
index 0000000..a2a6cb4
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Eye.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Eye.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Eye.imageset/Eye.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Eye.imageset/Eye.pdf
new file mode 100644
index 0000000..243e5ad
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Eye.imageset/Eye.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/File.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/File.imageset/Contents.json
new file mode 100644
index 0000000..5b6ce87
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/File.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "File.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/File.imageset/File.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/File.imageset/File.pdf
new file mode 100644
index 0000000..16830f0
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/File.imageset/File.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Filters.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Filters.imageset/Contents.json
new file mode 100644
index 0000000..fe1cdfc
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Filters.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Filters.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Filters.imageset/Filters.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Filters.imageset/Filters.pdf
new file mode 100644
index 0000000..09a580d
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Filters.imageset/Filters.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Info Circle.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Info Circle.imageset/Contents.json
new file mode 100644
index 0000000..2f29257
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Info Circle.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Info Circle.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Info Circle.imageset/Info Circle.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Info Circle.imageset/Info Circle.pdf
new file mode 100644
index 0000000..5f28551
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Info Circle.imageset/Info Circle.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Info.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Info.imageset/Contents.json
new file mode 100644
index 0000000..e809e27
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Info.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Info.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Info.imageset/Info.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Info.imageset/Info.pdf
new file mode 100644
index 0000000..7c6d524
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Info.imageset/Info.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Light Bulb.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Light Bulb.imageset/Contents.json
new file mode 100644
index 0000000..984e68d
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Light Bulb.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Light Bulb.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Light Bulb.imageset/Light Bulb.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Light Bulb.imageset/Light Bulb.pdf
new file mode 100644
index 0000000..6b7f151
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Light Bulb.imageset/Light Bulb.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Magnifier.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Magnifier.imageset/Contents.json
new file mode 100644
index 0000000..c4fb039
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Magnifier.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Magnifier.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Magnifier.imageset/Magnifier.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Magnifier.imageset/Magnifier.pdf
new file mode 100644
index 0000000..fcf8983
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Magnifier.imageset/Magnifier.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Mail.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Mail.imageset/Contents.json
new file mode 100644
index 0000000..7787fa7
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Mail.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Mail.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Mail.imageset/Mail.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Mail.imageset/Mail.pdf
new file mode 100644
index 0000000..3ab468d
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Mail.imageset/Mail.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Mobile.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Mobile.imageset/Contents.json
new file mode 100644
index 0000000..9cba2f2
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Mobile.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Mobile.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Mobile.imageset/Mobile.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Mobile.imageset/Mobile.pdf
new file mode 100644
index 0000000..96a96d6
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Mobile.imageset/Mobile.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Moon.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Moon.imageset/Contents.json
new file mode 100644
index 0000000..1513a9c
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Moon.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Moon.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Moon.imageset/Moon.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Moon.imageset/Moon.pdf
new file mode 100644
index 0000000..53c54c2
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Moon.imageset/Moon.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Nut.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Nut.imageset/Contents.json
new file mode 100644
index 0000000..960b99c
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Nut.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Nut.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Nut.imageset/Nut.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Nut.imageset/Nut.pdf
new file mode 100644
index 0000000..187de2e
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Nut.imageset/Nut.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Off.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Off.imageset/Contents.json
new file mode 100644
index 0000000..2c3a3e7
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Off.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Off.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Off.imageset/Off.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Off.imageset/Off.pdf
new file mode 100644
index 0000000..bc78536
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Off.imageset/Off.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Paste.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Paste.imageset/Contents.json
new file mode 100644
index 0000000..577b645
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Paste.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Paste.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Paste.imageset/Paste.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Paste.imageset/Paste.pdf
new file mode 100644
index 0000000..458b89f
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Paste.imageset/Paste.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Pen.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Pen.imageset/Contents.json
new file mode 100644
index 0000000..093dd4c
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Pen.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Pen.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Pen.imageset/Pen.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Pen.imageset/Pen.pdf
new file mode 100644
index 0000000..fc147e7
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Pen.imageset/Pen.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Plus.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Plus.imageset/Contents.json
new file mode 100644
index 0000000..74c8966
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Plus.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Plus.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Plus.imageset/Plus.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Plus.imageset/Plus.pdf
new file mode 100644
index 0000000..4c70ce4
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Plus.imageset/Plus.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/QR code.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/QR code.imageset/Contents.json
new file mode 100644
index 0000000..0abda80
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/QR code.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "QR code.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/QR code.imageset/QR code.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/QR code.imageset/QR code.pdf
new file mode 100644
index 0000000..f87dcf2
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/QR code.imageset/QR code.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Question Mark Circle.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Question Mark Circle.imageset/Contents.json
new file mode 100644
index 0000000..bf72a88
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Question Mark Circle.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Question Mark Circle-1.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Question Mark Circle.imageset/Question Mark Circle-1.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Question Mark Circle.imageset/Question Mark Circle-1.pdf
new file mode 100644
index 0000000..41f6900
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Question Mark Circle.imageset/Question Mark Circle-1.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Refresh.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Refresh.imageset/Contents.json
new file mode 100644
index 0000000..8a4468b
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Refresh.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Refresh.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Refresh.imageset/Refresh.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Refresh.imageset/Refresh.pdf
new file mode 100644
index 0000000..b8bf5bc
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Refresh.imageset/Refresh.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Sliders.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Sliders.imageset/Contents.json
new file mode 100644
index 0000000..09fbb71
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Sliders.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Sliders.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Sliders.imageset/Sliders.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Sliders.imageset/Sliders.pdf
new file mode 100644
index 0000000..e00c7e4
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Sliders.imageset/Sliders.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Squares.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Squares.imageset/Contents.json
new file mode 100644
index 0000000..0019864
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Squares.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Squares.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Squares.imageset/Squares.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Squares.imageset/Squares.pdf
new file mode 100644
index 0000000..f193215
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Squares.imageset/Squares.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Sun.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Sun.imageset/Contents.json
new file mode 100644
index 0000000..f8d3017
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Sun.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "MediumSun.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Sun.imageset/MediumSun.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Sun.imageset/MediumSun.pdf
new file mode 100644
index 0000000..80dda54
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Sun.imageset/MediumSun.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Swap Horizontal.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Swap Horizontal.imageset/Contents.json
new file mode 100644
index 0000000..a6e0cd8
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Swap Horizontal.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Swap Horizontal.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Swap Horizontal.imageset/Swap Horizontal.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Swap Horizontal.imageset/Swap Horizontal.pdf
new file mode 100644
index 0000000..450b336
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Swap Horizontal.imageset/Swap Horizontal.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Swap Vertical.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Swap Vertical.imageset/Contents.json
new file mode 100644
index 0000000..097be5b
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Swap Vertical.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Swap Vertical.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Swap Vertical.imageset/Swap Vertical.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Swap Vertical.imageset/Swap Vertical.pdf
new file mode 100644
index 0000000..ebe9d12
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Swap Vertical.imageset/Swap Vertical.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Twitter.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Twitter.imageset/Contents.json
new file mode 100644
index 0000000..8bc518e
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Twitter.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Twitter.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Twitter.imageset/Twitter.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Twitter.imageset/Twitter.pdf
new file mode 100644
index 0000000..13f308e
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Twitter.imageset/Twitter.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Wallet.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Wallet.imageset/Contents.json
new file mode 100644
index 0000000..5e974e1
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Wallet.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Wallet.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Wallet.imageset/Wallet.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Wallet.imageset/Wallet.pdf
new file mode 100644
index 0000000..d137229
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Wallet.imageset/Wallet.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Warning Circle.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Warning Circle.imageset/Contents.json
new file mode 100644
index 0000000..aab64b2
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Warning Circle.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Warning Circle.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Warning Circle.imageset/Warning Circle.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Warning Circle.imageset/Warning Circle.pdf
new file mode 100644
index 0000000..d32fb26
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Warning Circle.imageset/Warning Circle.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Web.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Web.imageset/Contents.json
new file mode 100644
index 0000000..3cdb76c
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Web.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Web.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Web.imageset/Web.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Web.imageset/Web.pdf
new file mode 100644
index 0000000..771c43b
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/Web.imageset/Web.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/X mark.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/X mark.imageset/Contents.json
new file mode 100644
index 0000000..21f004e
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/X mark.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "X mark.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/X mark.imageset/X mark.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/X mark.imageset/X mark.pdf
new file mode 100644
index 0000000..6b7559e
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/X mark.imageset/X mark.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/iOS.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/iOS.imageset/Contents.json
new file mode 100644
index 0000000..06050ad
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/iOS.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "iOS.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/iOS.imageset/iOS.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/iOS.imageset/iOS.pdf
new file mode 100644
index 0000000..626a83b
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Medium/iOS.imageset/iOS.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Add.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Add.imageset/Contents.json
new file mode 100644
index 0000000..120417a
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Add.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ },
+ "images" : [
+ {
+ "filename" : "iconAdd.pdf",
+ "idiom" : "universal"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Add.imageset/iconAdd.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Add.imageset/iconAdd.pdf
new file mode 100644
index 0000000..a9994d1
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Add.imageset/iconAdd.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Apple.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Apple.imageset/Contents.json
new file mode 100644
index 0000000..68e6492
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Apple.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ },
+ "images" : [
+ {
+ "filename" : "socialIconApple.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
\ No newline at end of file
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Apple.imageset/socialIconApple.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Apple.imageset/socialIconApple.pdf
new file mode 100644
index 0000000..211b3ec
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Apple.imageset/socialIconApple.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/ArrowDown.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/ArrowDown.imageset/Contents.json
new file mode 100644
index 0000000..9dcdbb2
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/ArrowDown.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ },
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "iconArrowDown.pdf"
+ }
+ ],
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
\ No newline at end of file
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/ArrowDown.imageset/iconArrowDown.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/ArrowDown.imageset/iconArrowDown.pdf
new file mode 100644
index 0000000..e6a7c2a
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/ArrowDown.imageset/iconArrowDown.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/ArrowExchange.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/ArrowExchange.imageset/Contents.json
new file mode 100644
index 0000000..1011cdd
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/ArrowExchange.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ },
+ "images" : [
+ {
+ "filename" : "iconArrowExchange.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
\ No newline at end of file
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/ArrowExchange.imageset/iconArrowExchange.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/ArrowExchange.imageset/iconArrowExchange.pdf
new file mode 100644
index 0000000..f8ebfe2
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/ArrowExchange.imageset/iconArrowExchange.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/ArrowLeft.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/ArrowLeft.imageset/Contents.json
new file mode 100644
index 0000000..882084d
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/ArrowLeft.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "properties" : {
+ "template-rendering-intent" : "template"
+ },
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ },
+ "images" : [
+ {
+ "filename" : "iconArrowLeft.pdf",
+ "idiom" : "universal"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/ArrowLeft.imageset/iconArrowLeft.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/ArrowLeft.imageset/iconArrowLeft.pdf
new file mode 100644
index 0000000..4e264a8
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/ArrowLeft.imageset/iconArrowLeft.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/ArrowRight.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/ArrowRight.imageset/Contents.json
new file mode 100644
index 0000000..d10acf8
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/ArrowRight.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ },
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "iconArrowRight.pdf"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/ArrowRight.imageset/iconArrowRight.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/ArrowRight.imageset/iconArrowRight.pdf
new file mode 100644
index 0000000..fe634ac
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/ArrowRight.imageset/iconArrowRight.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/ArrowUp.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/ArrowUp.imageset/Contents.json
new file mode 100644
index 0000000..0af36a4
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/ArrowUp.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ },
+ "images" : [
+ {
+ "filename" : "iconArrowUp.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
\ No newline at end of file
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/ArrowUp.imageset/iconArrowUp.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/ArrowUp.imageset/iconArrowUp.pdf
new file mode 100644
index 0000000..91f5ab5
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/ArrowUp.imageset/iconArrowUp.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/BackwardChevron.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/BackwardChevron.imageset/Contents.json
new file mode 100644
index 0000000..7c21905
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/BackwardChevron.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "properties" : {
+ "template-rendering-intent" : "template"
+ },
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ },
+ "images" : [
+ {
+ "filename" : "iconBackwardChevron.pdf",
+ "idiom" : "universal"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/BackwardChevron.imageset/iconBackwardChevron.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/BackwardChevron.imageset/iconBackwardChevron.pdf
new file mode 100644
index 0000000..32a7201
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/BackwardChevron.imageset/iconBackwardChevron.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Checkmark.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Checkmark.imageset/Contents.json
new file mode 100644
index 0000000..6996a2f
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Checkmark.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ },
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "iconCheckmark.pdf"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Checkmark.imageset/iconCheckmark.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Checkmark.imageset/iconCheckmark.pdf
new file mode 100644
index 0000000..963b5f4
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Checkmark.imageset/iconCheckmark.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Compass.imageset/Compass.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Compass.imageset/Compass.pdf
new file mode 100644
index 0000000..77b056b
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Compass.imageset/Compass.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Compass.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Compass.imageset/Contents.json
new file mode 100644
index 0000000..7eb503e
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Compass.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Compass.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Contents.json
new file mode 100644
index 0000000..6e96565
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Contents.json
@@ -0,0 +1,9 @@
+{
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "provides-namespace" : true
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Desktop.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Desktop.imageset/Contents.json
new file mode 100644
index 0000000..9bb494b
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Desktop.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ },
+ "images" : [
+ {
+ "filename" : "iconDesktop.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
\ No newline at end of file
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Desktop.imageset/iconDesktop.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Desktop.imageset/iconDesktop.pdf
new file mode 100644
index 0000000..f3b4059
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Desktop.imageset/iconDesktop.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Disconnect.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Disconnect.imageset/Contents.json
new file mode 100644
index 0000000..6e3ed49
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Disconnect.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "properties" : {
+ "template-rendering-intent" : "template"
+ },
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ },
+ "images" : [
+ {
+ "filename" : "iconDisconnect.pdf",
+ "idiom" : "universal"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Disconnect.imageset/iconDisconnect.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Disconnect.imageset/iconDisconnect.pdf
new file mode 100644
index 0000000..8e5b5cd
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Disconnect.imageset/iconDisconnect.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Discord.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Discord.imageset/Contents.json
new file mode 100644
index 0000000..b6c1191
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Discord.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "properties" : {
+ "template-rendering-intent" : "template"
+ },
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ },
+ "images" : [
+ {
+ "filename" : "socialIconDiscord.pdf",
+ "idiom" : "universal"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Discord.imageset/socialIconDiscord.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Discord.imageset/socialIconDiscord.pdf
new file mode 100644
index 0000000..64da48e
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Discord.imageset/socialIconDiscord.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/DownwardChevron.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/DownwardChevron.imageset/Contents.json
new file mode 100644
index 0000000..b04fa16
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/DownwardChevron.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ },
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "iconDownwardChevron.pdf"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/DownwardChevron.imageset/iconDownwardChevron.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/DownwardChevron.imageset/iconDownwardChevron.pdf
new file mode 100644
index 0000000..d4ff248
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/DownwardChevron.imageset/iconDownwardChevron.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Error.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Error.imageset/Contents.json
new file mode 100644
index 0000000..2f044cb
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Error.imageset/Contents.json
@@ -0,0 +1,22 @@
+{
+ "images" : [
+ {
+ "filename" : "error_light.pdf",
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "filename" : "error.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Error.imageset/error.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Error.imageset/error.pdf
new file mode 100644
index 0000000..eee3f6c
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Error.imageset/error.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Error.imageset/error_light.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Error.imageset/error_light.pdf
new file mode 100644
index 0000000..c1ec9fa
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Error.imageset/error_light.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Extension.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Extension.imageset/Contents.json
new file mode 100644
index 0000000..dea5400
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Extension.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ },
+ "images" : [
+ {
+ "filename" : "iconExtension.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
\ No newline at end of file
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Extension.imageset/iconExtension.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Extension.imageset/iconExtension.pdf
new file mode 100644
index 0000000..f375ae1
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Extension.imageset/iconExtension.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/ExternalLink.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/ExternalLink.imageset/Contents.json
new file mode 100644
index 0000000..27a75bd
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/ExternalLink.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "properties" : {
+ "template-rendering-intent" : "template"
+ },
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ },
+ "images" : [
+ {
+ "filename" : "iconExternalLink.pdf",
+ "idiom" : "universal"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/ExternalLink.imageset/iconExternalLink.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/ExternalLink.imageset/iconExternalLink.pdf
new file mode 100644
index 0000000..3df10bc
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/ExternalLink.imageset/iconExternalLink.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Facebook.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Facebook.imageset/Contents.json
new file mode 100644
index 0000000..5b66125
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Facebook.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ },
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "socialIconFacebook.pdf"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Facebook.imageset/socialIconFacebook.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Facebook.imageset/socialIconFacebook.pdf
new file mode 100644
index 0000000..49a0739
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Facebook.imageset/socialIconFacebook.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/ForwardChevron.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/ForwardChevron.imageset/Contents.json
new file mode 100644
index 0000000..b883d2a
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/ForwardChevron.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ },
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "iconForwardChevron.pdf"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/ForwardChevron.imageset/iconForwardChevron.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/ForwardChevron.imageset/iconForwardChevron.pdf
new file mode 100644
index 0000000..8499a34
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/ForwardChevron.imageset/iconForwardChevron.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Github.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Github.imageset/Contents.json
new file mode 100644
index 0000000..0d9c3b1
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Github.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ },
+ "images" : [
+ {
+ "filename" : "socialIconGithub.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
\ No newline at end of file
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Github.imageset/socialIconGithub.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Github.imageset/socialIconGithub.pdf
new file mode 100644
index 0000000..26a55ef
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Github.imageset/socialIconGithub.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Google.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Google.imageset/Contents.json
new file mode 100644
index 0000000..dcd047b
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Google.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "properties" : {
+ "template-rendering-intent" : "template"
+ },
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ },
+ "images" : [
+ {
+ "filename" : "socialIconGoogle.pdf",
+ "idiom" : "universal"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Google.imageset/socialIconGoogle.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Google.imageset/socialIconGoogle.pdf
new file mode 100644
index 0000000..63be357
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Google.imageset/socialIconGoogle.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Help.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Help.imageset/Contents.json
new file mode 100644
index 0000000..0738d25
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Help.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ },
+ "images" : [
+ {
+ "filename" : "iconHelp.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
\ No newline at end of file
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Help.imageset/iconHelp.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Help.imageset/iconHelp.pdf
new file mode 100644
index 0000000..98b561f
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Help.imageset/iconHelp.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/HelpSmall.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/HelpSmall.imageset/Contents.json
new file mode 100644
index 0000000..fb03063
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/HelpSmall.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "properties" : {
+ "template-rendering-intent" : "template"
+ },
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ },
+ "images" : [
+ {
+ "filename" : "iconHelpSmall.pdf",
+ "idiom" : "universal"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/HelpSmall.imageset/iconHelpSmall.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/HelpSmall.imageset/iconHelpSmall.pdf
new file mode 100644
index 0000000..3640e18
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/HelpSmall.imageset/iconHelpSmall.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/History.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/History.imageset/Contents.json
new file mode 100644
index 0000000..141c0fa
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/History.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ },
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "iconHistory.pdf"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/History.imageset/iconHistory.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/History.imageset/iconHistory.pdf
new file mode 100644
index 0000000..d56e137
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/History.imageset/iconHistory.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/LargeBackward.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/LargeBackward.imageset/Contents.json
new file mode 100644
index 0000000..c1a5f37
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/LargeBackward.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ },
+ "images" : [
+ {
+ "filename" : "iconLargeBackward.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
\ No newline at end of file
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/LargeBackward.imageset/iconLargeBackward.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/LargeBackward.imageset/iconLargeBackward.pdf
new file mode 100644
index 0000000..10caf6f
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/LargeBackward.imageset/iconLargeBackward.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/LargeClose.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/LargeClose.imageset/Contents.json
new file mode 100644
index 0000000..36700d2
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/LargeClose.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "properties" : {
+ "template-rendering-intent" : "template"
+ },
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ },
+ "images" : [
+ {
+ "filename" : "iconLargeClose.pdf",
+ "idiom" : "universal"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/LargeClose.imageset/iconLargeClose.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/LargeClose.imageset/iconLargeClose.pdf
new file mode 100644
index 0000000..642bcab
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/LargeClose.imageset/iconLargeClose.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/LargeCopy.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/LargeCopy.imageset/Contents.json
new file mode 100644
index 0000000..d8c07aa
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/LargeCopy.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ },
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "iconLargeCopy.pdf"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/LargeCopy.imageset/iconLargeCopy.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/LargeCopy.imageset/iconLargeCopy.pdf
new file mode 100644
index 0000000..6932659
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/LargeCopy.imageset/iconLargeCopy.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/LargeDesktop.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/LargeDesktop.imageset/Contents.json
new file mode 100644
index 0000000..dd33c4f
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/LargeDesktop.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ },
+ "images" : [
+ {
+ "filename" : "iconLargeDesktop.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
\ No newline at end of file
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/LargeDesktop.imageset/iconLargeDesktop.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/LargeDesktop.imageset/iconLargeDesktop.pdf
new file mode 100644
index 0000000..0c6ec13
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/LargeDesktop.imageset/iconLargeDesktop.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/LargeEmail.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/LargeEmail.imageset/Contents.json
new file mode 100644
index 0000000..ba5d7af
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/LargeEmail.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "properties" : {
+ "template-rendering-intent" : "template"
+ },
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ },
+ "images" : [
+ {
+ "filename" : "iconLargeEmail.pdf",
+ "idiom" : "universal"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/LargeEmail.imageset/iconLargeEmail.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/LargeEmail.imageset/iconLargeEmail.pdf
new file mode 100644
index 0000000..fd4bb78
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/LargeEmail.imageset/iconLargeEmail.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/LargeEmoji.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/LargeEmoji.imageset/Contents.json
new file mode 100644
index 0000000..bdbceec
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/LargeEmoji.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ },
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "iconLargeEmoji.pdf"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/LargeEmoji.imageset/iconLargeEmoji.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/LargeEmoji.imageset/iconLargeEmoji.pdf
new file mode 100644
index 0000000..c112e63
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/LargeEmoji.imageset/iconLargeEmoji.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/LargeMoon.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/LargeMoon.imageset/Contents.json
new file mode 100644
index 0000000..e2f14bc
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/LargeMoon.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ },
+ "images" : [
+ {
+ "filename" : "iconLargeMoon.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
\ No newline at end of file
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/LargeMoon.imageset/iconLargeMoon.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/LargeMoon.imageset/iconLargeMoon.pdf
new file mode 100644
index 0000000..0ff6c60
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/LargeMoon.imageset/iconLargeMoon.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/LargePhone.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/LargePhone.imageset/Contents.json
new file mode 100644
index 0000000..6eeb82d
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/LargePhone.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "properties" : {
+ "template-rendering-intent" : "template"
+ },
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ },
+ "images" : [
+ {
+ "filename" : "iconLargePhone.pdf",
+ "idiom" : "universal"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/LargePhone.imageset/iconLargePhone.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/LargePhone.imageset/iconLargePhone.pdf
new file mode 100644
index 0000000..1e4e891
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/LargePhone.imageset/iconLargePhone.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/LargeQrcode.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/LargeQrcode.imageset/Contents.json
new file mode 100644
index 0000000..fd5c1bb
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/LargeQrcode.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ },
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "iconLargeQrcode.pdf"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/LargeQrcode.imageset/iconLargeQrcode.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/LargeQrcode.imageset/iconLargeQrcode.pdf
new file mode 100644
index 0000000..acc1c79
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/LargeQrcode.imageset/iconLargeQrcode.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/LargeSun.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/LargeSun.imageset/Contents.json
new file mode 100644
index 0000000..10bf9c6
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/LargeSun.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ },
+ "images" : [
+ {
+ "filename" : "iconLargeSun.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
\ No newline at end of file
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/LargeSun.imageset/iconLargeSun.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/LargeSun.imageset/iconLargeSun.pdf
new file mode 100644
index 0000000..64ced8e
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/LargeSun.imageset/iconLargeSun.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/LargeTwitter.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/LargeTwitter.imageset/Contents.json
new file mode 100644
index 0000000..eace1e5
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/LargeTwitter.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ },
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "iconTwitter.pdf"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/LargeTwitter.imageset/iconTwitter.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/LargeTwitter.imageset/iconTwitter.pdf
new file mode 100644
index 0000000..78d0a63
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/LargeTwitter.imageset/iconTwitter.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Mail.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Mail.imageset/Contents.json
new file mode 100644
index 0000000..df0b05e
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Mail.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "properties" : {
+ "template-rendering-intent" : "template"
+ },
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ },
+ "images" : [
+ {
+ "filename" : "iconMail.pdf",
+ "idiom" : "universal"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Mail.imageset/iconMail.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Mail.imageset/iconMail.pdf
new file mode 100644
index 0000000..4bff5a2
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Mail.imageset/iconMail.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Off.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Off.imageset/Contents.json
new file mode 100644
index 0000000..2377ec5
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Off.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ },
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "iconOff.pdf"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Off.imageset/iconOff.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Off.imageset/iconOff.pdf
new file mode 100644
index 0000000..57c4311
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Off.imageset/iconOff.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Pen.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Pen.imageset/Contents.json
new file mode 100644
index 0000000..cd519e6
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Pen.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ },
+ "images" : [
+ {
+ "filename" : "iconPen.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
\ No newline at end of file
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Pen.imageset/iconPen.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Pen.imageset/iconPen.pdf
new file mode 100644
index 0000000..2f70a34
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Pen.imageset/iconPen.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Phone.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Phone.imageset/Contents.json
new file mode 100644
index 0000000..f5d42de
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Phone.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "properties" : {
+ "template-rendering-intent" : "template"
+ },
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ },
+ "images" : [
+ {
+ "filename" : "iconPhone.pdf",
+ "idiom" : "universal"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Phone.imageset/iconPhone.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Phone.imageset/iconPhone.pdf
new file mode 100644
index 0000000..79ca1b1
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Phone.imageset/iconPhone.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Popular.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Popular.imageset/Contents.json
new file mode 100644
index 0000000..68143b8
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Popular.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ },
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "iconPopular.pdf"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Popular.imageset/iconPopular.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Popular.imageset/iconPopular.pdf
new file mode 100644
index 0000000..ba4a8f0
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Popular.imageset/iconPopular.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Qrcode.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Qrcode.imageset/Contents.json
new file mode 100644
index 0000000..a492c77
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Qrcode.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ },
+ "images" : [
+ {
+ "filename" : "iconQrcode.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
\ No newline at end of file
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Qrcode.imageset/iconQrcode.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Qrcode.imageset/iconQrcode.pdf
new file mode 100644
index 0000000..4527f26
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Qrcode.imageset/iconQrcode.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/QuestionMarkCircle.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/QuestionMarkCircle.imageset/Contents.json
new file mode 100644
index 0000000..1ccdc2f
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/QuestionMarkCircle.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Question Mark Circle.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/QuestionMarkCircle.imageset/Question Mark Circle.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/QuestionMarkCircle.imageset/Question Mark Circle.pdf
new file mode 100644
index 0000000..a734159
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/QuestionMarkCircle.imageset/Question Mark Circle.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Recent.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Recent.imageset/Contents.json
new file mode 100644
index 0000000..fb03d2a
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Recent.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "properties" : {
+ "template-rendering-intent" : "template"
+ },
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ },
+ "images" : [
+ {
+ "filename" : "iconRecent.pdf",
+ "idiom" : "universal"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Recent.imageset/iconRecent.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Recent.imageset/iconRecent.pdf
new file mode 100644
index 0000000..9f850c0
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Recent.imageset/iconRecent.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Retry.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Retry.imageset/Contents.json
new file mode 100644
index 0000000..ee4b37a
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Retry.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ },
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "iconRetry.pdf"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Retry.imageset/iconRetry.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Retry.imageset/iconRetry.pdf
new file mode 100644
index 0000000..62346da
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Retry.imageset/iconRetry.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Scan.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Scan.imageset/Contents.json
new file mode 100644
index 0000000..e00deaf
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Scan.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ },
+ "images" : [
+ {
+ "filename" : "iconScan.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
\ No newline at end of file
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Scan.imageset/iconScan.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Scan.imageset/iconScan.pdf
new file mode 100644
index 0000000..3bbb374
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Scan.imageset/iconScan.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Search.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Search.imageset/Contents.json
new file mode 100644
index 0000000..6606320
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Search.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "properties" : {
+ "template-rendering-intent" : "template"
+ },
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ },
+ "images" : [
+ {
+ "filename" : "iconSearch.pdf",
+ "idiom" : "universal"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Search.imageset/iconSearch.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Search.imageset/iconSearch.pdf
new file mode 100644
index 0000000..ad94282
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Search.imageset/iconSearch.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Telegram.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Telegram.imageset/Contents.json
new file mode 100644
index 0000000..29086ed
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Telegram.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ },
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "socialIconTelegram.pdf"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Telegram.imageset/socialIconTelegram.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Telegram.imageset/socialIconTelegram.pdf
new file mode 100644
index 0000000..812d0b2
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Telegram.imageset/socialIconTelegram.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/ToastError.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/ToastError.imageset/Contents.json
new file mode 100644
index 0000000..022fa4a
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/ToastError.imageset/Contents.json
@@ -0,0 +1,22 @@
+{
+ "images" : [
+ {
+ "filename" : "Icon Boxlight-2.pdf",
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "filename" : "Icon Box-2.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/ToastError.imageset/Icon Box-2.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/ToastError.imageset/Icon Box-2.pdf
new file mode 100644
index 0000000..96cf383
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/ToastError.imageset/Icon Box-2.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/ToastError.imageset/Icon Boxlight-2.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/ToastError.imageset/Icon Boxlight-2.pdf
new file mode 100644
index 0000000..0cf9c34
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/ToastError.imageset/Icon Boxlight-2.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/ToastInfo.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/ToastInfo.imageset/Contents.json
new file mode 100644
index 0000000..7e36cc2
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/ToastInfo.imageset/Contents.json
@@ -0,0 +1,22 @@
+{
+ "images" : [
+ {
+ "filename" : "Icon Boxlight-1.pdf",
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "filename" : "Icon Box-1.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/ToastInfo.imageset/Icon Box-1.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/ToastInfo.imageset/Icon Box-1.pdf
new file mode 100644
index 0000000..68538fc
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/ToastInfo.imageset/Icon Box-1.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/ToastInfo.imageset/Icon Boxlight-1.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/ToastInfo.imageset/Icon Boxlight-1.pdf
new file mode 100644
index 0000000..5491091
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/ToastInfo.imageset/Icon Boxlight-1.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/ToastSuccess.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/ToastSuccess.imageset/Contents.json
new file mode 100644
index 0000000..d9968a3
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/ToastSuccess.imageset/Contents.json
@@ -0,0 +1,22 @@
+{
+ "images" : [
+ {
+ "filename" : "Icon Boxlight.pdf",
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "filename" : "Icon Box.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/ToastSuccess.imageset/Icon Box.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/ToastSuccess.imageset/Icon Box.pdf
new file mode 100644
index 0000000..5dfed0d
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/ToastSuccess.imageset/Icon Box.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/ToastSuccess.imageset/Icon Boxlight.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/ToastSuccess.imageset/Icon Boxlight.pdf
new file mode 100644
index 0000000..ee7d707
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/ToastSuccess.imageset/Icon Boxlight.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Twitch.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Twitch.imageset/Contents.json
new file mode 100644
index 0000000..5bd0b23
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Twitch.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ },
+ "images" : [
+ {
+ "filename" : "socialIconTwitch.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
\ No newline at end of file
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Twitch.imageset/socialIconTwitch.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Twitch.imageset/socialIconTwitch.pdf
new file mode 100644
index 0000000..cc8b13c
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Twitch.imageset/socialIconTwitch.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Twitter.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Twitter.imageset/Contents.json
new file mode 100644
index 0000000..91a81da
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Twitter.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "properties" : {
+ "template-rendering-intent" : "template"
+ },
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ },
+ "images" : [
+ {
+ "filename" : "socialIconTwitter.pdf",
+ "idiom" : "universal"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Twitter.imageset/socialIconTwitter.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Twitter.imageset/socialIconTwitter.pdf
new file mode 100644
index 0000000..b114e34
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Twitter.imageset/socialIconTwitter.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/UpwardChevron.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/UpwardChevron.imageset/Contents.json
new file mode 100644
index 0000000..ff4c669
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/UpwardChevron.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ },
+ "images" : [
+ {
+ "filename" : "iconUpwardChevron.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
\ No newline at end of file
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/UpwardChevron.imageset/iconUpwardChevron.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/UpwardChevron.imageset/iconUpwardChevron.pdf
new file mode 100644
index 0000000..b4d28ac
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/UpwardChevron.imageset/iconUpwardChevron.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Wallet.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Wallet.imageset/Contents.json
new file mode 100644
index 0000000..5e974e1
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Wallet.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Wallet.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Wallet.imageset/Wallet.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Wallet.imageset/Wallet.pdf
new file mode 100644
index 0000000..6d31a81
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Wallet.imageset/Wallet.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Website.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Website.imageset/Contents.json
new file mode 100644
index 0000000..e648fc1
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Website.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ },
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "iconWebsite.pdf"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Website.imageset/iconWebsite.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Website.imageset/iconWebsite.pdf
new file mode 100644
index 0000000..3069ea8
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Original/Website.imageset/iconWebsite.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/4 dots.imageset/4 dots.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/4 dots.imageset/4 dots.pdf
new file mode 100644
index 0000000..b162613
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/4 dots.imageset/4 dots.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/4 dots.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/4 dots.imageset/Contents.json
new file mode 100644
index 0000000..30239b8
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/4 dots.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "4 dots.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/App.imageset/App.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/App.imageset/App.pdf
new file mode 100644
index 0000000..521c9c7
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/App.imageset/App.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/App.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/App.imageset/Contents.json
new file mode 100644
index 0000000..55da715
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/App.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "App.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Arrow Bottom.imageset/Arrow Bottom.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Arrow Bottom.imageset/Arrow Bottom.pdf
new file mode 100644
index 0000000..64a27f4
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Arrow Bottom.imageset/Arrow Bottom.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Arrow Bottom.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Arrow Bottom.imageset/Contents.json
new file mode 100644
index 0000000..cce0756
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Arrow Bottom.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Arrow Bottom.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Bars.imageset/Bars.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Bars.imageset/Bars.pdf
new file mode 100644
index 0000000..a2d5195
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Bars.imageset/Bars.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Bars.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Bars.imageset/Contents.json
new file mode 100644
index 0000000..f6402c7
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Bars.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Bars.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Bell.imageset/Bell.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Bell.imageset/Bell.pdf
new file mode 100644
index 0000000..50c9cef
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Bell.imageset/Bell.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Bell.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Bell.imageset/Contents.json
new file mode 100644
index 0000000..c0a52e8
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Bell.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Bell.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Browser.imageset/Browser.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Browser.imageset/Browser.pdf
new file mode 100644
index 0000000..5402a27
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Browser.imageset/Browser.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Browser.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Browser.imageset/Contents.json
new file mode 100644
index 0000000..3f27bd6
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Browser.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Browser.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Chart.imageset/Chart.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Chart.imageset/Chart.pdf
new file mode 100644
index 0000000..a95eb6c
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Chart.imageset/Chart.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Chart.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Chart.imageset/Contents.json
new file mode 100644
index 0000000..95d6931
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Chart.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Chart.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Chat Bubble.imageset/Chat Bubble.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Chat Bubble.imageset/Chat Bubble.pdf
new file mode 100644
index 0000000..116eee0
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Chat Bubble.imageset/Chat Bubble.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Chat Bubble.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Chat Bubble.imageset/Contents.json
new file mode 100644
index 0000000..905119b
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Chat Bubble.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Chat Bubble.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Check Circle.imageset/Check Circle.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Check Circle.imageset/Check Circle.pdf
new file mode 100644
index 0000000..491fa13
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Check Circle.imageset/Check Circle.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Check Circle.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Check Circle.imageset/Contents.json
new file mode 100644
index 0000000..26a1ce5
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Check Circle.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Check Circle.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Checkmark.imageset/Checkmark.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Checkmark.imageset/Checkmark.pdf
new file mode 100644
index 0000000..93bb49e
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Checkmark.imageset/Checkmark.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Checkmark.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Checkmark.imageset/Contents.json
new file mode 100644
index 0000000..63f424b
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Checkmark.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Checkmark.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Chevron Left.imageset/Chevron Left.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Chevron Left.imageset/Chevron Left.pdf
new file mode 100644
index 0000000..43e3239
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Chevron Left.imageset/Chevron Left.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Chevron Left.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Chevron Left.imageset/Contents.json
new file mode 100644
index 0000000..80250da
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Chevron Left.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Chevron Left.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Code.imageset/Code.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Code.imageset/Code.pdf
new file mode 100644
index 0000000..e0b8890
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Code.imageset/Code.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Code.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Code.imageset/Contents.json
new file mode 100644
index 0000000..882467e
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Code.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Code.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Coin.imageset/Coin.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Coin.imageset/Coin.pdf
new file mode 100644
index 0000000..0492f8a
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Coin.imageset/Coin.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Coin.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Coin.imageset/Contents.json
new file mode 100644
index 0000000..fd03e84
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Coin.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Coin.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Compass.imageset/Compass.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Compass.imageset/Compass.pdf
new file mode 100644
index 0000000..a2e534b
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Compass.imageset/Compass.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Compass.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Compass.imageset/Contents.json
new file mode 100644
index 0000000..7eb503e
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Compass.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Compass.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Contents.json
new file mode 100644
index 0000000..6e96565
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Contents.json
@@ -0,0 +1,9 @@
+{
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "provides-namespace" : true
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Copy.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Copy.imageset/Contents.json
new file mode 100644
index 0000000..7cd8eaf
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Copy.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Copy.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Copy.imageset/Copy.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Copy.imageset/Copy.pdf
new file mode 100644
index 0000000..228cc4a
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Copy.imageset/Copy.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Desktop.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Desktop.imageset/Contents.json
new file mode 100644
index 0000000..6c3a2a4
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Desktop.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Desktop.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Desktop.imageset/Desktop.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Desktop.imageset/Desktop.pdf
new file mode 100644
index 0000000..227a9c1
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Desktop.imageset/Desktop.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Double Chevron Right.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Double Chevron Right.imageset/Contents.json
new file mode 100644
index 0000000..b6e6bc6
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Double Chevron Right.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Double Chevron Right.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Double Chevron Right.imageset/Double Chevron Right.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Double Chevron Right.imageset/Double Chevron Right.pdf
new file mode 100644
index 0000000..b4f1635
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Double Chevron Right.imageset/Double Chevron Right.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Extension.imageset/Browser-1.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Extension.imageset/Browser-1.pdf
new file mode 100644
index 0000000..1ade518
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Extension.imageset/Browser-1.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Extension.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Extension.imageset/Contents.json
new file mode 100644
index 0000000..0877f60
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Extension.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Browser-1.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/External Link.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/External Link.imageset/Contents.json
new file mode 100644
index 0000000..be6a2f0
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/External Link.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "External Link.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/External Link.imageset/External Link.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/External Link.imageset/External Link.pdf
new file mode 100644
index 0000000..a13bb05
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/External Link.imageset/External Link.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Eye Crossed.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Eye Crossed.imageset/Contents.json
new file mode 100644
index 0000000..db1c070
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Eye Crossed.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Eye Crossed.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Eye Crossed.imageset/Eye Crossed.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Eye Crossed.imageset/Eye Crossed.pdf
new file mode 100644
index 0000000..aa5862d
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Eye Crossed.imageset/Eye Crossed.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Eye.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Eye.imageset/Contents.json
new file mode 100644
index 0000000..a2a6cb4
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Eye.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Eye.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Eye.imageset/Eye.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Eye.imageset/Eye.pdf
new file mode 100644
index 0000000..5c16769
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Eye.imageset/Eye.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Filters.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Filters.imageset/Contents.json
new file mode 100644
index 0000000..fe1cdfc
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Filters.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Filters.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Filters.imageset/Filters.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Filters.imageset/Filters.pdf
new file mode 100644
index 0000000..7606230
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Filters.imageset/Filters.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Fingerprint.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Fingerprint.imageset/Contents.json
new file mode 100644
index 0000000..21e5f2d
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Fingerprint.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Fingerprint.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Fingerprint.imageset/Fingerprint.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Fingerprint.imageset/Fingerprint.pdf
new file mode 100644
index 0000000..43c6221
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Fingerprint.imageset/Fingerprint.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Image.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Image.imageset/Contents.json
new file mode 100644
index 0000000..55c299b
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Image.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Image.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Image.imageset/Image.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Image.imageset/Image.pdf
new file mode 100644
index 0000000..ab40049
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Image.imageset/Image.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Info.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Info.imageset/Contents.json
new file mode 100644
index 0000000..e809e27
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Info.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Info.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Info.imageset/Info.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Info.imageset/Info.pdf
new file mode 100644
index 0000000..4330f49
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Info.imageset/Info.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Link.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Link.imageset/Contents.json
new file mode 100644
index 0000000..b9a9ca0
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Link.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Link.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Link.imageset/Link.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Link.imageset/Link.pdf
new file mode 100644
index 0000000..8dbe882
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Link.imageset/Link.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Load.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Load.imageset/Contents.json
new file mode 100644
index 0000000..fc20c6c
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Load.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Load.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Load.imageset/Load.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Load.imageset/Load.pdf
new file mode 100644
index 0000000..73c72cd
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Load.imageset/Load.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Locker.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Locker.imageset/Contents.json
new file mode 100644
index 0000000..8cd20e2
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Locker.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Locker.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Locker.imageset/Locker.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Locker.imageset/Locker.pdf
new file mode 100644
index 0000000..6fa3fed
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Locker.imageset/Locker.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Magnifier.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Magnifier.imageset/Contents.json
new file mode 100644
index 0000000..577d182
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Magnifier.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Magnifier-1.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Magnifier.imageset/Magnifier-1.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Magnifier.imageset/Magnifier-1.pdf
new file mode 100644
index 0000000..2cb33db
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Magnifier.imageset/Magnifier-1.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Mail.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Mail.imageset/Contents.json
new file mode 100644
index 0000000..7787fa7
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Mail.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Mail.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Mail.imageset/Mail.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Mail.imageset/Mail.pdf
new file mode 100644
index 0000000..ec752d5
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Mail.imageset/Mail.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Mobile.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Mobile.imageset/Contents.json
new file mode 100644
index 0000000..9cba2f2
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Mobile.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Mobile.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Mobile.imageset/Mobile.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Mobile.imageset/Mobile.pdf
new file mode 100644
index 0000000..17c7a44
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Mobile.imageset/Mobile.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Moon.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Moon.imageset/Contents.json
new file mode 100644
index 0000000..1513a9c
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Moon.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Moon.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Moon.imageset/Moon.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Moon.imageset/Moon.pdf
new file mode 100644
index 0000000..75f7864
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Moon.imageset/Moon.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Network.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Network.imageset/Contents.json
new file mode 100644
index 0000000..b058983
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Network.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Network.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Network.imageset/Network.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Network.imageset/Network.pdf
new file mode 100644
index 0000000..65c5fc3
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Network.imageset/Network.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/QR code.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/QR code.imageset/Contents.json
new file mode 100644
index 0000000..0abda80
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/QR code.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "QR code.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/QR code.imageset/QR code.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/QR code.imageset/QR code.pdf
new file mode 100644
index 0000000..e1326f0
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/QR code.imageset/QR code.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Question Mark Circle.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Question Mark Circle.imageset/Contents.json
new file mode 100644
index 0000000..1ccdc2f
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Question Mark Circle.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Question Mark Circle.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Question Mark Circle.imageset/Question Mark Circle.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Question Mark Circle.imageset/Question Mark Circle.pdf
new file mode 100644
index 0000000..095cb4b
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Question Mark Circle.imageset/Question Mark Circle.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Question.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Question.imageset/Contents.json
new file mode 100644
index 0000000..1822e94
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Question.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Question.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Question.imageset/Question.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Question.imageset/Question.pdf
new file mode 100644
index 0000000..6edc35e
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Question.imageset/Question.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Sliders.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Sliders.imageset/Contents.json
new file mode 100644
index 0000000..09fbb71
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Sliders.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Sliders.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Sliders.imageset/Sliders.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Sliders.imageset/Sliders.pdf
new file mode 100644
index 0000000..6758386
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Sliders.imageset/Sliders.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Squares.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Squares.imageset/Contents.json
new file mode 100644
index 0000000..0019864
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Squares.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Squares.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Squares.imageset/Squares.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Squares.imageset/Squares.pdf
new file mode 100644
index 0000000..14e2d25
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Squares.imageset/Squares.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Sun.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Sun.imageset/Contents.json
new file mode 100644
index 0000000..3b849e2
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Sun.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Sun.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Sun.imageset/Sun.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Sun.imageset/Sun.pdf
new file mode 100644
index 0000000..b9ff4fd
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Sun.imageset/Sun.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Swap Horizontal.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Swap Horizontal.imageset/Contents.json
new file mode 100644
index 0000000..a6e0cd8
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Swap Horizontal.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Swap Horizontal.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Swap Horizontal.imageset/Swap Horizontal.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Swap Horizontal.imageset/Swap Horizontal.pdf
new file mode 100644
index 0000000..2b16ae9
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Swap Horizontal.imageset/Swap Horizontal.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Verif.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Verif.imageset/Contents.json
new file mode 100644
index 0000000..013c1fe
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Verif.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Verif.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Verif.imageset/Verif.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Verif.imageset/Verif.pdf
new file mode 100644
index 0000000..da23491
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Verif.imageset/Verif.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Wallet.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Wallet.imageset/Contents.json
new file mode 100644
index 0000000..681aab2
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Wallet.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Wallet-1.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Wallet.imageset/Wallet-1.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Wallet.imageset/Wallet-1.pdf
new file mode 100644
index 0000000..727e4d5
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Wallet.imageset/Wallet-1.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Warning Circle.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Warning Circle.imageset/Contents.json
new file mode 100644
index 0000000..aab64b2
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Warning Circle.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "Warning Circle.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Warning Circle.imageset/Warning Circle.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Warning Circle.imageset/Warning Circle.pdf
new file mode 100644
index 0000000..02638e9
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/Warning Circle.imageset/Warning Circle.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/X mark.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/X mark.imageset/Contents.json
new file mode 100644
index 0000000..21f004e
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/X mark.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "X mark.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/X mark.imageset/X mark.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/X mark.imageset/X mark.pdf
new file mode 100644
index 0000000..0afb7f4
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/Regular/X mark.imageset/X mark.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/ToastError.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/ToastError.imageset/Contents.json
new file mode 100644
index 0000000..022fa4a
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/ToastError.imageset/Contents.json
@@ -0,0 +1,22 @@
+{
+ "images" : [
+ {
+ "filename" : "Icon Boxlight-2.pdf",
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "filename" : "Icon Box-2.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/ToastError.imageset/Icon Box-2.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/ToastError.imageset/Icon Box-2.pdf
new file mode 100644
index 0000000..96cf383
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/ToastError.imageset/Icon Box-2.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/ToastError.imageset/Icon Boxlight-2.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/ToastError.imageset/Icon Boxlight-2.pdf
new file mode 100644
index 0000000..0cf9c34
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/ToastError.imageset/Icon Boxlight-2.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/ToastInfo.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/ToastInfo.imageset/Contents.json
new file mode 100644
index 0000000..7e36cc2
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/ToastInfo.imageset/Contents.json
@@ -0,0 +1,22 @@
+{
+ "images" : [
+ {
+ "filename" : "Icon Boxlight-1.pdf",
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "filename" : "Icon Box-1.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/ToastInfo.imageset/Icon Box-1.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/ToastInfo.imageset/Icon Box-1.pdf
new file mode 100644
index 0000000..68538fc
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/ToastInfo.imageset/Icon Box-1.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/ToastInfo.imageset/Icon Boxlight-1.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/ToastInfo.imageset/Icon Boxlight-1.pdf
new file mode 100644
index 0000000..5491091
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/ToastInfo.imageset/Icon Boxlight-1.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/ToastSuccess.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/ToastSuccess.imageset/Contents.json
new file mode 100644
index 0000000..d9968a3
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/ToastSuccess.imageset/Contents.json
@@ -0,0 +1,22 @@
+{
+ "images" : [
+ {
+ "filename" : "Icon Boxlight.pdf",
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "filename" : "Icon Box.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/ToastSuccess.imageset/Icon Box.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/ToastSuccess.imageset/Icon Box.pdf
new file mode 100644
index 0000000..5dfed0d
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/ToastSuccess.imageset/Icon Box.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/ToastSuccess.imageset/Icon Boxlight.pdf b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/ToastSuccess.imageset/Icon Boxlight.pdf
new file mode 100644
index 0000000..ee7d707
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Icons/ToastSuccess.imageset/Icon Boxlight.pdf differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/Contents.json
new file mode 100644
index 0000000..73c0059
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageBrowser.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageBrowser.imageset/Contents.json
new file mode 100644
index 0000000..205020a
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageBrowser.imageset/Contents.json
@@ -0,0 +1,23 @@
+{
+ "images" : [
+ {
+ "filename" : "imageBrowserL@1x.png",
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "filename" : "imageBrowserL@2x.png",
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "filename" : "imageBrowserL@3x.png",
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageBrowser.imageset/imageBrowserL@1x.png b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageBrowser.imageset/imageBrowserL@1x.png
new file mode 100644
index 0000000..c8c0e89
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageBrowser.imageset/imageBrowserL@1x.png differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageBrowser.imageset/imageBrowserL@2x.png b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageBrowser.imageset/imageBrowserL@2x.png
new file mode 100644
index 0000000..099be34
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageBrowser.imageset/imageBrowserL@2x.png differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageBrowser.imageset/imageBrowserL@3x.png b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageBrowser.imageset/imageBrowserL@3x.png
new file mode 100644
index 0000000..b066220
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageBrowser.imageset/imageBrowserL@3x.png differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageDao.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageDao.imageset/Contents.json
new file mode 100644
index 0000000..96435ba
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageDao.imageset/Contents.json
@@ -0,0 +1,23 @@
+{
+ "images" : [
+ {
+ "filename" : "imageDaoL@1x.png",
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "filename" : "imageDaoL@2x.png",
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "filename" : "imageDaoL@3x.png",
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageDao.imageset/imageDaoL@1x.png b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageDao.imageset/imageDaoL@1x.png
new file mode 100644
index 0000000..e9ee4f1
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageDao.imageset/imageDaoL@1x.png differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageDao.imageset/imageDaoL@2x.png b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageDao.imageset/imageDaoL@2x.png
new file mode 100644
index 0000000..e33e9a6
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageDao.imageset/imageDaoL@2x.png differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageDao.imageset/imageDaoL@3x.png b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageDao.imageset/imageDaoL@3x.png
new file mode 100644
index 0000000..c4e88e9
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageDao.imageset/imageDaoL@3x.png differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageDeFi.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageDeFi.imageset/Contents.json
new file mode 100644
index 0000000..fd80754
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageDeFi.imageset/Contents.json
@@ -0,0 +1,23 @@
+{
+ "images" : [
+ {
+ "filename" : "imageDeFiL@1x.png",
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "filename" : "imageDeFiL@2x.png",
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "filename" : "imageDeFiL@3x.png",
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageDeFi.imageset/imageDeFiL@1x.png b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageDeFi.imageset/imageDeFiL@1x.png
new file mode 100644
index 0000000..1a559a5
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageDeFi.imageset/imageDeFiL@1x.png differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageDeFi.imageset/imageDeFiL@2x.png b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageDeFi.imageset/imageDeFiL@2x.png
new file mode 100644
index 0000000..37a8d6a
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageDeFi.imageset/imageDeFiL@2x.png differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageDeFi.imageset/imageDeFiL@3x.png b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageDeFi.imageset/imageDeFiL@3x.png
new file mode 100644
index 0000000..711902f
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageDeFi.imageset/imageDeFiL@3x.png differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageDefiAlt.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageDefiAlt.imageset/Contents.json
new file mode 100644
index 0000000..076ec52
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageDefiAlt.imageset/Contents.json
@@ -0,0 +1,23 @@
+{
+ "images" : [
+ {
+ "filename" : "imageDefiAltL@1x.png",
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "filename" : "imageDefiAltL@2x.png",
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "filename" : "imageDefiAltL@3x.png",
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageDefiAlt.imageset/imageDefiAltL@1x.png b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageDefiAlt.imageset/imageDefiAltL@1x.png
new file mode 100644
index 0000000..c2da100
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageDefiAlt.imageset/imageDefiAltL@1x.png differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageDefiAlt.imageset/imageDefiAltL@2x.png b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageDefiAlt.imageset/imageDefiAltL@2x.png
new file mode 100644
index 0000000..94a7f81
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageDefiAlt.imageset/imageDefiAltL@2x.png differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageDefiAlt.imageset/imageDefiAltL@3x.png b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageDefiAlt.imageset/imageDefiAltL@3x.png
new file mode 100644
index 0000000..8cb79c0
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageDefiAlt.imageset/imageDefiAltL@3x.png differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageEth.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageEth.imageset/Contents.json
new file mode 100644
index 0000000..4cacae0
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageEth.imageset/Contents.json
@@ -0,0 +1,23 @@
+{
+ "images" : [
+ {
+ "filename" : "imageEthL@1x.png",
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "filename" : "imageEthL@2x.png",
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "filename" : "imageEthL@3x.png",
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageEth.imageset/imageEthL@1x.png b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageEth.imageset/imageEthL@1x.png
new file mode 100644
index 0000000..421904c
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageEth.imageset/imageEthL@1x.png differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageEth.imageset/imageEthL@2x.png b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageEth.imageset/imageEthL@2x.png
new file mode 100644
index 0000000..4ffdba0
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageEth.imageset/imageEthL@2x.png differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageEth.imageset/imageEthL@3x.png b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageEth.imageset/imageEthL@3x.png
new file mode 100644
index 0000000..bc2c6c9
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageEth.imageset/imageEthL@3x.png differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageLayers.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageLayers.imageset/Contents.json
new file mode 100644
index 0000000..cd0ac63
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageLayers.imageset/Contents.json
@@ -0,0 +1,23 @@
+{
+ "images" : [
+ {
+ "filename" : "imageLayersL@1x.png",
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "filename" : "imageLayersL@2x.png",
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "filename" : "imageLayersL@3x.png",
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageLayers.imageset/imageLayersL@1x.png b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageLayers.imageset/imageLayersL@1x.png
new file mode 100644
index 0000000..e879b9c
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageLayers.imageset/imageLayersL@1x.png differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageLayers.imageset/imageLayersL@2x.png b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageLayers.imageset/imageLayersL@2x.png
new file mode 100644
index 0000000..52c4b63
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageLayers.imageset/imageLayersL@2x.png differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageLayers.imageset/imageLayersL@3x.png b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageLayers.imageset/imageLayersL@3x.png
new file mode 100644
index 0000000..cc9c110
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageLayers.imageset/imageLayersL@3x.png differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageLock.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageLock.imageset/Contents.json
new file mode 100644
index 0000000..fef72f1
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageLock.imageset/Contents.json
@@ -0,0 +1,23 @@
+{
+ "images" : [
+ {
+ "filename" : "imageLockL@1x.png",
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "filename" : "imageLockL@2x.png",
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "filename" : "imageLockL@3x.png",
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageLock.imageset/imageLockL@1x.png b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageLock.imageset/imageLockL@1x.png
new file mode 100644
index 0000000..63ba11a
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageLock.imageset/imageLockL@1x.png differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageLock.imageset/imageLockL@2x.png b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageLock.imageset/imageLockL@2x.png
new file mode 100644
index 0000000..ddc550f
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageLock.imageset/imageLockL@2x.png differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageLock.imageset/imageLockL@3x.png b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageLock.imageset/imageLockL@3x.png
new file mode 100644
index 0000000..c7d3a77
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageLock.imageset/imageLockL@3x.png differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageLogin.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageLogin.imageset/Contents.json
new file mode 100644
index 0000000..e328988
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageLogin.imageset/Contents.json
@@ -0,0 +1,23 @@
+{
+ "images" : [
+ {
+ "filename" : "imageLoginL@1x.png",
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "filename" : "imageLoginL@2x.png",
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "filename" : "imageLoginL@3x.png",
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageLogin.imageset/imageLoginL@1x.png b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageLogin.imageset/imageLoginL@1x.png
new file mode 100644
index 0000000..18adb03
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageLogin.imageset/imageLoginL@1x.png differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageLogin.imageset/imageLoginL@2x.png b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageLogin.imageset/imageLoginL@2x.png
new file mode 100644
index 0000000..7e0d3fe
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageLogin.imageset/imageLoginL@2x.png differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageLogin.imageset/imageLoginL@3x.png b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageLogin.imageset/imageLoginL@3x.png
new file mode 100644
index 0000000..0953b4a
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageLogin.imageset/imageLoginL@3x.png differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageNetwork.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageNetwork.imageset/Contents.json
new file mode 100644
index 0000000..0595c3f
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageNetwork.imageset/Contents.json
@@ -0,0 +1,23 @@
+{
+ "images" : [
+ {
+ "filename" : "imageNetworkL@1x.png",
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "filename" : "imageNetworkL@2x.png",
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "filename" : "imageNetworkL@3x.png",
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageNetwork.imageset/imageNetworkL@1x.png b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageNetwork.imageset/imageNetworkL@1x.png
new file mode 100644
index 0000000..171579e
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageNetwork.imageset/imageNetworkL@1x.png differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageNetwork.imageset/imageNetworkL@2x.png b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageNetwork.imageset/imageNetworkL@2x.png
new file mode 100644
index 0000000..e0912ae
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageNetwork.imageset/imageNetworkL@2x.png differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageNetwork.imageset/imageNetworkL@3x.png b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageNetwork.imageset/imageNetworkL@3x.png
new file mode 100644
index 0000000..c64e864
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageNetwork.imageset/imageNetworkL@3x.png differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageNft.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageNft.imageset/Contents.json
new file mode 100644
index 0000000..2ee0e71
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageNft.imageset/Contents.json
@@ -0,0 +1,23 @@
+{
+ "images" : [
+ {
+ "filename" : "imageNftL@1x.png",
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "filename" : "imageNftL@2x.png",
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "filename" : "imageNftL@3x.png",
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageNft.imageset/imageNftL@1x.png b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageNft.imageset/imageNftL@1x.png
new file mode 100644
index 0000000..1a8dd70
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageNft.imageset/imageNftL@1x.png differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageNft.imageset/imageNftL@2x.png b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageNft.imageset/imageNftL@2x.png
new file mode 100644
index 0000000..a97b3d4
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageNft.imageset/imageNftL@2x.png differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageNft.imageset/imageNftL@3x.png b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageNft.imageset/imageNftL@3x.png
new file mode 100644
index 0000000..33fc8b7
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageNft.imageset/imageNftL@3x.png differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageNoun.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageNoun.imageset/Contents.json
new file mode 100644
index 0000000..83ee54b
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageNoun.imageset/Contents.json
@@ -0,0 +1,23 @@
+{
+ "images" : [
+ {
+ "filename" : "imageNounL@1x.png",
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "filename" : "imageNounL@2x.png",
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "filename" : "imageNounL@3x.png",
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageNoun.imageset/imageNounL@1x.png b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageNoun.imageset/imageNounL@1x.png
new file mode 100644
index 0000000..4f9f6d7
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageNoun.imageset/imageNounL@1x.png differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageNoun.imageset/imageNounL@2x.png b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageNoun.imageset/imageNounL@2x.png
new file mode 100644
index 0000000..a645ac6
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageNoun.imageset/imageNounL@2x.png differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageNoun.imageset/imageNounL@3x.png b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageNoun.imageset/imageNounL@3x.png
new file mode 100644
index 0000000..3df56ea
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageNoun.imageset/imageNounL@3x.png differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageProfile.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageProfile.imageset/Contents.json
new file mode 100644
index 0000000..3dfbc3d
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageProfile.imageset/Contents.json
@@ -0,0 +1,23 @@
+{
+ "images" : [
+ {
+ "filename" : "imageProfileL@1x.png",
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "filename" : "imageProfileL@2x.png",
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "filename" : "imageProfileL@3x.png",
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageProfile.imageset/imageProfileL@1x.png b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageProfile.imageset/imageProfileL@1x.png
new file mode 100644
index 0000000..f48d756
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageProfile.imageset/imageProfileL@1x.png differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageProfile.imageset/imageProfileL@2x.png b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageProfile.imageset/imageProfileL@2x.png
new file mode 100644
index 0000000..aa4615f
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageProfile.imageset/imageProfileL@2x.png differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageProfile.imageset/imageProfileL@3x.png b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageProfile.imageset/imageProfileL@3x.png
new file mode 100644
index 0000000..f34f6c6
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageProfile.imageset/imageProfileL@3x.png differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageSystem.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageSystem.imageset/Contents.json
new file mode 100644
index 0000000..f4bf13a
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageSystem.imageset/Contents.json
@@ -0,0 +1,23 @@
+{
+ "images" : [
+ {
+ "filename" : "imageSystemL@1x.png",
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "filename" : "imageSystemL@2x.png",
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "filename" : "imageSystemL@3x.png",
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageSystem.imageset/imageSystemL@1x.png b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageSystem.imageset/imageSystemL@1x.png
new file mode 100644
index 0000000..5eaabea
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageSystem.imageset/imageSystemL@1x.png differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageSystem.imageset/imageSystemL@2x.png b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageSystem.imageset/imageSystemL@2x.png
new file mode 100644
index 0000000..68047f8
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageSystem.imageset/imageSystemL@2x.png differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageSystem.imageset/imageSystemL@3x.png b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageSystem.imageset/imageSystemL@3x.png
new file mode 100644
index 0000000..df5c10c
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Images/imageSystem.imageset/imageSystemL@3x.png differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Mocks/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Mocks/Contents.json
new file mode 100644
index 0000000..73c0059
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Mocks/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Mocks/MockChainImage.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Mocks/MockChainImage.imageset/Contents.json
new file mode 100644
index 0000000..1777a61
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Mocks/MockChainImage.imageset/Contents.json
@@ -0,0 +1,21 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "filename" : "Polygon.png",
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Mocks/MockChainImage.imageset/Polygon.png b/Sources/Web3ModalUI/Resources/Assets.xcassets/Mocks/MockChainImage.imageset/Polygon.png
new file mode 100644
index 0000000..47e3458
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Mocks/MockChainImage.imageset/Polygon.png differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Mocks/MockWalletImage.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/Mocks/MockWalletImage.imageset/Contents.json
new file mode 100644
index 0000000..3929e95
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/Mocks/MockWalletImage.imageset/Contents.json
@@ -0,0 +1,21 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "filename" : "Rainbow.png",
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/Mocks/MockWalletImage.imageset/Rainbow.png b/Sources/Web3ModalUI/Resources/Assets.xcassets/Mocks/MockWalletImage.imageset/Rainbow.png
new file mode 100644
index 0000000..b4be2ec
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/Mocks/MockWalletImage.imageset/Rainbow.png differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/OptionIcon/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/OptionIcon/Contents.json
new file mode 100644
index 0000000..73c0059
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/OptionIcon/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/OptionIcon/optionAll.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/OptionIcon/optionAll.imageset/Contents.json
new file mode 100644
index 0000000..6b26fed
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/OptionIcon/optionAll.imageset/Contents.json
@@ -0,0 +1,54 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "filename" : "all@2x.png",
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "filename" : "all_dark@2x.png",
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "filename" : "all@3x.png",
+ "idiom" : "universal",
+ "scale" : "3x"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "filename" : "all_dark@3x.png",
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/OptionIcon/optionAll.imageset/all@2x.png b/Sources/Web3ModalUI/Resources/Assets.xcassets/OptionIcon/optionAll.imageset/all@2x.png
new file mode 100644
index 0000000..a29ebed
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/OptionIcon/optionAll.imageset/all@2x.png differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/OptionIcon/optionAll.imageset/all@3x.png b/Sources/Web3ModalUI/Resources/Assets.xcassets/OptionIcon/optionAll.imageset/all@3x.png
new file mode 100644
index 0000000..3e79ef5
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/OptionIcon/optionAll.imageset/all@3x.png differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/OptionIcon/optionAll.imageset/all_dark@2x.png b/Sources/Web3ModalUI/Resources/Assets.xcassets/OptionIcon/optionAll.imageset/all_dark@2x.png
new file mode 100644
index 0000000..0922e99
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/OptionIcon/optionAll.imageset/all_dark@2x.png differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/OptionIcon/optionAll.imageset/all_dark@3x.png b/Sources/Web3ModalUI/Resources/Assets.xcassets/OptionIcon/optionAll.imageset/all_dark@3x.png
new file mode 100644
index 0000000..5a34e94
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/OptionIcon/optionAll.imageset/all_dark@3x.png differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/OptionIcon/optionBrowser.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/OptionIcon/optionBrowser.imageset/Contents.json
new file mode 100644
index 0000000..692659e
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/OptionIcon/optionBrowser.imageset/Contents.json
@@ -0,0 +1,54 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "filename" : "optionBrowserThemeLightL@2x.png",
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "filename" : "optionBrowserThemeDarkL@2x.png",
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "filename" : "optionBrowserThemeLightL@3x.png",
+ "idiom" : "universal",
+ "scale" : "3x"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "filename" : "optionBrowserThemeDarkL@3x.png",
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/OptionIcon/optionBrowser.imageset/optionBrowserThemeDarkL@2x.png b/Sources/Web3ModalUI/Resources/Assets.xcassets/OptionIcon/optionBrowser.imageset/optionBrowserThemeDarkL@2x.png
new file mode 100644
index 0000000..fa17511
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/OptionIcon/optionBrowser.imageset/optionBrowserThemeDarkL@2x.png differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/OptionIcon/optionBrowser.imageset/optionBrowserThemeDarkL@3x.png b/Sources/Web3ModalUI/Resources/Assets.xcassets/OptionIcon/optionBrowser.imageset/optionBrowserThemeDarkL@3x.png
new file mode 100644
index 0000000..5d8b0f2
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/OptionIcon/optionBrowser.imageset/optionBrowserThemeDarkL@3x.png differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/OptionIcon/optionBrowser.imageset/optionBrowserThemeLightL@2x.png b/Sources/Web3ModalUI/Resources/Assets.xcassets/OptionIcon/optionBrowser.imageset/optionBrowserThemeLightL@2x.png
new file mode 100644
index 0000000..6bdd4fd
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/OptionIcon/optionBrowser.imageset/optionBrowserThemeLightL@2x.png differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/OptionIcon/optionBrowser.imageset/optionBrowserThemeLightL@3x.png b/Sources/Web3ModalUI/Resources/Assets.xcassets/OptionIcon/optionBrowser.imageset/optionBrowserThemeLightL@3x.png
new file mode 100644
index 0000000..7867f41
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/OptionIcon/optionBrowser.imageset/optionBrowserThemeLightL@3x.png differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/OptionIcon/optionExtension.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/OptionIcon/optionExtension.imageset/Contents.json
new file mode 100644
index 0000000..8d8cd67
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/OptionIcon/optionExtension.imageset/Contents.json
@@ -0,0 +1,54 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "filename" : "optionExtensionThemeLightL@2x.png",
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "filename" : "optionExtensionThemeDarkL@2x.png",
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "filename" : "optionExtensionThemeLightL@3x.png",
+ "idiom" : "universal",
+ "scale" : "3x"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "filename" : "optionExtensionThemeDarkL@3x.png",
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/OptionIcon/optionExtension.imageset/optionExtensionThemeDarkL@2x.png b/Sources/Web3ModalUI/Resources/Assets.xcassets/OptionIcon/optionExtension.imageset/optionExtensionThemeDarkL@2x.png
new file mode 100644
index 0000000..b3fcca3
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/OptionIcon/optionExtension.imageset/optionExtensionThemeDarkL@2x.png differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/OptionIcon/optionExtension.imageset/optionExtensionThemeDarkL@3x.png b/Sources/Web3ModalUI/Resources/Assets.xcassets/OptionIcon/optionExtension.imageset/optionExtensionThemeDarkL@3x.png
new file mode 100644
index 0000000..750626f
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/OptionIcon/optionExtension.imageset/optionExtensionThemeDarkL@3x.png differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/OptionIcon/optionExtension.imageset/optionExtensionThemeLightL@2x.png b/Sources/Web3ModalUI/Resources/Assets.xcassets/OptionIcon/optionExtension.imageset/optionExtensionThemeLightL@2x.png
new file mode 100644
index 0000000..c89b6d3
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/OptionIcon/optionExtension.imageset/optionExtensionThemeLightL@2x.png differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/OptionIcon/optionExtension.imageset/optionExtensionThemeLightL@3x.png b/Sources/Web3ModalUI/Resources/Assets.xcassets/OptionIcon/optionExtension.imageset/optionExtensionThemeLightL@3x.png
new file mode 100644
index 0000000..dae3781
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/OptionIcon/optionExtension.imageset/optionExtensionThemeLightL@3x.png differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/OptionIcon/optionQrCode.imageset/Contents.json b/Sources/Web3ModalUI/Resources/Assets.xcassets/OptionIcon/optionQrCode.imageset/Contents.json
new file mode 100644
index 0000000..f068bab
--- /dev/null
+++ b/Sources/Web3ModalUI/Resources/Assets.xcassets/OptionIcon/optionQrCode.imageset/Contents.json
@@ -0,0 +1,54 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "filename" : "optionQrCodeThemeLightL@2x.png",
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "filename" : "optionQrCodeThemeDarkL@2x.png",
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "filename" : "optionQrCodeThemeLightL@3x.png",
+ "idiom" : "universal",
+ "scale" : "3x"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "filename" : "optionQrCodeThemeDarkL@3x.png",
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/OptionIcon/optionQrCode.imageset/optionQrCodeThemeDarkL@2x.png b/Sources/Web3ModalUI/Resources/Assets.xcassets/OptionIcon/optionQrCode.imageset/optionQrCodeThemeDarkL@2x.png
new file mode 100644
index 0000000..74b7325
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/OptionIcon/optionQrCode.imageset/optionQrCodeThemeDarkL@2x.png differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/OptionIcon/optionQrCode.imageset/optionQrCodeThemeDarkL@3x.png b/Sources/Web3ModalUI/Resources/Assets.xcassets/OptionIcon/optionQrCode.imageset/optionQrCodeThemeDarkL@3x.png
new file mode 100644
index 0000000..27fbce0
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/OptionIcon/optionQrCode.imageset/optionQrCodeThemeDarkL@3x.png differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/OptionIcon/optionQrCode.imageset/optionQrCodeThemeLightL@2x.png b/Sources/Web3ModalUI/Resources/Assets.xcassets/OptionIcon/optionQrCode.imageset/optionQrCodeThemeLightL@2x.png
new file mode 100644
index 0000000..5239e7d
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/OptionIcon/optionQrCode.imageset/optionQrCodeThemeLightL@2x.png differ
diff --git a/Sources/Web3ModalUI/Resources/Assets.xcassets/OptionIcon/optionQrCode.imageset/optionQrCodeThemeLightL@3x.png b/Sources/Web3ModalUI/Resources/Assets.xcassets/OptionIcon/optionQrCode.imageset/optionQrCodeThemeLightL@3x.png
new file mode 100644
index 0000000..0893e93
Binary files /dev/null and b/Sources/Web3ModalUI/Resources/Assets.xcassets/OptionIcon/optionQrCode.imageset/optionQrCodeThemeLightL@3x.png differ
diff --git a/Sources/Web3ModalUI/Web3ModalImports copy.swift b/Sources/Web3ModalUI/Web3ModalImports copy.swift
new file mode 100644
index 0000000..2ccd394
--- /dev/null
+++ b/Sources/Web3ModalUI/Web3ModalImports copy.swift
@@ -0,0 +1,3 @@
+#if !CocoaPods
+@_exported import Web3ModalBackport
+#endif
diff --git a/Tests/Web3ModalTests/AccountButtonSnapshotTests.swift b/Tests/Web3ModalTests/AccountButtonSnapshotTests.swift
new file mode 100644
index 0000000..6ac83f0
--- /dev/null
+++ b/Tests/Web3ModalTests/AccountButtonSnapshotTests.swift
@@ -0,0 +1,13 @@
+import SnapshotTesting
+import SwiftUI
+@testable import Web3Modal
+import XCTest
+
+final class AccountButtonSnapshotTests: XCTestCase {
+
+// func test_snapshots() throws {
+// let view = AccountButtonPreviewView()
+// assertSnapshot(matching: view, as: .image(layout: .device(config: .iPhone13), traits: .init(userInterfaceStyle: .dark)))
+// assertSnapshot(matching: view, as: .image(layout: .device(config: .iPhone13), traits: .init(userInterfaceStyle: .light)))
+// }
+}
diff --git a/Tests/Web3ModalTests/NetworkButtonSnapshotTests.swift b/Tests/Web3ModalTests/NetworkButtonSnapshotTests.swift
new file mode 100644
index 0000000..a938c2f
--- /dev/null
+++ b/Tests/Web3ModalTests/NetworkButtonSnapshotTests.swift
@@ -0,0 +1,13 @@
+import SnapshotTesting
+import SwiftUI
+@testable import Web3Modal
+import XCTest
+
+final class NetworkButtonSnapshotTests: XCTestCase {
+
+ func test_snapshots() throws {
+ let view = NetworkButtonPreviewView()
+ assertSnapshot(matching: view, as: .image(layout: .device(config: .iPhone13), traits: .init(userInterfaceStyle: .dark)))
+ assertSnapshot(matching: view, as: .image(layout: .device(config: .iPhone13), traits: .init(userInterfaceStyle: .light)))
+ }
+}
diff --git a/Tests/Web3ModalTests/QRCodeViewSnapshotTests.swift b/Tests/Web3ModalTests/QRCodeViewSnapshotTests.swift
new file mode 100644
index 0000000..bed8565
--- /dev/null
+++ b/Tests/Web3ModalTests/QRCodeViewSnapshotTests.swift
@@ -0,0 +1,13 @@
+import SnapshotTesting
+import SwiftUI
+@testable import Web3Modal
+import XCTest
+
+final class QRCodeViewSnapshotTests: XCTestCase {
+
+ func test_snapshots() throws {
+ let view = QRCodeViewPreviewView()
+ assertSnapshot(matching: view, as: .image(layout: .device(config: .iPhone13), traits: .init(userInterfaceStyle: .dark)))
+ assertSnapshot(matching: view, as: .image(layout: .device(config: .iPhone13), traits: .init(userInterfaceStyle: .light)))
+ }
+}
diff --git a/Tests/Web3ModalTests/__Snapshots__/AccountButtonSnapshotTests/test_snapshots.1.png b/Tests/Web3ModalTests/__Snapshots__/AccountButtonSnapshotTests/test_snapshots.1.png
new file mode 100644
index 0000000..c7c6de5
Binary files /dev/null and b/Tests/Web3ModalTests/__Snapshots__/AccountButtonSnapshotTests/test_snapshots.1.png differ
diff --git a/Tests/Web3ModalTests/__Snapshots__/AccountButtonSnapshotTests/test_snapshots.2.png b/Tests/Web3ModalTests/__Snapshots__/AccountButtonSnapshotTests/test_snapshots.2.png
new file mode 100644
index 0000000..7403789
Binary files /dev/null and b/Tests/Web3ModalTests/__Snapshots__/AccountButtonSnapshotTests/test_snapshots.2.png differ
diff --git a/Tests/Web3ModalTests/__Snapshots__/NetworkButtonSnapshotTests/test_snapshots.1.png b/Tests/Web3ModalTests/__Snapshots__/NetworkButtonSnapshotTests/test_snapshots.1.png
new file mode 100644
index 0000000..7ed37c9
Binary files /dev/null and b/Tests/Web3ModalTests/__Snapshots__/NetworkButtonSnapshotTests/test_snapshots.1.png differ
diff --git a/Tests/Web3ModalTests/__Snapshots__/NetworkButtonSnapshotTests/test_snapshots.2.png b/Tests/Web3ModalTests/__Snapshots__/NetworkButtonSnapshotTests/test_snapshots.2.png
new file mode 100644
index 0000000..b6d71cf
Binary files /dev/null and b/Tests/Web3ModalTests/__Snapshots__/NetworkButtonSnapshotTests/test_snapshots.2.png differ
diff --git a/Tests/Web3ModalTests/__Snapshots__/QRCodeViewSnapshotTests/test_snapshots.1.png b/Tests/Web3ModalTests/__Snapshots__/QRCodeViewSnapshotTests/test_snapshots.1.png
new file mode 100644
index 0000000..bab3e30
Binary files /dev/null and b/Tests/Web3ModalTests/__Snapshots__/QRCodeViewSnapshotTests/test_snapshots.1.png differ
diff --git a/Tests/Web3ModalTests/__Snapshots__/QRCodeViewSnapshotTests/test_snapshots.2.png b/Tests/Web3ModalTests/__Snapshots__/QRCodeViewSnapshotTests/test_snapshots.2.png
new file mode 100644
index 0000000..22cabfd
Binary files /dev/null and b/Tests/Web3ModalTests/__Snapshots__/QRCodeViewSnapshotTests/test_snapshots.2.png differ
diff --git a/Tests/Web3ModalUITests/W3MActionEntrySnapshotTests.swift b/Tests/Web3ModalUITests/W3MActionEntrySnapshotTests.swift
new file mode 100644
index 0000000..c184565
--- /dev/null
+++ b/Tests/Web3ModalUITests/W3MActionEntrySnapshotTests.swift
@@ -0,0 +1,13 @@
+import SnapshotTesting
+import SwiftUI
+@testable import Web3ModalUI
+import XCTest
+
+final class W3MActionEntrySnapshotTests: XCTestCase {
+
+ func test_snapshots() throws {
+ let view = W3MActionEntryStylePreviewView()
+ assertSnapshot(matching: view, as: .image(layout: .device(config: .iPhone13), traits: .init(userInterfaceStyle: .dark)))
+ assertSnapshot(matching: view, as: .image(layout: .device(config: .iPhone13), traits: .init(userInterfaceStyle: .light)))
+ }
+}
diff --git a/Tests/Web3ModalUITests/W3MButtonSnapshotTests.swift b/Tests/Web3ModalUITests/W3MButtonSnapshotTests.swift
new file mode 100644
index 0000000..a2e82db
--- /dev/null
+++ b/Tests/Web3ModalUITests/W3MButtonSnapshotTests.swift
@@ -0,0 +1,13 @@
+import SnapshotTesting
+import SwiftUI
+@testable import Web3ModalUI
+import XCTest
+
+final class W3MButtonSnapshotTests: XCTestCase {
+
+ func test_snapshots() throws {
+ let view = W3MButtonStylePreviewView()
+ assertSnapshot(matching: view, as: .image(layout: .device(config: .iPhone13), traits: .init(userInterfaceStyle: .dark)))
+ assertSnapshot(matching: view, as: .image(layout: .device(config: .iPhone13), traits: .init(userInterfaceStyle: .light)))
+ }
+}
diff --git a/Tests/Web3ModalUITests/W3MCardSelectSnapshotTests.swift b/Tests/Web3ModalUITests/W3MCardSelectSnapshotTests.swift
new file mode 100644
index 0000000..79530ec
--- /dev/null
+++ b/Tests/Web3ModalUITests/W3MCardSelectSnapshotTests.swift
@@ -0,0 +1,13 @@
+import SnapshotTesting
+import SwiftUI
+@testable import Web3ModalUI
+import XCTest
+
+final class W3MCardSelectSnapshotTests: XCTestCase {
+
+ func test_snapshots() throws {
+ let view = W3MCardSelectStylePreviewView()
+ assertSnapshot(matching: view, as: .image(traits: .init(userInterfaceStyle: .dark)))
+ assertSnapshot(matching: view, as: .image(traits: .init(userInterfaceStyle: .light)))
+ }
+}
diff --git a/Tests/Web3ModalUITests/W3MChipButtonSnapshotTests.swift b/Tests/Web3ModalUITests/W3MChipButtonSnapshotTests.swift
new file mode 100644
index 0000000..3138dac
--- /dev/null
+++ b/Tests/Web3ModalUITests/W3MChipButtonSnapshotTests.swift
@@ -0,0 +1,13 @@
+import SnapshotTesting
+import SwiftUI
+@testable import Web3ModalUI
+import XCTest
+
+final class W3MChipButtonSnapshotTests: XCTestCase {
+
+ func test_snapshots() throws {
+ let view = W3MChipButtonStylePreviewView()
+ assertSnapshot(matching: view, as: .image(layout: .fixed(width: 800, height: 800), traits: .init(userInterfaceStyle: .dark)))
+ assertSnapshot(matching: view, as: .image(layout: .fixed(width: 800, height: 800), traits: .init(userInterfaceStyle: .light)))
+ }
+}
diff --git a/Tests/Web3ModalUITests/W3MListItemSnapshotTests.swift b/Tests/Web3ModalUITests/W3MListItemSnapshotTests.swift
new file mode 100644
index 0000000..3c47744
--- /dev/null
+++ b/Tests/Web3ModalUITests/W3MListItemSnapshotTests.swift
@@ -0,0 +1,26 @@
+import SnapshotTesting
+import SwiftUI
+@testable import Web3ModalUI
+import XCTest
+
+final class W3MListItemSnapshotTests: XCTestCase {
+ func test_snapshots() throws {
+ let view = W3MListItemButtonStylePreviewView()
+
+ assertSnapshot(matching: view, as: .image(layout: .device(config: .iPhone13), traits: .init(userInterfaceStyle: .dark)))
+ assertSnapshot(matching: view, as: .image(layout: .device(config: .iPhone13), traits: .init(userInterfaceStyle: .light)))
+
+ assertSnapshot(
+ matching: view,
+ as: .image(
+ layout: .device(config: .iPhone13),
+ traits: UITraitCollection(
+ traitsFrom: [
+ .init(userInterfaceStyle: .dark),
+ .init(preferredContentSizeCategory: .accessibilityExtraExtraLarge)
+ ]
+ )
+ )
+ )
+ }
+}
diff --git a/Tests/Web3ModalUITests/W3MListSelectSnapshotTests.swift b/Tests/Web3ModalUITests/W3MListSelectSnapshotTests.swift
new file mode 100644
index 0000000..06c506e
--- /dev/null
+++ b/Tests/Web3ModalUITests/W3MListSelectSnapshotTests.swift
@@ -0,0 +1,25 @@
+import SnapshotTesting
+import SwiftUI
+@testable import Web3ModalUI
+import XCTest
+
+final class W3MListSelectSnapshotTests: XCTestCase {
+ func test_snapshots() throws {
+ let view = W3MListSelectStylePreviewView()
+ assertSnapshot(matching: view, as: .image(layout: .device(config: .iPhone13), traits: .init(userInterfaceStyle: .dark)))
+ assertSnapshot(matching: view, as: .image(layout: .device(config: .iPhone13), traits: .init(userInterfaceStyle: .light)))
+
+ assertSnapshot(
+ matching: view,
+ as: .image(
+ layout: .device(config: .iPhone13),
+ traits: UITraitCollection(
+ traitsFrom: [
+ .init(userInterfaceStyle: .dark),
+ .init(preferredContentSizeCategory: .accessibilityExtraExtraLarge)
+ ]
+ )
+ )
+ )
+ }
+}
diff --git a/Tests/Web3ModalUITests/W3MTagSnapshotTests.swift b/Tests/Web3ModalUITests/W3MTagSnapshotTests.swift
new file mode 100644
index 0000000..37bf4b6
--- /dev/null
+++ b/Tests/Web3ModalUITests/W3MTagSnapshotTests.swift
@@ -0,0 +1,13 @@
+import SnapshotTesting
+import SwiftUI
+@testable import Web3ModalUI
+import XCTest
+
+final class W3MTagSnapshotTests: XCTestCase {
+
+ func test_snapshots() throws {
+ let view = W3MTagPreviewView()
+ assertSnapshot(matching: view, as: .image(layout: .fixed(width: 150, height: 250), traits: .init(userInterfaceStyle: .dark)))
+ assertSnapshot(matching: view, as: .image(layout: .fixed(width: 150, height: 250), traits: .init(userInterfaceStyle: .light)))
+ }
+}
diff --git a/Tests/Web3ModalUITests/W3MToastSnapshotTests .swift b/Tests/Web3ModalUITests/W3MToastSnapshotTests .swift
new file mode 100644
index 0000000..f2155ed
--- /dev/null
+++ b/Tests/Web3ModalUITests/W3MToastSnapshotTests .swift
@@ -0,0 +1,13 @@
+import SnapshotTesting
+import SwiftUI
+@testable import Web3ModalUI
+import XCTest
+
+final class W3MToastSnapshotTests: XCTestCase {
+
+ func test_snapshots() throws {
+ let view = ToastViewPreviewView()
+ assertSnapshot(matching: view, as: .image(layout: .fixed(width: 250, height: 250), traits: .init(userInterfaceStyle: .dark)))
+ assertSnapshot(matching: view, as: .image(layout: .fixed(width: 250, height: 250), traits: .init(userInterfaceStyle: .light)))
+ }
+}
diff --git a/Tests/Web3ModalUITests/__Snapshots__/W3MActionEntrySnapshotTests/test_snapshots.1.png b/Tests/Web3ModalUITests/__Snapshots__/W3MActionEntrySnapshotTests/test_snapshots.1.png
new file mode 100644
index 0000000..b2a8ed1
Binary files /dev/null and b/Tests/Web3ModalUITests/__Snapshots__/W3MActionEntrySnapshotTests/test_snapshots.1.png differ
diff --git a/Tests/Web3ModalUITests/__Snapshots__/W3MActionEntrySnapshotTests/test_snapshots.2.png b/Tests/Web3ModalUITests/__Snapshots__/W3MActionEntrySnapshotTests/test_snapshots.2.png
new file mode 100644
index 0000000..d8147f3
Binary files /dev/null and b/Tests/Web3ModalUITests/__Snapshots__/W3MActionEntrySnapshotTests/test_snapshots.2.png differ
diff --git a/Tests/Web3ModalUITests/__Snapshots__/W3MButtonSnapshotTests/test_snapshots.1.png b/Tests/Web3ModalUITests/__Snapshots__/W3MButtonSnapshotTests/test_snapshots.1.png
new file mode 100644
index 0000000..baa3932
Binary files /dev/null and b/Tests/Web3ModalUITests/__Snapshots__/W3MButtonSnapshotTests/test_snapshots.1.png differ
diff --git a/Tests/Web3ModalUITests/__Snapshots__/W3MButtonSnapshotTests/test_snapshots.2.png b/Tests/Web3ModalUITests/__Snapshots__/W3MButtonSnapshotTests/test_snapshots.2.png
new file mode 100644
index 0000000..79f4f94
Binary files /dev/null and b/Tests/Web3ModalUITests/__Snapshots__/W3MButtonSnapshotTests/test_snapshots.2.png differ
diff --git a/Tests/Web3ModalUITests/__Snapshots__/W3MCardSelectSnapshotTests/test_snapshots.1.png b/Tests/Web3ModalUITests/__Snapshots__/W3MCardSelectSnapshotTests/test_snapshots.1.png
new file mode 100644
index 0000000..4c39f3d
Binary files /dev/null and b/Tests/Web3ModalUITests/__Snapshots__/W3MCardSelectSnapshotTests/test_snapshots.1.png differ
diff --git a/Tests/Web3ModalUITests/__Snapshots__/W3MCardSelectSnapshotTests/test_snapshots.2.png b/Tests/Web3ModalUITests/__Snapshots__/W3MCardSelectSnapshotTests/test_snapshots.2.png
new file mode 100644
index 0000000..bf0e140
Binary files /dev/null and b/Tests/Web3ModalUITests/__Snapshots__/W3MCardSelectSnapshotTests/test_snapshots.2.png differ
diff --git a/Tests/Web3ModalUITests/__Snapshots__/W3MChipButtonSnapshotTests/test_snapshots.1.png b/Tests/Web3ModalUITests/__Snapshots__/W3MChipButtonSnapshotTests/test_snapshots.1.png
new file mode 100644
index 0000000..cfe1d3d
Binary files /dev/null and b/Tests/Web3ModalUITests/__Snapshots__/W3MChipButtonSnapshotTests/test_snapshots.1.png differ
diff --git a/Tests/Web3ModalUITests/__Snapshots__/W3MChipButtonSnapshotTests/test_snapshots.2.png b/Tests/Web3ModalUITests/__Snapshots__/W3MChipButtonSnapshotTests/test_snapshots.2.png
new file mode 100644
index 0000000..8d9d696
Binary files /dev/null and b/Tests/Web3ModalUITests/__Snapshots__/W3MChipButtonSnapshotTests/test_snapshots.2.png differ
diff --git a/Tests/Web3ModalUITests/__Snapshots__/W3MListItemSnapshotTests/test_snapshots.1.png b/Tests/Web3ModalUITests/__Snapshots__/W3MListItemSnapshotTests/test_snapshots.1.png
new file mode 100644
index 0000000..0322895
Binary files /dev/null and b/Tests/Web3ModalUITests/__Snapshots__/W3MListItemSnapshotTests/test_snapshots.1.png differ
diff --git a/Tests/Web3ModalUITests/__Snapshots__/W3MListItemSnapshotTests/test_snapshots.2.png b/Tests/Web3ModalUITests/__Snapshots__/W3MListItemSnapshotTests/test_snapshots.2.png
new file mode 100644
index 0000000..9fa0129
Binary files /dev/null and b/Tests/Web3ModalUITests/__Snapshots__/W3MListItemSnapshotTests/test_snapshots.2.png differ
diff --git a/Tests/Web3ModalUITests/__Snapshots__/W3MListItemSnapshotTests/test_snapshots.3.png b/Tests/Web3ModalUITests/__Snapshots__/W3MListItemSnapshotTests/test_snapshots.3.png
new file mode 100644
index 0000000..196f491
Binary files /dev/null and b/Tests/Web3ModalUITests/__Snapshots__/W3MListItemSnapshotTests/test_snapshots.3.png differ
diff --git a/Tests/Web3ModalUITests/__Snapshots__/W3MListSelectSnapshotTests/test_snapshots.1.png b/Tests/Web3ModalUITests/__Snapshots__/W3MListSelectSnapshotTests/test_snapshots.1.png
new file mode 100644
index 0000000..bd03496
Binary files /dev/null and b/Tests/Web3ModalUITests/__Snapshots__/W3MListSelectSnapshotTests/test_snapshots.1.png differ
diff --git a/Tests/Web3ModalUITests/__Snapshots__/W3MListSelectSnapshotTests/test_snapshots.2.png b/Tests/Web3ModalUITests/__Snapshots__/W3MListSelectSnapshotTests/test_snapshots.2.png
new file mode 100644
index 0000000..8ee144e
Binary files /dev/null and b/Tests/Web3ModalUITests/__Snapshots__/W3MListSelectSnapshotTests/test_snapshots.2.png differ
diff --git a/Tests/Web3ModalUITests/__Snapshots__/W3MListSelectSnapshotTests/test_snapshots.3.png b/Tests/Web3ModalUITests/__Snapshots__/W3MListSelectSnapshotTests/test_snapshots.3.png
new file mode 100644
index 0000000..8c166f7
Binary files /dev/null and b/Tests/Web3ModalUITests/__Snapshots__/W3MListSelectSnapshotTests/test_snapshots.3.png differ
diff --git a/Tests/Web3ModalUITests/__Snapshots__/W3MTagSnapshotTests/test_snapshots.1.png b/Tests/Web3ModalUITests/__Snapshots__/W3MTagSnapshotTests/test_snapshots.1.png
new file mode 100644
index 0000000..17018d1
Binary files /dev/null and b/Tests/Web3ModalUITests/__Snapshots__/W3MTagSnapshotTests/test_snapshots.1.png differ
diff --git a/Tests/Web3ModalUITests/__Snapshots__/W3MTagSnapshotTests/test_snapshots.2.png b/Tests/Web3ModalUITests/__Snapshots__/W3MTagSnapshotTests/test_snapshots.2.png
new file mode 100644
index 0000000..7a7e4b9
Binary files /dev/null and b/Tests/Web3ModalUITests/__Snapshots__/W3MTagSnapshotTests/test_snapshots.2.png differ
diff --git a/Tests/Web3ModalUITests/__Snapshots__/W3MToastSnapshotTests /test_snapshots.1.png b/Tests/Web3ModalUITests/__Snapshots__/W3MToastSnapshotTests /test_snapshots.1.png
new file mode 100644
index 0000000..d3f6485
Binary files /dev/null and b/Tests/Web3ModalUITests/__Snapshots__/W3MToastSnapshotTests /test_snapshots.1.png differ
diff --git a/Tests/Web3ModalUITests/__Snapshots__/W3MToastSnapshotTests /test_snapshots.2.png b/Tests/Web3ModalUITests/__Snapshots__/W3MToastSnapshotTests /test_snapshots.2.png
new file mode 100644
index 0000000..0a707e4
Binary files /dev/null and b/Tests/Web3ModalUITests/__Snapshots__/W3MToastSnapshotTests /test_snapshots.2.png differ
diff --git a/Web3Modal.podspec b/Web3Modal.podspec
new file mode 100644
index 0000000..2d5007c
--- /dev/null
+++ b/Web3Modal.podspec
@@ -0,0 +1,47 @@
+require "json"
+
+package = JSON.parse(File.read(File.join(__dir__, "Sources/Web3Modal/PackageConfig.json")))
+
+Pod::Spec.new do |spec|
+ spec.name = "Web3Modal"
+ spec.version = "#{package["version"]}"
+ spec.summary = "A single Web3 provider solution for all Wallets"
+ spec.description = "Your on-ramp to web3 multichain. Web3Modal is a versatile library that makes it super easy to connect users with your Dapp and start interacting with the blockchain."
+ spec.screenshots = "https://web3modal.com/images/hero-banner.png"
+ spec.homepage = "https://web3modal.com/"
+ spec.license = { :type => 'Apache-2.0', :file => 'LICENSE' }
+ spec.authors = "WalletConnect, Inc."
+ spec.social_media_url = "https://twitter.com/WalletConnect"
+ spec.platform = :ios, "13.0"
+ spec.swift_version = "5.9"
+
+ spec.source = { :git => "https://github.com/WalletConnect/web3modal-swift.git", :tag => "#{spec.version}" }
+
+ spec.pod_target_xcconfig = {
+ 'OTHER_SWIFT_FLAGS' => '-DCocoaPods'
+ }
+
+ # ――― Sub Specs ――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
+
+ spec.default_subspecs = 'Web3Modal'
+
+ spec.subspec 'Web3Modal' do |ss|
+ ss.source_files = 'Sources/Web3Modal/**/*.{h,m,swift}'
+ ss.dependency 'Web3Modal/Web3ModalUI'
+ ss.dependency 'Web3Modal/Web3ModalBackport'
+ ss.dependency 'WalletConnectSwiftV2/WalletConnectSign', '~> 1.9.0'
+ ss.dependency 'DSF_QRCode', '~> 16.1.1'
+ ss.dependency 'CoinbaseWalletSDK', '~> 1.0.4'
+ ss.resource_bundles = { 'Web3Modal' => ['Sources/Web3Modal/Resources/*'] }
+ end
+
+ spec.subspec 'Web3ModalUI' do |ss|
+ ss.source_files = 'Sources/Web3ModalUI/**/*.{h,m,swift}'
+ ss.dependency 'Web3Modal/Web3ModalBackport'
+ ss.resource_bundles = { 'Web3ModalUI' => ['Sources/Web3ModalUI/Resources/*'] }
+ end
+
+ spec.subspec 'Web3ModalBackport' do |ss|
+ ss.source_files = 'Sources/Web3ModalBackport/**/*.{h,m,swift}'
+ end
+end
diff --git a/Web3Modal.xcworkspace/contents.xcworkspacedata b/Web3Modal.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..572e1a8
--- /dev/null
+++ b/Web3Modal.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
diff --git a/Web3Modal.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Web3Modal.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
new file mode 100644
index 0000000..18d9810
--- /dev/null
+++ b/Web3Modal.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
@@ -0,0 +1,8 @@
+
+
+
+
+ IDEDidComputeMac32BitWarning
+
+
+
diff --git a/Web3Modal.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Web3Modal.xcworkspace/xcshareddata/swiftpm/Package.resolved
new file mode 100644
index 0000000..a84cfb4
--- /dev/null
+++ b/Web3Modal.xcworkspace/xcshareddata/swiftpm/Package.resolved
@@ -0,0 +1,86 @@
+{
+ "pins" : [
+ {
+ "identity" : "atlantis",
+ "kind" : "remoteSourceControl",
+ "location" : "https://github.com/ProxymanApp/atlantis",
+ "state" : {
+ "revision" : "5145a7041ec71421d09653db87dcc80c81792004",
+ "version" : "1.24.0"
+ }
+ },
+ {
+ "identity" : "qrcode",
+ "kind" : "remoteSourceControl",
+ "location" : "https://github.com/WalletConnect/QRCode",
+ "state" : {
+ "revision" : "263f280d2c8144adfb0b6676109846cfc8dd552b",
+ "version" : "14.3.1"
+ }
+ },
+ {
+ "identity" : "sentry-cocoa",
+ "kind" : "remoteSourceControl",
+ "location" : "https://github.com/getsentry/sentry-cocoa/",
+ "state" : {
+ "revision" : "38f4f70d07117b9f958a76b1bff278c2f29ffe0e",
+ "version" : "8.21.0"
+ }
+ },
+ {
+ "identity" : "starscream",
+ "kind" : "remoteSourceControl",
+ "location" : "https://github.com/daltoniam/Starscream",
+ "state" : {
+ "revision" : "a063fda2b8145a231953c20e7a646be254365396",
+ "version" : "3.1.2"
+ }
+ },
+ {
+ "identity" : "swift-qrcode-generator",
+ "kind" : "remoteSourceControl",
+ "location" : "https://github.com/dagronf/swift-qrcode-generator",
+ "state" : {
+ "revision" : "5ca09b6a2ad190f94aa3d6ddef45b187f8c0343b",
+ "version" : "1.0.3"
+ }
+ },
+ {
+ "identity" : "swift-snapshot-testing",
+ "kind" : "remoteSourceControl",
+ "location" : "https://github.com/pointfreeco/swift-snapshot-testing",
+ "state" : {
+ "revision" : "f29e2014f6230cf7d5138fc899da51c7f513d467",
+ "version" : "1.10.0"
+ }
+ },
+ {
+ "identity" : "swiftimagereadwrite",
+ "kind" : "remoteSourceControl",
+ "location" : "https://github.com/dagronf/SwiftImageReadWrite",
+ "state" : {
+ "revision" : "5596407d1cf61b953b8e658fa8636a471df3c509",
+ "version" : "1.1.6"
+ }
+ },
+ {
+ "identity" : "wallet-mobile-sdk",
+ "kind" : "remoteSourceControl",
+ "location" : "https://github.com/WalletConnect/wallet-mobile-sdk",
+ "state" : {
+ "revision" : "b6dfb7d6b8447c7c5b238a10443a1ac28223f38f",
+ "version" : "1.0.0"
+ }
+ },
+ {
+ "identity" : "walletconnectswiftv2",
+ "kind" : "remoteSourceControl",
+ "location" : "https://github.com/WalletConnect/WalletConnectSwiftV2",
+ "state" : {
+ "revision" : "4f93c19f02b5b9ae0a984794cae542b9ca1b7471",
+ "version" : "1.13.0"
+ }
+ }
+ ],
+ "version" : 2
+}
diff --git a/Web3Modal.xcworkspace/xcshareddata/xcschemes/swift-web3modal-Package.xcscheme b/Web3Modal.xcworkspace/xcshareddata/xcschemes/swift-web3modal-Package.xcscheme
new file mode 100644
index 0000000..0634222
--- /dev/null
+++ b/Web3Modal.xcworkspace/xcshareddata/xcschemes/swift-web3modal-Package.xcscheme
@@ -0,0 +1,135 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/fastlane/Appfile b/fastlane/Appfile
new file mode 100644
index 0000000..91ad3f0
--- /dev/null
+++ b/fastlane/Appfile
@@ -0,0 +1,2 @@
+itc_team_id("123564616")
+team_id("W5R8AG9K22")
diff --git a/fastlane/Fastfile b/fastlane/Fastfile
new file mode 100644
index 0000000..97d7075
--- /dev/null
+++ b/fastlane/Fastfile
@@ -0,0 +1,46 @@
+ENV["FASTLANE_XCODEBUILD_SETTINGS_TIMEOUT"] = "120"
+
+default_platform(:ios)
+
+platform :ios do
+ lane :release_testflight do |options|
+ setup_ci
+ api_key = app_store_connect_api_key(
+ key_id: ENV["APPLE_KEY_ID"],
+ issuer_id: ENV["APPLE_ISSUER_ID"],
+ key_content: ENV["APPLE_KEY_CONTENT"],
+ duration: 1200,
+ in_house: false,
+ )
+ match(
+ readonly: true,
+ type: "appstore",
+ app_identifier: ENV["MATCH_IDENTIFIERS"],
+ git_url: "https://github.com/WalletConnect/match-swift.git",
+ git_basic_authorization: options[:token],
+ api_key: api_key,
+ )
+ number = latest_testflight_build_number(
+ app_identifier: ENV["APP_IDENTIFIER"],
+ api_key: api_key
+ )
+ increment_build_number(
+ build_number: number + 1,
+ xcodeproj: "Sample/Example.xcodeproj"
+ )
+ gym(
+ configuration: "Release",
+ project: "Sample/Example.xcodeproj",
+ scheme: ENV["SCHEME"],
+ export_method: "app-store",
+ xcargs: "PROJECT_ID='#{options[:project_id]}'"
+ )
+ upload_to_testflight(
+ apple_id: ENV["APPLE_ID"],
+ app_identifier: ENV["APP_IDENTIFIER"],
+ changelog: "Web3Modal sample app weekly build 🚀",
+ skip_waiting_for_build_processing: true
+ )
+ clean_build_artifacts()
+ end
+end
\ No newline at end of file
diff --git a/fastlane/README.md b/fastlane/README.md
new file mode 100644
index 0000000..8b40179
--- /dev/null
+++ b/fastlane/README.md
@@ -0,0 +1,32 @@
+fastlane documentation
+----
+
+# Installation
+
+Make sure you have the latest version of the Xcode command line tools installed:
+
+```sh
+xcode-select --install
+```
+
+For _fastlane_ installation instructions, see [Installing _fastlane_](https://docs.fastlane.tools/#installing-fastlane)
+
+# Available Actions
+
+## iOS
+
+### ios release_testflight
+
+```sh
+[bundle exec] fastlane ios release_testflight
+```
+
+
+
+----
+
+This README.md is auto-generated and will be re-generated every time [_fastlane_](https://fastlane.tools) is run.
+
+More information about _fastlane_ can be found on [fastlane.tools](https://fastlane.tools).
+
+The documentation of _fastlane_ can be found on [docs.fastlane.tools](https://docs.fastlane.tools).
diff --git a/run_tests.sh b/run_tests.sh
new file mode 100755
index 0000000..231fc8c
--- /dev/null
+++ b/run_tests.sh
@@ -0,0 +1,106 @@
+#!/bin/zsh
+set -eE
+trap 'xcrun simctl delete "$DEVICE_ID"' ERR
+
+# Parse named arguments
+while [[ $# -gt 0 ]]; do
+ case $1 in
+ -s|--scheme) SCHEME="$2"; shift;;
+ -p|--project) PROJECT="$2"; shift;;
+ -t|--testplan) TESTPLAN="$2"; shift;;
+ esac
+ shift
+done
+
+if [ -z "$SCHEME" ]; then
+ echo "No scheme provided"
+ exit 1
+fi
+
+# Create ephemeral simulator
+DEVICE_ID=$(xcrun simctl create "EphemeralSim$SCHEME" "iPhone 15 Pro")
+echo "Created ephemeral simulator with id: $DEVICE_ID"
+
+# Set XCBuild defaults
+defaults write com.apple.dt.XCBuild IgnoreFileSystemDeviceInodeChanges -bool YES
+
+# Remove and recreate test_results directory
+echo "Removing and recreating test_results directory"
+rm -rf test_results
+mkdir test_results
+
+if [ -z "$TESTPLAN" ]; then
+ XCTESTRUN=$(find . -name "*_$SCHEME*.xctestrun")
+else
+ XCTESTRUN=$(find . -name "*_$TESTPLAN*.xctestrun")
+fi
+
+# If xctestrun file exists, update it and run test-without-building otherwise run regular test
+if [ -z "$XCTESTRUN" ]; then
+ echo "XCTESTRUN file not found"
+
+ (
+ set -x
+
+ #If xctestrun file does not exist, run regular test
+ set -o pipefail && env NSUnbufferedIO=YES \
+ xcodebuild \
+ ${PROJECT:+-project "$PROJECT"} \
+ ${TESTPLAN:+-testPlan "$TESTPLAN"} \
+ -scheme "$SCHEME" \
+ -destination "platform=iOS Simulator,id=$DEVICE_ID" \
+ -derivedDataPath DerivedDataCache \
+ -clonedSourcePackagesDirPath ../SourcePackagesCache \
+ -resultBundlePath "test_results/$SCHEME.xcresult" \
+ -enableCodeCoverage YES \
+ test \
+ | tee ./test_results/xcodebuild.log \
+ | xcbeautify --report junit --junit-report-filename report.junit --report-path ./test_results
+ )
+else
+
+ echo "XCTESTRUN file found: $XCTESTRUN"
+
+ # update_xctestrun --key "PROJECT_ID" --value "$PROJECT_ID" --target "$XCTESTRUN"
+
+ (
+ set -x
+
+ set -o pipefail && env NSUnbufferedIO=YES \
+ xcodebuild \
+ -xctestrun "$XCTESTRUN" \
+ -destination "platform=iOS Simulator,id=$DEVICE_ID" \
+ -derivedDataPath DerivedDataCache \
+ -clonedSourcePackagesDirPath ../SourcePackagesCache \
+ -resultBundlePath "test_results/$SCHEME.xcresult" \
+ -enableCodeCoverage YES \
+ test-without-building \
+ | tee ./test_results/xcodebuild.log \
+ | xcbeautify --report junit --junit-report-filename report.junit --report-path ./test_results
+ )
+fi
+
+echo "Removing ephemeral simulator"
+xcrun simctl delete "$DEVICE_ID"
+
+echo "Done"
+
+# Function to update xctestrun file
+update_xctestrun() {
+ # Parse named arguments
+ while [[ $# -gt 0 ]]; do
+ case $1 in
+ -k|--key) KEY="$2"; shift;;
+ -v|--value) VALUE="$2"; shift;;
+ -t|--target) TARGET="$2"; shift;;
+ esac
+ shift
+ done
+
+ if [ -n "$VALUE" ]; then
+ echo "Updating $KEY with $VALUE"
+ plutil -replace TestConfigurations.0.TestTargets.0.EnvironmentVariables.$KEY -string "$VALUE" "$TARGET"
+ else
+ echo "No value provided for $KEY"
+ fi
+}