diff --git a/.github/workflows/azure-pipelines.yml b/.github/workflows/azure-pipelines.yml
new file mode 100644
index 0000000000..04aeec669f
--- /dev/null
+++ b/.github/workflows/azure-pipelines.yml
@@ -0,0 +1,20 @@
+# Node.js
+# Build a general Node.js project with npm.
+# Add steps that analyze code, save build artifacts, deploy, and more:
+# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript
+
+ trigger:
+ - master
+
+ pool:
+ vmImage: ubuntu-latest
+
+ steps:
+ - task: NodeTool@0
+ inputs:
+ versionSpec: '10.x'
+ displayName: 'Install Node.js'
+ script: |
+ npm install
+ npm run build
+ displayName: 'npm install and build'
diff --git a/.github/workflows/defender-for-devops.yml b/.github/workflows/defender-for-devops.yml
new file mode 100644
index 0000000000..ccffad8c46
--- /dev/null
+++ b/.github/workflows/defender-for-devops.yml
@@ -0,0 +1,50 @@
+# This workflow uses actions that are not certified by GitHub.
+# They are provided by a third-party and are governed by
+# separate terms of service, privacy policy, and support
+# documentation.
+#
+# Microsoft Security DevOps (MSDO) is a command line application which integrates static analysis tools into the development cycle.
+# MSDO installs, configures and runs the latest versions of static analysis tools
+# (including, but not limited to, SDL/security and compliance tools).
+#
+# The Microsoft Security DevOps action is currently in beta and runs on the windows-latest queue,
+# as well as Windows self hosted agents. ubuntu-latest support coming soon.
+#
+# For more information about the action , check out https://github.com/microsoft/security-devops-action
+#
+# Please note this workflow do not integrate your GitHub Org with Microsoft Defender For DevOps. You have to create an integration
+# and provide permission before this can report data back to azure.
+# Read the official documentation here : https://learn.microsoft.com/en-us/azure/defender-for-cloud/quickstart-onboard-github
+
+name: "Microsoft Defender for DevOps"
+
+permissions:
+ contents: read
+
+on:
+ push:
+ branches: [ "master" ]
+ pull_request:
+ branches: [ "master" ]
+ schedule:
+ - cron: '32 12 * * 5'
+
+jobs:
+ MSDO:
+ # currently only windows latest is supported
+ runs-on: windows-latest
+
+ steps:
+ - uses: actions/checkout@v4
+ - uses: actions/setup-dotnet@v4
+ with:
+ dotnet-version: |
+ 5.0.x
+ 6.0.x
+ - name: Run Microsoft Security DevOps
+ uses: microsoft/security-devops-action@v1.6.0
+ id: msdo
+ - name: Upload results to Security tab
+ uses: github/codeql-action/upload-sarif@v3
+ with:
+ sarif_file: ${{ steps.msdo.outputs.sarifFile }}
diff --git a/.github/workflows/neuralegion.yml b/.github/workflows/neuralegion.yml
new file mode 100644
index 0000000000..33a05d29dc
--- /dev/null
+++ b/.github/workflows/neuralegion.yml
@@ -0,0 +1,177 @@
+# This workflow uses actions that are not certified by GitHub.
+# They are provided by a third-party and are governed by
+# separate terms of service, privacy policy, and support
+# documentation.
+#
+# Run a Nexploit Scan
+# This action runs a new security scan in Nexploit, or reruns an existing one.
+# Build Secure Apps & APIs. Fast.
+# [NeuraLegion](https://www.neuralegion.com) is a powerful dynamic application & API security testing (DAST) platform that security teams trust and developers love.
+# Automatically Tests Every Aspect of Your Apps & APIs
+# Scans any target, whether Web Apps, APIs (REST. & SOAP, GraphQL & more), Web sockets or mobile, providing actionable reports
+# Seamlessly integrates with the Tools and Workflows You Already Use
+#
+# NeuraLegion works with your existing CI/CD pipelines – trigger scans on every commit, pull request or build with unit testing.
+# Spin-Up, Configure and Control Scans with Code
+# One file. One command. One scan. No UI needed.
+#
+# Super-Fast Scans
+#
+# Interacts with applications and APIs, instead of just crawling them and guessing.
+# Scans are fast as our AI-powered engine can understand application architecture and generate sophisticated and targeted attacks.
+#
+# No False Positives
+#
+# Stop chasing ghosts and wasting time. NeuraLegion doesn’t return false positives, so you can focus on releasing code.
+#
+# Comprehensive Security Testing
+#
+# NeuraLegion tests for all common vulnerabilities, such as SQL injection, CSRF, XSS, and XXE -- as well as uncommon vulnerabilities, such as business logic vulnerabilities.
+#
+# More information is available on NeuraLegion’s:
+# * [Website](https://www.neuralegion.com/)
+# * [Knowledge base](https://docs.neuralegion.com/docs/quickstart)
+# * [YouTube channel](https://www.youtube.com/channel/UCoIC0T1pmozq3eKLsUR2uUw)
+# * [GitHub Actions](https://github.com/marketplace?query=neuralegion+)
+#
+# Inputs
+#
+# `name`
+#
+# **Required**. Scan name.
+#
+# _Example:_ `name: GitHub scan ${{ github.sha }}`
+#
+# `api_token`
+#
+# **Required**. Your Nexploit API authorization token (key). You can generate it in the **Organization** section on [nexploit.app](https://nexploit.app/login). Find more information [here](https://kb.neuralegion.com/#/guide/np-web-ui/advanced-set-up/managing-org?id=managing-organization-apicli-authentication-tokens).
+#
+# _Example:_ `api_token: ${{ secrets.NEXPLOIT_TOKEN }}`
+#
+# `restart_scan`
+#
+# **Required** when restarting an existing scan by its ID. You can get the scan ID in the Scans section on [nexploit.app](https://nexploit.app/login). Please make sure to only use the necessary parameters. Otherwise, you will get a response with the parameter usage requirements.
+#
+# _Example:_ `restart_scan: ai3LG8DmVn9Rn1YeqCNRGQ)`
+#
+# `discovery_types`
+#
+# **Required**. Array of discovery types. The following types are available:
+# * `archive` - uses an uploaded HAR-file for a scan
+# * `crawler` - uses a crawler to define the attack surface for a scan
+# * `oas` - uses an uploaded OpenAPI schema for a scan
+# If no discovery type is specified, `crawler` is applied by default.
+#
+# _Example:_
+#
+# ```yml
+# discovery_types: |
+# [ "crawler", "archive" ]
+# ```
+#
+# `file_id`
+#
+# **Required** if the discovery type is set to `archive` or `oas`. ID of a HAR-file or an OpenAPI schema you want to use for a scan. You can get the ID of an uploaded HAR-file or an OpenAPI schema in the **Storage** section on [nexploit.app](https://nexploit.app/login).
+#
+# _Example:_
+#
+# ```
+# FILE_ID=$(nexploit-cli archive:upload \
+# --token ${{ secrets.NEXPLOIT_TOKEN }} \
+# --discard true \
+# ./example.har)
+# ```
+#
+# `crawler_urls`
+#
+# **Required** if the discovery type is set to `crawler`. Target URLs to be used by the crawler to define the attack surface.
+#
+# _Example:_
+#
+# ```
+# crawler_urls: |
+# [ "http://vulnerable-bank.com" ]
+# ```
+#
+# `hosts_filter`
+#
+# **Required** when the the discovery type is set to `archive`. Allows selecting specific hosts for a scan.
+#
+# Outputs
+#
+# `url`
+#
+# Url of the resulting scan
+#
+# `id`
+#
+# ID of the created scan. This ID could then be used to restart the scan, or for the following GitHub actions:
+# * [Nexploit Wait for Issues](https://github.com/marketplace/actions/nexploit-wait-for-issues)
+# * [Nexploit Stop Scan](https://github.com/marketplace/actions/nexploit-stop-scan)
+#
+# Example usage
+#
+# Start a new scan with parameters
+#
+# ```yml
+# steps:
+# - name: Start Nexploit Scan
+# id: start
+# uses: NeuraLegion/run-scan@29ebd17b4fd6292ce7a238a59401668953b37fbe
+# with:
+# api_token: ${{ secrets.NEXPLOIT_TOKEN }}
+# name: GitHub scan ${{ github.sha }}
+# discovery_types: |
+# [ "crawler", "archive" ]
+# crawler_urls: |
+# [ "http://vulnerable-bank.com" ]
+# file_id: LiYknMYSdbSZbqgMaC9Sj
+# hosts_filter: |
+# [ ]
+# - name: Get the output scan url
+# run: echo "The scan was started on ${{ steps.start.outputs.url }}"
+# ```
+#
+# Restart an existing scan
+#
+# ```yml
+# steps:
+# - name: Start Nexploit Scan
+# id: start
+# uses: NeuraLegion/run-scan@29ebd17b4fd6292ce7a238a59401668953b37fbe
+# with:
+# api_token: ${{ secrets.NEXPLOIT_TOKEN }}
+# name: GitHub scan ${{ github.sha }}
+# restart_scan: ai3LG8DmVn9Rn1YeqCNRGQ
+# - name: Get the output scan url
+# run: echo "The scan was started on ${{ steps.start.outputs.url }}"
+
+
+name: "NeuraLegion"
+
+on:
+ push:
+ branches: [ "master" ]
+ pull_request:
+ branches: [ "master" ]
+ schedule:
+ - cron: '31 8 * * 2'
+
+jobs:
+ neuralegion_scan:
+ runs-on: ubuntu-18.04
+ name: A job to run a Nexploit scan
+ permissions:
+ contents: read
+ steps:
+ - uses: actions/checkout@v4
+ - name: Start Nexploit Scan 🏁
+ id: start
+ uses: NeuraLegion/run-scan@29ebd17b4fd6292ce7a238a59401668953b37fbe
+ with:
+ api_token: ${{ secrets.NEURALEGION_TOKEN }}
+ name: GitHub scan ${{ github.sha }}
+ discovery_types: |
+ [ "crawler" ]
+ crawler_urls: |
+ [ "https://brokencrystals.com" ] # ✏️ Update this to the url you wish to scan
diff --git a/.gitignore b/.gitignore
index e70ecd7f00..eae85e64a2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -38,4 +38,7 @@ yarn-error.log*
*.pem
# Husky
-.husky/
\ No newline at end of file
+.husky/
+/lib/signals-implicit-mode/Counter
+/lib/signals-implicit-mode/lib/signals-implicit-mode
+.env*.local
diff --git a/.hintrc b/.hintrc
new file mode 100644
index 0000000000..12c4655b47
--- /dev/null
+++ b/.hintrc
@@ -0,0 +1,8 @@
+{
+ "extends": [
+ "development"
+ ],
+ "hints": {
+ "typescript-config/strict": "off"
+ }
+}
\ No newline at end of file
diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000000..26d33521af
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/.idea/.name b/.idea/.name
new file mode 100644
index 0000000000..835472432f
--- /dev/null
+++ b/.idea/.name
@@ -0,0 +1 @@
+workspace.xml
\ No newline at end of file
diff --git a/.idea/AICommit.xml b/.idea/AICommit.xml
new file mode 100644
index 0000000000..2fa6456f44
--- /dev/null
+++ b/.idea/AICommit.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/caches/deviceStreaming.xml b/.idea/caches/deviceStreaming.xml
new file mode 100644
index 0000000000..94e429a7a2
--- /dev/null
+++ b/.idea/caches/deviceStreaming.xml
@@ -0,0 +1,2007 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml
new file mode 100644
index 0000000000..4bec4ea8ae
--- /dev/null
+++ b/.idea/codeStyles/Project.xml
@@ -0,0 +1,117 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ xmlns:android
+
+ ^$
+
+
+
+
+
+
+
+
+ xmlns:.*
+
+ ^$
+
+
+ BY_NAME
+
+
+
+
+
+
+ .*:id
+
+ http://schemas.android.com/apk/res/android
+
+
+
+
+
+
+
+
+ .*:name
+
+ http://schemas.android.com/apk/res/android
+
+
+
+
+
+
+
+
+ name
+
+ ^$
+
+
+
+
+
+
+
+
+ style
+
+ ^$
+
+
+
+
+
+
+
+
+ .*
+
+ ^$
+
+
+ BY_NAME
+
+
+
+
+
+
+ .*
+
+ http://schemas.android.com/apk/res/android
+
+
+ ANDROID_ATTRIBUTE_ORDER
+
+
+
+
+
+
+ .*
+
+ .*
+
+
+ BY_NAME
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml
new file mode 100644
index 0000000000..a55e7a179b
--- /dev/null
+++ b/.idea/codeStyles/codeStyleConfig.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/copilot.data.migration.ask2agent.xml b/.idea/copilot.data.migration.ask2agent.xml
new file mode 100644
index 0000000000..1f2ea11e7f
--- /dev/null
+++ b/.idea/copilot.data.migration.ask2agent.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
new file mode 100644
index 0000000000..50ea44ed90
--- /dev/null
+++ b/.idea/inspectionProfiles/Project_Default.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/jsonSchemas.xml b/.idea/jsonSchemas.xml
new file mode 100644
index 0000000000..583df9543c
--- /dev/null
+++ b/.idea/jsonSchemas.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/markdown.xml b/.idea/markdown.xml
new file mode 100644
index 0000000000..c61ea3346e
--- /dev/null
+++ b/.idea/markdown.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000000..a62e24909f
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000000..5691f15403
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/sequence.js.iml b/.idea/sequence.js.iml
new file mode 100644
index 0000000000..5bf7f4cf07
--- /dev/null
+++ b/.idea/sequence.js.iml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000000..ccc3562890
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/workspace.xml b/.idea/workspace.xml
new file mode 100644
index 0000000000..1444d76806
--- /dev/null
+++ b/.idea/workspace.xml
@@ -0,0 +1,137 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {
+ "lastFilter": {}
+}
+ {
+ "prStates": [
+ {
+ "id": {
+ "id": "PR_kwDOFtcLA86MvQBm",
+ "number": 26
+ },
+ "lastSeen": 1773929218845
+ }
+ ]
+}
+ {
+ "selectedUrlAndAccountId": {
+ "url": "git@github.com:0xsequence/demo-dapp.git",
+ "accountId": "901c3c88-76ca-48f1-af81-8988657f5914"
+ }
+}
+
+
+
+
+
+
+ {
+ "associatedIndex": 2
+}
+
+
+
+
+
+ {
+ "keyToString": {
+ "ASKED_SHARE_PROJECT_CONFIGURATION_FILES": "true",
+ "ModuleVcsDetector.initialDetectionPerformed": "true",
+ "RunOnceActivity.ShowReadmeOnStart": "true",
+ "RunOnceActivity.cidr.known.project.marker": "true",
+ "RunOnceActivity.readMode.enableVisualFormatting": "true",
+ "SHARE_PROJECT_CONFIGURATION_FILES": "true",
+ "cf.first.check.clang-format": "false",
+ "cidr.known.project.marker": "true",
+ "com.google.services.firebase.aqiPopupShown": "true",
+ "com.intellij.ml.llm.matterhorn.ej.ui.settings.DefaultModelSelectionForGA.v1": "true",
+ "dart.analysis.tool.window.visible": "false",
+ "git-widget-placeholder": "master",
+ "ignore.virus.scanning.warn.message": "true",
+ "junie.onboarding.icon.badge.shown": "true",
+ "kotlin-language-version-configured": "true",
+ "kronk.content.tree.expanded.paths": "",
+ "last_opened_file_path": "C:/Users/Legion/sequence.js",
+ "project.structure.last.edited": "Project",
+ "project.structure.proportion": "0.0",
+ "project.structure.side.proportion": "0.0",
+ "settings.editor.selected.configurable": "memory.settings",
+ "show.migrate.to.gradle.popup": "false",
+ "to.speed.mode.migration.done": "true"
+ }
+}
+
+
+
+ 1770786009107
+
+
+ 1770786009107
+
+
+
+ 1770790536574
+
+
+
+ 1770790536579
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.vscode/launch.json b/.vscode/launch.json
index dc22920a87..585147c876 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -6,8 +6,12 @@
"type": "node",
"request": "launch",
"program": "${workspaceFolder}/packages/wallet/primitives-cli/dist/index.js",
- "args": ["server"],
- "runtimeArgs": ["--enable-source-maps"],
+ "args": [
+ "server"
+ ],
+ "runtimeArgs": [
+ "--enable-source-maps"
+ ],
"cwd": "${workspaceFolder}",
"console": "integratedTerminal",
"sourceMaps": true,
@@ -23,6 +27,56 @@
"../packages/wallet/primitives/src/*": "${workspaceFolder}/packages/wallet/primitives/src/*",
"../packages/wallet/wdk/src/*": "${workspaceFolder}/packages/wallet/wdk/src/*"
}
+ },
+ {
+ "type": "msedge",
+ "name": "Launch Microsoft Edge",
+ "request": "launch",
+ "runtimeArgs": [
+ "--remote-debugging-port=9222"
+ ],
+ "url": "c:\\Users\\Legion\\.vscode\\extensions\\ms-edgedevtools.vscode-edge-devtools-2.1.10\\out\\startpage\\index.html",
+ "presentation": {
+ "hidden": true
+ }
+ },
+ {
+ "type": "msedge",
+ "name": "Launch Microsoft Edge in headless mode",
+ "request": "launch",
+ "runtimeArgs": [
+ "--headless",
+ "--remote-debugging-port=9222"
+ ],
+ "url": "c:\\Users\\Legion\\.vscode\\extensions\\ms-edgedevtools.vscode-edge-devtools-2.1.10\\out\\startpage\\index.html",
+ "presentation": {
+ "hidden": true
+ }
+ },
+ {
+ "type": "vscode-edge-devtools.debug",
+ "name": "Open Edge DevTools",
+ "request": "attach",
+ "url": "c:\\Users\\Legion\\.vscode\\extensions\\ms-edgedevtools.vscode-edge-devtools-2.1.10\\out\\startpage\\index.html",
+ "presentation": {
+ "hidden": true
+ }
+ }
+ ],
+ "compounds": [
+ {
+ "name": "Launch Edge Headless and attach DevTools",
+ "configurations": [
+ "Launch Microsoft Edge in headless mode",
+ "Open Edge DevTools"
+ ]
+ },
+ {
+ "name": "Launch Edge and attach DevTools",
+ "configurations": [
+ "Launch Microsoft Edge",
+ "Open Edge DevTools"
+ ]
}
]
-}
+}
\ No newline at end of file
diff --git a/extras/web/app/layout.tsx b/extras/web/app/layout.tsx
index 2e5719345e..a28c1043ea 100644
--- a/extras/web/app/layout.tsx
+++ b/extras/web/app/layout.tsx
@@ -1,5 +1,6 @@
import type { Metadata } from 'next'
import localFont from 'next/font/local'
+import { Analytics } from '@vercel/analytics/next'
import './globals.css'
const geistSans = localFont({
@@ -23,7 +24,10 @@ export default function RootLayout({
}>) {
return (
-
{children}
+
+ {children}
+
+
)
}
diff --git a/packages/0xsequence/README.md b/packages/0xsequence/README.md
new file mode 100644
index 0000000000..1b4b9e6704
--- /dev/null
+++ b/packages/0xsequence/README.md
@@ -0,0 +1,67 @@
+0xsequence
+==========
+
+## Install
+
+`npm install 0xsequence ethers`
+
+or
+
+`pnpm install 0xsequence ethers`
+
+or
+
+`yarn add 0xsequence ethers`
+
+
+## Development Workflow
+
+Sequence is a critical piece of software and any change should be delivered via a TDD (test-driven development)
+workflow.
+
+As well, sequence.js's monorepo tooling is setup with preconstruct, which links all sub-packages together
+so it feels like a single program and is easy to work with. Please run `pnpm dev` in the root of `sequence.js/`
+folder to ensure the monorepo is in 'dev-mode'.
+
+Second, you can run the test suite directly from console with a single `pnpm test`, or you can boot up the Typescript
+compiling server (`pnpm test:server`) and ethereum test node (`pnpm start:hardhat` and `pnpm start:hardhat2`) manually
+in separate terminals, and then run a specific test directly from your browser instance. We recommend running the
+test stack separately and running specific browser tests manually during development. See [here for recommended setup](./#from-browser).
+
+
+## Running E2E Tests
+
+This 0xsequence top-level package contains e2e tests which run in a headless chrome browser.
+
+You can view tests running directly from the browser directly, or from the cli which will communicate
+to the headless browser behind the scenes. See below. Please note, for an improved development workflow
+we highly recommend to view your tests running from the browser as its more clear and better experience.
+
+
+### From Browser
+
+1. `pnpm test:server` -- in one terminal, to start the webpack server compiling typescript
+2. `pnpm start:hardhat` -- in a second terminal, to start hardhat local ethereum test node
+3. `pnpm start:hardhat2` -- (2nd chain) in a third terminal, to start hardhat2 local ethereum test node
+4. open browser to `http://localhost:9999/{browser-test-dir}/{test-filename}.test.html` for example,
+ http://localhost:9999/wallet-provider/dapp.test.html
+5. open your browser console so you can see the tests running and their results.
+
+Finally, if you'd like to run only a specific test case, either add a temporary "return" statement
+following the last test case, so you will preempt the runner after a certain test case.
+
+As well, since you have all the services running in terminals, you can also execute commands via
+the cli by calling `test:run`, which is similar to step 4 above, but executing all tests from the terminal.
+There is also the `test:only` command if you'd like to execute a specific test from ./tests/browser/*.spec.ts
+file, ie. `pnpm test:only window-transport`.
+
+
+### From CLI
+
+With a single command, you can spin up the testing stack and execute tests:
+
+`pnpm test`
+
+This is useful for a sanity check to ensure tests pass, or using it with the CI. However, if you're
+developing on sequence.js, its highly recommended you follow the [development workflow instructions](./#development-workflow).
+
diff --git a/packages/0xsequence/hardhat.config.js b/packages/0xsequence/hardhat.config.js
new file mode 100644
index 0000000000..88c1e3f0a6
--- /dev/null
+++ b/packages/0xsequence/hardhat.config.js
@@ -0,0 +1,21 @@
+/**
+ * @type import('hardhat/config').HardhatUserConfig
+ */
+module.exports = {
+ solidity: '0.7.6',
+
+ networks: {
+ hardhat: {
+ // gas: 10000000000000,
+ // blockGasLimit: 10000000000000,
+ // gasPrice: 2,
+ initialBaseFeePerGas: 1,
+ chainId: 31337,
+ accounts: {
+ mnemonic: 'ripple axis someone ridge uniform wrist prosper there frog rate olympic knee'
+ },
+ // loggingEnabled: true
+ // verbose: true
+ },
+ }
+}
diff --git a/packages/0xsequence/hardhat2.config.js b/packages/0xsequence/hardhat2.config.js
new file mode 100644
index 0000000000..4ec2897be8
--- /dev/null
+++ b/packages/0xsequence/hardhat2.config.js
@@ -0,0 +1,21 @@
+/**
+ * @type import('hardhat/config').HardhatUserConfig
+ */
+module.exports = {
+ solidity: '0.7.6',
+
+ networks: {
+ hardhat: {
+ // gas: 10000000000000,
+ // blockGasLimit: 10000000000000,
+ // gasPrice: 2,
+ initialBaseFeePerGas: 1,
+ chainId: 31338,
+ accounts: {
+ mnemonic: 'ripple axis someone ridge uniform wrist prosper there frog rate olympic knee'
+ },
+ // loggingEnabled: true
+ // verbose: true
+ },
+ }
+}
diff --git a/packages/0xsequence/src/abi.ts b/packages/0xsequence/src/abi.ts
new file mode 100644
index 0000000000..56f239636f
--- /dev/null
+++ b/packages/0xsequence/src/abi.ts
@@ -0,0 +1 @@
+export * from '@0xsequence/abi'
diff --git a/packages/0xsequence/src/account.ts b/packages/0xsequence/src/account.ts
new file mode 100644
index 0000000000..5378d52938
--- /dev/null
+++ b/packages/0xsequence/src/account.ts
@@ -0,0 +1 @@
+export * from '@0xsequence/account'
diff --git a/packages/0xsequence/src/api.ts b/packages/0xsequence/src/api.ts
new file mode 100644
index 0000000000..157694d571
--- /dev/null
+++ b/packages/0xsequence/src/api.ts
@@ -0,0 +1 @@
+export * from '@0xsequence/api'
diff --git a/packages/0xsequence/src/auth.ts b/packages/0xsequence/src/auth.ts
new file mode 100644
index 0000000000..5ea89b7eae
--- /dev/null
+++ b/packages/0xsequence/src/auth.ts
@@ -0,0 +1 @@
+export * from '@0xsequence/auth'
diff --git a/packages/0xsequence/src/core.ts b/packages/0xsequence/src/core.ts
new file mode 100644
index 0000000000..c9df6528a9
--- /dev/null
+++ b/packages/0xsequence/src/core.ts
@@ -0,0 +1,6 @@
+import { commons } from '@0xsequence/core'
+
+export * from '@0xsequence/core'
+
+export type Config = commons.config.Config
+export type WalletContext = commons.context.WalletContext
diff --git a/packages/0xsequence/src/guard.ts b/packages/0xsequence/src/guard.ts
new file mode 100644
index 0000000000..d91cdc9030
--- /dev/null
+++ b/packages/0xsequence/src/guard.ts
@@ -0,0 +1 @@
+export * from '@0xsequence/guard'
diff --git a/packages/0xsequence/src/index.ts b/packages/0xsequence/src/index.ts
new file mode 100644
index 0000000000..e8f182e4c3
--- /dev/null
+++ b/packages/0xsequence/src/index.ts
@@ -0,0 +1,3 @@
+export * as sequence from './sequence'
+
+export { initWallet } from '@0xsequence/provider'
diff --git a/packages/0xsequence/src/indexer.ts b/packages/0xsequence/src/indexer.ts
new file mode 100644
index 0000000000..e59cb5bcef
--- /dev/null
+++ b/packages/0xsequence/src/indexer.ts
@@ -0,0 +1 @@
+export * from '@0xsequence/indexer'
diff --git a/packages/0xsequence/src/metadata.ts b/packages/0xsequence/src/metadata.ts
new file mode 100644
index 0000000000..cb9f181988
--- /dev/null
+++ b/packages/0xsequence/src/metadata.ts
@@ -0,0 +1 @@
+export * from '@0xsequence/metadata'
diff --git a/packages/0xsequence/src/migration.ts b/packages/0xsequence/src/migration.ts
new file mode 100644
index 0000000000..029dfd7095
--- /dev/null
+++ b/packages/0xsequence/src/migration.ts
@@ -0,0 +1 @@
+export * from '@0xsequence/migration'
diff --git a/packages/0xsequence/src/multicall.ts b/packages/0xsequence/src/multicall.ts
new file mode 100644
index 0000000000..76f619a9cb
--- /dev/null
+++ b/packages/0xsequence/src/multicall.ts
@@ -0,0 +1 @@
+export * from '@0xsequence/multicall'
diff --git a/packages/0xsequence/src/network.ts b/packages/0xsequence/src/network.ts
new file mode 100644
index 0000000000..137b376efd
--- /dev/null
+++ b/packages/0xsequence/src/network.ts
@@ -0,0 +1,14 @@
+export * from '@0xsequence/network'
+
+export type {
+ JsonRpcRequest,
+ JsonRpcResponse,
+ JsonRpcResponseCallback,
+ JsonRpcHandlerFunc,
+ JsonRpcFetchFunc,
+ JsonRpcRequestFunc,
+ JsonRpcMiddleware,
+ JsonRpcMiddlewareHandler,
+ NetworkConfig,
+ ChainIdLike
+} from '@0xsequence/network'
diff --git a/packages/0xsequence/src/provider.ts b/packages/0xsequence/src/provider.ts
new file mode 100644
index 0000000000..65262e5f43
--- /dev/null
+++ b/packages/0xsequence/src/provider.ts
@@ -0,0 +1,29 @@
+export * from '@0xsequence/provider'
+
+export type {
+ SequenceProvider,
+ ProviderConfig,
+ WalletSignInOptions,
+ ProviderTransport,
+ WalletTransport,
+ ProviderMessage,
+ ProviderMessageRequest,
+ ProviderMessageResponse,
+ ProviderMessageResponseCallback,
+ ProviderMessageRequestHandler,
+ ProviderMessageTransport,
+ WalletEventTypes,
+ ProviderEventTypes,
+ EventType,
+ WalletSession,
+ OpenState,
+ ConnectOptions,
+ ConnectDetails,
+ PromptConnectDetails,
+ OpenWalletIntent,
+ ETHAuthProof,
+ ProviderError,
+ MessageToSign,
+ ProviderRpcError,
+ ErrSignedInRequired
+} from '@0xsequence/provider'
diff --git a/packages/0xsequence/src/relayer.ts b/packages/0xsequence/src/relayer.ts
new file mode 100644
index 0000000000..92995de5f8
--- /dev/null
+++ b/packages/0xsequence/src/relayer.ts
@@ -0,0 +1,3 @@
+export * from '@0xsequence/relayer'
+
+export type { Relayer, RpcRelayerProto, RelayerTxReceipt } from '@0xsequence/relayer'
diff --git a/packages/0xsequence/src/sequence.ts b/packages/0xsequence/src/sequence.ts
new file mode 100644
index 0000000000..6eda8e9d93
--- /dev/null
+++ b/packages/0xsequence/src/sequence.ts
@@ -0,0 +1,21 @@
+export * as abi from './abi'
+export * as api from './api'
+export * as auth from './auth'
+export * as guard from './guard'
+export * as indexer from './indexer'
+export * as metadata from './metadata'
+export * as multicall from './multicall'
+export * as network from './network'
+export * as provider from './provider'
+export * as relayer from './relayer'
+export * as transactions from './transactions'
+export * as utils from './utils'
+export * as core from './core'
+export * as signhub from './signhub'
+export * as sessions from './sessions'
+export * as migration from './migration'
+export * as account from './account'
+
+export { initWallet, getWallet, unregisterWallet, SequenceProvider, SequenceClient, SequenceSigner } from '@0xsequence/provider'
+
+export type { ProviderConfig, WalletSession } from '@0xsequence/provider'
diff --git a/packages/0xsequence/src/sessions.ts b/packages/0xsequence/src/sessions.ts
new file mode 100644
index 0000000000..9a4eebe7c0
--- /dev/null
+++ b/packages/0xsequence/src/sessions.ts
@@ -0,0 +1 @@
+export * from '@0xsequence/sessions'
diff --git a/packages/0xsequence/src/signhub.ts b/packages/0xsequence/src/signhub.ts
new file mode 100644
index 0000000000..6c49ae506d
--- /dev/null
+++ b/packages/0xsequence/src/signhub.ts
@@ -0,0 +1 @@
+export * from '@0xsequence/signhub'
diff --git a/packages/0xsequence/src/transactions.ts b/packages/0xsequence/src/transactions.ts
new file mode 100644
index 0000000000..f2b08c462f
--- /dev/null
+++ b/packages/0xsequence/src/transactions.ts
@@ -0,0 +1,10 @@
+import { commons } from '@0xsequence/core'
+
+export const transactions = commons.transaction
+
+export type Transaction = commons.transaction.Transaction
+export type TransactionEncoded = commons.transaction.TransactionEncoded
+export type TransactionResponse = commons.transaction.TransactionResponse
+export type Transactionish = commons.transaction.Transactionish
+export type SignedTransactionBundle = commons.transaction.SignedTransactionBundle
+export type RelayReadyTransactionBundle = commons.transaction.RelayReadyTransactionBundle
diff --git a/packages/0xsequence/src/utils.ts b/packages/0xsequence/src/utils.ts
new file mode 100644
index 0000000000..b82801f35d
--- /dev/null
+++ b/packages/0xsequence/src/utils.ts
@@ -0,0 +1,5 @@
+export * from '@0xsequence/utils'
+
+export { isValidSignature, isValidMessageSignature, isValidTypedDataSignature, isWalletUpToDate } from '@0xsequence/provider'
+
+export type { Deferrable, TypedData, TypedDataDomain, TypedDataField, LogLevel, LoggerConfig } from '@0xsequence/utils'
diff --git a/packages/0xsequence/tests/browser/json-rpc-provider/rpc.test.ts b/packages/0xsequence/tests/browser/json-rpc-provider/rpc.test.ts
new file mode 100644
index 0000000000..1e234ee69b
--- /dev/null
+++ b/packages/0xsequence/tests/browser/json-rpc-provider/rpc.test.ts
@@ -0,0 +1,39 @@
+import { ethers } from 'ethers'
+import { test, assert } from '../../utils/assert'
+
+import { configureLogger } from '@0xsequence/utils'
+import { JsonRpcProvider, loggingProviderMiddleware } from '@0xsequence/network'
+
+configureLogger({ logLevel: 'DEBUG', silence: false })
+
+export const tests = async () => {
+ // const provider = new ethers.providers.JsonRpcProvider('http://localhost:8545', 31337)
+ const provider = new JsonRpcProvider('http://localhost:8545', { chainId: 31337 })
+
+ await test('sending a json-rpc request', async () => {
+ {
+ const network = await provider.getNetwork()
+ console.log('network?', network)
+ }
+ {
+ const chainId = await provider.send('eth_chainId', [])
+ assert.true(ethers.BigNumber.from(chainId).toString() === '31337')
+ }
+ {
+ const chainId = await provider.send('eth_chainId', [])
+ assert.true(ethers.BigNumber.from(chainId).toString() === '31337')
+ }
+ {
+ const chainId = await provider.send('eth_chainId', [])
+ assert.true(ethers.BigNumber.from(chainId).toString() === '31337')
+ }
+ {
+ const chainId = await provider.send('eth_chainId', [])
+ assert.true(ethers.BigNumber.from(chainId).toString() === '31337')
+ }
+ {
+ const netVersion = await provider.send('net_version', [])
+ assert.true(netVersion === '31337')
+ }
+ })
+}
diff --git a/packages/0xsequence/tests/browser/mock-wallet/mock-wallet.test.ts b/packages/0xsequence/tests/browser/mock-wallet/mock-wallet.test.ts
new file mode 100644
index 0000000000..6ee073cb7e
--- /dev/null
+++ b/packages/0xsequence/tests/browser/mock-wallet/mock-wallet.test.ts
@@ -0,0 +1,120 @@
+import { ethers } from 'ethers'
+import { WalletRequestHandler, WindowMessageHandler } from '@0xsequence/provider'
+import { Account } from '@0xsequence/account'
+import { NetworkConfig } from '@0xsequence/network'
+import { LocalRelayer } from '@0xsequence/relayer'
+import { configureLogger } from '@0xsequence/utils'
+
+import { testAccounts, getEOAWallet } from '../testutils'
+import { test, assert } from '../../utils/assert'
+import * as utils from '@0xsequence/tests'
+import { Orchestrator } from '@0xsequence/signhub'
+import { trackers } from '@0xsequence/sessions'
+
+configureLogger({ logLevel: 'DEBUG', silence: false })
+
+//
+// Wallet, a test wallet
+//
+
+const main = async () => {
+ //
+ // Providers
+ //
+ const provider = new ethers.providers.JsonRpcProvider('http://localhost:8545')
+ const provider2 = new ethers.providers.JsonRpcProvider('http://localhost:9545')
+
+ //
+ // Deploy Sequence WalletContext (deterministic)
+ //
+ const deployedWalletContext = await utils.context.deploySequenceContexts(provider.getSigner())
+ await utils.context.deploySequenceContexts(provider2.getSigner())
+
+ // Generate a new wallet every time, otherwise tests will fail
+ // due to EIP-6492 being used only sometimes (some tests deploy the wallet)
+ const owner = ethers.Wallet.createRandom()
+
+ const relayer = new LocalRelayer(getEOAWallet(testAccounts[5].privateKey))
+ const relayer2 = new LocalRelayer(getEOAWallet(testAccounts[5].privateKey, provider2))
+
+ // Network available list
+ const networks: NetworkConfig[] = [
+ {
+ name: 'hardhat',
+ chainId: 31337,
+ rpcUrl: provider.connection.url,
+ provider: provider,
+ relayer: relayer,
+ isDefaultChain: true,
+ nativeToken: {
+ symbol: 'ETH',
+ name: 'Ether',
+ decimals: 18
+ }
+ },
+ {
+ name: 'hardhat2',
+ chainId: 31338,
+ rpcUrl: provider2.connection.url,
+ provider: provider2,
+ relayer: relayer2,
+ nativeToken: {
+ symbol: 'ETH',
+ name: 'Ether',
+ decimals: 18
+ }
+ }
+ ]
+
+ // Account for managing multi-network wallets
+ // TODO: make this a 3-key multisig with threshold of 2
+ // const account = new Account(
+ // {
+ // initialConfig: wallet.config,
+ // networks,
+ // context: deployedWalletContext
+ // },
+ // owner
+ // )
+ const account = await Account.new({
+ config: {
+ threshold: 2,
+ checkpoint: 0,
+ signers: [
+ {
+ address: owner.address,
+ weight: 2
+ }
+ ]
+ },
+ networks,
+ contexts: deployedWalletContext,
+ orchestrator: new Orchestrator([owner]),
+ tracker: new trackers.local.LocalConfigTracker(provider)
+ })
+
+ // the json-rpc signer via the wallet
+ const walletRequestHandler = new WalletRequestHandler(undefined, null, networks)
+
+ // fake/force an async wallet initialization for the wallet-request handler. This is the behaviour
+ // of the wallet-webapp, so lets ensure the mock wallet does the same thing too.
+ setTimeout(() => {
+ walletRequestHandler.signIn(account)
+ }, 1000)
+
+ // setup and register window message transport
+ const windowHandler = new WindowMessageHandler(walletRequestHandler)
+ windowHandler.register()
+}
+
+main()
+
+export const tests = async () => {
+ // TODO: add tests() method to verify some wallet functionality such a login
+ // and adding / removing keys, etc..
+ // + mock in a RemoteSigner as well.
+
+ await test('stub', async () => {
+ assert.true(true, 'ok')
+ })
+}
diff --git a/packages/0xsequence/tests/browser/mux-transport/mux.test.ts b/packages/0xsequence/tests/browser/mux-transport/mux.test.ts
new file mode 100644
index 0000000000..d691143764
--- /dev/null
+++ b/packages/0xsequence/tests/browser/mux-transport/mux.test.ts
@@ -0,0 +1,175 @@
+import {
+ WalletRequestHandler,
+ ProxyMessageChannel,
+ ProxyMessageHandler,
+ WindowMessageHandler,
+ SequenceClient,
+ MemoryItemStore
+} from '@0xsequence/provider'
+import { ethers } from 'ethers'
+import { test, assert } from '../../utils/assert'
+import { NetworkConfig } from '@0xsequence/network'
+import { LocalRelayer } from '@0xsequence/relayer'
+import { configureLogger } from '@0xsequence/utils'
+import { testAccounts, getEOAWallet } from '../testutils'
+import * as utils from '@0xsequence/tests'
+import { Account } from '@0xsequence/account'
+import { Orchestrator } from '@0xsequence/signhub'
+import { trackers } from '@0xsequence/sessions'
+import { commons } from '@0xsequence/core'
+
+configureLogger({ logLevel: 'DEBUG', silence: false })
+
+// Tests simulates a multi-message provider environment by having a wallet available via the
+// proxy channel and wallet window.
+export const tests = async () => {
+ //
+ // Providers
+ //
+ const provider1 = new ethers.providers.JsonRpcProvider('http://localhost:8545')
+ const provider2 = new ethers.providers.JsonRpcProvider('http://localhost:9545')
+
+ //
+ // Deploy Sequence WalletContext (deterministic).
+ //
+ const deployedWalletContext = await utils.context.deploySequenceContexts(provider1.getSigner())
+ await utils.context.deploySequenceContexts(provider2.getSigner())
+ console.log('walletContext:', deployedWalletContext)
+
+ //
+ // Proxy Channel (normally would be out-of-band)
+ //
+ const ch = new ProxyMessageChannel()
+
+ //
+ // Wallet Handler (local mock wallet, same a mock-wallet tests)
+ //
+
+ // owner account address: 0x4e37E14f5d5AAC4DF1151C6E8DF78B7541680853
+ const owner = getEOAWallet(testAccounts[0].privateKey)
+
+ // relayers, account address: 0x3631d4d374c3710c3456d6b1de1ee8745fbff8ba
+ // const relayerAccount = getEOAWallet(testAccounts[5].privateKey)
+ const relayer1 = new LocalRelayer(getEOAWallet(testAccounts[5].privateKey))
+ const relayer2 = new LocalRelayer(getEOAWallet(testAccounts[5].privateKey, provider2))
+
+ // Network available list
+ const networks: NetworkConfig[] = [
+ {
+ name: 'hardhat',
+ chainId: 31337,
+ rpcUrl: provider1.connection.url,
+ provider: provider1,
+ relayer: relayer1,
+ isDefaultChain: true
+ },
+ {
+ name: 'hardhat2',
+ chainId: 31338,
+ rpcUrl: provider2.connection.url,
+ provider: provider2,
+ relayer: relayer2
+ }
+ ]
+
+ // Account for managing multi-network wallets
+ const saccount = await Account.new({
+ networks,
+ contexts: deployedWalletContext,
+ config: {
+ threshold: 1,
+ checkpoint: 0,
+ signers: [
+ {
+ address: owner.address,
+ weight: 1
+ }
+ ]
+ },
+ orchestrator: new Orchestrator([owner]),
+ tracker: new trackers.local.LocalConfigTracker(provider1)
+ })
+
+ // the rpc signer via the wallet
+ const walletRequestHandler = new WalletRequestHandler(saccount, null, networks)
+
+ // register wallet message handler, in this case using the ProxyMessage transport.
+ const proxyHandler = new ProxyMessageHandler(walletRequestHandler, ch.wallet)
+ proxyHandler.register()
+
+ // register window message transport
+ const windowHandler = new WindowMessageHandler(walletRequestHandler)
+ windowHandler.register()
+
+ //
+ // Dapp, wallet provider and dapp tests
+ //
+
+ // wallet client with multiple message provider transports enabled
+ const client = new SequenceClient(
+ {
+ windowTransport: { enabled: true },
+ proxyTransport: { enabled: true, appPort: ch.app }
+ },
+ new MemoryItemStore(),
+ {
+ defaultChainId: 31337
+ }
+ )
+
+ // provider + signer, by default if a chainId is not specified it will direct
+ // requests to the defaultChain
+ // const provider = wallet.getProvider()
+ // const signer = wallet.getSigner()
+
+ // clear it in case we're testing in browser session
+ client.disconnect()
+
+ await test('is disconnected / logged out', async () => {
+ assert.false(client.isConnected(), 'is logged out')
+ })
+
+ await test('is closed', async () => {
+ assert.false(client.isOpened(), 'is closed')
+ })
+
+ await test('connect', async () => {
+ const { connected } = await client.connect({
+ app: 'test',
+ keepWalletOpened: true
+ })
+
+ assert.true(connected, 'is connected')
+ })
+
+ await test('isOpened', async () => {
+ assert.true(client.isOpened(), 'is opened')
+ })
+
+ await test('isConnected', async () => {
+ assert.true(client.isConnected(), 'is connected')
+ })
+
+ await test('open wallet while its already opened', async () => {
+ // its already opened, but lets do it again
+ const opened = await client.openWallet()
+ assert.true(opened, 'wallet is opened')
+ })
+
+ let walletContext: commons.context.VersionedContext
+ await test('getWalletContext', async () => {
+ walletContext = await client.getWalletContext()
+ assert.equal(walletContext[2].factory, deployedWalletContext[2].factory, 'wallet context factory')
+ assert.equal(walletContext[2].guestModule, deployedWalletContext[2].guestModule, 'wallet context guestModule')
+ })
+
+ await test('getChainId', async () => {
+ const chainId = client.getChainId()
+ assert.equal(chainId, 31337, 'chainId is correct')
+ })
+
+ await test('switch chains', async () => {
+ client.setDefaultChainId(31338)
+ assert.equal(client.getChainId(), 31338, 'chainId of other chain is 31338')
+ })
+}
diff --git a/packages/0xsequence/tests/browser/proxy-transport/channel.test.ts b/packages/0xsequence/tests/browser/proxy-transport/channel.test.ts
new file mode 100644
index 0000000000..ae8e56f77b
--- /dev/null
+++ b/packages/0xsequence/tests/browser/proxy-transport/channel.test.ts
@@ -0,0 +1,172 @@
+import {
+ SequenceClient,
+ ProxyMessageProvider,
+ WalletRequestHandler,
+ ProxyMessageChannel,
+ ProxyMessageHandler,
+ prefixEIP191Message,
+ MemoryItemStore
+} from '@0xsequence/provider'
+import { ethers } from 'ethers'
+import { test, assert } from '../../utils/assert'
+import { LocalRelayer } from '@0xsequence/relayer'
+import { configureLogger, encodeMessageDigest } from '@0xsequence/utils'
+import { testAccounts, getEOAWallet } from '../testutils'
+import { Account } from '@0xsequence/account'
+import * as utils from '@0xsequence/tests'
+import { Orchestrator } from '@0xsequence/signhub'
+import { trackers } from '@0xsequence/sessions'
+import { commons } from '@0xsequence/core'
+
+configureLogger({ logLevel: 'DEBUG', silence: false })
+
+export const tests = async () => {
+ // ProxyMessageChannel object is to be instantiated by the app coordinating
+ // the channel, ie. such as the mobile application itself.
+ //
+ // `ch.app` (port) will be injected into the app, and `ch.wallet` (port) will be injected into the wallet.
+ //
+ // Sending messages to the app port will go through channel and get received by the wallet.
+ // Sending messages to the wallet port will go through channel and get received by the app.
+ const ch = new ProxyMessageChannel()
+
+ ch.app.on('open', openInfo => {
+ console.log('app, wallet opened.', openInfo)
+ })
+ ch.app.on('close', () => {
+ console.log('app, wallet closed.')
+ })
+ ch.app.on('connect', () => {
+ console.log('app, wallet connected.')
+ })
+ ch.app.on('disconnect', () => {
+ console.log('app, wallet disconnected.')
+ })
+ // ch.wallet.on('open', () => {
+ // console.log('wallet, wallet opened.')
+ // })
+ // ch.wallet.on('close', () => {
+ // console.log('wallet, wallet closed.')
+ // })
+ // ch.wallet.on('connect', () => {
+ // console.log('wallet, wallet connected.')
+ // })
+ // ch.wallet.on('disconnect', () => {
+ // console.log('wallet, wallet disconnected.')
+ // })
+
+ //
+ // Wallet Handler
+ //
+
+ // owner account address: 0x4e37E14f5d5AAC4DF1151C6E8DF78B7541680853
+ const owner = getEOAWallet(testAccounts[0].privateKey)
+
+ // relayer account is same as owner here
+ const relayer = new LocalRelayer(owner)
+ const rpcProvider = new ethers.providers.JsonRpcProvider('http://localhost:8545')
+ const contexts = await utils.context.deploySequenceContexts(rpcProvider.getSigner())
+
+ const networks = [
+ {
+ name: 'hardhat',
+ chainId: 31337,
+ rpcUrl: rpcProvider.connection.url,
+ provider: rpcProvider,
+ relayer: relayer,
+ isDefaultChain: true
+ }
+ ]
+
+ // wallet account address: 0x91A858FbBa42E7EE200b4303b1A8B2F0BD139663 based on the chainId
+ const account = await Account.new({
+ config: {
+ threshold: 1,
+ checkpoint: 1674142220,
+ signers: [
+ {
+ address: owner.address,
+ weight: 1
+ }
+ ]
+ },
+ networks,
+ contexts,
+ orchestrator: new Orchestrator([owner]),
+ tracker: new trackers.local.LocalConfigTracker(rpcProvider)
+ })
+
+ // the rpc signer via the wallet
+ const walletRequestHandler = new WalletRequestHandler(undefined, null, networks)
+
+ // register wallet message handler, in this case using the ProxyMessage transport.
+ const proxyHandler = new ProxyMessageHandler(walletRequestHandler, ch.wallet)
+ proxyHandler.register()
+
+ //
+ // App Provider
+ //
+ const walletProvider = new ProxyMessageProvider(ch.app)
+ walletProvider.register()
+
+ // setup web3 provider
+ const client = new SequenceClient(walletProvider, new MemoryItemStore(), { defaultChainId: 31337 })
+ const connectPromise = client.connect({ app: 'proxy-transport-channel test', keepWalletOpened: true })
+
+ // fake/force an async wallet initialization for the wallet-request handler. This is the behaviour
+ // of the wallet-webapp, so lets ensure the mock wallet does the same thing too.
+ walletRequestHandler.signIn(account, { connect: true })
+
+ await connectPromise
+
+ const address = client.getAddress()
+
+ await test('verifying getAddress result', async () => {
+ assert.equal(address, ethers.utils.getAddress('0x91A858FbBa42E7EE200b4303b1A8B2F0BD139663'), 'wallet address')
+ })
+
+ await test('sending a json-rpc request', async () => {
+ await walletProvider.sendAsync({ jsonrpc: '2.0', id: 88, method: 'eth_accounts', params: [] }, (err, resp) => {
+ assert.true(!err, 'error is empty')
+ assert.true(!!resp, 'response successful')
+ assert.true(resp!.result == address, 'response address check')
+ })
+ })
+
+ await test('get chain id', async () => {
+ const chainIdClient = client.getChainId()
+ assert.equal(chainIdClient, 31337, 'chain id match')
+
+ const netVersion = await client.send({ method: 'net_version' })
+ assert.equal(netVersion, '31337', 'net_version check')
+
+ const chainId = await client.send({ method: 'eth_chainId' })
+ assert.equal(chainId, '0x7a69', 'eth_chainId check')
+ })
+
+ await test('sign a message and validate/recover', async () => {
+ const message = ethers.utils.toUtf8Bytes('hihi')
+
+ //
+ // Sign the message
+ //
+ const sig = await client.signMessage(message)
+ assert.equal(
+ sig,
+ '0x000163c9620c0001045ea593a25d0053816f2cfb0239eb04c30cc08fd26193927bf6cf68f7f31a8239ecbcbd1365f18a6bf2bf3b13d544c91d85e35503696a28fcb96a4078a7556a1c02',
+ 'signature match'
+ )
+
+ const reader = new commons.reader.OnChainReader(rpcProvider)
+
+ //
+ // Verify the message signature
+ //
+ await account.doBootstrap(31337)
+ const messageDigest = encodeMessageDigest(prefixEIP191Message(message))
+ const isValid = await reader.isValidSignature(address, messageDigest, sig)
+ assert.true(isValid, 'signature is valid - 1')
+ })
+
+ walletProvider.closeWallet()
+}
diff --git a/packages/0xsequence/tests/browser/testutils/accounts.ts b/packages/0xsequence/tests/browser/testutils/accounts.ts
new file mode 100644
index 0000000000..1b8ad32e50
--- /dev/null
+++ b/packages/0xsequence/tests/browser/testutils/accounts.ts
@@ -0,0 +1,44 @@
+import { ethers, Wallet as EOAWallet, providers } from 'ethers'
+
+// testAccounts with 10000 ETH each
+export const testAccounts = [
+ {
+ address: '0x4e37e14f5d5aac4df1151c6e8df78b7541680853',
+ privateKey: '0xcd0434442164a4a6ef9bb677da8dc326fddf412cad4df65e1a3f2555aee5e2b3'
+ },
+ {
+ address: '0x8a6e090a13d2dc04f87a127699952ce2d4428cd9',
+ privateKey: '0x15d476cba8e6a981e77a00fa22a06ce7f418b80dbb3cb2860f67ea811da9b108'
+ },
+ {
+ address: '0xf1fc4872058b066578008519970b7e789eea5040',
+ privateKey: '0x5b7ce9d034f2d2d8cc5667fcd5986db6e4c1e73b51bc84d61fa0b197068e381a'
+ },
+ {
+ address: '0x4875692d103162f4e29ccdd5678806043d3f16c7',
+ privateKey: '0x02173b01073b895fa3f92335658b4b1bbb3686c06193069b5c5914157f6a360a'
+ },
+ {
+ address: '0xf4b294d1fce145a73ce91b860b871e77573957e5',
+ privateKey: '0xbbbf16b45613564ad7bff353d4cb9e249f5a6d6ac2ef27a256ffafb9afaf8d58'
+ },
+ {
+ address: '0x3631d4d374c3710c3456d6b1de1ee8745fbff8ba',
+ privateKey: '0x2c527b40d4db8eff67de1b6b583b5e15037d0e02f88143668e5626039199da48'
+ }
+]
+
+export const getEOAWallet = (privateKey: string, provider?: string | ethers.providers.Provider): EOAWallet => {
+ // defaults
+ if (!provider) {
+ provider = 'http://localhost:8545'
+ }
+
+ const wallet = new EOAWallet(privateKey)
+
+ if (typeof provider === 'string') {
+ return wallet.connect(new providers.JsonRpcProvider(provider))
+ } else {
+ return wallet.connect(provider)
+ }
+}
diff --git a/packages/0xsequence/tests/browser/testutils/deploy-wallet-context.ts b/packages/0xsequence/tests/browser/testutils/deploy-wallet-context.ts
new file mode 100644
index 0000000000..58bdeb1aa3
--- /dev/null
+++ b/packages/0xsequence/tests/browser/testutils/deploy-wallet-context.ts
@@ -0,0 +1,79 @@
+// import { ethers } from 'ethers'
+// import { UniversalDeployer } from '@0xsequence/deployer'
+// import { WalletContext } from '@0xsequence/network'
+// import { testAccounts, getEOAWallet } from './accounts'
+
+// // TODO/NOTE: it should be possible to import below from just '@0xsequence/wallet-contracts'
+// // however, experiencing a strange JS packaging/module resolution issue which leads to:
+// //
+// // mock-wallet.test.js:70822 Uncaught (in promise) TypeError: Class constructor ContractFactory cannot be invoked without 'new'
+// //
+// // by importing from '@0xsequence/wallet-contracts/gen/typechain', this issue goes away
+
+// import {
+// Factory__factory,
+// MainModule__factory,
+// MainModuleUpgradable__factory,
+// GuestModule__factory,
+// SequenceUtils__factory,
+// RequireFreshSigner__factory,
+// } from '@0xsequence/wallet-contracts'
+
+// const deployWalletContextCache: WalletContext[] = []
+
+// // deployWalletContext will deploy the Sequence WalletContext via the UniversalDeployer
+// // which will return deterministic contract addresses between calls.
+// export const deployWalletContext = async (...providers: ethers.providers.JsonRpcProvider[]): Promise => {
+// if (!providers || providers.length === 0) {
+// providers.push(new ethers.providers.JsonRpcProvider('http://localhost:8545'))
+// }
+
+// // Memoize the result. Even though its universal/deterministic, caching the result
+// // offers greater efficiency between calls
+// if (deployWalletContextCache.length === providers.length) {
+// return deployWalletContextCache[0]
+// }
+
+// await Promise.all(providers.map(async provider => {
+// // Deploying test accounts with the first test account
+// const wallet = getEOAWallet(testAccounts[0].privateKey, provider)
+
+// // Universal deployer for deterministic contract addresses
+// const universalDeployer = new UniversalDeployer('local', wallet.provider as ethers.providers.JsonRpcProvider)
+// const txParams = { gasLimit: 8000000, gasPrice: ethers.BigNumber.from(10).pow(9).mul(10) }
+
+// const walletFactory = await universalDeployer.deploy('WalletFactory', Factory__factory as any, txParams)
+// const mainModule = await universalDeployer.deploy('MainModule', MainModule__factory as any, txParams, 0, walletFactory.address)
+
+// await universalDeployer.deploy('MainModuleUpgradable', MainModuleUpgradable__factory as any, txParams)
+// await universalDeployer.deploy('GuestModule', GuestModule__factory as any, txParams)
+
+// const sequenceUtils = await universalDeployer.deploy('SequenceUtils', SequenceUtils__factory as any, txParams, 0, walletFactory.address, mainModule.address)
+// await universalDeployer.deploy('RequireFreshSignerLib', RequireFreshSigner__factory as any, txParams, 0, sequenceUtils.address)
+
+// const deployment = universalDeployer.getDeployment()
+
+// deployWalletContextCache.push({
+// factory: deployment['WalletFactory'].address,
+// mainModule: deployment['MainModule'].address,
+// mainModuleUpgradable: deployment['MainModuleUpgradable'].address,
+// guestModule: deployment['GuestModule'].address,
+// sequenceUtils: deployment['SequenceUtils'].address,
+// libs: {
+// requireFreshSigner: deployment['RequireFreshSignerLib'].address
+// }
+// })
+// }))
+
+// return deployWalletContextCache[0]
+// }
+
+// // testWalletContext is determined by the `deployWalletContext` method above. We can use this
+// // across instances, but, we must ensure the contracts are deployed by the mock-wallet at least.
+// export const testWalletContext: WalletContext = {
+// factory: "0xf9D09D634Fb818b05149329C1dcCFAeA53639d96",
+// guestModule: "0x02390F3E6E5FD1C6786CB78FD3027C117a9955A7",
+// mainModule: "0xd01F11855bCcb95f88D7A48492F66410d4637313",
+// mainModuleUpgradable: "0x7EFE6cE415956c5f80C6530cC6cc81b4808F6118",
+// sequenceUtils: "0xd130B43062D875a4B7aF3f8fc036Bc6e9D3E1B3E"
+// }
diff --git a/packages/0xsequence/tests/browser/testutils/index.ts b/packages/0xsequence/tests/browser/testutils/index.ts
new file mode 100644
index 0000000000..63f7cc82aa
--- /dev/null
+++ b/packages/0xsequence/tests/browser/testutils/index.ts
@@ -0,0 +1,3 @@
+export * from './accounts'
+// export * from './deploy-wallet-context'
+export * from './wallet'
diff --git a/packages/0xsequence/tests/browser/testutils/wallet.ts b/packages/0xsequence/tests/browser/testutils/wallet.ts
new file mode 100644
index 0000000000..52b7124d9c
--- /dev/null
+++ b/packages/0xsequence/tests/browser/testutils/wallet.ts
@@ -0,0 +1,16 @@
+import { ethers, Wallet as EOAWallet } from 'ethers'
+
+export const sendETH = (
+ eoaWallet: EOAWallet,
+ toAddress: string,
+ amount: ethers.BigNumber
+): Promise => {
+ const tx = {
+ gasPrice: '0x55555',
+ gasLimit: '0x55555',
+ to: toAddress,
+ value: amount.toHexString(),
+ data: '0x'
+ }
+ return eoaWallet.sendTransaction(tx)
+}
diff --git a/packages/0xsequence/tests/browser/wallet-provider/dapp.test.ts b/packages/0xsequence/tests/browser/wallet-provider/dapp.test.ts
new file mode 100644
index 0000000000..99c55cd031
--- /dev/null
+++ b/packages/0xsequence/tests/browser/wallet-provider/dapp.test.ts
@@ -0,0 +1,543 @@
+import { commons, v2 } from '@0xsequence/core'
+import { SequenceClient, SequenceProvider, DefaultProviderConfig, MemoryItemStore } from '@0xsequence/provider'
+import { context } from '@0xsequence/tests'
+import { configureLogger } from '@0xsequence/utils'
+import { ethers, TypedDataDomain, TypedDataField } from 'ethers'
+import { test, assert } from '../../utils/assert'
+import { testAccounts, getEOAWallet, sendETH } from '../testutils'
+
+configureLogger({ logLevel: 'DEBUG', silence: false })
+
+export const tests = async () => {
+ //
+ // Setup
+ //
+ const transportsConfig = {
+ ...DefaultProviderConfig.transports,
+ walletAppURL: 'http://localhost:9999/mock-wallet/mock-wallet.test.html'
+ }
+
+ //
+ // Deploy Sequence WalletContext (deterministic).
+ //
+ const deployedWalletContext = await (async () => {
+ const provider = new ethers.providers.JsonRpcProvider('http://localhost:8545')
+ const signer = provider.getSigner()
+ return context.deploySequenceContexts(signer)
+ })()
+
+ const hardhatProvider = new ethers.providers.JsonRpcProvider('http://localhost:8545')
+
+ const client = new SequenceClient(transportsConfig, new MemoryItemStore(), { defaultChainId: 31337 })
+ const wallet = new SequenceProvider(client, chainId => {
+ if (chainId === 31337) {
+ return hardhatProvider
+ }
+
+ if (chainId === 31338) {
+ return new ethers.providers.JsonRpcProvider('http://localhost:9545')
+ }
+
+ throw new Error(`No provider for chainId ${chainId}`)
+ })
+
+ // provider + signer, by default if a chainId is not specified it will direct
+ // requests to the defaultChain
+ const provider = wallet.getProvider()
+ const signer = wallet.getSigner()
+
+ // clear it in case we're testing in browser session
+ await wallet.disconnect()
+
+ await test('is disconnected / logged out', async () => {
+ assert.false(wallet.isConnected(), 'is connected')
+ })
+
+ await test('is closed', async () => {
+ assert.false(wallet.isOpened(), 'is closed')
+ })
+
+ await test('is disconnected', async () => {
+ assert.false(wallet.isConnected(), 'is disconnnected')
+ })
+
+ await test('connect', async () => {
+ const { connected } = await wallet.connect({
+ app: 'test',
+ keepWalletOpened: true
+ })
+ assert.true(connected, 'is connected')
+ })
+
+ await test('isOpened', async () => {
+ assert.true(wallet.isOpened(), 'is opened')
+ })
+
+ await test('isConnected', async () => {
+ assert.true(wallet.isConnected(), 'is connected')
+ })
+
+ let walletContext: commons.context.VersionedContext
+ await test('getWalletContext', async () => {
+ walletContext = await wallet.getWalletContext()
+ assert.equal(walletContext[1].factory, deployedWalletContext[1].factory, 'wallet context factory')
+ assert.equal(walletContext[1].guestModule, deployedWalletContext[1].guestModule, 'wallet context guestModule')
+ assert.equal(walletContext[2].factory, deployedWalletContext[2].factory, 'wallet context factory')
+ assert.equal(walletContext[2].guestModule, deployedWalletContext[2].guestModule, 'wallet context guestModule')
+ })
+
+ await test('getChainId', async () => {
+ const chainId = wallet.getChainId()
+ assert.equal(chainId, 31337, 'chainId is correct')
+ })
+
+ await test('networks', async () => {
+ const networks = await wallet.getNetworks()
+
+ assert.equal(networks.length, 2, '2 networks')
+ assert.true(networks[0].isDefaultChain!, '1st network is DefaultChain')
+ assert.true(!networks[1].isDefaultChain, '1st network is not DefaultChain')
+ assert.true(networks[1].chainId === 31338, 'authChainId is correct')
+
+ const authProvider = wallet.getProvider(31338)!
+ assert.equal(authProvider.getChainId(), 31338, 'authProvider chainId is 31338')
+
+ assert.equal(provider.getChainId(), 31337, 'provider chainId is 31337')
+ })
+
+ await test('getAddress', async () => {
+ const address = wallet.getAddress()
+ assert.true(ethers.utils.isAddress(address), 'wallet address is valid')
+ })
+
+ await test('getWalletConfig', async () => {
+ const allWalletConfigs = await wallet.getWalletConfig()
+
+ const config = allWalletConfigs as v2.config.WalletConfig
+ assert.equal(config.version, 2, 'wallet config version is correct')
+ assert.true(ethers.BigNumber.from(2).eq(config.threshold), 'config, 2 threshold')
+ assert.true(ethers.BigNumber.from(0).eq(config.checkpoint), 'config, 0 checkpoint')
+ assert.true(v2.config.isSignerLeaf(config.tree), 'config, isSignerLeaf')
+ assert.true(ethers.utils.isAddress((config.tree as v2.config.SignerLeaf).address), 'config, signer address')
+ assert.true(ethers.BigNumber.from(2).eq((config.tree as v2.config.SignerLeaf).weight), 'config, signer weight')
+ })
+
+ await test('multiple networks', async () => {
+ // chainId 31337
+ {
+ assert.equal(provider.getChainId(), 31337, 'provider chainId is 31337')
+
+ const network = await provider.getNetwork()
+ assert.equal(network.chainId, 31337, 'chain id match')
+
+ const netVersion = await provider.send('net_version', [])
+ assert.equal(netVersion, '31337', 'net_version check')
+
+ const chainId = await provider.send('eth_chainId', [])
+ assert.equal(chainId, ethers.utils.hexValue(31337), 'eth_chainId check')
+
+ const chainId2 = await signer.getChainId()
+ assert.equal(chainId2, 31337, 'chainId check')
+ }
+
+ // chainId 31338
+ {
+ const provider2 = wallet.getProvider(31338)
+ assert.equal(provider2.getChainId(), 31338, '2nd chain, chainId is 31338 - 2')
+
+ const network = await provider2.getNetwork()
+ assert.equal(network.chainId, 31338, '2nd chain, chain id match - 3')
+
+ const netVersion = await provider2.send('net_version', [])
+ assert.equal(netVersion, '31338', '2nd chain, net_version check - 4')
+
+ const chainId = await provider2.send('eth_chainId', [])
+ assert.equal(chainId, ethers.utils.hexValue(31338), '2nd chain, eth_chainId check - 5')
+
+ const chainId2 = await provider2.getSigner().getChainId()
+ assert.equal(chainId2, 31338, '2nd chain, chainId check - 6')
+ }
+ })
+
+ await test('listAccounts', async () => {
+ const signers = provider.listAccounts()
+ assert.true(signers.length === 1, 'signers, single owner')
+ assert.true(signers[0] === wallet.getAddress(), 'signers, check address')
+ })
+
+ await test('signMessage on defaultChain', async () => {
+ const address = wallet.getAddress()
+ const chainId = wallet.getChainId()
+
+ const message = 'hihi'
+ const message2 = ethers.utils.toUtf8Bytes('hihi')
+
+ // Sign the message
+ const sigs = await Promise.all(
+ [message, message2].map(async m => {
+ assert.equal(await signer.getChainId(), 31337, 'signer chainId is 31337')
+
+ // NOTE: below line is equivalent to `signer.signMessage(m)` call
+ // const sig = await wallet.utils.signMessage(m)
+ const sig = await signer.signMessage(m, { eip6492: true })
+
+ // Non-deployed wallet (with EIP6492) should return a signature
+ // that ends with the EIP-6492 magic bytes
+ const suffix = '6492649264926492649264926492649264926492649264926492649264926492'
+ assert.true(sig.endsWith(suffix), 'signature ends with EIP-6492 magic bytes')
+
+ return sig
+ })
+ )
+ const sig = sigs[0]
+
+ // Verify the signature
+ const isValid = await wallet.utils.isValidMessageSignature(address, message, sig, chainId)
+ assert.true(isValid, 'signature is valid - 2')
+ })
+
+ await test('signTypedData on defaultChain', async () => {
+ const address = wallet.getAddress()
+ const chainId = wallet.getChainId()
+
+ const domain: TypedDataDomain = {
+ name: 'Ether Mail',
+ version: '1',
+ chainId: chainId,
+ verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC'
+ }
+
+ const types: { [key: string]: TypedDataField[] } = {
+ Person: [
+ { name: 'name', type: 'string' },
+ { name: 'wallet', type: 'address' }
+ ]
+ }
+
+ const message = {
+ name: 'Bob',
+ wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB'
+ }
+
+ const sig = await signer.signTypedData(domain, types, message)
+
+ // Verify typed data
+ const isValid = await wallet.utils.isValidTypedDataSignature(address, { domain, types, message }, sig, chainId)
+ assert.true(isValid, 'signature is valid - 3')
+ })
+
+ await test('signAuthMessage', async () => {
+ const address = wallet.getAddress()
+ const chainId = 31337
+ const authProvider = wallet.getProvider(chainId)!
+
+ assert.equal(chainId, 31337, 'chainId is 31337 (authChain)')
+ assert.equal(authProvider.getChainId(), 31337, 'authProvider chainId is 31337')
+ assert.equal(authProvider.getChainId(), await authProvider.getSigner().getChainId(), 'authProvider signer chainId is 31337')
+
+ // Sign the message
+ const message = 'hihi'
+ const sig = await signer.signMessage(message, { chainId })
+
+ // confirm that authSigner, the chain-bound provider, derived from the authProvider returns the same signature
+ const authSigner = authProvider.getSigner()
+ const sigChk = await authSigner.signMessage(message, { chainId })
+ assert.equal(sigChk, sig, 'authSigner.signMessage returns the same sig')
+
+ // Verify the signature
+ const isValid = await wallet.utils.isValidMessageSignature(address, message, sig, chainId)
+ assert.true(isValid, 'signAuthMessage, signature is valid')
+ })
+
+ await test('getBalance', async () => {
+ // technically, the mock-wallet's single signer owner has some ETH..
+ const balanceSigner1 = await provider.getBalance('0x4e37E14f5d5AAC4DF1151C6E8DF78B7541680853')
+ assert.true(balanceSigner1.gt(ethers.BigNumber.from(0)), 'signer1 balance > 0')
+ })
+
+ await test('fund sequence wallet', async () => {
+ // fund Sequence wallet with some ETH from test seed account
+ const testAccount = getEOAWallet(testAccounts[0].privateKey)
+ const walletBalanceBefore = await signer.getBalance()
+
+ const ethAmount = ethers.utils.parseEther('10.1234')
+ const txResp = await sendETH(testAccount, wallet.getAddress(), ethAmount)
+ const txReceipt = await provider.getTransactionReceipt(txResp.hash)
+ assert.true(txReceipt.status === 1, 'eth sent from signer1')
+
+ const walletBalanceAfter = await signer.getBalance()
+ assert.true(walletBalanceAfter.sub(walletBalanceBefore).eq(ethAmount), `wallet received ${ethAmount} eth`)
+ })
+
+ const testSendETH = async (
+ title: string,
+ opts: {
+ gasLimit?: string
+ } = {}
+ ) =>
+ test(title, async () => {
+ // sequence wallet to now send some eth back to another seed account
+ // via the relayer
+ {
+ const walletAddress = wallet.getAddress()
+ const walletBalanceBefore = await signer.getBalance()
+
+ // send eth from sequence smart wallet to another test account
+ const toAddress = testAccounts[1].address
+ const toBalanceBefore = await provider.getBalance(toAddress)
+
+ const ethAmount = ethers.utils.parseEther('1.4242')
+
+ // NOTE: when a wallet is undeployed (counterfactual), and although the txn contents are to send from our
+ // sequence wallet to the test account, the transaction by the Sequence Wallet instance will be sent `to` the
+ // `GuestModule` smart contract address of the Sequence context `from` the Sequence Relayer (local) account.
+ //
+ // However, when a wallet is deployed on-chain, and the txn object is to send from our sequence wallet to the
+ // test account, the transaction will be sent `to` the smart wallet contract address of the sender by
+ // the relayer. The transaction will then be delegated through the Smart Wallet and transfer will occur
+ // as an internal transaction on-chain.
+ //
+ // Also note, the gasLimit and gasPrice can be estimated by the relayer, or optionally may be specified.
+
+ //--
+
+ // Record wallet deployed state before, so we can check the receipt.to below. We have to do this
+ // because a wallet will automatically get bundled for deployment when it sends a transaction.
+ const beforeWalletDeployed = (await hardhatProvider.getCode(wallet.getAddress())) !== '0x'
+
+ // NOTE/TODO: gasPrice even if set will be set again by the LocalRelayer, we should allow it to be overridden
+ const tx: ethers.providers.TransactionRequest = {
+ from: walletAddress,
+ to: toAddress,
+ value: ethAmount
+ }
+
+ // specifying gasLimit manually
+ if (opts.gasLimit) {
+ tx.gasLimit = opts.gasLimit
+ }
+
+ const txResp = await signer.sendTransaction(tx)
+ const txReceipt = await txResp.wait()
+
+ assert.true(txReceipt.status === 1, 'txn sent successfully')
+ assert.true(
+ (await hardhatProvider.getCode(wallet.getAddress())) !== '0x',
+ 'wallet must be in deployed state after the txn'
+ )
+
+ // transaction is sent to the deployed wallet, if the wallet is deployed.. otherwise its sent to guestModule
+ if (beforeWalletDeployed) {
+ assert.equal(txReceipt.to, wallet.getAddress(), 'recipient is correct')
+ } else {
+ assert.equal(txReceipt.to, walletContext[2].guestModule, 'recipient is correct')
+ }
+
+ // Ensure fromAddress sent their eth
+ const walletBalanceAfter = await signer.getBalance()
+ const sent = walletBalanceAfter.sub(walletBalanceBefore).mul(-1)
+
+ assert.true(sent.eq(ethAmount), `wallet sent ${sent} eth while expected ${ethAmount}`)
+
+ // Ensure toAddress received their eth
+ const toBalanceAfter = await provider.getBalance(toAddress)
+ const received = toBalanceAfter.sub(toBalanceBefore)
+ assert.true(received.eq(ethAmount), `toAddress received ${received} eth while expected ${ethAmount}`)
+
+ // Extra checks
+ if (opts.gasLimit) {
+ // In our test, we are passing a high gas limit for an internal transaction, so overall
+ // transaction must be higher than this value if it used our value correctly
+ assert.true(txResp.gasLimit.gte(opts.gasLimit), 'sendETH, using higher gasLimit')
+ }
+ }
+ })
+
+ await testSendETH('sendETH (defaultChain)')
+
+ // NOTE: this will pass, as we set the gasLimit low on the txn, but the LocalRelayer will re-estimate
+ // the entire transaction to have it pass.
+ await testSendETH('sendETH with high gasLimit override (defaultChain)', { gasLimit: '0x55555' })
+
+ await test('sendTransaction batch', async () => {
+ const testAccount = getEOAWallet(testAccounts[1].privateKey)
+
+ const ethAmount1 = ethers.utils.parseEther('1.234')
+ const ethAmount2 = ethers.utils.parseEther('0.456')
+
+ const tx1: ethers.providers.TransactionRequest = {
+ to: testAccount.address,
+ value: ethAmount1
+ }
+ const tx2: ethers.providers.TransactionRequest = {
+ to: testAccount.address,
+ value: ethAmount2
+ }
+
+ const toBalanceBefore = await provider.getBalance(testAccount.address)
+ const txnResp = await signer.sendTransaction([tx1, tx2])
+
+ await txnResp.wait()
+
+ const toBalanceAfter = await provider.getBalance(testAccount.address)
+ const sent = toBalanceAfter.sub(toBalanceBefore)
+ const expected = ethAmount1.add(ethAmount2)
+ assert.true(
+ sent.eq(ethAmount1.add(ethAmount2)),
+ `wallet sent ${sent} eth while expected ${expected} (${ethAmount1} + ${ethAmount2})`
+ )
+ })
+
+ await test('sendTransaction batch format 2', async () => {
+ const testAccount = getEOAWallet(testAccounts[1].privateKey)
+
+ const ethAmount1 = ethers.utils.parseEther('1.234')
+ const ethAmount2 = ethers.utils.parseEther('0.456')
+
+ const tx1: ethers.providers.TransactionRequest = {
+ to: testAccount.address,
+ value: ethAmount1
+ }
+
+ const tx2: ethers.providers.TransactionRequest = {
+ to: testAccount.address,
+ value: ethAmount2
+ }
+
+ const toBalanceBefore = await provider.getBalance(testAccount.address)
+ const txnResp = await signer.sendTransaction([tx1, tx2])
+
+ await txnResp.wait()
+
+ const toBalanceAfter = await provider.getBalance(testAccount.address)
+ const sent = toBalanceAfter.sub(toBalanceBefore)
+ const expected = ethAmount1.add(ethAmount2)
+ assert.true(
+ sent.eq(ethAmount1.add(ethAmount2)),
+ `wallet sent ${sent} eth while expected ${expected} (${ethAmount1} + ${ethAmount2})`
+ )
+ })
+
+ await test('sendTransaction batch format 3', async () => {
+ const testAccount = getEOAWallet(testAccounts[1].privateKey)
+
+ const ethAmount1 = ethers.utils.parseEther('1.234')
+ const ethAmount2 = ethers.utils.parseEther('0.456')
+
+ const tx1: commons.transaction.Transaction = {
+ to: testAccount.address,
+ value: ethAmount1
+ }
+
+ const tx2: commons.transaction.Transaction = {
+ to: testAccount.address,
+ value: ethAmount2
+ }
+
+ const toBalanceBefore = await provider.getBalance(testAccount.address)
+
+ const txnResp = await signer.sendTransaction([tx1, tx2])
+ await txnResp.wait()
+
+ const toBalanceAfter = await provider.getBalance(testAccount.address)
+ const sent = toBalanceAfter.sub(toBalanceBefore)
+ const expected = ethAmount1.add(ethAmount2)
+ assert.true(
+ sent.eq(ethAmount1.add(ethAmount2)),
+ `wallet sent ${sent} eth while expected ${expected} (${ethAmount1} + ${ethAmount2})`
+ )
+ })
+
+ await test('sendETH from the sequence smart wallet (authChain)', async () => {
+ // multi-chain to send eth on an alternative chain, in this case the authChain
+ //
+ // NOTE: the account addresses are both chains have been seeded with the same private key
+ // so we can have overlapping addresses and keys for ease of use duringtesting
+
+ // get provider of the 2nd chain
+ const provider2 = wallet.getProvider('hardhat2')!
+
+ assert.equal(provider2.getChainId(), 31338, 'provider is the 2nd chain - 1')
+ assert.equal(provider2.getChainId(), wallet.getProvider(31338)!.getChainId(), 'provider2 code path check')
+
+ const signer2 = provider2.getSigner()
+
+ // confirm all account addresses are the same and correct
+ {
+ assert.equal(wallet.getAddress(), await signer.getAddress(), 'wallet and signer address match')
+ assert.equal(wallet.getAddress(), await signer2.getAddress(), 'wallet and signer2 address match')
+ assert.true(wallet.getAddress() !== testAccounts[0].address, 'wallet is not subkey address')
+ }
+
+ // initial balances
+ {
+ const testAccount = getEOAWallet(testAccounts[0].privateKey, provider2)
+ const walletBalanceBefore = await testAccount.getBalance()
+
+ const mainTestAccount = getEOAWallet(testAccounts[0].privateKey, wallet.getProvider())
+ const mainWalletBalanceBefore = await mainTestAccount.getBalance()
+
+ assert.true(walletBalanceBefore.toString() !== mainWalletBalanceBefore.toString(), 'balances across networks do not match')
+
+ // test different code paths lead to same results
+ assert.equal(
+ (await provider2.getBalance(await testAccount.getAddress())).toString(),
+ (await testAccount.getBalance()).toString(),
+ 'balance match 1'
+ )
+ assert.equal(
+ (await provider.getBalance(await mainTestAccount.getAddress())).toString(),
+ (await mainTestAccount.getBalance()).toString(),
+ 'balance match 2'
+ )
+ }
+
+ // first, lets move some ETH info the wallet from teh testnet seed account
+ {
+ const testAccount = getEOAWallet(testAccounts[0].privateKey, provider2)
+ const walletBalanceBefore = await signer2.getBalance()
+
+ const ethAmount = ethers.utils.parseEther('4.2')
+
+ // const txResp = await sendETH(testAccount, await wallet.getAddress(), ethAmount)
+ // const txReceipt = await provider2.getTransactionReceipt(txResp.hash)
+
+ const txReceipt = await (await sendETH(testAccount, wallet.getAddress(), ethAmount)).wait()
+ assert.true(txReceipt.status === 1, 'eth sent')
+
+ const walletBalanceAfter = await signer2.getBalance()
+ assert.true(walletBalanceAfter.sub(walletBalanceBefore).eq(ethAmount), `wallet received ${ethAmount} eth`)
+ }
+
+ // using sequence wallet on the authChain, send eth back to anotehr seed account via
+ // the authChain relayer
+ {
+ const walletAddress = wallet.getAddress()
+ const walletBalanceBefore = await signer2.getBalance()
+
+ // send eth from sequence smart wallet to another test account
+ const toAddress = testAccounts[1].address
+ const toBalanceBefore = await provider2.getBalance(toAddress)
+
+ const ethAmount = ethers.utils.parseEther('1.1234')
+
+ const tx = {
+ from: walletAddress,
+ to: toAddress,
+ value: ethAmount
+ }
+ const txReceipt = await (await signer2.sendTransaction(tx)).wait()
+
+ assert.true(txReceipt.status === 1, 'txn sent successfully')
+ assert.true((await hardhatProvider.getCode(walletAddress)) !== '0x', 'wallet must be in deployed state after the txn')
+
+ // Ensure fromAddress sent their eth
+ const walletBalanceAfter = await signer2.getBalance()
+ assert.true(walletBalanceAfter.sub(walletBalanceBefore).mul(-1).eq(ethAmount), `wallet sent ${ethAmount} eth`)
+
+ // Ensure toAddress received their eth
+ const toBalanceAfter = await provider2.getBalance(toAddress)
+ assert.true(toBalanceAfter.sub(toBalanceBefore).eq(ethAmount), `toAddress received ${ethAmount} eth`)
+ }
+ })
+}
diff --git a/packages/0xsequence/tests/browser/wallet-provider/dapp2.test.ts b/packages/0xsequence/tests/browser/wallet-provider/dapp2.test.ts
new file mode 100644
index 0000000000..79d1c75977
--- /dev/null
+++ b/packages/0xsequence/tests/browser/wallet-provider/dapp2.test.ts
@@ -0,0 +1,116 @@
+import { DefaultProviderConfig, MemoryItemStore, SequenceClient, SequenceProvider } from '@0xsequence/provider'
+import { configureLogger } from '@0xsequence/utils'
+import { ethers, TypedDataDomain, TypedDataField } from 'ethers'
+import { test, assert } from '../../utils/assert'
+
+configureLogger({ logLevel: 'DEBUG', silence: false })
+
+export const tests = async () => {
+ //
+ // Setup
+ //
+ const transportsConfig = {
+ ...DefaultProviderConfig.transports,
+ walletAppURL: 'http://localhost:9999/mock-wallet/mock-wallet.test.html'
+ }
+
+ const hardhatProvider = new ethers.providers.JsonRpcProvider('http://localhost:8545')
+
+ const client = new SequenceClient(transportsConfig, new MemoryItemStore(), { defaultChainId: 31338 })
+ const provider = new SequenceProvider(client, chainId => {
+ if (chainId === 31337) {
+ return hardhatProvider
+ }
+
+ if (chainId === 31338) {
+ return new ethers.providers.JsonRpcProvider('http://localhost:9545')
+ }
+
+ throw new Error(`No provider for chainId ${chainId}`)
+ })
+
+ // clear it in case we're testing in browser session
+ provider.disconnect()
+
+ await test('is logged out', async () => {
+ assert.false(provider.isConnected(), 'is logged out')
+ })
+
+ await test('is disconnected', async () => {
+ assert.false(provider.isConnected(), 'is disconnnected')
+ })
+
+ await test('connect / login', async () => {
+ const { connected } = await provider.connect({
+ app: 'test',
+ keepWalletOpened: true
+ })
+
+ assert.true(connected, 'is connected')
+ })
+
+ await test('isConnected', async () => {
+ assert.true(provider.isConnected(), 'is connected')
+ })
+
+ await test('check defaultNetwork is 31338', async () => {
+ assert.equal(provider.getChainId(), 31338, 'provider chainId is 31338')
+
+ const network = await provider.getNetwork()
+ assert.equal(network.chainId, 31338, 'chain id match')
+ })
+
+ await test('getNetworks()', async () => {
+ const networks = await provider.getNetworks()
+ console.log('=> networks', networks)
+
+ // There should be two chains, hardhat and hardhat2
+ assert.equal(networks.length, 2, 'networks length is 2')
+ assert.equal(networks[0].chainId, 31337, 'chain id match')
+ assert.equal(networks[1].chainId, 31338, 'chain id match')
+ })
+
+ await test('signMessage with our custom defaultChain', async () => {
+ console.log('signing message...')
+ const signer = provider.getSigner()
+
+ const message = 'Hi there! Please sign this message, 123456789, thanks.'
+
+ // sign
+ const sig = await signer.signMessage(message)
+
+ // validate
+ const isValid = await provider.utils.isValidMessageSignature(provider.getAddress(), message, sig, await signer.getChainId())
+ assert.true(isValid, 'signMessage sig is valid')
+ })
+
+ await test('signTypedData on defaultChain (in this case, hardhat2)', async () => {
+ const address = provider.getAddress()
+ const chainId = provider.getChainId()
+
+ const domain: TypedDataDomain = {
+ name: 'Ether Mail',
+ version: '1',
+ chainId: chainId,
+ verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC'
+ }
+
+ const types: { [key: string]: TypedDataField[] } = {
+ Person: [
+ { name: 'name', type: 'string' },
+ { name: 'wallet', type: 'address' }
+ ]
+ }
+
+ const message = {
+ name: 'Bob',
+ wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB'
+ }
+
+ const sig = await provider.getSigner().signTypedData(domain, types, message)
+
+ // Verify typed data
+ const isValid = await provider.utils.isValidTypedDataSignature(address, { domain, types, message }, sig, chainId)
+ assert.true(isValid, 'signature is valid - 4')
+ })
+}
diff --git a/packages/0xsequence/tests/browser/window-transport/dapp.test.ts b/packages/0xsequence/tests/browser/window-transport/dapp.test.ts
new file mode 100644
index 0000000000..aa0812c29f
--- /dev/null
+++ b/packages/0xsequence/tests/browser/window-transport/dapp.test.ts
@@ -0,0 +1,135 @@
+import { isValidSignature, prefixEIP191Message, WindowMessageProvider } from '@0xsequence/provider'
+import { context } from '@0xsequence/tests'
+import { configureLogger, encodeMessageDigest, packMessageData } from '@0xsequence/utils'
+import { ethers } from 'ethers'
+import { test, assert } from '../../utils/assert'
+
+configureLogger({ logLevel: 'DEBUG', silence: false })
+
+const walletProvider = new WindowMessageProvider('http://localhost:9999/mock-wallet/mock-wallet.test.html')
+walletProvider.register()
+
+// ;(window as any).walletProvider = walletProvider
+
+export const tests = async () => {
+ await (async () => {
+ const provider = new ethers.providers.JsonRpcProvider('http://localhost:8545')
+ const signer = provider.getSigner()
+ return context.deploySequenceContexts(signer)
+ })()
+
+ walletProvider.openWallet()
+
+ await test('provider opened the wallet', async () => {
+ const opened = await walletProvider.waitUntilOpened()
+ assert.true(!!opened, 'opened is true')
+ })
+
+ // TODO: try this again, but turn off hardhat, to ensure our error reponses are working correctly..
+ // ..
+ const provider = new ethers.providers.Web3Provider(walletProvider)
+ const signer = provider.getSigner()
+ const address = await signer.getAddress()
+ const chainId = await signer.getChainId()
+
+ await test('getAddress', async () => {
+ assert.true(ethers.utils.isAddress(address), 'wallet address')
+ })
+
+ await test('sending a json-rpc request', async () => {
+ await walletProvider.sendAsync({ jsonrpc: '2.0', id: 88, method: 'eth_accounts', params: [] }, (err, resp) => {
+ assert.true(!err, 'error is empty')
+ assert.true(!!resp, 'response successful')
+ assert.true(resp!.result[0] === address, 'response address check')
+ })
+
+ const resp = await provider.send('eth_accounts', [])
+ assert.true(!!resp, 'response successful')
+ assert.true(resp[0] === address, 'response address check')
+ })
+
+ await test('get chain id', async () => {
+ const network = await provider.getNetwork()
+ assert.equal(network.chainId, 31337, 'chain id match')
+
+ const netVersion = await provider.send('net_version', [])
+ assert.equal(netVersion, '31337', 'net_version check')
+
+ const chainId = await provider.send('eth_chainId', [])
+ assert.equal(chainId, '0x7a69', 'eth_chainId check')
+
+ const chainId2 = await signer.getChainId()
+ assert.equal(chainId2, 31337, 'chainId check')
+ })
+
+ // NOTE: when a dapp wants to verify SmartWallet signed messages, they will need to verify against EIP-1271
+ await test('sign a message and validate/recover', async () => {
+ const message = ethers.utils.toUtf8Bytes('hihi')
+
+ // TODO: signer should be a Sequence signer, and should be able to specify the chainId
+ // however, for a single wallet, it can check the chainId and throw if doesnt match, for multi-wallet it will select
+
+ // Deploy the wallet (by sending a random tx)
+ // (this step is performed by wallet-webapp when signing without EIP-6492 support)
+ await signer.sendTransaction({ to: ethers.Wallet.createRandom().address })
+
+ //
+ // Sign the message
+ //
+ const sig = await signer.signMessage(message)
+
+ //
+ // Verify the message signature
+ //
+ const messageDigest = encodeMessageDigest(prefixEIP191Message(message))
+ const isValid = await isValidSignature(address, messageDigest, sig, provider)
+ assert.true(isValid, 'signature is valid - 5')
+
+ // also compute the subDigest of the message, to be provided to the end-user
+ // in order to recover the config properly, the subDigest + sig is required.
+ const subDigest = packMessageData(address, chainId, messageDigest)
+ })
+
+ await test('sign EIP712 typed data and validate/recover', async () => {
+ const typedData = {
+ types: {
+ Person: [
+ { name: 'name', type: 'string' },
+ { name: 'wallet', type: 'address' }
+ ]
+ },
+ primaryType: 'Person' as const,
+ domain: {
+ name: 'Ether Mail',
+ version: '1',
+ chainId: 31337,
+ verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC'
+ },
+ message: {
+ name: 'Bob',
+ wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB'
+ }
+ }
+
+ //
+ // Sign the message
+ //
+ const sig = await provider.send('eth_signTypedData', [address, typedData])
+
+ // NOTE: verification of message below is identical to verifying a message with eth_sign,
+ // the difference is we have to provide 'message' as the typedData digest format
+
+ //
+ // Verify the message signature
+ //
+
+ const messageHash = ethers.utils._TypedDataEncoder.hash(typedData.domain, typedData.types, typedData.message)
+ const messageDigest = ethers.utils.arrayify(messageHash)
+ const isValid = await isValidSignature(address, messageDigest, sig, provider)
+ assert.true(isValid, 'signature is valid - 6')
+
+ // also compute the subDigest of the message, to be provided to the end-user
+ // in order to recover the config properly, the subDigest + sig is required.
+ const subDigest = packMessageData(address, chainId, messageDigest)
+ })
+}
diff --git a/packages/0xsequence/tests/json-rpc-provider.spec.ts b/packages/0xsequence/tests/json-rpc-provider.spec.ts
new file mode 100644
index 0000000000..3171949494
--- /dev/null
+++ b/packages/0xsequence/tests/json-rpc-provider.spec.ts
@@ -0,0 +1,3 @@
+import { runBrowserTests } from './utils/browser-test-runner'
+
+runBrowserTests('json-rpc-provider', 'json-rpc-provider/rpc.test.html')
diff --git a/packages/0xsequence/tests/mock-wallet.spec.ts b/packages/0xsequence/tests/mock-wallet.spec.ts
new file mode 100644
index 0000000000..62f770985e
--- /dev/null
+++ b/packages/0xsequence/tests/mock-wallet.spec.ts
@@ -0,0 +1,3 @@
+import { runBrowserTests } from './utils/browser-test-runner'
+
+runBrowserTests('mock-wallet', 'mock-wallet/mock-wallet.test.html')
diff --git a/packages/0xsequence/tests/mux-transport.spec.ts b/packages/0xsequence/tests/mux-transport.spec.ts
new file mode 100644
index 0000000000..814f019ec3
--- /dev/null
+++ b/packages/0xsequence/tests/mux-transport.spec.ts
@@ -0,0 +1,3 @@
+import { runBrowserTests } from './utils/browser-test-runner'
+
+runBrowserTests('mux-transport', 'mux-transport/mux.test.html')
diff --git a/packages/0xsequence/tests/proxy-transport.spec.ts b/packages/0xsequence/tests/proxy-transport.spec.ts
new file mode 100644
index 0000000000..338fb0fc30
--- /dev/null
+++ b/packages/0xsequence/tests/proxy-transport.spec.ts
@@ -0,0 +1,3 @@
+import { runBrowserTests } from './utils/browser-test-runner'
+
+runBrowserTests('proxy-transport-channel', 'proxy-transport/channel.test.html')
diff --git a/packages/0xsequence/tests/utils/assert.ts b/packages/0xsequence/tests/utils/assert.ts
new file mode 100644
index 0000000000..413851dcd0
--- /dev/null
+++ b/packages/0xsequence/tests/utils/assert.ts
@@ -0,0 +1,76 @@
+const testResults = []
+
+;(window as any).__testResults = testResults
+
+export const test = async (title: string, run: () => void) => {
+ const entry = {
+ title: title,
+ pass: null,
+ startTime: performance.now(),
+ error: null,
+ stack: null
+ }
+ testResults.push(entry)
+
+ try {
+ await run()
+ entry.pass = true
+ } catch (err) {
+ entry.error = err.message
+ entry.stack = err.stack
+ // throw new Error(`case '${title}' failed due to ${err.message}`)
+ // throw err
+ err.message = `case '${title}' failed due to ${err.message}`
+ throw err
+ }
+}
+
+export const assert = {
+ true: function (cond: boolean, msg?: string) {
+ if (cond !== true) {
+ if (msg) {
+ throw new Error(`invalid condition, '${msg}'`)
+ } else {
+ throw new Error(`invalid condition`)
+ }
+ }
+ },
+
+ false: function (cond: boolean, msg?: string) {
+ return assert.true(!cond, msg)
+ },
+
+ equal: function (actual: any, expected: any, msg?: string) {
+ if (actual !== expected) {
+ if (msg) {
+ throw new Error(`expected '${expected}' but got '${actual}', '${msg}'`)
+ } else {
+ throw new Error(`expected '${expected}' but got '${actual}'`)
+ }
+ }
+ },
+
+ rejected: async function (promise: Promise, msg?: string) {
+ let wasRejected = false
+
+ try {
+ await promise
+ } catch {
+ wasRejected = true
+ }
+
+ if (!wasRejected) {
+ if (msg) {
+ throw new Error(`expected to be rejected`)
+ } else {
+ throw new Error(`expected to be rejected, ${msg}`)
+ }
+ }
+ }
+}
+
+export const sleep = (time: number) => {
+ return new Promise((resolve, reject) => {
+ setTimeout(resolve, time)
+ })
+}
diff --git a/packages/0xsequence/tests/utils/browser-test-runner.ts b/packages/0xsequence/tests/utils/browser-test-runner.ts
new file mode 100644
index 0000000000..5bb74cf41f
--- /dev/null
+++ b/packages/0xsequence/tests/utils/browser-test-runner.ts
@@ -0,0 +1,90 @@
+import test from 'ava'
+import puppeteer from 'puppeteer'
+import { spawnSync } from 'child_process'
+
+export const runBrowserTests = async (title: string, path: string) => {
+ test.serial(title, browserContext, async (t, page: puppeteer.Page) => {
+ await page.goto('http://localhost:9999/' + path, {
+ waitUntil: 'networkidle0',
+ timeout: 30000
+ })
+
+ // confirm
+ t.true((await page.title()) === 'test')
+
+ // debugging
+ page.on('console', msg => console.log(`console: ${msg.text()}`))
+
+ // catch uncaught errors
+ page.on('pageerror', err => {
+ page.close()
+ t.fail(`${err}`)
+ })
+
+ // run the test
+ try {
+ const timeout = setTimeout(() => {
+ throw `Test runner timed out after 60s!`
+ }, 60000) // 60 seconds to run the tests
+
+ const testResults = await page.evaluate(async () => {
+ // @ts-ignore
+ await lib.tests()
+
+ // @ts-ignore
+ return window.__testResults
+ })
+
+ clearTimeout(timeout)
+
+ for (let i = 0; i < testResults.length; i++) {
+ const result = testResults[i]
+ if (result.pass === true) {
+ t.log(`${result.title}: \x1b[32mPASS\x1b[0m`)
+ } else {
+ t.log(`${result.title}: \x1b[31mFAIL\x1b[0m`)
+ if (result.error) {
+ t.fail(`WHOOPS! case '${result.title}' failed due to ${result.error} !`)
+ } else {
+ t.fail(`WHOOPS! case '${result.title}' failed !`)
+ }
+ }
+ }
+ } catch (err) {
+ t.fail(`${err}`)
+ }
+ })
+}
+
+export const browserContext = async (t, run) => {
+ const browser = await puppeteer.launch({
+ executablePath: getChromePath(),
+ args: ['--headless']
+ })
+ const page = await browser.newPage()
+ try {
+ await run(t, page)
+ } finally {
+ await page.close()
+ await browser.close()
+ }
+}
+
+const getChromePath = (): string | undefined => {
+ if (process.env['NIX_PATH']) {
+ // nixos users are unable to use the chrome bin packaged with puppeteer,
+ // so instead we use the locally installed chrome or chromium binary.
+ for (const bin of ['google-chrome-stable', 'chromium']) {
+ const out = spawnSync('which', [bin])
+ if (out.status === 0) {
+ const executablePath = out.stdout.toString().trim()
+ return executablePath
+ }
+ }
+ console.error('Unable to find `google-chrome-stable` or `chromium` binary on your NixOS system.')
+ process.exit(1)
+ } else {
+ // undefined will use the chrome version packaged with puppeteer npm package
+ return undefined
+ }
+}
diff --git a/packages/0xsequence/tests/utils/webpack-test-server.ts b/packages/0xsequence/tests/utils/webpack-test-server.ts
new file mode 100644
index 0000000000..8b4a050d4c
--- /dev/null
+++ b/packages/0xsequence/tests/utils/webpack-test-server.ts
@@ -0,0 +1,31 @@
+import webpack from 'webpack'
+import WebpackDevServer from 'webpack-dev-server'
+import webpackTestConfig from '../webpack.config'
+
+export const DEFAULT_PORT = 9999
+
+// NOTE: currently not in use, instead we run the server as a separate process via `pnpm test:server`
+
+export const createWebpackTestServer = async (port = DEFAULT_PORT) => {
+ const testServer = new WebpackDevServer(
+ // @ts-ignore
+ webpack(webpackTestConfig),
+ {
+ clientLogLevel: 'silent',
+ open: false,
+ host: '0.0.0.0',
+ historyApiFallback: true,
+ stats: 'errors-only',
+ disableHostCheck: true,
+ publicPath: '/',
+ inline: false,
+ hot: false
+ }
+ )
+
+ await testServer.listen(port, '0.0.0.0', function (err) {
+ if (err) {
+ console.error(err)
+ }
+ })
+}
diff --git a/packages/0xsequence/tests/wallet-provider.spec.ts b/packages/0xsequence/tests/wallet-provider.spec.ts
new file mode 100644
index 0000000000..418cefd9fb
--- /dev/null
+++ b/packages/0xsequence/tests/wallet-provider.spec.ts
@@ -0,0 +1,4 @@
+import { runBrowserTests } from './utils/browser-test-runner'
+
+runBrowserTests('wallet-provider/dapp', 'wallet-provider/dapp.test.html')
+runBrowserTests('wallet-provider/dapp2', 'wallet-provider/dapp2.test.html')
diff --git a/packages/0xsequence/tests/webpack.config.js b/packages/0xsequence/tests/webpack.config.js
new file mode 100644
index 0000000000..9b02970794
--- /dev/null
+++ b/packages/0xsequence/tests/webpack.config.js
@@ -0,0 +1,165 @@
+const path = require('path')
+const fs = require('fs')
+const webpack = require('webpack')
+const HtmlWebpackPlugin = require('html-webpack-plugin')
+
+const port = process.env['PORT'] || 9999
+
+const appDirectory = fs.realpathSync(process.cwd())
+const resolveCwd = (relativePath) => path.resolve(appDirectory, relativePath)
+
+const resolvePackages = () => {
+ const pkgs = path.resolve(fs.realpathSync(process.cwd()), '..')
+ return fs.readdirSync(pkgs).reduce((list, dir) => {
+ const p = path.join(pkgs, dir, 'src')
+ if (fs.existsSync(p)) {
+ list.push(p)
+ }
+ return list
+ }, [])
+}
+
+// Include extra sources for compilation.
+//
+// NOTE: if you experience an error in your webpack builder such as,
+// Module parse failed: Unexpected token (11:20)
+// You may need an appropriate loader to handle this file type, currently no loaders are
+// configured to process this file. See https://webpack.js.org/concepts#loaders
+//
+// The above error is due to not passing the TypeScript files to the module.rules for
+// babel below. The solution is to include the path to the source files below, and
+// the error will go away.
+const resolveExtras = [
+ // resolveCwd('../wallet/tests/utils'),
+ resolveCwd('../../node_modules/@0xsequence/wallet-contracts/gen')
+]
+
+const resolveTestEntries = (location) => {
+ return fs.readdirSync(location).reduce((list, f) => {
+ const n = path.join(location, f)
+ if (fs.lstatSync(n).isDirectory()) {
+ list.push(...resolveTestEntries(n))
+ } else {
+ if (n.endsWith(".test.ts") > 0) list.push(n)
+ }
+ return list
+ }, [])
+}
+
+const resolveEntry = () => {
+ const browserTestRoot = fs.realpathSync(path.join(process.cwd(), 'tests', 'browser'))
+ const entry = { 'lib': './src/index.ts' }
+ const testEntries = resolveTestEntries(browserTestRoot)
+ testEntries.forEach(v => entry[v.slice(browserTestRoot.length+1, v.length-3)] = v)
+ return entry
+}
+
+const resolveHtmlPlugins = (entry) => {
+ const plugins = []
+ for (let k in entry) {
+ if (k === 'lib') continue
+ plugins.push(new HtmlWebpackPlugin({
+ inject: false,
+ filename: `${k}.html`,
+ templateContent: htmlTemplate(k)
+ }))
+ }
+ return plugins
+}
+
+const htmlTemplate = (k) => `
+
+
+
+ test
+
+
+ ${k}
+
+
+ TEST
+
+
+
+
+
+
+
+`
+
+const entry = resolveEntry()
+
+module.exports = {
+ mode: 'none',
+ context: process.cwd(),
+ entry: entry,
+ output: {
+ library: 'lib',
+ libraryTarget: 'umd'
+ },
+ watch: false,
+ plugins: [...resolveHtmlPlugins(entry)],
+ module: {
+ rules: [
+ {
+ test: /\.(js|mjs|ts)$/,
+ include: [...resolvePackages(), resolveCwd('./tests'), ...resolveExtras],
+ loader: require.resolve('babel-loader'),
+ options: {
+ presets: ['@babel/preset-typescript'],
+ plugins: [
+ [require.resolve('@babel/plugin-transform-class-properties'), { loose: true }]
+ ],
+ cacheCompression: false,
+ compact: false,
+ },
+ },
+ {
+ test: /\.(jpe?g|png|gif|svg)$/i,
+ use: [
+ {
+ loader: 'url-loader',
+ options: {
+ limit: 8192000
+ }
+ }
+ ]
+ }
+ ]
+ },
+ resolve: {
+ modules: ['node_modules', resolveCwd('node_modules')],
+ extensions: ['.ts', '.js', '.png', '.jpg', '.d.ts'],
+ alias: {},
+ fallback: {
+ fs: false,
+ stream: false,
+ readline: false,
+ assert: false
+ }
+ },
+ devServer: {
+ clientLogLevel: 'silent',
+ open: false,
+ host: '0.0.0.0',
+ port: port,
+ historyApiFallback: true,
+ stats: 'errors-only',
+ disableHostCheck: true,
+ contentBase: path.resolve(process.cwd(), 'tests/browser'),
+ publicPath: '/',
+ inline: false,
+ hot: false
+ }
+}
diff --git a/packages/0xsequence/tests/window-transport.spec.ts b/packages/0xsequence/tests/window-transport.spec.ts
new file mode 100644
index 0000000000..d56374379b
--- /dev/null
+++ b/packages/0xsequence/tests/window-transport.spec.ts
@@ -0,0 +1,3 @@
+import { runBrowserTests } from './utils/browser-test-runner'
+
+runBrowserTests('window-transport', 'window-transport/dapp.test.html')
diff --git a/packages/abi/CHANGELOG.md b/packages/abi/CHANGELOG.md
new file mode 100644
index 0000000000..15772c27df
--- /dev/null
+++ b/packages/abi/CHANGELOG.md
@@ -0,0 +1,2085 @@
+# @0xsequence/abi
+
+## 2.3.8
+
+### Patch Changes
+
+- indexer: update clients
+
+## 2.3.7
+
+### Patch Changes
+
+- Metadata updates
+
+## 2.3.6
+
+### Patch Changes
+
+- New chains
+
+## 2.3.5
+
+### Patch Changes
+
+- Add Frequency Testnet
+
+## 2.3.4
+
+### Patch Changes
+
+- metadata: exclude deprecated methods on rpc client
+
+## 2.3.3
+
+### Patch Changes
+
+- metadata: client update
+
+## 2.3.2
+
+### Patch Changes
+
+- metadata: update rpc client
+
+## 2.3.1
+
+### Patch Changes
+
+- indexer: update rpc client
+
+## 2.3.0
+
+### Minor Changes
+
+- update metadata rpc client
+
+## 2.2.15
+
+### Patch Changes
+
+- API updates
+
+## 2.2.14
+
+### Patch Changes
+
+- Somnia Testnet and Monad Testnet
+
+## 2.2.13
+
+### Patch Changes
+
+- Add XR1 to all networks
+
+## 2.2.12
+
+### Patch Changes
+
+- Add XR1
+
+## 2.2.11
+
+### Patch Changes
+
+- Relayer updates
+
+## 2.2.10
+
+### Patch Changes
+
+- Etherlink support
+
+## 2.2.9
+
+### Patch Changes
+
+- Indexer gateway native token balances
+
+## 2.2.8
+
+### Patch Changes
+
+- Add Moonbeam and Moonbase Alpha
+
+## 2.2.7
+
+### Patch Changes
+
+- Update Builder package
+
+## 2.2.6
+
+### Patch Changes
+
+- Update relayer package
+
+## 2.2.5
+
+### Patch Changes
+
+- auth: fix sequence indexer gateway url
+- account: immutable wallet proxy hook
+
+## 2.2.4
+
+### Patch Changes
+
+- network: update soneium mainnet block explorer url
+- waas: signTypedData intent support
+
+## 2.2.3
+
+### Patch Changes
+
+- provider: updating initWallet to use connected network configs if they exist
+
+## 2.2.2
+
+### Patch Changes
+
+- pass projectAccessKey to relayer at all times
+
+## 2.2.1
+
+### Patch Changes
+
+- waas-ethers: sign typed data
+
+## 2.2.0
+
+### Minor Changes
+
+- indexer: gateway client
+- @0xsequence/builder
+- upgrade puppeteer to v23.10.3
+
+## 2.1.8
+
+### Patch Changes
+
+- Add Soneium Mainnet
+
+## 2.1.7
+
+### Patch Changes
+
+- guard: pass project access key to guard requests
+
+## 2.1.6
+
+### Patch Changes
+
+- Add LAOS and Telos Testnet chains
+
+## 2.1.5
+
+### Patch Changes
+
+- account: save presigned configuration with reference chain id 1
+
+## 2.1.4
+
+### Patch Changes
+
+- provider: pass projectAccessKey into MuxMessageProvider
+
+## 2.1.3
+
+### Patch Changes
+
+- waas: time drift date fix due to strange browser quirk
+
+## 2.1.2
+
+### Patch Changes
+
+- provider: export analytics correctly
+
+## 2.1.1
+
+### Patch Changes
+
+- Add LAOS chain support
+
+## 2.1.0
+
+### Minor Changes
+
+- account: forward project access key when estimating fees and sending transactions
+
+### Patch Changes
+
+- sessions: save signatures with reference chain id
+
+## 2.0.26
+
+### Patch Changes
+
+- account: fix chain id comparison
+
+## 2.0.25
+
+### Patch Changes
+
+- skale-nebula: deploy gas limit = 10m
+
+## 2.0.24
+
+### Patch Changes
+
+- sessions: arweave: configurable gateway url
+- waas: use /status to get time drift before sending any intents
+
+## 2.0.23
+
+### Patch Changes
+
+- Add The Root Network support
+
+## 2.0.22
+
+### Patch Changes
+
+- Add SKALE Nebula Mainnet support
+
+## 2.0.21
+
+### Patch Changes
+
+- account: add publishWitnessFor
+
+## 2.0.20
+
+### Patch Changes
+
+- upgrade deps, and improve waas session status handling
+
+## 2.0.19
+
+### Patch Changes
+
+- Add Immutable zkEVM support
+
+## 2.0.18
+
+### Patch Changes
+
+- waas: new contractCall transaction type
+- sessions: add arweave owner
+
+## 2.0.17
+
+### Patch Changes
+
+- update waas auth to clear session before signIn
+
+## 2.0.16
+
+### Patch Changes
+
+- Removed Astar chains
+
+## 2.0.15
+
+### Patch Changes
+
+- indexer: update bindings with token balance additions
+
+## 2.0.14
+
+### Patch Changes
+
+- sessions: arweave config reader
+- network: add b3 and apechain mainnet configs
+
+## 2.0.13
+
+### Patch Changes
+
+- network: toy-testnet
+
+## 2.0.12
+
+### Patch Changes
+
+- api: update bindings
+
+## 2.0.11
+
+### Patch Changes
+
+- waas: intents test fix
+- api: update bindings
+
+## 2.0.10
+
+### Patch Changes
+
+- network: soneium minato testnet
+
+## 2.0.9
+
+### Patch Changes
+
+- network: fix SKALE network name
+
+## 2.0.8
+
+### Patch Changes
+
+- metadata: update bindings
+
+## 2.0.7
+
+### Patch Changes
+
+- wallet request handler fix
+
+## 2.0.6
+
+### Patch Changes
+
+- network: matic -> pol
+
+## 2.0.5
+
+### Patch Changes
+
+- provider: update databeat to 0.9.2
+
+## 2.0.4
+
+### Patch Changes
+
+- network: add skale-nebula-testnet
+
+## 2.0.3
+
+### Patch Changes
+
+- waas: check session status in SequenceWaaS.isSignedIn()
+
+## 2.0.2
+
+### Patch Changes
+
+- sessions: property convert serialized bignumber hex value to bigint
+
+## 2.0.1
+
+### Patch Changes
+
+- waas: http signature check for authenticator requests
+- provider: unwrap legacy json rpc responses
+- use json replacer and reviver for bigints
+
+## 2.0.0
+
+### Major Changes
+
+- ethers v6
+
+## 1.10.15
+
+### Patch Changes
+
+- utils: extractProjectIdFromAccessKey
+
+## 1.10.14
+
+### Patch Changes
+
+- network: add borne-testnet to allNetworks
+
+## 1.10.13
+
+### Patch Changes
+
+- network: add borne testnet
+
+## 1.10.12
+
+### Patch Changes
+
+- api: update bindings
+- global/window -> globalThis
+
+## 1.10.11
+
+### Patch Changes
+
+- waas: updated intent.gen without webrpc types, errors exported from authenticator.gen
+
+## 1.10.10
+
+### Patch Changes
+
+- metadata: update bindings with new contract collections api
+
+## 1.10.9
+
+### Patch Changes
+
+- waas minor update
+
+## 1.10.8
+
+### Patch Changes
+
+- update metadata bindings
+
+## 1.10.7
+
+### Patch Changes
+
+- minor fixes to waas client
+
+## 1.10.6
+
+### Patch Changes
+
+- metadata: update bindings
+
+## 1.10.5
+
+### Patch Changes
+
+- network: ape-chain-testnet -> apechain-testnet
+
+## 1.10.4
+
+### Patch Changes
+
+- network: add b3-sepolia, ape-chain-testnet, blast, blast-sepolia
+
+## 1.10.3
+
+### Patch Changes
+
+- typing fix
+
+## 1.10.2
+
+### Patch Changes
+
+- - waas: add getIdToken method
+ - indexer: update api client
+
+## 1.10.1
+
+### Patch Changes
+
+- metadata: update bindings
+
+## 1.10.0
+
+### Minor Changes
+
+- waas release v1.3.0
+
+## 1.9.37
+
+### Patch Changes
+
+- network: adds nativeToken data to NetworkMetadata constants
+
+## 1.9.36
+
+### Patch Changes
+
+- guard: export client
+
+## 1.9.35
+
+### Patch Changes
+
+- guard: update bindings
+
+## 1.9.34
+
+### Patch Changes
+
+- waas: always use lowercase email
+
+## 1.9.33
+
+### Patch Changes
+
+- waas: umd build
+
+## 1.9.32
+
+### Patch Changes
+
+- indexer: update bindings
+
+## 1.9.31
+
+### Patch Changes
+
+- metadata: token directory changes
+
+## 1.9.30
+
+### Patch Changes
+
+- update
+
+## 1.9.29
+
+### Patch Changes
+
+- disable gnosis chain
+
+## 1.9.28
+
+### Patch Changes
+
+- add utils/merkletree
+
+## 1.9.27
+
+### Patch Changes
+
+- network: optimistic -> optimism
+- waas: remove defaults
+- api, sessions: update bindings
+
+## 1.9.26
+
+### Patch Changes
+
+- - add backend interfaces for pluggable interfaces
+ - introduce @0xsequence/react-native
+ - update pnpm to lockfile v9
+
+## 1.9.25
+
+### Patch Changes
+
+- update webrpc clients with new error types
+
+## 1.9.24
+
+### Patch Changes
+
+- waas: add memoryStore backend to localStore
+
+## 1.9.23
+
+### Patch Changes
+
+- update api client bindings
+
+## 1.9.22
+
+### Patch Changes
+
+- update metadata client bindings
+
+## 1.9.21
+
+### Patch Changes
+
+- api client bindings
+
+## 1.9.20
+
+### Patch Changes
+
+- api client bindings update
+
+## 1.9.19
+
+### Patch Changes
+
+- waas update
+
+## 1.9.18
+
+### Patch Changes
+
+- provider: prohibit dangerous functions
+
+## 1.9.17
+
+### Patch Changes
+
+- network: add xr-sepolia
+
+## 1.9.16
+
+### Patch Changes
+
+- waas: sequence.feeOptions
+
+## 1.9.15
+
+### Patch Changes
+
+- metadata: collection external_link field name fix
+
+## 1.9.14
+
+### Patch Changes
+
+- network: astar-zkatana -> astar-zkyoto
+- network: deprecate polygon mumbai network
+- network: add xai and polygon amoy
+
+## 1.9.13
+
+### Patch Changes
+
+- waas: fix @0xsequence/network dependency
+
+## 1.9.12
+
+### Patch Changes
+
+- indexer: update rpc bindings
+- provider: signMessage: Serialize the BytesLike or string message into hexstring before sending
+- waas: SessionAuthProof
+
+## 1.9.11
+
+### Patch Changes
+
+- metdata, update rpc bindings
+
+## 1.9.10
+
+### Patch Changes
+
+- update metadata rpc bindings
+
+## 1.9.9
+
+### Patch Changes
+
+- metadata, add SequenceCollections rpc client
+
+## 1.9.8
+
+### Patch Changes
+
+- waas client update
+
+## 1.9.7
+
+### Patch Changes
+
+- update rpc client bindings for api, metadata and relayer
+
+## 1.9.6
+
+### Patch Changes
+
+- waas package update
+
+## 1.9.5
+
+### Patch Changes
+
+- RpcRelayer prioritize project access key
+
+## 1.9.4
+
+### Patch Changes
+
+- waas: fix network dependency
+
+## 1.9.3
+
+### Patch Changes
+
+- provider: don't append access key to RPC url if user has already provided it
+
+## 1.9.2
+
+### Patch Changes
+
+- network: add xai-sepolia
+
+## 1.9.1
+
+### Patch Changes
+
+- analytics fix
+
+## 1.9.0
+
+### Minor Changes
+
+- waas release
+
+## 1.8.8
+
+### Patch Changes
+
+- update metadata bindings
+
+## 1.8.7
+
+### Patch Changes
+
+- provider: update databeat to 0.9.1
+
+## 1.8.6
+
+### Patch Changes
+
+- guard: SignedOwnershipProof
+
+## 1.8.5
+
+### Patch Changes
+
+- guard: signOwnershipProof and isSignedOwnershipProof
+
+## 1.8.4
+
+### Patch Changes
+
+- network: add homeverse to networks list
+
+## 1.8.3
+
+### Patch Changes
+
+- api: introduce basic linked wallet support
+
+## 1.8.2
+
+### Patch Changes
+
+- provider: don't initialize analytics unless explicitly requested
+
+## 1.8.1
+
+### Patch Changes
+
+- update to analytics provider
+
+## 1.8.0
+
+### Minor Changes
+
+- provider: project analytics
+
+## 1.7.2
+
+### Patch Changes
+
+- 0xsequence: ChainId should not be exported as a type
+- account, wallet: fix nonce selection
+
+## 1.7.1
+
+### Patch Changes
+
+- network: add missing avalanche logoURI
+
+## 1.7.0
+
+### Minor Changes
+
+- provider: projectAccessKey is now required
+
+### Patch Changes
+
+- network: add NetworkMetadata.logoURI property for all networks
+
+## 1.6.3
+
+### Patch Changes
+
+- network list update
+
+## 1.6.2
+
+### Patch Changes
+
+- auth: projectAccessKey option
+- wallet: use 12 bytes for random space
+
+## 1.6.1
+
+### Patch Changes
+
+- core: add simple config from subdigest support
+- core: fix encode tree with subdigest
+- account: implement buildOnChainSignature on Account
+
+## 1.6.0
+
+### Minor Changes
+
+- account, wallet: parallel transactions by default
+
+### Patch Changes
+
+- provider: emit disconnect on sign out
+
+## 1.5.0
+
+### Minor Changes
+
+- signhub: add 'signing' signer status
+
+### Patch Changes
+
+- auth: Session.open: onAccountAddress callback
+- account: allow empty transaction bundles
+
+## 1.4.9
+
+### Patch Changes
+
+- rename SequenceMetadataClient to SequenceMetadata
+
+## 1.4.8
+
+### Patch Changes
+
+- account: Account.getSigners
+
+## 1.4.7
+
+### Patch Changes
+
+- update indexer client bindings
+
+## 1.4.6
+
+### Patch Changes
+
+- - add sepolia networks, mark goerli as deprecated
+ - update indexer client bindings
+
+## 1.4.5
+
+### Patch Changes
+
+- indexer/metadata: update client bindings
+- auth: selectWallet with new address
+
+## 1.4.4
+
+### Patch Changes
+
+- indexer: update bindings
+- auth: handle jwt expiry
+
+## 1.4.3
+
+### Patch Changes
+
+- guard: return active status from GuardSigner.getAuthMethods
+
+## 1.4.2
+
+### Patch Changes
+
+- guard: update bindings
+
+## 1.4.1
+
+### Patch Changes
+
+- network: remove unused networks
+- signhub: orchestrator interface
+- guard: auth methods interface
+- guard: update bindings for pin and totp
+- guard: no more retry logic
+
+## 1.4.0
+
+### Minor Changes
+
+- project access key support
+
+## 1.3.0
+
+### Minor Changes
+
+- signhub: account children
+
+### Patch Changes
+
+- guard: do not throw when building deploy transaction
+- network: snowtrace.io -> subnets.avax.network/c-chain
+
+## 1.2.9
+
+### Patch Changes
+
+- account: AccountSigner.sendTransaction simulateForFeeOptions
+- relayer: update bindings
+
+## 1.2.8
+
+### Patch Changes
+
+- rename X-Sequence-Token-Key header to X-Access-Key
+
+## 1.2.7
+
+### Patch Changes
+
+- add x-sequence-token-key to clients
+
+## 1.2.6
+
+### Patch Changes
+
+- Fix bind multicall provider
+
+## 1.2.5
+
+### Patch Changes
+
+- Multicall default configuration fixes
+
+## 1.2.4
+
+### Patch Changes
+
+- provider: Adding missing payment provider types to PaymentProviderOption
+- provider: WalletRequestHandler.notifyChainChanged
+
+## 1.2.3
+
+### Patch Changes
+
+- auth, provider: connect to accept optional authorizeNonce
+
+## 1.2.2
+
+### Patch Changes
+
+- provider: allow createContract calls
+- core: check for explicit zero address in contract deployments
+
+## 1.2.1
+
+### Patch Changes
+
+- auth: use sequence api chain id as reference chain id if available
+
+## 1.2.0
+
+### Minor Changes
+
+- split services from session, better local support
+
+## 1.1.15
+
+### Patch Changes
+
+- guard: remove error filtering
+
+## 1.1.14
+
+### Patch Changes
+
+- guard: add GuardSigner.onError
+
+## 1.1.13
+
+### Patch Changes
+
+- provider: pass client version with connect options
+- provider: removing large from BannerSize
+
+## 1.1.12
+
+### Patch Changes
+
+- provider: adding bannerSize to ConnectOptions
+
+## 1.1.11
+
+### Patch Changes
+
+- add homeverse configs
+
+## 1.1.10
+
+### Patch Changes
+
+- handle default EIP6492 on send
+
+## 1.1.9
+
+### Patch Changes
+
+- Custom default EIP6492 on client
+
+## 1.1.8
+
+### Patch Changes
+
+- metadata: searchMetadata: add types filter
+
+## 1.1.7
+
+### Patch Changes
+
+- adding signInWith connect settings option to allow dapps to automatically login their users with a certain provider optimizing the normal authentication flow
+
+## 1.1.6
+
+### Patch Changes
+
+- metadata: searchMetadata: add chainID and excludeTokenMetadata filters
+
+## 1.1.5
+
+### Patch Changes
+
+- account: re-compute meta-transaction id for wallet deployment transactions
+
+## 1.1.4
+
+### Patch Changes
+
+- network: rename base-mainnet to base
+- provider: override isDefaultChain with ConnectOptions.networkId if provided
+
+## 1.1.3
+
+### Patch Changes
+
+- provider: use network id from transport session
+- provider: sign authorization using ConnectOptions.networkId if provided
+
+## 1.1.2
+
+### Patch Changes
+
+- provider: jsonrpc chain id fixes
+
+## 1.1.1
+
+### Patch Changes
+
+- network: add base mainnet and sepolia
+- provider: reject toxic transaction requests
+
+## 1.1.0
+
+### Minor Changes
+
+- Refactor dapp facing provider
+
+## 1.0.5
+
+### Patch Changes
+
+- network: export network constants
+- guard: use the correct global for fetch
+- network: nova-explorer.arbitrum.io -> nova.arbiscan.io
+
+## 1.0.4
+
+### Patch Changes
+
+- provider: accept name or number for networkId
+
+## 1.0.3
+
+### Patch Changes
+
+- Simpler isValidSignature helpers
+
+## 1.0.2
+
+### Patch Changes
+
+- add extra signature validation utils methods
+
+## 1.0.1
+
+### Patch Changes
+
+- add homeverse testnet
+
+## 1.0.0
+
+### Major Changes
+
+- https://sequence.xyz/blog/sequence-wallet-light-state-sync-full-merkle-wallets
+
+## 0.43.34
+
+### Patch Changes
+
+- auth: no jwt for indexer
+
+## 0.43.33
+
+### Patch Changes
+
+- Adding onConnectOptionsChange handler to WalletRequestHandler
+
+## 0.43.32
+
+### Patch Changes
+
+- add Base Goerli network
+
+## 0.43.31
+
+### Patch Changes
+
+- remove AuxDataProvider, add promptSignInConnect
+
+## 0.43.30
+
+### Patch Changes
+
+- add arbitrum goerli testnet
+
+## 0.43.29
+
+### Patch Changes
+
+- provider: check availability of window object
+
+## 0.43.28
+
+### Patch Changes
+
+- update api bindings
+
+## 0.43.27
+
+### Patch Changes
+
+- Add rpc is sequence method
+
+## 0.43.26
+
+### Patch Changes
+
+- add zkevm url to enum
+
+## 0.43.25
+
+### Patch Changes
+
+- added polygon zkevm to mainnet networks
+
+## 0.43.24
+
+### Patch Changes
+
+- name change from zkevm to polygon-zkevm
+
+## 0.43.23
+
+### Patch Changes
+
+- update zkEVM name to Polygon zkEVM
+
+## 0.43.22
+
+### Patch Changes
+
+- add zkevm chain
+
+## 0.43.21
+
+### Patch Changes
+
+- api: update client bindings
+
+## 0.43.20
+
+### Patch Changes
+
+- indexer: update bindings
+
+## 0.43.19
+
+### Patch Changes
+
+- session proof update
+
+## 0.43.18
+
+### Patch Changes
+
+- rpc client global check, hardening
+
+## 0.43.17
+
+### Patch Changes
+
+- rpc clients, check of 'global' is defined
+
+## 0.43.16
+
+### Patch Changes
+
+- ethers peerDep to v5, update rpc client global use
+
+## 0.43.15
+
+### Patch Changes
+
+- - provider: expand receiver type on some util methods
+
+## 0.43.14
+
+### Patch Changes
+
+- bump
+
+## 0.43.13
+
+### Patch Changes
+
+- update rpc bindings
+
+## 0.43.12
+
+### Patch Changes
+
+- provider: single wallet init, and add new unregisterWallet() method
+
+## 0.43.11
+
+### Patch Changes
+
+- fix lockfiles
+- re-add mocha type deleter
+
+## 0.43.10
+
+### Patch Changes
+
+- various improvements
+
+## 0.43.9
+
+### Patch Changes
+
+- update deps
+
+## 0.43.8
+
+### Patch Changes
+
+- network: JsonRpcProvider with caching
+
+## 0.43.7
+
+### Patch Changes
+
+- provider: fix wallet network init
+
+## 0.43.6
+
+### Patch Changes
+
+- metadatata: update rpc bindings
+
+## 0.43.5
+
+### Patch Changes
+
+- provider: do not set default network for connect messages
+- provider: forward missing error message
+
+## 0.43.4
+
+### Patch Changes
+
+- no-change version bump to fix incorrectly tagged snapshot build
+
+## 0.43.3
+
+### Patch Changes
+
+- metadata: update bindings
+
+## 0.43.2
+
+### Patch Changes
+
+- provider: implement connectUnchecked
+
+## 0.43.1
+
+### Patch Changes
+
+- update to latest ethauth dep
+
+## 0.43.0
+
+### Minor Changes
+
+- move ethers to a peer dependency
+
+## 0.42.10
+
+### Patch Changes
+
+- add auxDataProvider
+
+## 0.42.9
+
+### Patch Changes
+
+- provider: add eip-191 exceptions
+
+## 0.42.8
+
+### Patch Changes
+
+- provider: skip setting intent origin if we're unity plugin
+
+## 0.42.7
+
+### Patch Changes
+
+- Add sign in options to connection settings
+
+## 0.42.6
+
+### Patch Changes
+
+- api bindings update
+
+## 0.42.5
+
+### Patch Changes
+
+- relayer: don't treat missing receipt as hard failure
+
+## 0.42.4
+
+### Patch Changes
+
+- provider: add custom app protocol to connect options
+
+## 0.42.3
+
+### Patch Changes
+
+- update api bindings
+
+## 0.42.2
+
+### Patch Changes
+
+- disable rinkeby network
+
+## 0.42.1
+
+### Patch Changes
+
+- wallet: optional waitForReceipt parameter
+
+## 0.42.0
+
+### Minor Changes
+
+- relayer: estimateGasLimits -> simulate
+- add simulator package
+
+### Patch Changes
+
+- transactions: fix flattenAuxTransactions
+- provider: only filter nullish values
+- provider: re-map transaction 'gas' back to 'gasLimit'
+
+## 0.41.3
+
+### Patch Changes
+
+- api bindings update
+
+## 0.41.2
+
+### Patch Changes
+
+- api bindings update
+
+## 0.41.1
+
+### Patch Changes
+
+- update default networks
+
+## 0.41.0
+
+### Minor Changes
+
+- relayer: fix Relayer.wait() interface
+
+ The interface for calling Relayer.wait() has changed. Instead of a single optional ill-defined timeout/delay parameter, there are three optional parameters, in order:
+ - timeout: the maximum time to wait for the transaction receipt
+ - delay: the polling interval, i.e. the time to wait between requests
+ - maxFails: the maximum number of hard failures to tolerate before giving up
+
+ Please update your codebase accordingly.
+
+- relayer: add optional waitForReceipt parameter to Relayer.relay
+
+ The behaviour of Relayer.relay() was not well-defined with respect to whether or not it waited for a receipt.
+ This change allows the caller to specify whether to wait or not, with the default behaviour being to wait.
+
+### Patch Changes
+
+- relayer: wait receipt retry logic
+- fix wrapped object error
+- provider: forward delegateCall and revertOnError transaction fields
+
+## 0.40.6
+
+### Patch Changes
+
+- add arbitrum-nova chain
+
+## 0.40.5
+
+### Patch Changes
+
+- api: update bindings
+
+## 0.40.4
+
+### Patch Changes
+
+- add unreal transport
+
+## 0.40.3
+
+### Patch Changes
+
+- provider: fix MessageToSign message type
+
+## 0.40.2
+
+### Patch Changes
+
+- Wallet provider, loadSession method
+
+## 0.40.1
+
+### Patch Changes
+
+- export sequence.initWallet and sequence.getWallet
+
+## 0.40.0
+
+### Minor Changes
+
+- add sequence.initWallet(network, config) and sequence.getWallet() helper methods
+
+## 0.39.6
+
+### Patch Changes
+
+- indexer: update client bindings
+
+## 0.39.5
+
+### Patch Changes
+
+- provider: fix networkRpcUrl config option
+
+## 0.39.4
+
+### Patch Changes
+
+- api: update client bindings
+
+## 0.39.3
+
+### Patch Changes
+
+- add request method on Web3Provider
+
+## 0.39.2
+
+### Patch Changes
+
+- update umd name
+
+## 0.39.1
+
+### Patch Changes
+
+- add Aurora network
+- add origin info for accountsChanged event to handle it per dapp
+
+## 0.39.0
+
+### Minor Changes
+
+- abstract window.localStorage to interface type
+
+## 0.38.2
+
+### Patch Changes
+
+- provider: add Settings.defaultPurchaseAmount
+
+## 0.38.1
+
+### Patch Changes
+
+- update api and metadata rpc bindings
+
+## 0.38.0
+
+### Minor Changes
+
+- api: update bindings, change TokenPrice interface
+- bridge: remove @0xsequence/bridge package
+- api: update bindings, rename ContractCallArg to TupleComponent
+
+## 0.37.1
+
+### Patch Changes
+
+- Add back sortNetworks - Removing sorting was a breaking change for dapps on older versions which directly integrate sequence.
+
+## 0.37.0
+
+### Minor Changes
+
+- network related fixes and improvements
+- api: bindings: exchange rate lookups
+
+## 0.36.13
+
+### Patch Changes
+
+- api: update bindings with new price endpoints
+
+## 0.36.12
+
+### Patch Changes
+
+- wallet: skip remote signers if not needed
+- auth: check that signature meets threshold before requesting auth token
+
+## 0.36.11
+
+### Patch Changes
+
+- Prefix EIP191 message on wallet-request-handler
+
+## 0.36.10
+
+### Patch Changes
+
+- support bannerUrl on connect
+
+## 0.36.9
+
+### Patch Changes
+
+- minor dev xp improvements
+
+## 0.36.8
+
+### Patch Changes
+
+- more connect options (theme, payment providers, funding currencies)
+
+## 0.36.7
+
+### Patch Changes
+
+- fix missing break
+
+## 0.36.6
+
+### Patch Changes
+
+- wallet_switchEthereumChain support
+
+## 0.36.5
+
+### Patch Changes
+
+- auth: bump ethauth to 0.7.0
+ network, wallet: don't assume position of auth network in list
+ api/indexer/metadata: trim trailing slash on hostname, and add endpoint urls
+ relayer: Allow to specify local relayer transaction parameters like gas price or gas limit
+
+## 0.36.4
+
+### Patch Changes
+
+- Updating list of chain ids to include other ethereum compatible chains
+
+## 0.36.3
+
+### Patch Changes
+
+- provider: pass connect options to prompter methods
+
+## 0.36.2
+
+### Patch Changes
+
+- transactions: Setting target to 0x0 when empty to during SequenceTxAbiEncode
+
+## 0.36.1
+
+### Patch Changes
+
+- metadata: update client with more fields
+
+## 0.36.0
+
+### Minor Changes
+
+- relayer, wallet: fee quote support
+
+## 0.35.12
+
+### Patch Changes
+
+- provider: rename wallet.commands to wallet.utils
+
+## 0.35.11
+
+### Patch Changes
+
+- provider/utils: smoother message validation
+
+## 0.35.10
+
+### Patch Changes
+
+- upgrade deps
+
+## 0.35.9
+
+### Patch Changes
+
+- provider: window-transport override event handlers with new wallet instance
+
+## 0.35.8
+
+### Patch Changes
+
+- provider: async wallet sign in improvements
+
+## 0.35.7
+
+### Patch Changes
+
+- config: cache wallet configs
+
+## 0.35.6
+
+### Patch Changes
+
+- provider: support async signin of wallet request handler
+
+## 0.35.5
+
+### Patch Changes
+
+- wallet: skip threshold check during fee estimation
+
+## 0.35.4
+
+### Patch Changes
+
+- - browser extension mode, center window
+
+## 0.35.3
+
+### Patch Changes
+
+- - update window position when in browser extension mode
+
+## 0.35.2
+
+### Patch Changes
+
+- - provider: WindowMessageHandler accept optional windowHref
+
+## 0.35.1
+
+### Patch Changes
+
+- wallet: update config on undeployed too
+
+## 0.35.0
+
+### Minor Changes
+
+- - config: add buildStubSignature
+ - provider: add checks to signing cases for wallet deployment and config statuses
+ - provider: add prompt for wallet deployment
+ - relayer: add BaseRelayer.prependWalletDeploy
+ - relayer: add Relayer.feeOptions
+ - relayer: account for wallet deployment in fee estimation
+ - transactions: add fromTransactionish
+ - wallet: add Account.prependConfigUpdate
+ - wallet: add Account.getFeeOptions
+
+## 0.34.0
+
+### Minor Changes
+
+- - upgrade deps
+
+## 0.31.0
+
+### Minor Changes
+
+- - upgrading to ethers v5.5
+
+## 0.30.0
+
+### Minor Changes
+
+- - upgrade most deps
+
+## 0.29.8
+
+### Patch Changes
+
+- update api
+
+## 0.29.0
+
+### Minor Changes
+
+- major architectural changes in Sequence design
+ - only one API instance, API is no longer a per-chain service
+ - separate per-chain indexer service, API no longer handles indexing
+ - single contract metadata service, API no longer serves metadata
+
+ chaind package has been removed, indexer and metadata packages have been added
+
+ stronger typing with new explicit ChainId type
+
+ multicall fixes and improvements
+
+ forbid "wait" transactions in sendTransactionBatch calls
+
+## 0.28.0
+
+### Minor Changes
+
+- extension provider
+
+## 0.27.0
+
+### Minor Changes
+
+- Add requireFreshSigner lib to sessions
+
+## 0.25.1
+
+### Patch Changes
+
+- Fix build typescrypt issue
+
+## 0.25.0
+
+### Minor Changes
+
+- 10c8af8: Add estimator package
+ Fix multicall few calls bug
+
+## 0.23.0
+
+### Minor Changes
+
+- - relayer: offer variety of gas fee options from the relayer service"
+
+## 0.22.2
+
+### Patch Changes
+
+- e1c109e: Fix authProof on expired sessions
+
+## 0.22.1
+
+### Patch Changes
+
+- transport session cache
+
+## 0.22.0
+
+### Minor Changes
+
+- e667b65: Expose all relayer options on networks
+
+## 0.21.5
+
+### Patch Changes
+
+- Give priority to metaTxnId returned by relayer
+
+## 0.21.4
+
+### Patch Changes
+
+- Add has enough signers method
+
+## 0.21.3
+
+### Patch Changes
+
+- add window session cache
+
+## 0.21.2
+
+### Patch Changes
+
+- exception handlind in relayer
+
+## 0.21.0
+
+### Minor Changes
+
+- - fix gas estimation on wallets with large number of signers
+ - update to session handling and wallet config construction upon auth
+
+## 0.19.3
+
+### Patch Changes
+
+- jwtAuth visibility, package version sync
+
+## 0.19.2
+
+### Patch Changes
+
+- - api: change jwtAuth visibility
+
+## 0.19.0
+
+### Minor Changes
+
+- - provider, improve dapp / wallet transport io
+
+## 0.18.0
+
+### Minor Changes
+
+- relayer improvements and pending transaction handling
+
+## 0.16.0
+
+### Minor Changes
+
+- relayer as its own service separate from chaind
+
+## 0.15.1
+
+### Patch Changes
+
+- update api clients
+
+## 0.14.3
+
+### Patch Changes
+
+- Fix 0xSequence relayer dependencies
+
+## 0.14.2
+
+### Patch Changes
+
+- Add debug logs to rpc-relayer
+
+## 0.14.0
+
+### Minor Changes
+
+- update sequence utils finder which includes optimization
+
+## 0.13.0
+
+### Minor Changes
+
+- Update SequenceUtils deployed contract
+
+## 0.12.1
+
+### Patch Changes
+
+- npm bump
+
+## 0.12.0
+
+### Minor Changes
+
+- provider: improvements to window transport
+
+## 0.11.4
+
+### Patch Changes
+
+- update api client
+
+## 0.11.3
+
+### Patch Changes
+
+- improve openWindow state options handling
+
+## 0.11.2
+
+### Patch Changes
+
+- Fix multicall proxy scopes
+
+## 0.11.1
+
+### Patch Changes
+
+- Add support for dynamic and nested signatures
+
+## 0.11.0
+
+### Minor Changes
+
+- Update wallet context to 1.7 contracts
+
+## 0.10.9
+
+### Patch Changes
+
+- add support for public addresses as signers in session.open
+
+## 0.10.8
+
+### Patch Changes
+
+- Multicall production configuration
+
+## 0.10.7
+
+### Patch Changes
+
+- allow provider transport to force disconnect
+
+## 0.10.6
+
+### Patch Changes
+
+- - fix getWalletState method
+
+## 0.10.5
+
+### Patch Changes
+
+- update relayer gas refund options
+
+## 0.10.4
+
+### Patch Changes
+
+- Update api proto
+
+## 0.10.3
+
+### Patch Changes
+
+- Fix loading config cross-chain
+
+## 0.10.2
+
+### Patch Changes
+
+- - message digest fix
+
+## 0.10.1
+
+### Patch Changes
+
+- upgrade deps
+
+## 0.10.0
+
+### Minor Changes
+
+- Deployed new contracts with ERC1271 signer support
+
+## 0.9.6
+
+### Patch Changes
+
+- Update ABIs for latest sequence contracts
+
+## 0.9.3
+
+### Patch Changes
+
+- - minor improvements
+
+## 0.9.1
+
+### Patch Changes
+
+- - patch bump
+
+## 0.9.0
+
+### Minor Changes
+
+- - provider transport hardening
+
+## 0.8.5
+
+### Patch Changes
+
+- - use latest wallet-contracts
+
+## 0.8.4
+
+### Patch Changes
+
+- - minor improvements, name updates and comments
+
+## 0.8.3
+
+### Patch Changes
+
+- - refinements
+
+ - normalize signer address in config
+
+ - provider: getWalletState() method to WalletProvider
+
+## 0.8.2
+
+### Patch Changes
+
+- - field rename and ethauth dependency bump
+
+## 0.8.1
+
+### Patch Changes
+
+- - variety of optimizations
+
+## 0.8.0
+
+### Minor Changes
+
+- - changeset fix
+
+## 0.7.0
+
+### Patch Changes
+
+- 6f11ed7: sequence.js, init release
diff --git a/packages/abi/README.md b/packages/abi/README.md
new file mode 100644
index 0000000000..e0bbc2309a
--- /dev/null
+++ b/packages/abi/README.md
@@ -0,0 +1,4 @@
+@0xsequence/abi
+===============
+
+See [0xsequence project page](https://github.com/0xsequence/sequence.js).
diff --git a/packages/abi/package.json b/packages/abi/package.json
new file mode 100644
index 0000000000..c0305eccc1
--- /dev/null
+++ b/packages/abi/package.json
@@ -0,0 +1,22 @@
+{
+ "name": "@0xsequence/abi",
+ "version": "2.0.0",
+ "description": "abi sub-package for Sequence",
+ "repository": "https://github.com/0xsequence/sequence.js/tree/master/packages/abi",
+ "source": "src/index.ts",
+ "main": "dist/0xsequence-abi.cjs.js",
+ "module": "dist/0xsequence-abi.esm.js",
+ "author": "Horizon Blockchain Games",
+ "license": "Apache-2.0",
+ "scripts": {
+ "test": "echo",
+ "typecheck": "tsc --noEmit"
+ },
+ "dependencies": {},
+ "peerDependencies": {},
+ "devDependencies": {},
+ "files": [
+ "src",
+ "dist"
+ ]
+}
diff --git a/packages/abi/src/index.ts b/packages/abi/src/index.ts
new file mode 100644
index 0000000000..6537ee23d2
--- /dev/null
+++ b/packages/abi/src/index.ts
@@ -0,0 +1 @@
+export { walletContracts } from './wallet'
diff --git a/packages/abi/src/tokens/erc1155.ts b/packages/abi/src/tokens/erc1155.ts
new file mode 100644
index 0000000000..1e20ce4050
--- /dev/null
+++ b/packages/abi/src/tokens/erc1155.ts
@@ -0,0 +1,3 @@
+export const abi = []
+
+export const returns = {}
diff --git a/packages/abi/src/tokens/erc20.ts b/packages/abi/src/tokens/erc20.ts
new file mode 100644
index 0000000000..1e20ce4050
--- /dev/null
+++ b/packages/abi/src/tokens/erc20.ts
@@ -0,0 +1,3 @@
+export const abi = []
+
+export const returns = {}
diff --git a/packages/abi/src/tokens/erc721.ts b/packages/abi/src/tokens/erc721.ts
new file mode 100644
index 0000000000..1e20ce4050
--- /dev/null
+++ b/packages/abi/src/tokens/erc721.ts
@@ -0,0 +1,3 @@
+export const abi = []
+
+export const returns = {}
diff --git a/packages/abi/src/wallet/erc1271.ts b/packages/abi/src/wallet/erc1271.ts
new file mode 100644
index 0000000000..14e0576117
--- /dev/null
+++ b/packages/abi/src/wallet/erc1271.ts
@@ -0,0 +1,26 @@
+export const abi = [
+ {
+ type: 'function',
+ name: 'isValidSignature',
+ constant: true,
+ inputs: [
+ {
+ type: 'bytes32'
+ },
+ {
+ type: 'bytes'
+ }
+ ],
+ outputs: [
+ {
+ type: 'bytes4'
+ }
+ ],
+ payable: false,
+ stateMutability: 'view'
+ }
+]
+
+export const returns = {
+ isValidSignatureBytes32: '0x1626ba7e'
+}
diff --git a/packages/abi/src/wallet/erc5719.ts b/packages/abi/src/wallet/erc5719.ts
new file mode 100644
index 0000000000..2f9b43b6ab
--- /dev/null
+++ b/packages/abi/src/wallet/erc5719.ts
@@ -0,0 +1,19 @@
+export const abi = [
+ {
+ inputs: [
+ {
+ internalType: 'bytes32',
+ type: 'bytes32'
+ }
+ ],
+ name: 'getAlternativeSignature',
+ outputs: [
+ {
+ internalType: 'string',
+ type: 'string'
+ }
+ ],
+ stateMutability: 'view',
+ type: 'function'
+ }
+]
diff --git a/packages/abi/src/wallet/erc6492.ts b/packages/abi/src/wallet/erc6492.ts
new file mode 100644
index 0000000000..dcaf022a50
--- /dev/null
+++ b/packages/abi/src/wallet/erc6492.ts
@@ -0,0 +1,61 @@
+export const abi = [
+ { inputs: [{ internalType: 'bytes', name: 'error', type: 'bytes' }], name: 'ERC1271Revert', type: 'error' },
+ { inputs: [{ internalType: 'bytes', name: 'error', type: 'bytes' }], name: 'ERC6492DeployFailed', type: 'error' },
+ {
+ inputs: [
+ { internalType: 'address', name: '_signer', type: 'address' },
+ { internalType: 'bytes32', name: '_hash', type: 'bytes32' },
+ { internalType: 'bytes', name: '_signature', type: 'bytes' }
+ ],
+ name: 'isValidSig',
+ outputs: [{ internalType: 'bool', name: '', type: 'bool' }],
+ stateMutability: 'nonpayable',
+ type: 'function'
+ },
+ {
+ inputs: [
+ { internalType: 'address', name: '_signer', type: 'address' },
+ { internalType: 'bytes32', name: '_hash', type: 'bytes32' },
+ { internalType: 'bytes', name: '_signature', type: 'bytes' },
+ { internalType: 'bool', name: 'allowSideEffects', type: 'bool' },
+ { internalType: 'bool', name: 'deployAlreadyDeployed', type: 'bool' }
+ ],
+ name: 'isValidSigImpl',
+ outputs: [{ internalType: 'bool', name: '', type: 'bool' }],
+ stateMutability: 'nonpayable',
+ type: 'function'
+ },
+ {
+ inputs: [
+ { internalType: 'address', name: '_signer', type: 'address' },
+ { internalType: 'bytes32', name: '_hash', type: 'bytes32' },
+ { internalType: 'bytes', name: '_signature', type: 'bytes' }
+ ],
+ name: 'isValidSigNoThrow',
+ outputs: [{ internalType: 'bool', name: '', type: 'bool' }],
+ stateMutability: 'nonpayable',
+ type: 'function'
+ },
+ {
+ inputs: [
+ { internalType: 'address', name: '_signer', type: 'address' },
+ { internalType: 'bytes32', name: '_hash', type: 'bytes32' },
+ { internalType: 'bytes', name: '_signature', type: 'bytes' }
+ ],
+ name: 'isValidSigWithSideEffects',
+ outputs: [{ internalType: 'bool', name: '', type: 'bool' }],
+ stateMutability: 'nonpayable',
+ type: 'function'
+ },
+ {
+ inputs: [
+ { internalType: 'address', name: '_signer', type: 'address' },
+ { internalType: 'bytes32', name: '_hash', type: 'bytes32' },
+ { internalType: 'bytes', name: '_signature', type: 'bytes' }
+ ],
+ name: 'isValidSigWithSideEffectsNoThrow',
+ outputs: [{ internalType: 'bool', name: '', type: 'bool' }],
+ stateMutability: 'nonpayable',
+ type: 'function'
+ }
+]
diff --git a/packages/abi/src/wallet/factory.ts b/packages/abi/src/wallet/factory.ts
new file mode 100644
index 0000000000..df5ef5fc66
--- /dev/null
+++ b/packages/abi/src/wallet/factory.ts
@@ -0,0 +1,18 @@
+export const abi = [
+ {
+ type: 'function',
+ name: 'deploy',
+ constant: false,
+ inputs: [
+ {
+ type: 'address'
+ },
+ {
+ type: 'bytes32'
+ }
+ ],
+ outputs: [],
+ payable: true,
+ stateMutability: 'payable'
+ }
+]
diff --git a/packages/abi/src/wallet/index.ts b/packages/abi/src/wallet/index.ts
new file mode 100644
index 0000000000..cb9bdf867c
--- /dev/null
+++ b/packages/abi/src/wallet/index.ts
@@ -0,0 +1,19 @@
+import * as erc5719 from './erc5719'
+import * as erc1271 from './erc1271'
+import * as erc6492 from './erc6492'
+import * as factory from './factory'
+import * as mainModule from './mainModule'
+import * as mainModuleUpgradable from './mainModuleUpgradable'
+import * as sequenceUtils from './sequenceUtils'
+import * as requireFreshSigner from './libs/requireFreshSigners'
+
+export const walletContracts = {
+ erc6492,
+ erc5719,
+ erc1271,
+ factory,
+ mainModule,
+ mainModuleUpgradable,
+ sequenceUtils,
+ requireFreshSigner
+}
diff --git a/packages/abi/src/wallet/libs/requireFreshSigners.ts b/packages/abi/src/wallet/libs/requireFreshSigners.ts
new file mode 100644
index 0000000000..ef8f78657c
--- /dev/null
+++ b/packages/abi/src/wallet/libs/requireFreshSigners.ts
@@ -0,0 +1,15 @@
+export const abi = [
+ {
+ inputs: [
+ {
+ internalType: 'address',
+ name: '',
+ type: 'address'
+ }
+ ],
+ name: 'requireFreshSigner',
+ outputs: [],
+ stateMutability: 'nonpayable',
+ type: 'function'
+ }
+]
diff --git a/packages/abi/src/wallet/mainModule.ts b/packages/abi/src/wallet/mainModule.ts
new file mode 100644
index 0000000000..e92fde8f1d
--- /dev/null
+++ b/packages/abi/src/wallet/mainModule.ts
@@ -0,0 +1,158 @@
+export const abi = [
+ {
+ type: 'function',
+ name: 'nonce',
+ constant: true,
+ inputs: [],
+ outputs: [
+ {
+ type: 'uint256'
+ }
+ ],
+ payable: false,
+ stateMutability: 'view'
+ },
+ {
+ type: 'function',
+ name: 'readNonce',
+ constant: true,
+ inputs: [
+ {
+ type: 'uint256'
+ }
+ ],
+ outputs: [
+ {
+ type: 'uint256'
+ }
+ ],
+ payable: false,
+ stateMutability: 'view'
+ },
+ {
+ type: 'function',
+ name: 'updateImplementation',
+ constant: false,
+ inputs: [
+ {
+ type: 'address'
+ }
+ ],
+ outputs: [],
+ payable: false,
+ stateMutability: 'nonpayable'
+ },
+ {
+ type: 'function',
+ name: 'selfExecute',
+ constant: false,
+ inputs: [
+ {
+ components: [
+ {
+ type: 'bool',
+ name: 'delegateCall'
+ },
+ {
+ type: 'bool',
+ name: 'revertOnError'
+ },
+ {
+ type: 'uint256',
+ name: 'gasLimit'
+ },
+ {
+ type: 'address',
+ name: 'target'
+ },
+ {
+ type: 'uint256',
+ name: 'value'
+ },
+ {
+ type: 'bytes',
+ name: 'data'
+ }
+ ],
+ type: 'tuple[]'
+ }
+ ],
+ outputs: [],
+ payable: false,
+ stateMutability: 'nonpayable'
+ },
+ {
+ type: 'function',
+ name: 'execute',
+ constant: false,
+ inputs: [
+ {
+ components: [
+ {
+ type: 'bool',
+ name: 'delegateCall'
+ },
+ {
+ type: 'bool',
+ name: 'revertOnError'
+ },
+ {
+ type: 'uint256',
+ name: 'gasLimit'
+ },
+ {
+ type: 'address',
+ name: 'target'
+ },
+ {
+ type: 'uint256',
+ name: 'value'
+ },
+ {
+ type: 'bytes',
+ name: 'data'
+ }
+ ],
+ type: 'tuple[]'
+ },
+ {
+ type: 'uint256'
+ },
+ {
+ type: 'bytes'
+ }
+ ],
+ outputs: [],
+ payable: false,
+ stateMutability: 'nonpayable'
+ },
+ {
+ type: 'function',
+ name: 'createContract',
+ inputs: [
+ {
+ type: 'bytes'
+ }
+ ],
+ payable: true,
+ stateMutability: 'payable'
+ },
+ {
+ type: 'function',
+ name: 'setExtraImageHash',
+ constant: false,
+ inputs: [
+ {
+ type: 'bytes32',
+ name: 'imageHash'
+ },
+ {
+ type: 'uint256',
+ name: 'expiration'
+ }
+ ],
+ outputs: [],
+ payable: false,
+ stateMutability: 'nonpayable'
+ }
+]
diff --git a/packages/abi/src/wallet/mainModuleUpgradable.ts b/packages/abi/src/wallet/mainModuleUpgradable.ts
new file mode 100644
index 0000000000..e49298a38f
--- /dev/null
+++ b/packages/abi/src/wallet/mainModuleUpgradable.ts
@@ -0,0 +1,28 @@
+export const abi = [
+ {
+ type: 'function',
+ name: 'updateImageHash',
+ constant: true,
+ inputs: [
+ {
+ type: 'bytes32'
+ }
+ ],
+ outputs: [],
+ payable: false,
+ stateMutability: 'view'
+ },
+ {
+ type: 'function',
+ name: 'imageHash',
+ constant: true,
+ inputs: [],
+ outputs: [
+ {
+ type: 'bytes32'
+ }
+ ],
+ payable: false,
+ stateMutability: 'view'
+ }
+]
diff --git a/packages/abi/src/wallet/sequenceUtils.ts b/packages/abi/src/wallet/sequenceUtils.ts
new file mode 100644
index 0000000000..7b52c69c8a
--- /dev/null
+++ b/packages/abi/src/wallet/sequenceUtils.ts
@@ -0,0 +1,516 @@
+export const abi = [
+ {
+ inputs: [
+ {
+ internalType: 'address',
+ name: '_factory',
+ type: 'address'
+ },
+ {
+ internalType: 'address',
+ name: '_mainModule',
+ type: 'address'
+ }
+ ],
+ stateMutability: 'nonpayable',
+ type: 'constructor'
+ },
+ {
+ anonymous: false,
+ inputs: [
+ {
+ indexed: true,
+ internalType: 'address',
+ name: '_wallet',
+ type: 'address'
+ },
+ {
+ indexed: true,
+ internalType: 'bytes32',
+ name: '_imageHash',
+ type: 'bytes32'
+ },
+ {
+ indexed: false,
+ internalType: 'uint256',
+ name: '_threshold',
+ type: 'uint256'
+ },
+ {
+ indexed: false,
+ internalType: 'bytes',
+ name: '_signers',
+ type: 'bytes'
+ }
+ ],
+ name: 'RequiredConfig',
+ type: 'event'
+ },
+ {
+ anonymous: false,
+ inputs: [
+ {
+ indexed: true,
+ internalType: 'address',
+ name: '_wallet',
+ type: 'address'
+ },
+ {
+ indexed: true,
+ internalType: 'address',
+ name: '_signer',
+ type: 'address'
+ }
+ ],
+ name: 'RequiredSigner',
+ type: 'event'
+ },
+ {
+ inputs: [
+ {
+ internalType: 'address',
+ name: '_addr',
+ type: 'address'
+ }
+ ],
+ name: 'callBalanceOf',
+ outputs: [
+ {
+ internalType: 'uint256',
+ name: '',
+ type: 'uint256'
+ }
+ ],
+ stateMutability: 'view',
+ type: 'function'
+ },
+ {
+ inputs: [],
+ name: 'callBlockNumber',
+ outputs: [
+ {
+ internalType: 'uint256',
+ name: '',
+ type: 'uint256'
+ }
+ ],
+ stateMutability: 'view',
+ type: 'function'
+ },
+ {
+ inputs: [
+ {
+ internalType: 'uint256',
+ name: '_i',
+ type: 'uint256'
+ }
+ ],
+ name: 'callBlockhash',
+ outputs: [
+ {
+ internalType: 'bytes32',
+ name: '',
+ type: 'bytes32'
+ }
+ ],
+ stateMutability: 'view',
+ type: 'function'
+ },
+ {
+ inputs: [],
+ name: 'callChainId',
+ outputs: [
+ {
+ internalType: 'uint256',
+ name: 'id',
+ type: 'uint256'
+ }
+ ],
+ stateMutability: 'pure',
+ type: 'function'
+ },
+ {
+ inputs: [
+ {
+ internalType: 'address',
+ name: '_addr',
+ type: 'address'
+ }
+ ],
+ name: 'callCode',
+ outputs: [
+ {
+ internalType: 'bytes',
+ name: 'code',
+ type: 'bytes'
+ }
+ ],
+ stateMutability: 'view',
+ type: 'function'
+ },
+ {
+ inputs: [
+ {
+ internalType: 'address',
+ name: '_addr',
+ type: 'address'
+ }
+ ],
+ name: 'callCodeHash',
+ outputs: [
+ {
+ internalType: 'bytes32',
+ name: 'codeHash',
+ type: 'bytes32'
+ }
+ ],
+ stateMutability: 'view',
+ type: 'function'
+ },
+ {
+ inputs: [
+ {
+ internalType: 'address',
+ name: '_addr',
+ type: 'address'
+ }
+ ],
+ name: 'callCodeSize',
+ outputs: [
+ {
+ internalType: 'uint256',
+ name: 'size',
+ type: 'uint256'
+ }
+ ],
+ stateMutability: 'view',
+ type: 'function'
+ },
+ {
+ inputs: [],
+ name: 'callCoinbase',
+ outputs: [
+ {
+ internalType: 'address',
+ name: '',
+ type: 'address'
+ }
+ ],
+ stateMutability: 'view',
+ type: 'function'
+ },
+ {
+ inputs: [],
+ name: 'callDifficulty',
+ outputs: [
+ {
+ internalType: 'uint256',
+ name: '',
+ type: 'uint256'
+ }
+ ],
+ stateMutability: 'view',
+ type: 'function'
+ },
+ {
+ inputs: [],
+ name: 'callGasLeft',
+ outputs: [
+ {
+ internalType: 'uint256',
+ name: '',
+ type: 'uint256'
+ }
+ ],
+ stateMutability: 'view',
+ type: 'function'
+ },
+ {
+ inputs: [],
+ name: 'callGasLimit',
+ outputs: [
+ {
+ internalType: 'uint256',
+ name: '',
+ type: 'uint256'
+ }
+ ],
+ stateMutability: 'view',
+ type: 'function'
+ },
+ {
+ inputs: [],
+ name: 'callGasPrice',
+ outputs: [
+ {
+ internalType: 'uint256',
+ name: '',
+ type: 'uint256'
+ }
+ ],
+ stateMutability: 'view',
+ type: 'function'
+ },
+ {
+ inputs: [],
+ name: 'callOrigin',
+ outputs: [
+ {
+ internalType: 'address',
+ name: '',
+ type: 'address'
+ }
+ ],
+ stateMutability: 'view',
+ type: 'function'
+ },
+ {
+ inputs: [],
+ name: 'callTimestamp',
+ outputs: [
+ {
+ internalType: 'uint256',
+ name: '',
+ type: 'uint256'
+ }
+ ],
+ stateMutability: 'view',
+ type: 'function'
+ },
+ {
+ inputs: [
+ {
+ internalType: 'address',
+ name: '',
+ type: 'address'
+ }
+ ],
+ name: 'knownImageHashes',
+ outputs: [
+ {
+ internalType: 'bytes32',
+ name: '',
+ type: 'bytes32'
+ }
+ ],
+ stateMutability: 'view',
+ type: 'function'
+ },
+ {
+ inputs: [
+ {
+ internalType: 'bytes32',
+ name: '',
+ type: 'bytes32'
+ }
+ ],
+ name: 'lastImageHashUpdate',
+ outputs: [
+ {
+ internalType: 'uint256',
+ name: '',
+ type: 'uint256'
+ }
+ ],
+ stateMutability: 'view',
+ type: 'function'
+ },
+ {
+ inputs: [
+ {
+ internalType: 'address',
+ name: '',
+ type: 'address'
+ }
+ ],
+ name: 'lastSignerUpdate',
+ outputs: [
+ {
+ internalType: 'uint256',
+ name: '',
+ type: 'uint256'
+ }
+ ],
+ stateMutability: 'view',
+ type: 'function'
+ },
+ {
+ inputs: [
+ {
+ internalType: 'address',
+ name: '',
+ type: 'address'
+ }
+ ],
+ name: 'lastWalletUpdate',
+ outputs: [
+ {
+ internalType: 'uint256',
+ name: '',
+ type: 'uint256'
+ }
+ ],
+ stateMutability: 'view',
+ type: 'function'
+ },
+ {
+ inputs: [
+ {
+ components: [
+ {
+ internalType: 'bool',
+ name: 'delegateCall',
+ type: 'bool'
+ },
+ {
+ internalType: 'bool',
+ name: 'revertOnError',
+ type: 'bool'
+ },
+ {
+ internalType: 'uint256',
+ name: 'gasLimit',
+ type: 'uint256'
+ },
+ {
+ internalType: 'address',
+ name: 'target',
+ type: 'address'
+ },
+ {
+ internalType: 'uint256',
+ name: 'value',
+ type: 'uint256'
+ },
+ {
+ internalType: 'bytes',
+ name: 'data',
+ type: 'bytes'
+ }
+ ],
+ internalType: 'struct IModuleCalls.Transaction[]',
+ name: '_txs',
+ type: 'tuple[]'
+ }
+ ],
+ name: 'multiCall',
+ outputs: [
+ {
+ internalType: 'bool[]',
+ name: '_successes',
+ type: 'bool[]'
+ },
+ {
+ internalType: 'bytes[]',
+ name: '_results',
+ type: 'bytes[]'
+ }
+ ],
+ stateMutability: 'payable',
+ type: 'function'
+ },
+ {
+ inputs: [
+ {
+ internalType: 'address',
+ name: '_wallet',
+ type: 'address'
+ },
+ {
+ internalType: 'uint256',
+ name: '_threshold',
+ type: 'uint256'
+ },
+ {
+ components: [
+ {
+ internalType: 'uint256',
+ name: 'weight',
+ type: 'uint256'
+ },
+ {
+ internalType: 'address',
+ name: 'signer',
+ type: 'address'
+ }
+ ],
+ internalType: 'struct RequireUtils.Member[]',
+ name: '_members',
+ type: 'tuple[]'
+ },
+ {
+ internalType: 'bool',
+ name: '_index',
+ type: 'bool'
+ }
+ ],
+ name: 'publishConfig',
+ outputs: [],
+ stateMutability: 'nonpayable',
+ type: 'function'
+ },
+ {
+ inputs: [
+ {
+ internalType: 'address',
+ name: '_wallet',
+ type: 'address'
+ },
+ {
+ internalType: 'bytes32',
+ name: '_hash',
+ type: 'bytes32'
+ },
+ {
+ internalType: 'uint256',
+ name: '_sizeMembers',
+ type: 'uint256'
+ },
+ {
+ internalType: 'bytes',
+ name: '_signature',
+ type: 'bytes'
+ },
+ {
+ internalType: 'bool',
+ name: '_index',
+ type: 'bool'
+ }
+ ],
+ name: 'publishInitialSigners',
+ outputs: [],
+ stateMutability: 'nonpayable',
+ type: 'function'
+ },
+ {
+ inputs: [
+ {
+ internalType: 'address',
+ name: '_wallet',
+ type: 'address'
+ },
+ {
+ internalType: 'uint256',
+ name: '_nonce',
+ type: 'uint256'
+ }
+ ],
+ name: 'requireMinNonce',
+ outputs: [],
+ stateMutability: 'view',
+ type: 'function'
+ },
+ {
+ inputs: [
+ {
+ internalType: 'uint256',
+ name: '_expiration',
+ type: 'uint256'
+ }
+ ],
+ name: 'requireNonExpired',
+ outputs: [],
+ stateMutability: 'view',
+ type: 'function'
+ }
+]
diff --git a/packages/account/CHANGELOG.md b/packages/account/CHANGELOG.md
new file mode 100644
index 0000000000..c506f50538
--- /dev/null
+++ b/packages/account/CHANGELOG.md
@@ -0,0 +1,1770 @@
+# @0xsequence/account
+
+## 2.0.0
+
+### Major Changes
+
+- changeset
+
+### Patch Changes
+
+- Updated dependencies
+ - @0xsequence/abi@2.0.0
+ - @0xsequence/core@2.0.0
+ - @0xsequence/migration@2.0.0
+ - @0xsequence/network@2.0.0
+ - @0xsequence/relayer@2.0.0
+ - @0xsequence/sessions@2.0.0
+ - @0xsequence/utils@2.0.0
+ - @0xsequence/wallet@2.0.0
+
+## 1.10.14
+
+### Patch Changes
+
+- network: add borne-testnet to allNetworks
+- Updated dependencies
+ - @0xsequence/abi@1.10.14
+ - @0xsequence/core@1.10.14
+ - @0xsequence/migration@1.10.14
+ - @0xsequence/network@1.10.14
+ - @0xsequence/relayer@1.10.14
+ - @0xsequence/sessions@1.10.14
+ - @0xsequence/utils@1.10.14
+ - @0xsequence/wallet@1.10.14
+
+## 1.10.13
+
+### Patch Changes
+
+- network: add borne testnet
+- Updated dependencies
+ - @0xsequence/abi@1.10.13
+ - @0xsequence/core@1.10.13
+ - @0xsequence/migration@1.10.13
+ - @0xsequence/network@1.10.13
+ - @0xsequence/relayer@1.10.13
+ - @0xsequence/sessions@1.10.13
+ - @0xsequence/utils@1.10.13
+ - @0xsequence/wallet@1.10.13
+
+## 1.10.12
+
+### Patch Changes
+
+- api: update bindings
+- global/window -> globalThis
+- Updated dependencies
+- Updated dependencies
+ - @0xsequence/abi@1.10.12
+ - @0xsequence/core@1.10.12
+ - @0xsequence/migration@1.10.12
+ - @0xsequence/network@1.10.12
+ - @0xsequence/relayer@1.10.12
+ - @0xsequence/sessions@1.10.12
+ - @0xsequence/utils@1.10.12
+ - @0xsequence/wallet@1.10.12
+
+## 1.10.11
+
+### Patch Changes
+
+- waas: updated intent.gen without webrpc types, errors exported from authenticator.gen
+- Updated dependencies
+ - @0xsequence/abi@1.10.11
+ - @0xsequence/core@1.10.11
+ - @0xsequence/migration@1.10.11
+ - @0xsequence/network@1.10.11
+ - @0xsequence/relayer@1.10.11
+ - @0xsequence/sessions@1.10.11
+ - @0xsequence/utils@1.10.11
+ - @0xsequence/wallet@1.10.11
+
+## 1.10.10
+
+### Patch Changes
+
+- metadata: update bindings with new contract collections api
+- Updated dependencies
+ - @0xsequence/abi@1.10.10
+ - @0xsequence/core@1.10.10
+ - @0xsequence/migration@1.10.10
+ - @0xsequence/network@1.10.10
+ - @0xsequence/relayer@1.10.10
+ - @0xsequence/sessions@1.10.10
+ - @0xsequence/utils@1.10.10
+ - @0xsequence/wallet@1.10.10
+
+## 1.10.9
+
+### Patch Changes
+
+- waas minor update
+- Updated dependencies
+ - @0xsequence/abi@1.10.9
+ - @0xsequence/core@1.10.9
+ - @0xsequence/migration@1.10.9
+ - @0xsequence/network@1.10.9
+ - @0xsequence/relayer@1.10.9
+ - @0xsequence/sessions@1.10.9
+ - @0xsequence/utils@1.10.9
+ - @0xsequence/wallet@1.10.9
+
+## 1.10.8
+
+### Patch Changes
+
+- update metadata bindings
+- Updated dependencies
+ - @0xsequence/abi@1.10.8
+ - @0xsequence/core@1.10.8
+ - @0xsequence/migration@1.10.8
+ - @0xsequence/network@1.10.8
+ - @0xsequence/relayer@1.10.8
+ - @0xsequence/sessions@1.10.8
+ - @0xsequence/utils@1.10.8
+ - @0xsequence/wallet@1.10.8
+
+## 1.10.7
+
+### Patch Changes
+
+- minor fixes to waas client
+- Updated dependencies
+ - @0xsequence/abi@1.10.7
+ - @0xsequence/core@1.10.7
+ - @0xsequence/migration@1.10.7
+ - @0xsequence/network@1.10.7
+ - @0xsequence/relayer@1.10.7
+ - @0xsequence/sessions@1.10.7
+ - @0xsequence/utils@1.10.7
+ - @0xsequence/wallet@1.10.7
+
+## 1.10.6
+
+### Patch Changes
+
+- metadata: update bindings
+- Updated dependencies
+ - @0xsequence/abi@1.10.6
+ - @0xsequence/core@1.10.6
+ - @0xsequence/migration@1.10.6
+ - @0xsequence/network@1.10.6
+ - @0xsequence/relayer@1.10.6
+ - @0xsequence/sessions@1.10.6
+ - @0xsequence/utils@1.10.6
+ - @0xsequence/wallet@1.10.6
+
+## 1.10.5
+
+### Patch Changes
+
+- network: ape-chain-testnet -> apechain-testnet
+- Updated dependencies
+ - @0xsequence/abi@1.10.5
+ - @0xsequence/core@1.10.5
+ - @0xsequence/migration@1.10.5
+ - @0xsequence/network@1.10.5
+ - @0xsequence/relayer@1.10.5
+ - @0xsequence/sessions@1.10.5
+ - @0xsequence/utils@1.10.5
+ - @0xsequence/wallet@1.10.5
+
+## 1.10.4
+
+### Patch Changes
+
+- network: add b3-sepolia, ape-chain-testnet, blast, blast-sepolia
+- Updated dependencies
+ - @0xsequence/abi@1.10.4
+ - @0xsequence/core@1.10.4
+ - @0xsequence/migration@1.10.4
+ - @0xsequence/network@1.10.4
+ - @0xsequence/relayer@1.10.4
+ - @0xsequence/sessions@1.10.4
+ - @0xsequence/utils@1.10.4
+ - @0xsequence/wallet@1.10.4
+
+## 1.10.3
+
+### Patch Changes
+
+- typing fix
+- Updated dependencies
+ - @0xsequence/abi@1.10.3
+ - @0xsequence/core@1.10.3
+ - @0xsequence/migration@1.10.3
+ - @0xsequence/network@1.10.3
+ - @0xsequence/relayer@1.10.3
+ - @0xsequence/sessions@1.10.3
+ - @0xsequence/utils@1.10.3
+ - @0xsequence/wallet@1.10.3
+
+## 1.10.2
+
+### Patch Changes
+
+- - waas: add getIdToken method
+ - indexer: update api client
+- Updated dependencies
+ - @0xsequence/abi@1.10.2
+ - @0xsequence/core@1.10.2
+ - @0xsequence/migration@1.10.2
+ - @0xsequence/network@1.10.2
+ - @0xsequence/relayer@1.10.2
+ - @0xsequence/sessions@1.10.2
+ - @0xsequence/utils@1.10.2
+ - @0xsequence/wallet@1.10.2
+
+## 1.10.1
+
+### Patch Changes
+
+- metadata: update bindings
+- Updated dependencies
+ - @0xsequence/abi@1.10.1
+ - @0xsequence/core@1.10.1
+ - @0xsequence/migration@1.10.1
+ - @0xsequence/network@1.10.1
+ - @0xsequence/relayer@1.10.1
+ - @0xsequence/sessions@1.10.1
+ - @0xsequence/utils@1.10.1
+ - @0xsequence/wallet@1.10.1
+
+## 1.10.0
+
+### Minor Changes
+
+- waas release v1.3.0
+
+### Patch Changes
+
+- Updated dependencies
+ - @0xsequence/abi@1.10.0
+ - @0xsequence/core@1.10.0
+ - @0xsequence/migration@1.10.0
+ - @0xsequence/network@1.10.0
+ - @0xsequence/relayer@1.10.0
+ - @0xsequence/sessions@1.10.0
+ - @0xsequence/utils@1.10.0
+ - @0xsequence/wallet@1.10.0
+
+## 1.9.37
+
+### Patch Changes
+
+- network: adds nativeToken data to NetworkMetadata constants
+- Updated dependencies
+ - @0xsequence/abi@1.9.37
+ - @0xsequence/core@1.9.37
+ - @0xsequence/migration@1.9.37
+ - @0xsequence/network@1.9.37
+ - @0xsequence/relayer@1.9.37
+ - @0xsequence/sessions@1.9.37
+ - @0xsequence/utils@1.9.37
+ - @0xsequence/wallet@1.9.37
+
+## 1.9.36
+
+### Patch Changes
+
+- guard: export client
+- Updated dependencies
+ - @0xsequence/abi@1.9.36
+ - @0xsequence/core@1.9.36
+ - @0xsequence/migration@1.9.36
+ - @0xsequence/network@1.9.36
+ - @0xsequence/relayer@1.9.36
+ - @0xsequence/sessions@1.9.36
+ - @0xsequence/utils@1.9.36
+ - @0xsequence/wallet@1.9.36
+
+## 1.9.35
+
+### Patch Changes
+
+- guard: update bindings
+- Updated dependencies
+ - @0xsequence/abi@1.9.35
+ - @0xsequence/core@1.9.35
+ - @0xsequence/migration@1.9.35
+ - @0xsequence/network@1.9.35
+ - @0xsequence/relayer@1.9.35
+ - @0xsequence/sessions@1.9.35
+ - @0xsequence/utils@1.9.35
+ - @0xsequence/wallet@1.9.35
+
+## 1.9.34
+
+### Patch Changes
+
+- waas: always use lowercase email
+- Updated dependencies
+ - @0xsequence/abi@1.9.34
+ - @0xsequence/core@1.9.34
+ - @0xsequence/migration@1.9.34
+ - @0xsequence/network@1.9.34
+ - @0xsequence/relayer@1.9.34
+ - @0xsequence/sessions@1.9.34
+ - @0xsequence/utils@1.9.34
+ - @0xsequence/wallet@1.9.34
+
+## 1.9.33
+
+### Patch Changes
+
+- waas: umd build
+- Updated dependencies
+ - @0xsequence/abi@1.9.33
+ - @0xsequence/core@1.9.33
+ - @0xsequence/migration@1.9.33
+ - @0xsequence/network@1.9.33
+ - @0xsequence/relayer@1.9.33
+ - @0xsequence/sessions@1.9.33
+ - @0xsequence/utils@1.9.33
+ - @0xsequence/wallet@1.9.33
+
+## 1.9.32
+
+### Patch Changes
+
+- indexer: update bindings
+- Updated dependencies
+ - @0xsequence/abi@1.9.32
+ - @0xsequence/core@1.9.32
+ - @0xsequence/migration@1.9.32
+ - @0xsequence/network@1.9.32
+ - @0xsequence/relayer@1.9.32
+ - @0xsequence/sessions@1.9.32
+ - @0xsequence/utils@1.9.32
+ - @0xsequence/wallet@1.9.32
+
+## 1.9.31
+
+### Patch Changes
+
+- metadata: token directory changes
+- Updated dependencies
+ - @0xsequence/abi@1.9.31
+ - @0xsequence/core@1.9.31
+ - @0xsequence/migration@1.9.31
+ - @0xsequence/network@1.9.31
+ - @0xsequence/relayer@1.9.31
+ - @0xsequence/sessions@1.9.31
+ - @0xsequence/utils@1.9.31
+ - @0xsequence/wallet@1.9.31
+
+## 1.9.30
+
+### Patch Changes
+
+- update
+- Updated dependencies
+ - @0xsequence/abi@1.9.30
+ - @0xsequence/core@1.9.30
+ - @0xsequence/migration@1.9.30
+ - @0xsequence/network@1.9.30
+ - @0xsequence/relayer@1.9.30
+ - @0xsequence/sessions@1.9.30
+ - @0xsequence/utils@1.9.30
+ - @0xsequence/wallet@1.9.30
+
+## 1.9.29
+
+### Patch Changes
+
+- disable gnosis chain
+- Updated dependencies
+ - @0xsequence/abi@1.9.29
+ - @0xsequence/core@1.9.29
+ - @0xsequence/migration@1.9.29
+ - @0xsequence/network@1.9.29
+ - @0xsequence/relayer@1.9.29
+ - @0xsequence/sessions@1.9.29
+ - @0xsequence/utils@1.9.29
+ - @0xsequence/wallet@1.9.29
+
+## 1.9.28
+
+### Patch Changes
+
+- add utils/merkletree
+- Updated dependencies
+ - @0xsequence/abi@1.9.28
+ - @0xsequence/core@1.9.28
+ - @0xsequence/migration@1.9.28
+ - @0xsequence/network@1.9.28
+ - @0xsequence/relayer@1.9.28
+ - @0xsequence/sessions@1.9.28
+ - @0xsequence/utils@1.9.28
+ - @0xsequence/wallet@1.9.28
+
+## 1.9.27
+
+### Patch Changes
+
+- network: optimistic -> optimism
+- waas: remove defaults
+- api, sessions: update bindings
+- Updated dependencies
+- Updated dependencies
+- Updated dependencies
+ - @0xsequence/abi@1.9.27
+ - @0xsequence/core@1.9.27
+ - @0xsequence/migration@1.9.27
+ - @0xsequence/network@1.9.27
+ - @0xsequence/relayer@1.9.27
+ - @0xsequence/sessions@1.9.27
+ - @0xsequence/utils@1.9.27
+ - @0xsequence/wallet@1.9.27
+
+## 1.9.26
+
+### Patch Changes
+
+- - add backend interfaces for pluggable interfaces
+ - introduce @0xsequence/react-native
+ - update pnpm to lockfile v9
+- Updated dependencies
+ - @0xsequence/abi@1.9.26
+ - @0xsequence/core@1.9.26
+ - @0xsequence/migration@1.9.26
+ - @0xsequence/network@1.9.26
+ - @0xsequence/relayer@1.9.26
+ - @0xsequence/sessions@1.9.26
+ - @0xsequence/utils@1.9.26
+ - @0xsequence/wallet@1.9.26
+
+## 1.9.25
+
+### Patch Changes
+
+- update webrpc clients with new error types
+- Updated dependencies
+ - @0xsequence/abi@1.9.25
+ - @0xsequence/core@1.9.25
+ - @0xsequence/migration@1.9.25
+ - @0xsequence/network@1.9.25
+ - @0xsequence/relayer@1.9.25
+ - @0xsequence/sessions@1.9.25
+ - @0xsequence/utils@1.9.25
+ - @0xsequence/wallet@1.9.25
+
+## 1.9.24
+
+### Patch Changes
+
+- waas: add memoryStore backend to localStore
+- Updated dependencies
+ - @0xsequence/abi@1.9.24
+ - @0xsequence/core@1.9.24
+ - @0xsequence/migration@1.9.24
+ - @0xsequence/network@1.9.24
+ - @0xsequence/relayer@1.9.24
+ - @0xsequence/sessions@1.9.24
+ - @0xsequence/utils@1.9.24
+ - @0xsequence/wallet@1.9.24
+
+## 1.9.23
+
+### Patch Changes
+
+- update api client bindings
+- Updated dependencies
+ - @0xsequence/abi@1.9.23
+ - @0xsequence/core@1.9.23
+ - @0xsequence/migration@1.9.23
+ - @0xsequence/network@1.9.23
+ - @0xsequence/relayer@1.9.23
+ - @0xsequence/sessions@1.9.23
+ - @0xsequence/utils@1.9.23
+ - @0xsequence/wallet@1.9.23
+
+## 1.9.22
+
+### Patch Changes
+
+- update metadata client bindings
+- Updated dependencies
+ - @0xsequence/abi@1.9.22
+ - @0xsequence/core@1.9.22
+ - @0xsequence/migration@1.9.22
+ - @0xsequence/network@1.9.22
+ - @0xsequence/relayer@1.9.22
+ - @0xsequence/sessions@1.9.22
+ - @0xsequence/utils@1.9.22
+ - @0xsequence/wallet@1.9.22
+
+## 1.9.21
+
+### Patch Changes
+
+- api client bindings
+- Updated dependencies
+ - @0xsequence/abi@1.9.21
+ - @0xsequence/core@1.9.21
+ - @0xsequence/migration@1.9.21
+ - @0xsequence/network@1.9.21
+ - @0xsequence/relayer@1.9.21
+ - @0xsequence/sessions@1.9.21
+ - @0xsequence/utils@1.9.21
+ - @0xsequence/wallet@1.9.21
+
+## 1.9.20
+
+### Patch Changes
+
+- api client bindings update
+- Updated dependencies
+ - @0xsequence/abi@1.9.20
+ - @0xsequence/core@1.9.20
+ - @0xsequence/migration@1.9.20
+ - @0xsequence/network@1.9.20
+ - @0xsequence/relayer@1.9.20
+ - @0xsequence/sessions@1.9.20
+ - @0xsequence/utils@1.9.20
+ - @0xsequence/wallet@1.9.20
+
+## 1.9.19
+
+### Patch Changes
+
+- waas update
+- Updated dependencies
+ - @0xsequence/abi@1.9.19
+ - @0xsequence/core@1.9.19
+ - @0xsequence/migration@1.9.19
+ - @0xsequence/network@1.9.19
+ - @0xsequence/relayer@1.9.19
+ - @0xsequence/sessions@1.9.19
+ - @0xsequence/utils@1.9.19
+ - @0xsequence/wallet@1.9.19
+
+## 1.9.18
+
+### Patch Changes
+
+- provider: prohibit dangerous functions
+- Updated dependencies
+ - @0xsequence/abi@1.9.18
+ - @0xsequence/core@1.9.18
+ - @0xsequence/migration@1.9.18
+ - @0xsequence/network@1.9.18
+ - @0xsequence/relayer@1.9.18
+ - @0xsequence/sessions@1.9.18
+ - @0xsequence/utils@1.9.18
+ - @0xsequence/wallet@1.9.18
+
+## 1.9.17
+
+### Patch Changes
+
+- network: add xr-sepolia
+- Updated dependencies
+ - @0xsequence/network@1.9.17
+ - @0xsequence/abi@1.9.17
+ - @0xsequence/core@1.9.17
+ - @0xsequence/migration@1.9.17
+ - @0xsequence/relayer@1.9.17
+ - @0xsequence/sessions@1.9.17
+ - @0xsequence/utils@1.9.17
+ - @0xsequence/wallet@1.9.17
+
+## 1.9.16
+
+### Patch Changes
+
+- waas: sequence.feeOptions
+- Updated dependencies
+ - @0xsequence/abi@1.9.16
+ - @0xsequence/core@1.9.16
+ - @0xsequence/migration@1.9.16
+ - @0xsequence/network@1.9.16
+ - @0xsequence/relayer@1.9.16
+ - @0xsequence/sessions@1.9.16
+ - @0xsequence/utils@1.9.16
+ - @0xsequence/wallet@1.9.16
+
+## 1.9.15
+
+### Patch Changes
+
+- metadata: collection external_link field name fix
+- Updated dependencies
+ - @0xsequence/abi@1.9.15
+ - @0xsequence/core@1.9.15
+ - @0xsequence/migration@1.9.15
+ - @0xsequence/network@1.9.15
+ - @0xsequence/relayer@1.9.15
+ - @0xsequence/sessions@1.9.15
+ - @0xsequence/utils@1.9.15
+ - @0xsequence/wallet@1.9.15
+
+## 1.9.14
+
+### Patch Changes
+
+- network: astar-zkatana -> astar-zkyoto
+- network: deprecate polygon mumbai network
+- network: add xai and polygon amoy
+- Updated dependencies
+- Updated dependencies
+- Updated dependencies
+ - @0xsequence/abi@1.9.14
+ - @0xsequence/core@1.9.14
+ - @0xsequence/migration@1.9.14
+ - @0xsequence/network@1.9.14
+ - @0xsequence/relayer@1.9.14
+ - @0xsequence/sessions@1.9.14
+ - @0xsequence/utils@1.9.14
+ - @0xsequence/wallet@1.9.14
+
+## 1.9.13
+
+### Patch Changes
+
+- waas: fix @0xsequence/network dependency
+- Updated dependencies
+ - @0xsequence/abi@1.9.13
+ - @0xsequence/core@1.9.13
+ - @0xsequence/migration@1.9.13
+ - @0xsequence/network@1.9.13
+ - @0xsequence/relayer@1.9.13
+ - @0xsequence/sessions@1.9.13
+ - @0xsequence/utils@1.9.13
+ - @0xsequence/wallet@1.9.13
+
+## 1.9.12
+
+### Patch Changes
+
+- indexer: update rpc bindings
+- provider: signMessage: Serialize the BytesLike or string message into hexstring before sending
+- waas: SessionAuthProof
+- Updated dependencies
+- Updated dependencies
+- Updated dependencies
+ - @0xsequence/abi@1.9.12
+ - @0xsequence/core@1.9.12
+ - @0xsequence/migration@1.9.12
+ - @0xsequence/network@1.9.12
+ - @0xsequence/relayer@1.9.12
+ - @0xsequence/sessions@1.9.12
+ - @0xsequence/utils@1.9.12
+ - @0xsequence/wallet@1.9.12
+
+## 1.9.11
+
+### Patch Changes
+
+- metdata, update rpc bindings
+- Updated dependencies
+ - @0xsequence/abi@1.9.11
+ - @0xsequence/core@1.9.11
+ - @0xsequence/migration@1.9.11
+ - @0xsequence/network@1.9.11
+ - @0xsequence/relayer@1.9.11
+ - @0xsequence/sessions@1.9.11
+ - @0xsequence/utils@1.9.11
+ - @0xsequence/wallet@1.9.11
+
+## 1.9.10
+
+### Patch Changes
+
+- update metadata rpc bindings
+- Updated dependencies
+ - @0xsequence/abi@1.9.10
+ - @0xsequence/core@1.9.10
+ - @0xsequence/migration@1.9.10
+ - @0xsequence/network@1.9.10
+ - @0xsequence/relayer@1.9.10
+ - @0xsequence/sessions@1.9.10
+ - @0xsequence/utils@1.9.10
+ - @0xsequence/wallet@1.9.10
+
+## 1.9.9
+
+### Patch Changes
+
+- metadata, add SequenceCollections rpc client
+- Updated dependencies
+ - @0xsequence/abi@1.9.9
+ - @0xsequence/core@1.9.9
+ - @0xsequence/migration@1.9.9
+ - @0xsequence/network@1.9.9
+ - @0xsequence/relayer@1.9.9
+ - @0xsequence/sessions@1.9.9
+ - @0xsequence/utils@1.9.9
+ - @0xsequence/wallet@1.9.9
+
+## 1.9.8
+
+### Patch Changes
+
+- waas client update
+- Updated dependencies
+ - @0xsequence/abi@1.9.8
+ - @0xsequence/core@1.9.8
+ - @0xsequence/migration@1.9.8
+ - @0xsequence/network@1.9.8
+ - @0xsequence/relayer@1.9.8
+ - @0xsequence/sessions@1.9.8
+ - @0xsequence/utils@1.9.8
+ - @0xsequence/wallet@1.9.8
+
+## 1.9.7
+
+### Patch Changes
+
+- update rpc client bindings for api, metadata and relayer
+- Updated dependencies
+ - @0xsequence/abi@1.9.7
+ - @0xsequence/core@1.9.7
+ - @0xsequence/migration@1.9.7
+ - @0xsequence/network@1.9.7
+ - @0xsequence/relayer@1.9.7
+ - @0xsequence/sessions@1.9.7
+ - @0xsequence/utils@1.9.7
+ - @0xsequence/wallet@1.9.7
+
+## 1.9.6
+
+### Patch Changes
+
+- waas package update
+- Updated dependencies
+ - @0xsequence/abi@1.9.6
+ - @0xsequence/core@1.9.6
+ - @0xsequence/migration@1.9.6
+ - @0xsequence/network@1.9.6
+ - @0xsequence/relayer@1.9.6
+ - @0xsequence/sessions@1.9.6
+ - @0xsequence/utils@1.9.6
+ - @0xsequence/wallet@1.9.6
+
+## 1.9.5
+
+### Patch Changes
+
+- RpcRelayer prioritize project access key
+- Updated dependencies
+ - @0xsequence/abi@1.9.5
+ - @0xsequence/core@1.9.5
+ - @0xsequence/migration@1.9.5
+ - @0xsequence/network@1.9.5
+ - @0xsequence/relayer@1.9.5
+ - @0xsequence/sessions@1.9.5
+ - @0xsequence/utils@1.9.5
+ - @0xsequence/wallet@1.9.5
+
+## 1.9.4
+
+### Patch Changes
+
+- waas: fix network dependency
+- Updated dependencies
+ - @0xsequence/abi@1.9.4
+ - @0xsequence/core@1.9.4
+ - @0xsequence/migration@1.9.4
+ - @0xsequence/network@1.9.4
+ - @0xsequence/relayer@1.9.4
+ - @0xsequence/sessions@1.9.4
+ - @0xsequence/utils@1.9.4
+ - @0xsequence/wallet@1.9.4
+
+## 1.9.3
+
+### Patch Changes
+
+- provider: don't append access key to RPC url if user has already provided it
+- Updated dependencies
+ - @0xsequence/abi@1.9.3
+ - @0xsequence/core@1.9.3
+ - @0xsequence/migration@1.9.3
+ - @0xsequence/network@1.9.3
+ - @0xsequence/relayer@1.9.3
+ - @0xsequence/sessions@1.9.3
+ - @0xsequence/utils@1.9.3
+ - @0xsequence/wallet@1.9.3
+
+## 1.9.2
+
+### Patch Changes
+
+- network: add xai-sepolia
+- Updated dependencies
+ - @0xsequence/abi@1.9.2
+ - @0xsequence/core@1.9.2
+ - @0xsequence/migration@1.9.2
+ - @0xsequence/network@1.9.2
+ - @0xsequence/relayer@1.9.2
+ - @0xsequence/sessions@1.9.2
+ - @0xsequence/utils@1.9.2
+ - @0xsequence/wallet@1.9.2
+
+## 1.9.1
+
+### Patch Changes
+
+- analytics fix
+- Updated dependencies
+ - @0xsequence/abi@1.9.1
+ - @0xsequence/core@1.9.1
+ - @0xsequence/migration@1.9.1
+ - @0xsequence/network@1.9.1
+ - @0xsequence/relayer@1.9.1
+ - @0xsequence/sessions@1.9.1
+ - @0xsequence/utils@1.9.1
+ - @0xsequence/wallet@1.9.1
+
+## 1.9.0
+
+### Minor Changes
+
+- waas release
+
+### Patch Changes
+
+- Updated dependencies
+ - @0xsequence/abi@1.9.0
+ - @0xsequence/core@1.9.0
+ - @0xsequence/migration@1.9.0
+ - @0xsequence/network@1.9.0
+ - @0xsequence/relayer@1.9.0
+ - @0xsequence/sessions@1.9.0
+ - @0xsequence/utils@1.9.0
+ - @0xsequence/wallet@1.9.0
+
+## 1.8.8
+
+### Patch Changes
+
+- update metadata bindings
+- Updated dependencies
+ - @0xsequence/abi@1.8.8
+ - @0xsequence/core@1.8.8
+ - @0xsequence/migration@1.8.8
+ - @0xsequence/network@1.8.8
+ - @0xsequence/relayer@1.8.8
+ - @0xsequence/sessions@1.8.8
+ - @0xsequence/utils@1.8.8
+ - @0xsequence/wallet@1.8.8
+
+## 1.8.7
+
+### Patch Changes
+
+- provider: update databeat to 0.9.1
+- Updated dependencies
+ - @0xsequence/abi@1.8.7
+ - @0xsequence/core@1.8.7
+ - @0xsequence/migration@1.8.7
+ - @0xsequence/network@1.8.7
+ - @0xsequence/relayer@1.8.7
+ - @0xsequence/sessions@1.8.7
+ - @0xsequence/utils@1.8.7
+ - @0xsequence/wallet@1.8.7
+
+## 1.8.6
+
+### Patch Changes
+
+- guard: SignedOwnershipProof
+- Updated dependencies
+ - @0xsequence/abi@1.8.6
+ - @0xsequence/core@1.8.6
+ - @0xsequence/migration@1.8.6
+ - @0xsequence/network@1.8.6
+ - @0xsequence/relayer@1.8.6
+ - @0xsequence/sessions@1.8.6
+ - @0xsequence/utils@1.8.6
+ - @0xsequence/wallet@1.8.6
+
+## 1.8.5
+
+### Patch Changes
+
+- guard: signOwnershipProof and isSignedOwnershipProof
+- Updated dependencies
+ - @0xsequence/abi@1.8.5
+ - @0xsequence/core@1.8.5
+ - @0xsequence/migration@1.8.5
+ - @0xsequence/network@1.8.5
+ - @0xsequence/relayer@1.8.5
+ - @0xsequence/sessions@1.8.5
+ - @0xsequence/utils@1.8.5
+ - @0xsequence/wallet@1.8.5
+
+## 1.8.4
+
+### Patch Changes
+
+- network: add homeverse to networks list
+- Updated dependencies
+ - @0xsequence/abi@1.8.4
+ - @0xsequence/core@1.8.4
+ - @0xsequence/migration@1.8.4
+ - @0xsequence/network@1.8.4
+ - @0xsequence/relayer@1.8.4
+ - @0xsequence/sessions@1.8.4
+ - @0xsequence/utils@1.8.4
+ - @0xsequence/wallet@1.8.4
+
+## 1.8.3
+
+### Patch Changes
+
+- api: introduce basic linked wallet support
+- Updated dependencies
+ - @0xsequence/abi@1.8.3
+ - @0xsequence/core@1.8.3
+ - @0xsequence/migration@1.8.3
+ - @0xsequence/network@1.8.3
+ - @0xsequence/relayer@1.8.3
+ - @0xsequence/sessions@1.8.3
+ - @0xsequence/utils@1.8.3
+ - @0xsequence/wallet@1.8.3
+
+## 1.8.2
+
+### Patch Changes
+
+- provider: don't initialize analytics unless explicitly requested
+- Updated dependencies
+ - @0xsequence/abi@1.8.2
+ - @0xsequence/core@1.8.2
+ - @0xsequence/migration@1.8.2
+ - @0xsequence/network@1.8.2
+ - @0xsequence/relayer@1.8.2
+ - @0xsequence/sessions@1.8.2
+ - @0xsequence/utils@1.8.2
+ - @0xsequence/wallet@1.8.2
+
+## 1.8.1
+
+### Patch Changes
+
+- update to analytics provider
+- Updated dependencies
+ - @0xsequence/abi@1.8.1
+ - @0xsequence/core@1.8.1
+ - @0xsequence/migration@1.8.1
+ - @0xsequence/network@1.8.1
+ - @0xsequence/relayer@1.8.1
+ - @0xsequence/sessions@1.8.1
+ - @0xsequence/utils@1.8.1
+ - @0xsequence/wallet@1.8.1
+
+## 1.8.0
+
+### Minor Changes
+
+- provider: project analytics
+
+### Patch Changes
+
+- Updated dependencies
+ - @0xsequence/abi@1.8.0
+ - @0xsequence/core@1.8.0
+ - @0xsequence/migration@1.8.0
+ - @0xsequence/network@1.8.0
+ - @0xsequence/relayer@1.8.0
+ - @0xsequence/sessions@1.8.0
+ - @0xsequence/utils@1.8.0
+ - @0xsequence/wallet@1.8.0
+
+## 1.7.2
+
+### Patch Changes
+
+- 0xsequence: ChainId should not be exported as a type
+- account, wallet: fix nonce selection
+- Updated dependencies
+- Updated dependencies
+ - @0xsequence/abi@1.7.2
+ - @0xsequence/core@1.7.2
+ - @0xsequence/migration@1.7.2
+ - @0xsequence/network@1.7.2
+ - @0xsequence/relayer@1.7.2
+ - @0xsequence/sessions@1.7.2
+ - @0xsequence/utils@1.7.2
+ - @0xsequence/wallet@1.7.2
+
+## 1.7.1
+
+### Patch Changes
+
+- network: add missing avalanche logoURI
+- Updated dependencies
+ - @0xsequence/abi@1.7.1
+ - @0xsequence/core@1.7.1
+ - @0xsequence/migration@1.7.1
+ - @0xsequence/network@1.7.1
+ - @0xsequence/relayer@1.7.1
+ - @0xsequence/sessions@1.7.1
+ - @0xsequence/utils@1.7.1
+ - @0xsequence/wallet@1.7.1
+
+## 1.7.0
+
+### Minor Changes
+
+- provider: projectAccessKey is now required
+
+### Patch Changes
+
+- network: add NetworkMetadata.logoURI property for all networks
+- Updated dependencies
+- Updated dependencies
+ - @0xsequence/abi@1.7.0
+ - @0xsequence/core@1.7.0
+ - @0xsequence/migration@1.7.0
+ - @0xsequence/network@1.7.0
+ - @0xsequence/relayer@1.7.0
+ - @0xsequence/sessions@1.7.0
+ - @0xsequence/utils@1.7.0
+ - @0xsequence/wallet@1.7.0
+
+## 1.6.3
+
+### Patch Changes
+
+- network list update
+- Updated dependencies
+ - @0xsequence/abi@1.6.3
+ - @0xsequence/core@1.6.3
+ - @0xsequence/migration@1.6.3
+ - @0xsequence/network@1.6.3
+ - @0xsequence/relayer@1.6.3
+ - @0xsequence/sessions@1.6.3
+ - @0xsequence/utils@1.6.3
+ - @0xsequence/wallet@1.6.3
+
+## 1.6.2
+
+### Patch Changes
+
+- auth: projectAccessKey option
+- wallet: use 12 bytes for random space
+- Updated dependencies
+- Updated dependencies
+ - @0xsequence/abi@1.6.2
+ - @0xsequence/core@1.6.2
+ - @0xsequence/migration@1.6.2
+ - @0xsequence/network@1.6.2
+ - @0xsequence/relayer@1.6.2
+ - @0xsequence/sessions@1.6.2
+ - @0xsequence/utils@1.6.2
+ - @0xsequence/wallet@1.6.2
+
+## 1.6.1
+
+### Patch Changes
+
+- core: add simple config from subdigest support
+- core: fix encode tree with subdigest
+- account: implement buildOnChainSignature on Account
+- Updated dependencies
+- Updated dependencies
+- Updated dependencies
+ - @0xsequence/abi@1.6.1
+ - @0xsequence/core@1.6.1
+ - @0xsequence/migration@1.6.1
+ - @0xsequence/network@1.6.1
+ - @0xsequence/relayer@1.6.1
+ - @0xsequence/sessions@1.6.1
+ - @0xsequence/utils@1.6.1
+ - @0xsequence/wallet@1.6.1
+
+## 1.6.0
+
+### Minor Changes
+
+- account, wallet: parallel transactions by default
+
+### Patch Changes
+
+- provider: emit disconnect on sign out
+- Updated dependencies
+- Updated dependencies
+ - @0xsequence/core@1.6.0
+ - @0xsequence/migration@1.6.0
+ - @0xsequence/network@1.6.0
+ - @0xsequence/relayer@1.6.0
+ - @0xsequence/sessions@1.6.0
+ - @0xsequence/utils@1.6.0
+ - @0xsequence/wallet@1.6.0
+
+## 1.5.0
+
+### Minor Changes
+
+- signhub: add 'signing' signer status
+
+### Patch Changes
+
+- auth: Session.open: onAccountAddress callback
+- account: allow empty transaction bundles
+- Updated dependencies
+- Updated dependencies
+- Updated dependencies
+ - @0xsequence/core@1.5.0
+ - @0xsequence/migration@1.5.0
+ - @0xsequence/network@1.5.0
+ - @0xsequence/relayer@1.5.0
+ - @0xsequence/sessions@1.5.0
+ - @0xsequence/utils@1.5.0
+ - @0xsequence/wallet@1.5.0
+
+## 1.4.9
+
+### Patch Changes
+
+- rename SequenceMetadataClient to SequenceMetadata
+- Updated dependencies
+ - @0xsequence/core@1.4.9
+ - @0xsequence/migration@1.4.9
+ - @0xsequence/network@1.4.9
+ - @0xsequence/relayer@1.4.9
+ - @0xsequence/sessions@1.4.9
+ - @0xsequence/utils@1.4.9
+ - @0xsequence/wallet@1.4.9
+
+## 1.4.8
+
+### Patch Changes
+
+- account: Account.getSigners
+- Updated dependencies
+ - @0xsequence/core@1.4.8
+ - @0xsequence/migration@1.4.8
+ - @0xsequence/network@1.4.8
+ - @0xsequence/relayer@1.4.8
+ - @0xsequence/sessions@1.4.8
+ - @0xsequence/utils@1.4.8
+ - @0xsequence/wallet@1.4.8
+
+## 1.4.7
+
+### Patch Changes
+
+- update indexer client bindings
+- Updated dependencies
+ - @0xsequence/core@1.4.7
+ - @0xsequence/migration@1.4.7
+ - @0xsequence/network@1.4.7
+ - @0xsequence/relayer@1.4.7
+ - @0xsequence/sessions@1.4.7
+ - @0xsequence/utils@1.4.7
+ - @0xsequence/wallet@1.4.7
+
+## 1.4.6
+
+### Patch Changes
+
+- - add sepolia networks, mark goerli as deprecated
+ - update indexer client bindings
+- Updated dependencies
+ - @0xsequence/core@1.4.6
+ - @0xsequence/migration@1.4.6
+ - @0xsequence/network@1.4.6
+ - @0xsequence/relayer@1.4.6
+ - @0xsequence/sessions@1.4.6
+ - @0xsequence/utils@1.4.6
+ - @0xsequence/wallet@1.4.6
+
+## 1.4.5
+
+### Patch Changes
+
+- indexer/metadata: update client bindings
+- auth: selectWallet with new address
+- Updated dependencies
+- Updated dependencies
+ - @0xsequence/core@1.4.5
+ - @0xsequence/migration@1.4.5
+ - @0xsequence/network@1.4.5
+ - @0xsequence/relayer@1.4.5
+ - @0xsequence/sessions@1.4.5
+ - @0xsequence/utils@1.4.5
+ - @0xsequence/wallet@1.4.5
+
+## 1.4.4
+
+### Patch Changes
+
+- indexer: update bindings
+- auth: handle jwt expiry
+- Updated dependencies
+- Updated dependencies
+ - @0xsequence/core@1.4.4
+ - @0xsequence/migration@1.4.4
+ - @0xsequence/network@1.4.4
+ - @0xsequence/relayer@1.4.4
+ - @0xsequence/sessions@1.4.4
+ - @0xsequence/utils@1.4.4
+ - @0xsequence/wallet@1.4.4
+
+## 1.4.3
+
+### Patch Changes
+
+- guard: return active status from GuardSigner.getAuthMethods
+- Updated dependencies
+ - @0xsequence/core@1.4.3
+ - @0xsequence/migration@1.4.3
+ - @0xsequence/network@1.4.3
+ - @0xsequence/relayer@1.4.3
+ - @0xsequence/sessions@1.4.3
+ - @0xsequence/utils@1.4.3
+ - @0xsequence/wallet@1.4.3
+
+## 1.4.2
+
+### Patch Changes
+
+- guard: update bindings
+- Updated dependencies
+ - @0xsequence/core@1.4.2
+ - @0xsequence/migration@1.4.2
+ - @0xsequence/network@1.4.2
+ - @0xsequence/relayer@1.4.2
+ - @0xsequence/sessions@1.4.2
+ - @0xsequence/utils@1.4.2
+ - @0xsequence/wallet@1.4.2
+
+## 1.4.1
+
+### Patch Changes
+
+- network: remove unused networks
+- signhub: orchestrator interface
+- guard: auth methods interface
+- guard: update bindings for pin and totp
+- guard: no more retry logic
+- Updated dependencies
+- Updated dependencies
+- Updated dependencies
+- Updated dependencies
+- Updated dependencies
+ - @0xsequence/core@1.4.1
+ - @0xsequence/migration@1.4.1
+ - @0xsequence/network@1.4.1
+ - @0xsequence/relayer@1.4.1
+ - @0xsequence/sessions@1.4.1
+ - @0xsequence/utils@1.4.1
+ - @0xsequence/wallet@1.4.1
+
+## 1.4.0
+
+### Minor Changes
+
+- project access key support
+
+### Patch Changes
+
+- Updated dependencies
+ - @0xsequence/core@1.4.0
+ - @0xsequence/migration@1.4.0
+ - @0xsequence/network@1.4.0
+ - @0xsequence/relayer@1.4.0
+ - @0xsequence/sessions@1.4.0
+ - @0xsequence/utils@1.4.0
+ - @0xsequence/wallet@1.4.0
+
+## 1.3.0
+
+### Minor Changes
+
+- signhub: account children
+
+### Patch Changes
+
+- guard: do not throw when building deploy transaction
+- network: snowtrace.io -> subnets.avax.network/c-chain
+- Updated dependencies
+- Updated dependencies
+- Updated dependencies
+ - @0xsequence/core@1.3.0
+ - @0xsequence/migration@1.3.0
+ - @0xsequence/network@1.3.0
+ - @0xsequence/relayer@1.3.0
+ - @0xsequence/sessions@1.3.0
+ - @0xsequence/utils@1.3.0
+ - @0xsequence/wallet@1.3.0
+
+## 1.2.9
+
+### Patch Changes
+
+- account: AccountSigner.sendTransaction simulateForFeeOptions
+- relayer: update bindings
+- Updated dependencies
+- Updated dependencies
+ - @0xsequence/core@1.2.9
+ - @0xsequence/migration@1.2.9
+ - @0xsequence/network@1.2.9
+ - @0xsequence/relayer@1.2.9
+ - @0xsequence/sessions@1.2.9
+ - @0xsequence/utils@1.2.9
+ - @0xsequence/wallet@1.2.9
+
+## 1.2.8
+
+### Patch Changes
+
+- rename X-Sequence-Token-Key header to X-Access-Key
+- Updated dependencies
+ - @0xsequence/core@1.2.8
+ - @0xsequence/migration@1.2.8
+ - @0xsequence/network@1.2.8
+ - @0xsequence/relayer@1.2.8
+ - @0xsequence/sessions@1.2.8
+ - @0xsequence/utils@1.2.8
+ - @0xsequence/wallet@1.2.8
+
+## 1.2.7
+
+### Patch Changes
+
+- add x-sequence-token-key to clients
+- Updated dependencies
+ - @0xsequence/core@1.2.7
+ - @0xsequence/migration@1.2.7
+ - @0xsequence/network@1.2.7
+ - @0xsequence/relayer@1.2.7
+ - @0xsequence/sessions@1.2.7
+ - @0xsequence/utils@1.2.7
+ - @0xsequence/wallet@1.2.7
+
+## 1.2.6
+
+### Patch Changes
+
+- Fix bind multicall provider
+- Updated dependencies
+ - @0xsequence/core@1.2.6
+ - @0xsequence/migration@1.2.6
+ - @0xsequence/network@1.2.6
+ - @0xsequence/relayer@1.2.6
+ - @0xsequence/sessions@1.2.6
+ - @0xsequence/utils@1.2.6
+ - @0xsequence/wallet@1.2.6
+
+## 1.2.5
+
+### Patch Changes
+
+- Multicall default configuration fixes
+- Updated dependencies
+ - @0xsequence/core@1.2.5
+ - @0xsequence/migration@1.2.5
+ - @0xsequence/network@1.2.5
+ - @0xsequence/relayer@1.2.5
+ - @0xsequence/sessions@1.2.5
+ - @0xsequence/utils@1.2.5
+ - @0xsequence/wallet@1.2.5
+
+## 1.2.4
+
+### Patch Changes
+
+- provider: Adding missing payment provider types to PaymentProviderOption
+- provider: WalletRequestHandler.notifyChainChanged
+- Updated dependencies
+- Updated dependencies
+ - @0xsequence/core@1.2.4
+ - @0xsequence/migration@1.2.4
+ - @0xsequence/network@1.2.4
+ - @0xsequence/relayer@1.2.4
+ - @0xsequence/sessions@1.2.4
+ - @0xsequence/utils@1.2.4
+ - @0xsequence/wallet@1.2.4
+
+## 1.2.3
+
+### Patch Changes
+
+- auth, provider: connect to accept optional authorizeNonce
+- Updated dependencies
+ - @0xsequence/core@1.2.3
+ - @0xsequence/migration@1.2.3
+ - @0xsequence/network@1.2.3
+ - @0xsequence/relayer@1.2.3
+ - @0xsequence/sessions@1.2.3
+ - @0xsequence/utils@1.2.3
+ - @0xsequence/wallet@1.2.3
+
+## 1.2.2
+
+### Patch Changes
+
+- provider: allow createContract calls
+- core: check for explicit zero address in contract deployments
+- Updated dependencies
+- Updated dependencies
+ - @0xsequence/core@1.2.2
+ - @0xsequence/migration@1.2.2
+ - @0xsequence/network@1.2.2
+ - @0xsequence/relayer@1.2.2
+ - @0xsequence/sessions@1.2.2
+ - @0xsequence/utils@1.2.2
+ - @0xsequence/wallet@1.2.2
+
+## 1.2.1
+
+### Patch Changes
+
+- auth: use sequence api chain id as reference chain id if available
+- Updated dependencies
+ - @0xsequence/core@1.2.1
+ - @0xsequence/migration@1.2.1
+ - @0xsequence/network@1.2.1
+ - @0xsequence/relayer@1.2.1
+ - @0xsequence/sessions@1.2.1
+ - @0xsequence/utils@1.2.1
+ - @0xsequence/wallet@1.2.1
+
+## 1.2.0
+
+### Minor Changes
+
+- split services from session, better local support
+
+### Patch Changes
+
+- Updated dependencies
+ - @0xsequence/core@1.2.0
+ - @0xsequence/migration@1.2.0
+ - @0xsequence/network@1.2.0
+ - @0xsequence/relayer@1.2.0
+ - @0xsequence/sessions@1.2.0
+ - @0xsequence/utils@1.2.0
+ - @0xsequence/wallet@1.2.0
+
+## 1.1.15
+
+### Patch Changes
+
+- guard: remove error filtering
+- Updated dependencies
+ - @0xsequence/core@1.1.15
+ - @0xsequence/migration@1.1.15
+ - @0xsequence/network@1.1.15
+ - @0xsequence/relayer@1.1.15
+ - @0xsequence/sessions@1.1.15
+ - @0xsequence/utils@1.1.15
+ - @0xsequence/wallet@1.1.15
+
+## 1.1.14
+
+### Patch Changes
+
+- guard: add GuardSigner.onError
+- Updated dependencies
+ - @0xsequence/core@1.1.14
+ - @0xsequence/migration@1.1.14
+ - @0xsequence/network@1.1.14
+ - @0xsequence/relayer@1.1.14
+ - @0xsequence/sessions@1.1.14
+ - @0xsequence/utils@1.1.14
+ - @0xsequence/wallet@1.1.14
+
+## 1.1.13
+
+### Patch Changes
+
+- provider: pass client version with connect options
+- provider: removing large from BannerSize
+- Updated dependencies
+- Updated dependencies
+ - @0xsequence/core@1.1.13
+ - @0xsequence/migration@1.1.13
+ - @0xsequence/network@1.1.13
+ - @0xsequence/relayer@1.1.13
+ - @0xsequence/sessions@1.1.13
+ - @0xsequence/utils@1.1.13
+ - @0xsequence/wallet@1.1.13
+
+## 1.1.12
+
+### Patch Changes
+
+- provider: adding bannerSize to ConnectOptions
+- Updated dependencies
+ - @0xsequence/core@1.1.12
+ - @0xsequence/migration@1.1.12
+ - @0xsequence/network@1.1.12
+ - @0xsequence/relayer@1.1.12
+ - @0xsequence/sessions@1.1.12
+ - @0xsequence/utils@1.1.12
+ - @0xsequence/wallet@1.1.12
+
+## 1.1.11
+
+### Patch Changes
+
+- add homeverse configs
+- Updated dependencies
+ - @0xsequence/core@1.1.11
+ - @0xsequence/migration@1.1.11
+ - @0xsequence/network@1.1.11
+ - @0xsequence/relayer@1.1.11
+ - @0xsequence/sessions@1.1.11
+ - @0xsequence/utils@1.1.11
+ - @0xsequence/wallet@1.1.11
+
+## 1.1.10
+
+### Patch Changes
+
+- handle default EIP6492 on send
+- Updated dependencies
+ - @0xsequence/core@1.1.10
+ - @0xsequence/migration@1.1.10
+ - @0xsequence/network@1.1.10
+ - @0xsequence/relayer@1.1.10
+ - @0xsequence/sessions@1.1.10
+ - @0xsequence/utils@1.1.10
+ - @0xsequence/wallet@1.1.10
+
+## 1.1.9
+
+### Patch Changes
+
+- Custom default EIP6492 on client
+- Updated dependencies
+ - @0xsequence/core@1.1.9
+ - @0xsequence/migration@1.1.9
+ - @0xsequence/network@1.1.9
+ - @0xsequence/relayer@1.1.9
+ - @0xsequence/sessions@1.1.9
+ - @0xsequence/utils@1.1.9
+ - @0xsequence/wallet@1.1.9
+
+## 1.1.8
+
+### Patch Changes
+
+- metadata: searchMetadata: add types filter
+- Updated dependencies
+ - @0xsequence/core@1.1.8
+ - @0xsequence/migration@1.1.8
+ - @0xsequence/network@1.1.8
+ - @0xsequence/relayer@1.1.8
+ - @0xsequence/sessions@1.1.8
+ - @0xsequence/utils@1.1.8
+ - @0xsequence/wallet@1.1.8
+
+## 1.1.7
+
+### Patch Changes
+
+- adding signInWith connect settings option to allow dapps to automatically login their users with a certain provider optimizing the normal authentication flow
+- Updated dependencies
+ - @0xsequence/core@1.1.7
+ - @0xsequence/migration@1.1.7
+ - @0xsequence/network@1.1.7
+ - @0xsequence/relayer@1.1.7
+ - @0xsequence/sessions@1.1.7
+ - @0xsequence/utils@1.1.7
+ - @0xsequence/wallet@1.1.7
+
+## 1.1.6
+
+### Patch Changes
+
+- metadata: searchMetadata: add chainID and excludeTokenMetadata filters
+- Updated dependencies
+ - @0xsequence/core@1.1.6
+ - @0xsequence/migration@1.1.6
+ - @0xsequence/network@1.1.6
+ - @0xsequence/relayer@1.1.6
+ - @0xsequence/sessions@1.1.6
+ - @0xsequence/utils@1.1.6
+ - @0xsequence/wallet@1.1.6
+
+## 1.1.5
+
+### Patch Changes
+
+- account: re-compute meta-transaction id for wallet deployment transactions
+- Updated dependencies
+ - @0xsequence/core@1.1.5
+ - @0xsequence/migration@1.1.5
+ - @0xsequence/network@1.1.5
+ - @0xsequence/relayer@1.1.5
+ - @0xsequence/sessions@1.1.5
+ - @0xsequence/utils@1.1.5
+ - @0xsequence/wallet@1.1.5
+
+## 1.1.4
+
+### Patch Changes
+
+- network: rename base-mainnet to base
+- provider: override isDefaultChain with ConnectOptions.networkId if provided
+- Updated dependencies
+- Updated dependencies
+ - @0xsequence/core@1.1.4
+ - @0xsequence/migration@1.1.4
+ - @0xsequence/network@1.1.4
+ - @0xsequence/relayer@1.1.4
+ - @0xsequence/sessions@1.1.4
+ - @0xsequence/utils@1.1.4
+ - @0xsequence/wallet@1.1.4
+
+## 1.1.3
+
+### Patch Changes
+
+- provider: use network id from transport session
+- provider: sign authorization using ConnectOptions.networkId if provided
+- Updated dependencies
+- Updated dependencies
+ - @0xsequence/core@1.1.3
+ - @0xsequence/migration@1.1.3
+ - @0xsequence/network@1.1.3
+ - @0xsequence/relayer@1.1.3
+ - @0xsequence/sessions@1.1.3
+ - @0xsequence/utils@1.1.3
+ - @0xsequence/wallet@1.1.3
+
+## 1.1.2
+
+### Patch Changes
+
+- provider: jsonrpc chain id fixes
+- Updated dependencies
+ - @0xsequence/core@1.1.2
+ - @0xsequence/migration@1.1.2
+ - @0xsequence/network@1.1.2
+ - @0xsequence/relayer@1.1.2
+ - @0xsequence/sessions@1.1.2
+ - @0xsequence/utils@1.1.2
+ - @0xsequence/wallet@1.1.2
+
+## 1.1.1
+
+### Patch Changes
+
+- network: add base mainnet and sepolia
+- provider: reject toxic transaction requests
+- Updated dependencies
+- Updated dependencies
+ - @0xsequence/core@1.1.1
+ - @0xsequence/migration@1.1.1
+ - @0xsequence/network@1.1.1
+ - @0xsequence/relayer@1.1.1
+ - @0xsequence/sessions@1.1.1
+ - @0xsequence/utils@1.1.1
+ - @0xsequence/wallet@1.1.1
+
+## 1.1.0
+
+### Minor Changes
+
+- Refactor dapp facing provider
+
+### Patch Changes
+
+- Updated dependencies
+ - @0xsequence/core@1.1.0
+ - @0xsequence/migration@1.1.0
+ - @0xsequence/network@1.1.0
+ - @0xsequence/relayer@1.1.0
+ - @0xsequence/sessions@1.1.0
+ - @0xsequence/utils@1.1.0
+ - @0xsequence/wallet@1.1.0
+
+## 1.0.5
+
+### Patch Changes
+
+- network: export network constants
+- guard: use the correct global for fetch
+- network: nova-explorer.arbitrum.io -> nova.arbiscan.io
+- Updated dependencies
+- Updated dependencies
+- Updated dependencies
+ - @0xsequence/core@1.0.5
+ - @0xsequence/migration@1.0.5
+ - @0xsequence/network@1.0.5
+ - @0xsequence/relayer@1.0.5
+ - @0xsequence/sessions@1.0.5
+ - @0xsequence/utils@1.0.5
+ - @0xsequence/wallet@1.0.5
+
+## 1.0.4
+
+### Patch Changes
+
+- provider: accept name or number for networkId
+- Updated dependencies
+ - @0xsequence/core@1.0.4
+ - @0xsequence/migration@1.0.4
+ - @0xsequence/network@1.0.4
+ - @0xsequence/relayer@1.0.4
+ - @0xsequence/sessions@1.0.4
+ - @0xsequence/utils@1.0.4
+ - @0xsequence/wallet@1.0.4
+
+## 1.0.3
+
+### Patch Changes
+
+- Simpler isValidSignature helpers
+- Updated dependencies
+ - @0xsequence/core@1.0.3
+ - @0xsequence/migration@1.0.3
+ - @0xsequence/network@1.0.3
+ - @0xsequence/relayer@1.0.3
+ - @0xsequence/sessions@1.0.3
+ - @0xsequence/utils@1.0.3
+ - @0xsequence/wallet@1.0.3
+
+## 1.0.2
+
+### Patch Changes
+
+- add extra signature validation utils methods
+- Updated dependencies
+ - @0xsequence/core@1.0.2
+ - @0xsequence/migration@1.0.2
+ - @0xsequence/network@1.0.2
+ - @0xsequence/relayer@1.0.2
+ - @0xsequence/sessions@1.0.2
+ - @0xsequence/utils@1.0.2
+ - @0xsequence/wallet@1.0.2
+
+## 1.0.1
+
+### Patch Changes
+
+- add homeverse testnet
+- Updated dependencies
+ - @0xsequence/core@1.0.1
+ - @0xsequence/migration@1.0.1
+ - @0xsequence/network@1.0.1
+ - @0xsequence/relayer@1.0.1
+ - @0xsequence/sessions@1.0.1
+ - @0xsequence/utils@1.0.1
+ - @0xsequence/wallet@1.0.1
+
+## 1.0.0
+
+### Major Changes
+
+- https://sequence.xyz/blog/sequence-wallet-light-state-sync-full-merkle-wallets
+
+### Patch Changes
+
+- Updated dependencies
+ - @0xsequence/core@1.0.0
+ - @0xsequence/migration@1.0.0
+ - @0xsequence/network@1.0.0
+ - @0xsequence/relayer@1.0.0
+ - @0xsequence/sessions@1.0.0
+ - @0xsequence/utils@1.0.0
+ - @0xsequence/wallet@1.0.0
diff --git a/packages/account/hardhat.config.js b/packages/account/hardhat.config.js
new file mode 100644
index 0000000000..9e73336b07
--- /dev/null
+++ b/packages/account/hardhat.config.js
@@ -0,0 +1,12 @@
+
+module.exports = {
+ networks: {
+ hardhat: {
+ chainId: 31337,
+ port: 7146,
+ accounts: {
+ mnemonic: 'ripple axis someone ridge uniform wrist prosper there frog rate olympic knee'
+ },
+ },
+ }
+}
diff --git a/packages/account/hardhat2.config.js b/packages/account/hardhat2.config.js
new file mode 100644
index 0000000000..e984fc2e79
--- /dev/null
+++ b/packages/account/hardhat2.config.js
@@ -0,0 +1,11 @@
+
+module.exports = {
+ networks: {
+ hardhat: {
+ chainId: 31338,
+ accounts: {
+ mnemonic: 'ripple axis someone ridge uniform wrist prosper there frog rate olympic knee'
+ }
+ }
+ }
+}
diff --git a/packages/account/package.json b/packages/account/package.json
new file mode 100644
index 0000000000..ddaefabe13
--- /dev/null
+++ b/packages/account/package.json
@@ -0,0 +1,40 @@
+{
+ "name": "@0xsequence/account",
+ "version": "2.0.0",
+ "description": "tools for migrating sequence wallets to new versions",
+ "repository": "https://github.com/0xsequence/sequence.js/tree/master/packages/account",
+ "source": "src/index.ts",
+ "main": "dist/0xsequence-account.cjs.js",
+ "module": "dist/0xsequence-account.esm.js",
+ "author": "Horizon Blockchain Games",
+ "license": "Apache-2.0",
+ "scripts": {
+ "test": "pnpm test:concurrently 'pnpm test:run'",
+ "test:run": "pnpm test:file tests/**/*.spec.ts",
+ "test:file": "TS_NODE_PROJECT=../../tsconfig.test.json mocha -r ts-node/register --timeout 120000",
+ "test:concurrently": "concurrently -k --success first 'pnpm start:hardhat2 > /dev/null'",
+ "start:hardhat2": "hardhat node --hostname 0.0.0.0 --port 7048 --config ./hardhat2.config.js",
+ "test:coverage": "nyc pnpm test"
+ },
+ "dependencies": {
+ "@0xsequence/abi": "workspace:*",
+ "@0xsequence/core": "workspace:*",
+ "@0xsequence/migration": "workspace:*",
+ "@0xsequence/network": "workspace:*",
+ "@0xsequence/relayer": "workspace:*",
+ "@0xsequence/sessions": "workspace:*",
+ "@0xsequence/utils": "workspace:*",
+ "@0xsequence/wallet": "workspace:*",
+ "ethers": "^5.5.2"
+ },
+ "devDependencies": {
+ "@0xsequence/signhub": "workspace:*",
+ "@0xsequence/tests": "workspace:*",
+ "@istanbuljs/nyc-config-typescript": "^1.0.2",
+ "nyc": "^15.1.0"
+ },
+ "files": [
+ "src",
+ "dist"
+ ]
+}
diff --git a/packages/account/src/account.ts b/packages/account/src/account.ts
new file mode 100644
index 0000000000..3243842eb8
--- /dev/null
+++ b/packages/account/src/account.ts
@@ -0,0 +1,1085 @@
+import { walletContracts } from '@0xsequence/abi'
+import { commons, universal } from '@0xsequence/core'
+import { WalletSignRequestMetadata } from '@0xsequence/core/src/commons'
+import { migrator, defaults, version } from '@0xsequence/migration'
+import { ChainId, NetworkConfig } from '@0xsequence/network'
+import { FeeOption, FeeQuote, isRelayer, Relayer, RpcRelayer } from '@0xsequence/relayer'
+import { tracker } from '@0xsequence/sessions'
+import { SignatureOrchestrator } from '@0xsequence/signhub'
+import { encodeTypedDataDigest, getEthersConnectionInfo } from '@0xsequence/utils'
+import { Wallet } from '@0xsequence/wallet'
+import { ethers, TypedDataDomain, TypedDataField } from 'ethers'
+import { AccountSigner, AccountSignerOptions } from './signer'
+
+export type AccountStatus = {
+ original: {
+ version: number
+ imageHash: string
+ context: commons.context.WalletContext
+ }
+ onChain: {
+ imageHash: string
+ config: commons.config.Config
+ version: number
+ deployed: boolean
+ }
+ fullyMigrated: boolean
+ signedMigrations: migrator.SignedMigration[]
+ version: number
+ presignedConfigurations: tracker.PresignedConfigLink[]
+ imageHash: string
+ config: commons.config.Config
+ checkpoint: ethers.BigNumberish
+ canOnchainValidate: boolean
+}
+
+export type AccountOptions = {
+ // The only unique identifier for a wallet is the address
+ address: string
+
+ // The config tracker keeps track of chained configs,
+ // counterfactual addresses and reverse lookups for configurations
+ // it must implement both the ConfigTracker and MigrationTracker
+ tracker: tracker.ConfigTracker & migrator.PresignedMigrationTracker
+
+ // Versioned contexts contains the context information for each Sequence version
+ contexts: commons.context.VersionedContext
+
+ // Optional list of migrations, if not provided, the default migrations will be used
+ // NOTICE: the last vestion is considered the "current" version for the account
+ migrations?: migrator.Migrations
+
+ // Orchestrator manages signing messages and transactions
+ orchestrator: SignatureOrchestrator
+
+ // Networks information and providers
+ networks: NetworkConfig[]
+
+ // Jwt
+ jwt?: string
+
+ // Project access key
+ projectAccessKey?: string
+}
+
+export interface PreparedTransactions {
+ transactions: commons.transaction.SimulatedTransaction[]
+ flatDecorated: commons.transaction.Transaction[]
+ feeOptions: FeeOption[]
+ feeQuote?: FeeQuote
+}
+
+class Chain0Reader implements commons.reader.Reader {
+ async isDeployed(_wallet: string): Promise {
+ return false
+ }
+
+ async implementation(_wallet: string): Promise {
+ return undefined
+ }
+
+ async imageHash(_wallet: string): Promise {
+ return undefined
+ }
+
+ async nonce(_wallet: string, _space: ethers.BigNumberish): Promise {
+ return ethers.constants.Zero
+ }
+
+ async isValidSignature(_wallet: string, _digest: ethers.utils.BytesLike, _signature: ethers.utils.BytesLike): Promise {
+ throw new Error('Method not supported.')
+ }
+}
+
+export class Account {
+ public readonly address: string
+
+ public readonly networks: NetworkConfig[]
+ public readonly tracker: tracker.ConfigTracker & migrator.PresignedMigrationTracker
+ public readonly contexts: commons.context.VersionedContext
+
+ public readonly migrator: migrator.Migrator
+ public readonly migrations: migrator.Migrations
+
+ private orchestrator: SignatureOrchestrator
+
+ private jwt?: string
+
+ private projectAccessKey?: string
+
+ constructor(options: AccountOptions) {
+ this.address = ethers.utils.getAddress(options.address)
+
+ this.contexts = options.contexts
+ this.tracker = options.tracker
+ this.networks = options.networks
+ this.orchestrator = options.orchestrator
+ this.jwt = options.jwt
+ this.projectAccessKey = options.projectAccessKey
+
+ this.migrations = options.migrations || defaults.DefaultMigrations
+ this.migrator = new migrator.Migrator(options.tracker, this.migrations, this.contexts)
+ }
+
+ getSigner(chainId: ChainId, options?: AccountSignerOptions): AccountSigner {
+ return new AccountSigner(this, chainId, options)
+ }
+
+ static async new(options: {
+ config: commons.config.SimpleConfig
+ tracker: tracker.ConfigTracker & migrator.PresignedMigrationTracker
+ contexts: commons.context.VersionedContext
+ orchestrator: SignatureOrchestrator
+ networks: NetworkConfig[]
+ migrations?: migrator.Migrations
+ projectAccessKey?: string
+ }): Promise {
+ const mig = new migrator.Migrator(options.tracker, options.migrations ?? defaults.DefaultMigrations, options.contexts)
+
+ const lastMigration = mig.lastMigration()
+ const lastCoder = lastMigration.configCoder
+
+ const config = lastCoder.fromSimple(options.config)
+ const imageHash = lastCoder.imageHashOf(config)
+ const context = options.contexts[lastMigration.version]
+ const address = commons.context.addressOf(context, imageHash)
+
+ await options.tracker.saveCounterfactualWallet({ config, context: Object.values(options.contexts) })
+
+ return new Account({
+ address,
+ tracker: options.tracker,
+ contexts: options.contexts,
+ networks: options.networks,
+ orchestrator: options.orchestrator,
+ migrations: options.migrations,
+ projectAccessKey: options.projectAccessKey
+ })
+ }
+
+ getAddress(): Promise {
+ return Promise.resolve(this.address)
+ }
+
+ get version(): number {
+ return this.migrator.lastMigration().version
+ }
+
+ get coders(): {
+ signature: commons.signature.SignatureCoder
+ config: commons.config.ConfigCoder
+ } {
+ const lastMigration = this.migrator.lastMigration()
+
+ return {
+ signature: lastMigration.signatureCoder,
+ config: lastMigration.configCoder
+ }
+ }
+
+ network(chainId: ethers.BigNumberish): NetworkConfig {
+ const tcid = ethers.BigNumber.from(chainId)
+ const found = this.networks.find(n => tcid.eq(n.chainId))
+ if (!found) throw new Error(`Network not found for chainId ${chainId}`)
+ return found
+ }
+
+ providerFor(chainId: ethers.BigNumberish): ethers.providers.Provider {
+ const found = this.network(chainId)
+ if (!found.provider && !found.rpcUrl) throw new Error(`Provider not found for chainId ${chainId}`)
+ return (
+ found.provider ||
+ new ethers.providers.StaticJsonRpcProvider(getEthersConnectionInfo(found.rpcUrl, this.projectAccessKey, this.jwt), {
+ name: '',
+ chainId: ethers.BigNumber.from(chainId).toNumber()
+ })
+ )
+ }
+
+ reader(chainId: ethers.BigNumberish): commons.reader.Reader {
+ if (ethers.constants.Zero.eq(chainId)) return new Chain0Reader()
+
+ // TODO: Networks should be able to provide a reader directly
+ // and we should default to the on-chain reader
+ return new commons.reader.OnChainReader(this.providerFor(chainId))
+ }
+
+ relayer(chainId: ethers.BigNumberish): Relayer {
+ const found = this.network(chainId)
+ if (!found.relayer) throw new Error(`Relayer not found for chainId ${chainId}`)
+ if (isRelayer(found.relayer)) return found.relayer
+ return new RpcRelayer({
+ ...found.relayer,
+ // If there's an access key, we don't pass the JWT, because browser-side usage of this code mandates an access key
+ // and passing a JWT causes a CORS error.
+ ...(this.projectAccessKey ? { projectAccessKey: this.projectAccessKey } : { jwtAuth: this.jwt })
+ })
+ }
+
+ setOrchestrator(orchestrator: SignatureOrchestrator) {
+ this.orchestrator = orchestrator
+ }
+
+ setJwt(jwt: string) {
+ this.jwt = jwt
+ }
+
+ contextFor(version: number): commons.context.WalletContext {
+ const ctx = this.contexts[version]
+ if (!ctx) throw new Error(`Context not found for version ${version}`)
+ return ctx
+ }
+
+ walletForStatus(chainId: ethers.BigNumberish, status: Pick & Pick): Wallet {
+ const coder = universal.coderFor(status.version)
+ return this.walletFor(chainId, this.contextFor(status.version), status.config, coder)
+ }
+
+ walletFor(
+ chainId: ethers.BigNumberish,
+ context: commons.context.WalletContext,
+ config: commons.config.Config,
+ coders: typeof this.coders
+ ): Wallet {
+ const isNetworkZero = ethers.constants.Zero.eq(chainId)
+ return new Wallet({
+ config,
+ context,
+ chainId,
+ coders,
+ relayer: isNetworkZero ? undefined : this.relayer(chainId),
+ address: this.address,
+ orchestrator: this.orchestrator,
+ reader: this.reader(chainId)
+ })
+ }
+
+ // Get the status of the account on a given network
+ // this does the following process:
+ // 1. Get the current on-chain status of the wallet (version + imageHash)
+ // 2. Get any pending migrations that have been signed by the wallet
+ // 3. Get any pending configuration updates that have been signed by the wallet
+ // 4. Fetch reverse lookups for both on-chain and pending configurations
+ async status(chainId: ethers.BigNumberish, longestPath: boolean = false): Promise {
+ const isDeployedPromise = this.reader(chainId).isDeployed(this.address)
+
+ const counterfactualImageHashPromise = this.tracker
+ .imageHashOfCounterfactualWallet({
+ wallet: this.address
+ })
+ .then(r => {
+ if (!r) throw new Error(`Counterfactual imageHash not found for wallet ${this.address}`)
+ return r
+ })
+
+ const counterFactualVersionPromise = counterfactualImageHashPromise.then(r => {
+ return version.counterfactualVersion(this.address, r.imageHash, Object.values(this.contexts))
+ })
+
+ const onChainVersionPromise = (async () => {
+ const isDeployed = await isDeployedPromise
+ if (!isDeployed) return counterFactualVersionPromise
+
+ const implementation = await this.reader(chainId).implementation(this.address)
+ if (!implementation) throw new Error(`Implementation not found for wallet ${this.address}`)
+
+ const versions = Object.values(this.contexts)
+ for (let i = 0; i < versions.length; i++) {
+ if (versions[i].mainModule === implementation || versions[i].mainModuleUpgradable === implementation) {
+ return versions[i].version
+ }
+ }
+
+ throw new Error(`Version not found for implementation ${implementation}`)
+ })()
+
+ const onChainImageHashPromise = (async () => {
+ const deployedImageHash = await this.reader(chainId).imageHash(this.address)
+ if (deployedImageHash) return deployedImageHash
+ const counterfactualImageHash = await counterfactualImageHashPromise
+ if (counterfactualImageHash) return counterfactualImageHash.imageHash
+ throw new Error(`On-chain imageHash not found for wallet ${this.address}`)
+ })()
+
+ const onChainConfigPromise = (async () => {
+ const onChainImageHash = await onChainImageHashPromise
+ const onChainConfig = await this.tracker.configOfImageHash({ imageHash: onChainImageHash })
+ if (onChainConfig) return onChainConfig
+ throw new Error(`On-chain config not found for imageHash ${onChainImageHash}`)
+ })()
+
+ const onChainVersion = await onChainVersionPromise
+ const onChainImageHash = await onChainImageHashPromise
+
+ let fromImageHash = onChainImageHash
+ let lastVersion = onChainVersion
+ let signedMigrations: migrator.SignedMigration[] = []
+
+ if (onChainVersion !== this.version) {
+ // We either need to use the presigned configuration updates, or we haven't performed
+ // any updates yet, so we can only use the on-chain imageHash as-is
+ const presignedMigrate = await this.migrator.getAllMigratePresignedTransaction({
+ address: this.address,
+ fromImageHash: onChainImageHash,
+ fromVersion: onChainVersion,
+ chainId
+ })
+
+ // The migrator returns the original version and imageHash
+ // if no presigned migration is found, so no need to check here
+ fromImageHash = presignedMigrate.lastImageHash
+ lastVersion = presignedMigrate.lastVersion
+
+ signedMigrations = presignedMigrate.signedMigrations
+ }
+
+ const presigned = await this.tracker.loadPresignedConfiguration({
+ wallet: this.address,
+ fromImageHash: fromImageHash,
+ longestPath
+ })
+
+ const imageHash = presigned && presigned.length > 0 ? presigned[presigned.length - 1].nextImageHash : fromImageHash
+ const config = await this.tracker.configOfImageHash({ imageHash })
+ if (!config) {
+ throw new Error(`Config not found for imageHash ${imageHash}`)
+ }
+
+ const isDeployed = await isDeployedPromise
+ const counterfactualImageHash = await counterfactualImageHashPromise
+ const checkpoint = universal.coderFor(lastVersion).config.checkpointOf(config as any)
+
+ return {
+ original: {
+ ...counterfactualImageHash,
+ version: await counterFactualVersionPromise
+ },
+ onChain: {
+ imageHash: onChainImageHash,
+ config: await onChainConfigPromise,
+ version: onChainVersion,
+ deployed: isDeployed
+ },
+ fullyMigrated: lastVersion === this.version,
+ signedMigrations,
+ version: lastVersion,
+ presignedConfigurations: presigned,
+ imageHash,
+ config,
+ checkpoint,
+ canOnchainValidate: onChainVersion === this.version && isDeployed
+ }
+ }
+
+ private mustBeFullyMigrated(status: AccountStatus) {
+ if (!status.fullyMigrated) {
+ throw new Error(`Wallet ${this.address} is not fully migrated`)
+ }
+ }
+
+ async predecorateSignedTransactions(
+ status: AccountStatus,
+ chainId: ethers.BigNumberish
+ ): Promise {
+ // Request signed predecorate transactions from child wallets
+ const bundles = await this.orchestrator.predecorateSignedTransactions({ chainId })
+ // Get signed predecorate transaction
+ const predecorated = await this.predecorateTransactions([], status, chainId)
+ if (commons.transaction.fromTransactionish(this.address, predecorated).length > 0) {
+ // Sign it
+ bundles.push(await this.signTransactions(predecorated, chainId))
+ }
+ return bundles
+ }
+
+ async predecorateTransactions(
+ txs: commons.transaction.Transactionish,
+ status: AccountStatus,
+ chainId: ethers.BigNumberish
+ ): Promise {
+ // if onchain wallet config is not up to date
+ // then we should append an extra transaction that updates it
+ // to the latest "lazy" state
+ if (status.onChain.imageHash !== status.imageHash) {
+ const wallet = this.walletForStatus(chainId, status)
+ const updateConfig = await wallet.buildUpdateConfigurationTransaction(status.config)
+ return [Array.isArray(txs) ? txs : [txs], updateConfig.transactions].flat()
+ }
+
+ return txs
+ }
+
+ async decorateTransactions(
+ bundles: commons.transaction.IntendedTransactionBundle | commons.transaction.IntendedTransactionBundle[],
+ status: AccountStatus,
+ chainId?: ethers.BigNumberish
+ ): Promise {
+ if (!Array.isArray(bundles)) {
+ // Recurse with array
+ return this.decorateTransactions([bundles], status, chainId)
+ }
+
+ // Default to chainId of first bundle when not supplied
+ chainId = chainId ?? bundles[0].chainId
+
+ const bootstrapBundle = await this.buildBootstrapTransactions(status, chainId)
+ const hasBootstrapTxs = bootstrapBundle.transactions.length > 0
+
+ if (!hasBootstrapTxs && bundles.length === 1) {
+ return bundles[0]
+ }
+
+ // Intent defaults to first bundle when no bootstrap transaction
+ const { entrypoint } = hasBootstrapTxs ? bootstrapBundle : bundles[0]
+
+ const decoratedBundle = {
+ entrypoint,
+ chainId,
+ // Intent of the first bundle is used
+ intent: bundles[0]?.intent,
+ transactions: [
+ ...bootstrapBundle.transactions,
+ ...bundles.map(
+ (bundle): commons.transaction.Transaction => ({
+ to: bundle.entrypoint,
+ data: commons.transaction.encodeBundleExecData(bundle),
+ gasLimit: 0,
+ delegateCall: false,
+ revertOnError: true,
+ value: 0
+ })
+ )
+ ]
+ }
+
+ // Re-compute the meta-transaction id to use the guest module subdigest
+ if (!status.onChain.deployed) {
+ const id = commons.transaction.subdigestOfGuestModuleTransactions(
+ this.contexts[this.version].guestModule,
+ chainId,
+ decoratedBundle.transactions
+ )
+
+ if (decoratedBundle.intent === undefined) {
+ decoratedBundle.intent = { id, wallet: this.address }
+ } else {
+ decoratedBundle.intent.id = id
+ }
+ }
+
+ return decoratedBundle
+ }
+
+ async decorateSignature(
+ signature: T,
+ status: Partial>
+ ): Promise {
+ if (!status.presignedConfigurations || status.presignedConfigurations.length === 0) {
+ return signature
+ }
+
+ const coder = this.coders.signature
+
+ const chain = status.presignedConfigurations.map(c => c.signature)
+ const chainedSignature = coder.chainSignatures(signature, chain)
+ return coder.trim(chainedSignature)
+ }
+
+ async publishWitness(): Promise {
+ const digest = ethers.utils.keccak256(ethers.utils.toUtf8Bytes(`This is a Sequence account woo! ${Date.now()}`))
+ const signature = await this.signDigest(digest, 0, false)
+ const decoded = this.coders.signature.decode(signature)
+ const signatures = this.coders.signature.signaturesOfDecoded(decoded)
+ return this.tracker.saveWitnesses({ wallet: this.address, digest, chainId: 0, signatures })
+ }
+
+ async signDigest(
+ digest: ethers.BytesLike,
+ chainId: ethers.BigNumberish,
+ decorate: boolean = true,
+ cantValidateBehavior: 'ignore' | 'eip6492' | 'throw' = 'ignore',
+ metadata?: object
+ ): Promise {
+ // If we are signing a digest for chainId zero then we can never be fully migrated
+ // because Sequence v1 doesn't allow for signing a message on "all chains"
+
+ // So we ignore the state on "chain zero" and instead use one of the states of the networks
+ // wallet-webapp should ensure the wallet is as migrated as possible, trying to mimic
+ // the behaviour of being migrated on all chains
+ const chainRef = ethers.constants.Zero.eq(chainId) ? this.networks[0].chainId : chainId
+ const status = await this.status(chainRef)
+ this.mustBeFullyMigrated(status)
+
+ // Check if we can validate onchain and what to do if we can't
+ // revert early, since there is no point in signing a digest now
+ if (!status.canOnchainValidate && cantValidateBehavior === 'throw') {
+ throw new Error('Wallet cannot validate onchain')
+ }
+
+ const wallet = this.walletForStatus(chainId, status)
+ const signature = await wallet.signDigest(digest, metadata)
+
+ const decorated = decorate ? this.decorateSignature(signature, status) : signature
+
+ // If the wallet can't validate onchain then we
+ // need to prefix the decorated signature with all deployments and migrations
+ // aka doing a bootstrap using EIP-6492
+ if (!status.canOnchainValidate) {
+ switch (cantValidateBehavior) {
+ // NOTICE: We covered this case before signing the digest
+ // case 'throw':
+ // throw new Error('Wallet cannot validate on-chain')
+ case 'ignore':
+ return decorated
+
+ case 'eip6492':
+ return this.buildEIP6492Signature(await decorated, status, chainId)
+ }
+ }
+
+ return decorated
+ }
+
+ buildOnChainSignature(digest: ethers.BytesLike): { bundle: commons.transaction.TransactionBundle; signature: string } {
+ const subdigest = commons.signature.subdigestOf({ digest: ethers.utils.hexlify(digest), chainId: 0, address: this.address })
+ const hexSubdigest = ethers.utils.hexlify(subdigest)
+ const config = this.coders.config.fromSimple({
+ // Threshold *only* needs to be > 0, this is not a magic number
+ // we only use 2 ** 15 because it may lead to lower gas costs in some chains
+ threshold: 32768,
+ checkpoint: 0,
+ signers: [],
+ subdigests: [hexSubdigest]
+ })
+
+ const walletInterface = new ethers.utils.Interface(walletContracts.mainModule.abi)
+ const bundle: commons.transaction.TransactionBundle = {
+ entrypoint: this.address,
+ transactions: [
+ {
+ to: this.address,
+ data: walletInterface.encodeFunctionData(
+ // *NEVER* use updateImageHash here, as it would effectively destroy the wallet
+ // setExtraImageHash sets an additional imageHash, without changing the current one
+ 'setExtraImageHash',
+ [
+ this.coders.config.imageHashOf(config),
+ // 2 ** 255 instead of max uint256, to have more zeros in the calldata
+ '57896044618658097711785492504343953926634992332820282019728792003956564819968'
+ ]
+ ),
+ // Conservative gas limit, used because the current relayer
+ // has trouble estimating gas for this transaction
+ gasLimit: 250000
+ }
+ ]
+ }
+
+ // Fire and forget request to save the config
+ this.tracker.saveWalletConfig({ config })
+
+ // Encode a signature proof for the given subdigest
+ // use `chainId = 0` to make it simpler, as this signature is only a proof
+ const signature = this.coders.signature.encodeSigners(config, new Map(), [hexSubdigest], 0).encoded
+ return { bundle, signature }
+ }
+
+ private async buildEIP6492Signature(signature: string, status: AccountStatus, chainId: ethers.BigNumberish): Promise {
+ const bootstrapBundle = await this.buildBootstrapTransactions(status, chainId)
+ if (bootstrapBundle.transactions.length === 0) {
+ throw new Error('Cannot build EIP-6492 signature without bootstrap transactions')
+ }
+
+ const encoded = ethers.utils.defaultAbiCoder.encode(
+ ['address', 'bytes', 'bytes'],
+ [bootstrapBundle.entrypoint, commons.transaction.encodeBundleExecData(bootstrapBundle), signature]
+ )
+
+ return ethers.utils.solidityPack(['bytes', 'bytes32'], [encoded, commons.EIP6492.EIP_6492_SUFFIX])
+ }
+
+ async editConfig(changes: {
+ add?: commons.config.SimpleSigner[]
+ remove?: string[]
+ threshold?: ethers.BigNumberish
+ }): Promise {
+ const currentConfig = await this.status(0).then(s => s.config)
+ const newConfig = this.coders.config.editConfig(currentConfig, {
+ ...changes,
+ checkpoint: this.coders.config.checkpointOf(currentConfig).add(1)
+ })
+
+ return this.updateConfig(newConfig)
+ }
+
+ async updateConfig(config: commons.config.Config): Promise {
+ // config should be for the current version of the wallet
+ if (!this.coders.config.isWalletConfig(config)) {
+ throw new Error(`Invalid config for wallet ${this.address}`)
+ }
+
+ const nextImageHash = this.coders.config.imageHashOf(config)
+
+ // sign an update config struct
+ const updateStruct = this.coders.signature.hashSetImageHash(nextImageHash)
+
+ // sign the update struct, using chain id 0
+ const signature = await this.signDigest(updateStruct, 0, false)
+
+ // save the presigned transaction to the sessions tracker
+ await this.tracker.savePresignedConfiguration({
+ wallet: this.address,
+ nextConfig: config,
+ signature
+ })
+
+ // safety check, tracker should have a reverse lookup for the imageHash
+ // outside of the local cache
+ const reverseConfig = await this.tracker.configOfImageHash({
+ imageHash: nextImageHash,
+ noCache: true
+ })
+
+ if (!reverseConfig || this.coders.config.imageHashOf(reverseConfig) !== nextImageHash) {
+ throw Error(`Reverse lookup failed for imageHash ${nextImageHash}`)
+ }
+ }
+
+ /**
+ * This method is used to bootstrap the wallet on a given chain.
+ * this deploys the wallets and executes all the necessary transactions
+ * for that wallet to start working with the given version.
+ *
+ * This usually involves: (a) deploying the wallet, (b) executing migrations
+ *
+ * Notice: It should NOT explicitly include chained signatures. Unless internally used
+ * by any of the migrations.
+ *
+ */
+ async buildBootstrapTransactions(
+ status: AccountStatus,
+ chainId: ethers.BigNumberish
+ ): Promise {
+ const bundle = await this.orchestrator.buildDeployTransaction({ chainId })
+ const transactions: commons.transaction.Transaction[] = bundle?.transactions ?? []
+
+ // Add wallet deployment if needed
+ if (!status.onChain.deployed) {
+ // Wallet deployment will vary depending on the version
+ // so we need to use the context to get the correct deployment
+ const deployTransaction = Wallet.buildDeployTransaction(status.original.context, status.original.imageHash)
+
+ transactions.push(...deployTransaction.transactions)
+ }
+ const len = transactions.length
+
+ // Get pending migrations
+ transactions.push(
+ ...status.signedMigrations.map(m => ({
+ to: m.tx.entrypoint,
+ data: commons.transaction.encodeBundleExecData(m.tx),
+ value: 0,
+ gasLimit: 0,
+ revertOnError: true,
+ delegateCall: false
+ }))
+ )
+
+ // Build the transaction intent, if the transaction has migrations
+ // then we should use one of the intents of the migrations (anyone will do)
+ // if it doesn't, then the only intent we could use if the GuestModule one
+ // ... but this may fail if the relayer uses a different GuestModule
+ const id =
+ status.signedMigrations.length > 0
+ ? status.signedMigrations[0].tx.intent.id
+ : commons.transaction.subdigestOfGuestModuleTransactions(this.contexts[this.version].guestModule, chainId, transactions)
+
+ // Everything is encoded as a bundle
+ // using the GuestModule of the account version
+ const { guestModule } = this.contextFor(status.version)
+ return { entrypoint: guestModule, transactions, chainId, intent: { id, wallet: this.address } }
+ }
+
+ async bootstrapTransactions(
+ chainId: ethers.BigNumberish,
+ prestatus?: AccountStatus
+ ): Promise> {
+ const status = prestatus || (await this.status(chainId))
+ return this.buildBootstrapTransactions(status, chainId)
+ }
+
+ async doBootstrap(chainId: ethers.BigNumberish, feeQuote?: FeeQuote, prestatus?: AccountStatus) {
+ const bootstrapTxs = await this.bootstrapTransactions(chainId, prestatus)
+ return this.relayer(chainId).relay({ ...bootstrapTxs, chainId }, feeQuote)
+ }
+
+ signMessage(
+ message: ethers.BytesLike,
+ chainId: ethers.BigNumberish,
+ cantValidateBehavior: 'ignore' | 'eip6492' | 'throw' = 'ignore'
+ ): Promise {
+ return this.signDigest(ethers.utils.keccak256(message), chainId, true, cantValidateBehavior)
+ }
+
+ async signTransactions(
+ txs: commons.transaction.Transactionish,
+ chainId: ethers.BigNumberish,
+ pstatus?: AccountStatus,
+ options?: {
+ nonceSpace?: ethers.BigNumberish
+ serial?: boolean
+ }
+ ): Promise {
+ const status = pstatus || (await this.status(chainId))
+ this.mustBeFullyMigrated(status)
+
+ const wallet = this.walletForStatus(chainId, status)
+
+ const metadata: WalletSignRequestMetadata = {
+ address: this.address,
+ digest: '', // Set in wallet.signTransactions
+ chainId,
+ config: { version: this.version },
+ decorate: true,
+ cantValidateBehavior: 'ignore'
+ }
+
+ const nonceOptions = options?.serial
+ ? { serial: true }
+ : options?.nonceSpace !== undefined
+ ? { space: options.nonceSpace }
+ : undefined
+
+ const signed = await wallet.signTransactions(txs, nonceOptions, metadata)
+
+ return {
+ ...signed,
+ signature: await this.decorateSignature(signed.signature, status)
+ }
+ }
+
+ async signMigrations(
+ chainId: ethers.BigNumberish,
+ editConfig: (prevConfig: commons.config.Config) => commons.config.Config
+ ): Promise {
+ const status = await this.status(chainId)
+ if (status.fullyMigrated) return false
+
+ const wallet = this.walletForStatus(chainId, status)
+ const nextConfig = editConfig(wallet.config)
+ const signed = await this.migrator.signNextMigration(this.address, status.version, wallet, nextConfig)
+ if (!signed) return false
+
+ // Make sure the tracker has a copy of the config
+ // before attempting to save the migration
+ // otherwise if this second step fails the tracker could end up
+ // with a migration to an unknown config
+ await this.tracker.saveWalletConfig({ config: nextConfig })
+ const nextCoder = universal.coderFor(nextConfig.version).config
+ const nextImageHash = nextCoder.imageHashOf(nextConfig as any)
+ const reverseConfig = await this.tracker.configOfImageHash({ imageHash: nextImageHash, noCache: true })
+ if (!reverseConfig || nextCoder.imageHashOf(reverseConfig as any) !== nextImageHash) {
+ throw Error(`Reverse lookup failed for imageHash ${nextImageHash}`)
+ }
+
+ await this.tracker.saveMigration(this.address, signed, this.contexts)
+
+ return true
+ }
+
+ async signAllMigrations(
+ editConfig: (prevConfig: commons.config.Config) => commons.config.Config
+ ): Promise<{ signedMigrations: Array; failedChains: number[] }> {
+ const failedChains: number[] = []
+ const signedMigrations = await Promise.all(
+ this.networks.map(async n => {
+ try {
+ // Signing migrations for each chain
+ return await this.signMigrations(n.chainId, editConfig)
+ } catch (error) {
+ console.warn(`Failed to sign migrations for chain ${n.chainId}`, error)
+
+ // Adding failed chainId to the failedChains array
+ failedChains.push(n.chainId)
+ // Using null as a placeholder for failed chains
+ return null
+ }
+ })
+ )
+
+ // Filter out null values to get only the successful signed migrations
+ const successfulSignedMigrations = signedMigrations.filter(migration => migration !== null)
+
+ return { signedMigrations: successfulSignedMigrations, failedChains }
+ }
+
+ async isMigratedAllChains(): Promise<{ migratedAllChains: boolean; failedChains: number[] }> {
+ const failedChains: number[] = []
+ const statuses = await Promise.all(
+ this.networks.map(async n => {
+ try {
+ return await this.status(n.chainId)
+ } catch (error) {
+ failedChains.push(n.chainId)
+
+ console.warn(`Failed to get status for chain ${n.chainId}`, error)
+
+ // default to true for failed chains
+ return { fullyMigrated: true }
+ }
+ })
+ )
+
+ const migratedAllChains = statuses.every(s => s.fullyMigrated)
+ return { migratedAllChains, failedChains }
+ }
+
+ async sendSignedTransactions(
+ signedBundle: commons.transaction.IntendedTransactionBundle | commons.transaction.IntendedTransactionBundle[],
+ chainId: ethers.BigNumberish,
+ quote?: FeeQuote,
+ pstatus?: AccountStatus,
+ callback?: (bundle: commons.transaction.IntendedTransactionBundle) => void
+ ): Promise {
+ if (!Array.isArray(signedBundle)) {
+ return this.sendSignedTransactions([signedBundle], chainId, quote, pstatus, callback)
+ }
+ const status = pstatus || (await this.status(chainId))
+ this.mustBeFullyMigrated(status)
+
+ const decoratedBundle = await this.decorateTransactions(signedBundle, status, chainId)
+ callback?.(decoratedBundle)
+
+ return this.relayer(chainId).relay(decoratedBundle, quote)
+ }
+
+ async fillGasLimits(
+ txs: commons.transaction.Transactionish,
+ chainId: ethers.BigNumberish,
+ status?: AccountStatus
+ ): Promise {
+ const wallet = this.walletForStatus(chainId, status || (await this.status(chainId)))
+ return wallet.fillGasLimits(txs)
+ }
+
+ async gasRefundQuotes(
+ txs: commons.transaction.Transactionish,
+ chainId: ethers.BigNumberish,
+ stubSignatureOverrides: Map,
+ status?: AccountStatus,
+ options?: {
+ simulate?: boolean
+ }
+ ): Promise<{
+ options: FeeOption[]
+ quote?: FeeQuote
+ decorated: commons.transaction.IntendedTransactionBundle
+ }> {
+ const wstatus = status || (await this.status(chainId))
+ const wallet = this.walletForStatus(chainId, wstatus)
+
+ const predecorated = await this.predecorateTransactions(txs, wstatus, chainId)
+ const transactions = commons.transaction.fromTransactionish(this.address, predecorated)
+
+ // We can't sign the transactions (because we don't want to bother the user)
+ // so we use the latest configuration to build a "stub" signature, the relayer
+ // knows to ignore the wallet signatures
+ const stubSignature = wallet.coders.config.buildStubSignature(wallet.config, stubSignatureOverrides)
+
+ // Now we can decorate the transactions as always, but we need to manually build the signed bundle
+ const intentId = ethers.utils.hexlify(ethers.utils.randomBytes(32))
+ const signedBundle: commons.transaction.SignedTransactionBundle = {
+ chainId,
+ intent: {
+ id: intentId,
+ wallet: this.address
+ },
+ signature: stubSignature,
+ transactions,
+ entrypoint: this.address,
+ nonce: 0 // The relayer also ignored the nonce
+ }
+
+ const decoratedBundle = await this.decorateTransactions(signedBundle, wstatus)
+ const data = commons.transaction.encodeBundleExecData(decoratedBundle)
+ const res = await this.relayer(chainId).getFeeOptionsRaw(decoratedBundle.entrypoint, data, options)
+ return { ...res, decorated: decoratedBundle }
+ }
+
+ async prepareTransactions(args: {
+ txs: commons.transaction.Transactionish
+ chainId: ethers.BigNumberish
+ stubSignatureOverrides: Map
+ simulateForFeeOptions?: boolean
+ }): Promise {
+ const status = await this.status(args.chainId)
+
+ const transactions = await this.fillGasLimits(args.txs, args.chainId, status)
+ const gasRefundQuote = await this.gasRefundQuotes(transactions, args.chainId, args.stubSignatureOverrides, status, {
+ simulate: args.simulateForFeeOptions
+ })
+ const flatDecorated = commons.transaction.unwind(this.address, gasRefundQuote.decorated.transactions)
+
+ return {
+ transactions,
+ flatDecorated,
+ feeOptions: gasRefundQuote.options,
+ feeQuote: gasRefundQuote.quote
+ }
+ }
+
+ async sendTransaction(
+ txs: commons.transaction.Transactionish,
+ chainId: ethers.BigNumberish,
+ quote?: FeeQuote,
+ skipPreDecorate: boolean = false,
+ callback?: (bundle: commons.transaction.IntendedTransactionBundle) => void,
+ options?: {
+ nonceSpace?: ethers.BigNumberish
+ serial?: boolean
+ }
+ ): Promise {
+ const status = await this.status(chainId)
+
+ const predecorated = skipPreDecorate ? txs : await this.predecorateTransactions(txs, status, chainId)
+ const hasTxs = commons.transaction.fromTransactionish(this.address, predecorated).length > 0
+ const signed = hasTxs ? await this.signTransactions(predecorated, chainId, undefined, options) : undefined
+
+ const childBundles = await this.orchestrator.predecorateSignedTransactions({ chainId })
+
+ const bundles: commons.transaction.SignedTransactionBundle[] = []
+ if (signed !== undefined && signed.transactions.length > 0) {
+ bundles.push(signed)
+ }
+ bundles.push(...childBundles.filter(b => b.transactions.length > 0))
+
+ return this.sendSignedTransactions(bundles, chainId, quote, undefined, callback)
+ }
+
+ async signTypedData(
+ domain: TypedDataDomain,
+ types: Record>,
+ message: Record,
+ chainId: ethers.BigNumberish,
+ cantValidateBehavior: 'ignore' | 'eip6492' | 'throw' = 'ignore'
+ ): Promise {
+ const digest = encodeTypedDataDigest({ domain, types, message })
+ return this.signDigest(digest, chainId, true, cantValidateBehavior)
+ }
+
+ async getSigners(): Promise> {
+ const last = (ts: T[]): T | undefined => (ts.length ? ts[ts.length - 1] : undefined)
+
+ return (
+ await Promise.all(
+ this.networks.map(async ({ chainId, name }) => {
+ try {
+ const status = await this.status(chainId)
+
+ let latestImageHash = last(status.presignedConfigurations)?.nextImageHash
+ if (!latestImageHash) {
+ if (status.onChain.version !== status.version) {
+ const migration = last(status.signedMigrations)
+ if (migration) {
+ const { toVersion, toConfig } = migration
+ const coder = universal.genericCoderFor(toVersion)
+ latestImageHash = coder.config.imageHashOf(toConfig)
+ }
+ }
+ }
+ if (!latestImageHash) {
+ latestImageHash = status.onChain.imageHash
+ }
+
+ const latestConfig = await this.tracker.configOfImageHash({ imageHash: latestImageHash })
+ if (!latestConfig) {
+ throw new Error(`unable to find config for image hash ${latestImageHash}`)
+ }
+
+ const coder = universal.genericCoderFor(latestConfig.version)
+ const signers = coder.config.signersOf(latestConfig)
+
+ return signers.map(signer => ({ ...signer, network: chainId }))
+ } catch (error) {
+ console.warn(`unable to get signers on network ${chainId} ${name}`, error)
+ return []
+ }
+ })
+ )
+ ).flat()
+ }
+
+ async getAllSigners(): Promise<
+ {
+ address: string
+ weight: number
+ network: number
+ flaggedForRemoval: boolean
+ }[]
+ > {
+ const allSigners: {
+ address: string
+ weight: number
+ network: number
+ flaggedForRemoval: boolean
+ }[] = []
+
+ // We need to get the signers for each status
+ await Promise.all(
+ this.networks.map(async network => {
+ const chainId = network.chainId
+
+ // Getting the status with `longestPath` set to true will give us all the possible configurations
+ // between the current onChain config and the latest config, including the ones "flagged for removal"
+ const status = await this.status(chainId, true)
+
+ const fullChain = [
+ status.onChain.imageHash,
+ ...(status.onChain.version !== status.version
+ ? status.signedMigrations.map(m => universal.coderFor(m.toVersion).config.imageHashOf(m.toConfig as any))
+ : []),
+ ...status.presignedConfigurations.map(update => update.nextImageHash)
+ ]
+
+ return Promise.all(
+ fullChain.map(async (nextImageHash, iconf) => {
+ const isLast = iconf === fullChain.length - 1
+ const config = await this.tracker.configOfImageHash({ imageHash: nextImageHash })
+
+ if (!config) {
+ console.warn(`AllSigners may be incomplete, config not found for imageHash ${nextImageHash}`)
+ return
+ }
+
+ const coder = universal.genericCoderFor(config.version)
+ const signers = coder.config.signersOf(config)
+
+ signers.forEach(signer => {
+ const exists = allSigners.find(s => s.address === signer.address && s.network === chainId)
+
+ if (exists && isLast && exists.flaggedForRemoval) {
+ exists.flaggedForRemoval = false
+ return
+ }
+
+ if (exists) return
+
+ allSigners.push({
+ address: signer.address,
+ weight: signer.weight,
+ network: chainId,
+ flaggedForRemoval: !isLast
+ })
+ })
+ })
+ )
+ })
+ )
+
+ return allSigners
+ }
+}
+
+export function isAccount(value: any): value is Account {
+ return value instanceof Account
+}
diff --git a/packages/account/src/index.ts b/packages/account/src/index.ts
new file mode 100644
index 0000000000..8a695b2e25
--- /dev/null
+++ b/packages/account/src/index.ts
@@ -0,0 +1 @@
+export * from './account'
diff --git a/packages/account/src/orchestrator/wrapper.ts b/packages/account/src/orchestrator/wrapper.ts
new file mode 100644
index 0000000000..ab9e16c3fd
--- /dev/null
+++ b/packages/account/src/orchestrator/wrapper.ts
@@ -0,0 +1,69 @@
+import { commons } from '@0xsequence/core'
+import { signers, Status } from '@0xsequence/signhub'
+import { ethers } from 'ethers'
+import { Account } from '../account'
+
+export type MetadataWithChainId = {
+ chainId: ethers.BigNumberish
+}
+
+// Implements a wrapper for using Sequence accounts as nested signers in the signhub orchestrator.
+export class AccountOrchestratorWrapper implements signers.SapientSigner {
+ constructor(public account: Account) {}
+
+ async getAddress(): Promise {
+ return this.account.address
+ }
+
+ getChainIdFromMetadata(metadata: object): ethers.BigNumber {
+ try {
+ const { chainId } = metadata as MetadataWithChainId
+ return ethers.BigNumber.from(chainId)
+ } catch (err) {
+ // Invalid metadata object
+ throw new Error('AccountOrchestratorWrapper only supports metadata with chain id')
+ }
+ }
+
+ async buildDeployTransaction(metadata: object): Promise {
+ const chainId = this.getChainIdFromMetadata(metadata)
+ const status = await this.account.status(chainId)
+ return this.account.buildBootstrapTransactions(status, chainId)
+ }
+
+ async predecorateSignedTransactions(metadata: object): Promise {
+ const chainId = this.getChainIdFromMetadata(metadata)
+ const status = await this.account.status(chainId)
+ return this.account.predecorateSignedTransactions(status, chainId)
+ }
+
+ async decorateTransactions(
+ bundle: commons.transaction.IntendedTransactionBundle,
+ metadata: object
+ ): Promise {
+ const chainId = this.getChainIdFromMetadata(metadata)
+ const status = await this.account.status(chainId)
+ return this.account.decorateTransactions(bundle, status)
+ }
+
+ sign(message: ethers.utils.BytesLike, metadata: object): Promise {
+ if (!commons.isWalletSignRequestMetadata(metadata)) {
+ throw new Error('AccountOrchestratorWrapper only supports wallet metadata requests')
+ }
+
+ const { chainId, decorate } = metadata
+ // EIP-6492 not supported on nested signatures
+ // Default to throw instead of ignore. Ignoring should be explicit
+ const cantValidateBehavior = metadata.cantValidateBehavior ?? 'throw'
+
+ // For Sequence nested signatures we must use `signDigest` and not `signMessage`
+ // otherwise the account will hash the digest and the signature will be invalid.
+ return this.account.signDigest(message, chainId, decorate, cantValidateBehavior, metadata)
+ }
+
+ notifyStatusChange(_i: string, _s: Status, _m: object): void {}
+
+ suffix(): ethers.utils.BytesLike {
+ return [3]
+ }
+}
diff --git a/packages/account/src/signer.ts b/packages/account/src/signer.ts
new file mode 100644
index 0000000000..1ffd1f4fd3
--- /dev/null
+++ b/packages/account/src/signer.ts
@@ -0,0 +1,223 @@
+import { ChainId } from '@0xsequence/network'
+import { Account } from './account'
+import { ethers } from 'ethers'
+import { commons } from '@0xsequence/core'
+import { FeeOption, proto } from '@0xsequence/relayer'
+import { isDeferrable } from './utils'
+
+export type AccountSignerOptions = {
+ nonceSpace?: ethers.BigNumberish
+ cantValidateBehavior?: 'ignore' | 'eip6492' | 'throw'
+ stubSignatureOverrides?: Map
+ selectFee?: (
+ txs: ethers.utils.Deferrable | commons.transaction.Transactionish,
+ options: FeeOption[]
+ ) => Promise
+}
+
+function encodeGasRefundTransaction(option?: FeeOption) {
+ if (!option) return []
+
+ const value = ethers.BigNumber.from(option.value)
+
+ switch (option.token.type) {
+ case proto.FeeTokenType.UNKNOWN:
+ return [
+ {
+ delegateCall: false,
+ revertOnError: true,
+ gasLimit: option.gasLimit,
+ to: option.to,
+ value: value.toHexString(),
+ data: '0x'
+ }
+ ]
+
+ case proto.FeeTokenType.ERC20_TOKEN:
+ if (!option.token.contractAddress) {
+ throw new Error(`No contract address for ERC-20 fee option`)
+ }
+
+ return [
+ {
+ delegateCall: false,
+ revertOnError: true,
+ gasLimit: option.gasLimit,
+ to: option.token.contractAddress,
+ value: 0,
+ data: new ethers.utils.Interface([
+ {
+ constant: false,
+ inputs: [{ type: 'address' }, { type: 'uint256' }],
+ name: 'transfer',
+ outputs: [],
+ type: 'function'
+ }
+ ]).encodeFunctionData('transfer', [option.to, value.toHexString()])
+ }
+ ]
+
+ default:
+ throw new Error(`Unhandled fee token type ${option.token.type}`)
+ }
+}
+
+export class AccountSigner implements ethers.Signer {
+ public readonly _isSigner = true
+
+ constructor(
+ public account: Account,
+ public chainId: ChainId,
+ public readonly options?: AccountSignerOptions
+ ) {}
+
+ get provider() {
+ return this.account.providerFor(this.chainId)
+ }
+
+ async getAddress(): Promise {
+ return this.account.address
+ }
+
+ signMessage(message: string | ethers.utils.Bytes): Promise {
+ return this.account.signMessage(message, this.chainId, this.options?.cantValidateBehavior ?? 'throw')
+ }
+
+ private async defaultSelectFee(
+ _txs: ethers.utils.Deferrable | commons.transaction.Transactionish,
+ options: FeeOption[]
+ ): Promise {
+ // If no options, return undefined
+ if (options.length === 0) return undefined
+
+ // If there are multiple options, try them one by one
+ // until we find one that satisfies the balance requirement
+ const balanceOfAbi = [
+ {
+ constant: true,
+ inputs: [{ type: 'address' }],
+ name: 'balanceOf',
+ outputs: [{ type: 'uint256' }],
+ type: 'function'
+ }
+ ]
+
+ for (const option of options) {
+ if (option.token.type === proto.FeeTokenType.UNKNOWN) {
+ // Native token
+ const balance = await this.getBalance()
+ if (balance.gte(ethers.BigNumber.from(option.value))) {
+ return option
+ }
+ } else if (option.token.contractAddress && option.token.type === proto.FeeTokenType.ERC20_TOKEN) {
+ // ERC20 token
+ const token = new ethers.Contract(option.token.contractAddress, balanceOfAbi, this.provider)
+ const balance = await token.balanceOf(this.account.address)
+ if (balance.gte(ethers.BigNumber.from(option.value))) {
+ return option
+ }
+ } else {
+ // Unsupported token type
+ }
+ }
+
+ throw new Error('No fee option available - not enough balance')
+ }
+
+ async sendTransaction(
+ txsPromise: ethers.utils.Deferrable | commons.transaction.Transactionish,
+ options?: {
+ simulateForFeeOptions?: boolean
+ }
+ ): Promise {
+ const txs = isDeferrable(txsPromise)
+ ? await ethers.utils.resolveProperties(txsPromise as ethers.utils.Deferrable)
+ : txsPromise
+
+ const prepare = await this.account.prepareTransactions({
+ txs,
+ chainId: this.chainId,
+ stubSignatureOverrides: this.options?.stubSignatureOverrides ?? new Map(),
+ simulateForFeeOptions: options?.simulateForFeeOptions
+ })
+
+ const selectMethod = this.options?.selectFee ?? this.defaultSelectFee.bind(this)
+ const feeOption = await selectMethod(txs, prepare.feeOptions)
+
+ const finalTransactions = [...prepare.transactions, ...encodeGasRefundTransaction(feeOption)]
+
+ return this.account.sendTransaction(
+ finalTransactions,
+ this.chainId,
+ prepare.feeQuote,
+ undefined,
+ undefined,
+ this.options?.nonceSpace !== undefined
+ ? {
+ nonceSpace: this.options.nonceSpace
+ }
+ : undefined
+ ) as Promise // Will always have a transaction response
+ }
+
+ getBalance(blockTag?: ethers.providers.BlockTag | undefined): Promise {
+ return this.provider.getBalance(this.account.address, blockTag)
+ }
+
+ call(
+ transaction: ethers.utils.Deferrable,
+ blockTag?: ethers.providers.BlockTag | undefined
+ ): Promise {
+ return this.provider.call(transaction, blockTag)
+ }
+
+ async resolveName(name: string): Promise {
+ const res = await this.provider.resolveName(name)
+ if (!res) throw new Error(`Could not resolve name ${name}`)
+ return res
+ }
+
+ connect(_provider: ethers.providers.Provider): ethers.Signer {
+ throw new Error('Method not implemented.')
+ }
+
+ signTransaction(transaction: ethers.utils.Deferrable): Promise {
+ throw new Error('Method not implemented.')
+ }
+
+ getTransactionCount(blockTag?: ethers.providers.BlockTag | undefined): Promise {
+ throw new Error('Method not implemented.')
+ }
+
+ estimateGas(transaction: ethers.utils.Deferrable): Promise {
+ throw new Error('Method not implemented.')
+ }
+
+ getChainId(): Promise {
+ return Promise.resolve(ethers.BigNumber.from(this.chainId).toNumber())
+ }
+
+ getGasPrice(): Promise {
+ throw new Error('Method not implemented.')
+ }
+
+ getFeeData(): Promise {
+ throw new Error('Method not implemented.')
+ }
+
+ checkTransaction(
+ transaction: ethers.utils.Deferrable
+ ): ethers.utils.Deferrable {
+ throw new Error('Method not implemented.')
+ }
+
+ populateTransaction(
+ transaction: ethers.utils.Deferrable
+ ): Promise {
+ throw new Error('Method not implemented.')
+ }
+
+ _checkProvider(operation?: string | undefined): void {
+ throw new Error('Method not implemented.')
+ }
+}
diff --git a/packages/account/src/utils.ts b/packages/account/src/utils.ts
new file mode 100644
index 0000000000..b8d715ec6c
--- /dev/null
+++ b/packages/account/src/utils.ts
@@ -0,0 +1,14 @@
+import { ethers } from 'ethers'
+
+function isPromise(value: any): value is Promise {
+ return !!value && typeof value.then === 'function'
+}
+
+export function isDeferrable(value: any): value is ethers.utils.Deferrable {
+ // The value is deferrable if any of the properties is a Promises
+ if (typeof value === 'object') {
+ return Object.keys(value).some(key => isPromise(value[key]))
+ }
+
+ return false
+}
diff --git a/packages/account/tests/account.spec.ts b/packages/account/tests/account.spec.ts
new file mode 100644
index 0000000000..056e226861
--- /dev/null
+++ b/packages/account/tests/account.spec.ts
@@ -0,0 +1,1536 @@
+import { walletContracts } from '@0xsequence/abi'
+import { commons, v1, v2 } from '@0xsequence/core'
+import { migrator } from '@0xsequence/migration'
+import { NetworkConfig } from '@0xsequence/network'
+import { LocalRelayer, Relayer } from '@0xsequence/relayer'
+import { tracker, trackers } from '@0xsequence/sessions'
+import { Orchestrator } from '@0xsequence/signhub'
+import * as utils from '@0xsequence/tests'
+import { Wallet } from '@0xsequence/wallet'
+import * as chai from 'chai'
+import chaiAsPromised from 'chai-as-promised'
+import { ethers } from 'ethers'
+import hardhat from 'hardhat'
+
+import { Account } from '../src/account'
+import { AccountOrchestratorWrapper } from '../src/orchestrator/wrapper'
+
+const { expect } = chai.use(chaiAsPromised)
+
+const deterministic = false
+
+describe('Account', () => {
+ let provider1: ethers.providers.JsonRpcProvider
+ let provider2: ethers.providers.JsonRpcProvider
+
+ let signer1: ethers.Signer
+ let signer2: ethers.Signer
+
+ let contexts: commons.context.VersionedContext
+ let networks: NetworkConfig[]
+
+ let tracker: tracker.ConfigTracker & migrator.PresignedMigrationTracker
+
+ let defaultArgs: {
+ contexts: commons.context.VersionedContext
+ networks: NetworkConfig[]
+ tracker: tracker.ConfigTracker & migrator.PresignedMigrationTracker
+ }
+
+ let defaultTx: commons.transaction.Transaction
+
+ const createNestedAccount = async (entropy: string, bootstrapInner = true, bootstrapOuter = true) => {
+ const signer = randomWallet(entropy)
+
+ const configInner = {
+ threshold: 1,
+ checkpoint: Math.floor(now() / 1000),
+ signers: [{ address: signer.address, weight: 1 }]
+ }
+ const accountInner = await Account.new({
+ ...defaultArgs,
+ config: configInner,
+ orchestrator: new Orchestrator([signer])
+ })
+ if (bootstrapInner) {
+ await accountInner.doBootstrap(networks[0].chainId)
+ }
+
+ const configOuter = {
+ threshold: 1,
+ checkpoint: Math.floor(now() / 1000),
+ signers: [{ address: accountInner.address, weight: 1 }]
+ }
+ const accountOuter = await Account.new({
+ ...defaultArgs,
+ config: configOuter,
+ orchestrator: new Orchestrator([new AccountOrchestratorWrapper(accountInner)])
+ })
+ if (bootstrapOuter) {
+ await accountOuter.doBootstrap(networks[0].chainId)
+ }
+
+ return { signer, accountInner, accountOuter }
+ }
+
+ const getEth = async (address: string, signer?: ethers.Signer) => {
+ if (signer === undefined) {
+ // Do both networks
+ await getEth(address, signer1)
+ await getEth(address, signer2)
+ return
+ }
+ // Signer sends the address some ETH for defaultTx use
+ const tx = await signer.sendTransaction({
+ to: address,
+ value: 10 // Should be plenty
+ })
+ await tx.wait()
+ }
+
+ before(async () => {
+ provider1 = new ethers.providers.Web3Provider(hardhat.network.provider as any)
+ provider2 = new ethers.providers.JsonRpcProvider('http://127.0.0.1:7048')
+
+ // TODO: Implement migrations on local config tracker
+ tracker = new trackers.local.LocalConfigTracker(provider1)
+
+ signer1 = provider1.getSigner()
+ signer2 = provider2.getSigner()
+
+ networks = [
+ {
+ chainId: 31337,
+ name: 'hardhat',
+ provider: provider1,
+ rpcUrl: '',
+ relayer: new LocalRelayer(signer1),
+ nativeToken: {
+ symbol: 'ETH',
+ name: 'Ether',
+ decimals: 18
+ }
+ },
+ {
+ chainId: 31338,
+ name: 'hardhat2',
+ provider: provider2,
+ rpcUrl: 'http://127.0.0.1:7048',
+ relayer: new LocalRelayer(signer2),
+ nativeToken: {
+ symbol: 'ETH',
+ name: 'Ether',
+ decimals: 18
+ }
+ }
+ ]
+
+ const context1 = utils.context.deploySequenceContexts(signer1)
+ const context2 = utils.context.deploySequenceContexts(signer2)
+ expect(await context1).to.deep.equal(await context2)
+ contexts = await context1
+
+ defaultArgs = {
+ contexts,
+ networks,
+ tracker
+ }
+
+ defaultTx = {
+ to: await signer1.getAddress(),
+ value: 1
+ }
+ })
+
+ describe('New account', () => {
+ it('Should create a new account', async () => {
+ const signer = randomWallet('Should create a new account')
+ const config = {
+ threshold: 1,
+ checkpoint: Math.floor(now() / 1000),
+ signers: [{ address: signer.address, weight: 1 }]
+ }
+
+ const account = await Account.new({
+ ...defaultArgs,
+ config,
+ orchestrator: new Orchestrator([signer])
+ })
+
+ expect(account).to.be.instanceOf(Account)
+ expect(account.address).to.not.be.undefined
+
+ await getEth(account.address)
+ const tx = await account.sendTransaction([defaultTx], networks[0].chainId)
+ expect(tx).to.not.be.undefined
+
+ const status = await account.status(networks[0].chainId)
+ expect(status.fullyMigrated).to.be.true
+ expect(status.onChain.deployed).to.be.true
+ expect(status.onChain.version).to.equal(2)
+ })
+
+ it('Should create new nested accounts', async () => {
+ const { accountInner, accountOuter } = await createNestedAccount('create new nested accounts', false, false)
+
+ await getEth(accountOuter.address)
+ await accountOuter.sendTransaction([defaultTx], networks[0].chainId)
+
+ const statusOuter = await accountOuter.status(networks[0].chainId)
+
+ expect(statusOuter.fullyMigrated).to.be.true
+ expect(statusOuter.onChain.deployed).to.be.true
+ expect(statusOuter.onChain.version).to.equal(2)
+
+ const statusInner = await accountInner.status(networks[0].chainId)
+ expect(statusInner.fullyMigrated).to.be.true
+ expect(statusInner.onChain.deployed).to.be.true
+ expect(statusInner.onChain.version).to.equal(2)
+ })
+
+ it('Should send tx on nested accounts', async () => {
+ const { accountInner, accountOuter } = await createNestedAccount('sent tx on nested accounts', true, true)
+
+ await getEth(accountOuter.address)
+ await accountOuter.sendTransaction([defaultTx], networks[0].chainId)
+
+ const statusOuter = await accountOuter.status(networks[0].chainId)
+
+ expect(statusOuter.fullyMigrated).to.be.true
+ expect(statusOuter.onChain.deployed).to.be.true
+ expect(statusOuter.onChain.version).to.equal(2)
+
+ const statusInner = await accountInner.status(networks[0].chainId)
+ expect(statusInner.fullyMigrated).to.be.true
+ expect(statusInner.onChain.deployed).to.be.true
+ expect(statusInner.onChain.version).to.equal(2)
+ })
+
+ it('Should send transactions on multiple networks', async () => {
+ const signer = randomWallet('Should send transactions on multiple networks')
+ const config = {
+ threshold: 1,
+ checkpoint: Math.floor(now() / 1000),
+ signers: [{ address: signer.address, weight: 1 }]
+ }
+
+ const account = await Account.new({
+ ...defaultArgs,
+ config,
+ orchestrator: new Orchestrator([signer])
+ })
+
+ await getEth(account.address)
+ await account.sendTransaction([defaultTx], networks[0].chainId)
+ await account.sendTransaction([defaultTx], networks[1].chainId)
+
+ const status1 = await account.status(networks[0].chainId)
+ const status2 = await account.status(networks[1].chainId)
+
+ expect(status1.fullyMigrated).to.be.true
+ expect(status1.onChain.deployed).to.be.true
+ expect(status1.onChain.version).to.equal(2)
+
+ expect(status2.fullyMigrated).to.be.true
+ expect(status2.onChain.deployed).to.be.true
+ expect(status2.onChain.version).to.equal(2)
+ })
+
+ it('Should create a new account with many signers', async () => {
+ const signers = new Array(24).fill(0).map(() => randomWallet('Should create a new account with many signers'))
+ const config = {
+ threshold: 3,
+ checkpoint: Math.floor(now() / 1000),
+ signers: signers.map(signer => ({
+ address: signer.address,
+ weight: 1
+ }))
+ }
+
+ const rsigners = signers.sort(() => randomFraction('Should create a new account with many signers 2') - 0.5)
+ const account = await Account.new({
+ ...defaultArgs,
+ config,
+ orchestrator: new Orchestrator(rsigners.slice(0, 4))
+ })
+
+ await getEth(account.address)
+ await account.sendTransaction([defaultTx], networks[0].chainId)
+
+ const status = await account.status(networks[0].chainId)
+ expect(status.fullyMigrated).to.be.true
+ expect(status.onChain.deployed).to.be.true
+ expect(status.onChain.version).to.equal(2)
+ })
+
+ it('Should sign and validate a message', async () => {
+ const signer = randomWallet('Should sign and validate a message')
+ const config = {
+ threshold: 1,
+ checkpoint: Math.floor(now() / 1000),
+ signers: [{ address: signer.address, weight: 1 }]
+ }
+
+ const account = await Account.new({
+ ...defaultArgs,
+ config,
+ orchestrator: new Orchestrator([signer])
+ })
+
+ await account.doBootstrap(networks[0].chainId)
+
+ const msg = ethers.utils.toUtf8Bytes('Hello World')
+ const sig = await account.signMessage(msg, networks[0].chainId)
+
+ const valid = await commons.EIP1271.isValidEIP1271Signature(
+ account.address,
+ ethers.utils.keccak256(msg),
+ sig,
+ networks[0].provider!
+ )
+
+ expect(valid).to.be.true
+ })
+
+ it('Should sign and validate a message with nested account', async () => {
+ const { accountOuter } = await createNestedAccount('sign and validate nested')
+
+ const msg = ethers.utils.toUtf8Bytes('Hello World')
+ const sig = await accountOuter.signMessage(msg, networks[0].chainId)
+
+ const valid = await commons.EIP1271.isValidEIP1271Signature(
+ accountOuter.address,
+ ethers.utils.keccak256(msg),
+ sig,
+ networks[0].provider!
+ )
+
+ expect(valid).to.be.true
+ })
+
+ it('Should update account to new configuration', async () => {
+ const signer = randomWallet('Should update account to new configuration')
+ const simpleConfig1 = {
+ threshold: 1,
+ checkpoint: Math.floor(now() / 1000),
+ signers: [{ address: signer.address, weight: 1 }]
+ }
+ const config1 = v2.config.ConfigCoder.fromSimple(simpleConfig1)
+
+ const account = await Account.new({
+ ...defaultArgs,
+ config: simpleConfig1,
+ orchestrator: new Orchestrator([signer])
+ })
+
+ const signer2a = randomWallet('Should update account to new configuration 2')
+ const signer2b = randomWallet('Should update account to new configuration 3')
+
+ const simpleConfig2 = {
+ threshold: 4,
+ checkpoint: Math.floor(now() / 1000) + 1,
+ signers: [
+ {
+ address: signer2a.address,
+ weight: 2
+ },
+ {
+ address: signer2b.address,
+ weight: 2
+ }
+ ]
+ }
+
+ const config2 = v2.config.ConfigCoder.fromSimple(simpleConfig2)
+ await account.updateConfig(config2)
+
+ const status2 = await account.status(networks[0].chainId)
+ expect(status2.fullyMigrated).to.be.true
+ expect(status2.onChain.deployed).to.be.false
+ expect(status2.onChain.version).to.equal(2)
+ expect(status2.onChain.imageHash).to.deep.equal(v2.config.ConfigCoder.imageHashOf(config1))
+ expect(status2.imageHash).to.deep.equal(v2.config.ConfigCoder.imageHashOf(config2))
+ })
+
+ it('Should sign and validate a message without being deployed', async () => {
+ const signer = randomWallet('Should sign and validate a message without being deployed')
+ const config = {
+ threshold: 1,
+ checkpoint: Math.floor(now() / 1000),
+ signers: [{ address: signer.address, weight: 1 }]
+ }
+
+ const account = await Account.new({
+ ...defaultArgs,
+ config,
+ orchestrator: new Orchestrator([signer])
+ })
+
+ const msg = ethers.utils.toUtf8Bytes('Hello World')
+ const sig = await account.signMessage(msg, networks[0].chainId, 'eip6492')
+
+ const valid = await account.reader(networks[0].chainId).isValidSignature(account.address, ethers.utils.keccak256(msg), sig)
+
+ expect(valid).to.be.true
+ })
+
+ it('Should sign and validate a message without being deployed with nested account', async () => {
+ const { accountOuter } = await createNestedAccount('sign and validate nested undeployed', true, false)
+
+ const msg = ethers.utils.toUtf8Bytes('Hello World')
+ const sig = await accountOuter.signMessage(msg, networks[0].chainId, 'eip6492')
+
+ const valid = await accountOuter
+ .reader(networks[0].chainId)
+ .isValidSignature(accountOuter.address, ethers.utils.keccak256(msg), sig)
+
+ expect(valid).to.be.true
+ })
+
+ it('Should sign and validate a message with undeployed nested account and signer', async () => {
+ // Testing that an undeployed account doesn't error as other signer can satisfy threshold
+ const signerA = randomWallet('Nested account signer A')
+ const signerB = randomWallet('Nested account signer B')
+
+ const configInner = {
+ threshold: 1,
+ checkpoint: Math.floor(now() / 1000),
+ signers: [{ address: signerA.address, weight: 1 }]
+ }
+ const accountInner = await Account.new({
+ ...defaultArgs,
+ config: configInner,
+ orchestrator: new Orchestrator([signerA])
+ }) // Undeployed
+
+ const configOuter = {
+ threshold: 1,
+ checkpoint: Math.floor(now() / 1000),
+ signers: [
+ { address: accountInner.address, weight: 1 },
+ { address: signerB.address, weight: 1 }
+ ]
+ }
+ const accountOuter = await Account.new({
+ ...defaultArgs,
+ config: configOuter,
+ orchestrator: new Orchestrator([new AccountOrchestratorWrapper(accountInner), signerB])
+ })
+ await accountOuter.doBootstrap(networks[0].chainId)
+
+ const msg = ethers.utils.toUtf8Bytes('Hello World')
+ const sig = await accountOuter.signMessage(msg, networks[0].chainId)
+
+ const valid = await accountOuter
+ .reader(networks[0].chainId)
+ .isValidSignature(accountOuter.address, ethers.utils.keccak256(msg), sig)
+
+ expect(valid).to.be.true
+ })
+
+ it('Should refuse to sign when not deployed', async () => {
+ const signer = randomWallet('Should refuse to sign when not deployed')
+ const config = {
+ threshold: 1,
+ checkpoint: Math.floor(now() / 1000),
+ signers: [{ address: signer.address, weight: 1 }]
+ }
+
+ const account = await Account.new({
+ ...defaultArgs,
+ config,
+ orchestrator: new Orchestrator([signer])
+ })
+
+ const msg = ethers.utils.toUtf8Bytes('Hello World')
+ const sig = account.signMessage(msg, networks[0].chainId, 'throw')
+
+ expect(sig).to.be.rejected
+ })
+
+ it('Should refuse to sign when not deployed (nested)', async () => {
+ const { accountOuter } = await createNestedAccount('refuse to sign undeployed', false, false)
+
+ const msg = ethers.utils.toUtf8Bytes('Hello World')
+ const sig = accountOuter.signMessage(msg, networks[0].chainId, 'eip6492') // Note EIP-6492 throws when nested not deployed
+
+ expect(sig).to.be.rejected
+ })
+
+ describe('After upgrading', () => {
+ let account: Account
+
+ let signer1: ethers.Wallet
+ let signer2a: ethers.Wallet
+ let signer2b: ethers.Wallet
+ let signerIndex = 1
+
+ beforeEach(async () => {
+ signer1 = randomWallet(`After upgrading ${signerIndex++}`)
+ const simpleConfig1 = {
+ threshold: 1,
+ checkpoint: Math.floor(now() / 1000) + 1,
+ signers: [{ address: signer1.address, weight: 1 }]
+ }
+
+ account = await Account.new({
+ ...defaultArgs,
+ config: simpleConfig1,
+ orchestrator: new Orchestrator([signer1])
+ })
+ await getEth(account.address)
+
+ signer2a = randomWallet(`After upgrading ${signerIndex++}`)
+ signer2b = randomWallet(`After upgrading ${signerIndex++}`)
+
+ const simpleConfig2 = {
+ threshold: 4,
+ checkpoint: await account.status(0).then(s => ethers.BigNumber.from(s.checkpoint).add(1)),
+ signers: [
+ {
+ address: signer2a.address,
+ weight: 2
+ },
+ {
+ address: signer2b.address,
+ weight: 2
+ }
+ ]
+ }
+
+ const config2 = v2.config.ConfigCoder.fromSimple(simpleConfig2)
+ await account.updateConfig(config2)
+ account.setOrchestrator(new Orchestrator([signer2a, signer2b]))
+ })
+
+ it('Should send a transaction', async () => {
+ const tx = await account.sendTransaction([defaultTx], networks[0].chainId)
+ expect(tx).to.not.be.undefined
+
+ const status = await account.status(networks[0].chainId)
+ expect(status.fullyMigrated).to.be.true
+ expect(status.onChain.deployed).to.be.true
+ expect(status.onChain.imageHash).to.equal(status.imageHash)
+ })
+
+ it('Should send a transaction on nested account', async () => {
+ const configOuter = {
+ threshold: 1,
+ checkpoint: Math.floor(now() / 1000),
+ signers: [{ address: account.address, weight: 1 }]
+ }
+ const accountOuter = await Account.new({
+ ...defaultArgs,
+ config: configOuter,
+ orchestrator: new Orchestrator([new AccountOrchestratorWrapper(account)])
+ })
+
+ await accountOuter.doBootstrap(networks[0].chainId)
+
+ const tx = await accountOuter.sendTransaction([], networks[0].chainId)
+ expect(tx).to.not.be.undefined
+
+ const statusOuter = await accountOuter.status(networks[0].chainId)
+ expect(statusOuter.fullyMigrated).to.be.true
+ expect(statusOuter.onChain.deployed).to.be.true
+ expect(statusOuter.onChain.imageHash).to.equal(statusOuter.imageHash)
+
+ const status = await account.status(networks[0].chainId)
+ expect(status.fullyMigrated).to.be.true
+ expect(status.onChain.deployed).to.be.true
+ expect(status.onChain.imageHash).to.equal(status.imageHash)
+ })
+
+ it('Should send a transaction on undeployed nested account', async () => {
+ const configOuter = {
+ threshold: 1,
+ checkpoint: Math.floor(now() / 1000),
+ signers: [{ address: account.address, weight: 1 }]
+ }
+ const accountOuter = await Account.new({
+ ...defaultArgs,
+ config: configOuter,
+ orchestrator: new Orchestrator([new AccountOrchestratorWrapper(account)])
+ })
+
+ await getEth(accountOuter.address)
+ const tx = await accountOuter.sendTransaction([defaultTx], networks[0].chainId)
+ expect(tx).to.not.be.undefined
+
+ const status = await account.status(networks[0].chainId)
+ expect(status.fullyMigrated).to.be.true
+ expect(status.onChain.deployed).to.be.true
+ expect(status.onChain.imageHash).to.equal(status.imageHash)
+ })
+
+ it('Should sign a message', async () => {
+ const msg = ethers.utils.toUtf8Bytes('Hello World')
+ const sig = await account.signMessage(msg, networks[0].chainId)
+
+ const canOnchainValidate = await account.status(networks[0].chainId).then(s => s.canOnchainValidate)
+ expect(canOnchainValidate).to.be.false
+ await account.doBootstrap(networks[0].chainId)
+
+ const valid = await commons.EIP1271.isValidEIP1271Signature(
+ account.address,
+ ethers.utils.keccak256(msg),
+ sig,
+ networks[0].provider!
+ )
+
+ expect(valid).to.be.true
+ })
+
+ it('Should fail to use old signer', async () => {
+ account.setOrchestrator(new Orchestrator([signer1]))
+ const tx = account.sendTransaction([defaultTx], networks[0].chainId)
+ await expect(tx).to.be.rejected
+ })
+
+ it('Should send a transaction on a different network', async () => {
+ const tx = await account.sendTransaction([defaultTx], networks[1].chainId)
+ expect(tx).to.not.be.undefined
+
+ const status = await account.status(networks[1].chainId)
+ expect(status.fullyMigrated).to.be.true
+ expect(status.onChain.deployed).to.be.true
+ expect(status.onChain.imageHash).to.equal(status.imageHash)
+ })
+
+ describe('After reloading the account', () => {
+ beforeEach(async () => {
+ account = new Account({
+ ...defaultArgs,
+ address: account.address,
+ orchestrator: new Orchestrator([signer2a, signer2b])
+ })
+ await getEth(account.address)
+ })
+
+ it('Should send a transaction', async () => {
+ const tx = await account.sendTransaction([defaultTx], networks[0].chainId)
+ expect(tx).to.not.be.undefined
+
+ const status = await account.status(networks[0].chainId)
+ expect(status.fullyMigrated).to.be.true
+ expect(status.onChain.deployed).to.be.true
+ expect(status.onChain.imageHash).to.equal(status.imageHash)
+ })
+
+ it('Should sign a message', async () => {
+ const msg = ethers.utils.toUtf8Bytes('Hello World')
+ const sig = await account.signMessage(msg, networks[0].chainId)
+
+ const canOnchainValidate = await account.status(networks[0].chainId).then(s => s.canOnchainValidate)
+ expect(canOnchainValidate).to.be.false
+ await account.doBootstrap(networks[0].chainId)
+
+ const valid = await commons.EIP1271.isValidEIP1271Signature(
+ account.address,
+ ethers.utils.keccak256(msg),
+ sig,
+ networks[0].provider!
+ )
+
+ expect(valid).to.be.true
+ })
+ })
+
+ describe('After updating the config again', () => {
+ let signer3a: ethers.Wallet
+ let signer3b: ethers.Wallet
+ let signer3c: ethers.Wallet
+ let signerIndex = 1
+
+ let config3: v2.config.WalletConfig
+
+ beforeEach(async () => {
+ signer3a = randomWallet(`After updating the config again ${signerIndex++}`)
+ signer3b = randomWallet(`After updating the config again ${signerIndex++}`)
+ signer3c = randomWallet(`After updating the config again ${signerIndex++}`)
+
+ const simpleConfig3 = {
+ threshold: 5,
+ checkpoint: await account.status(0).then(s => ethers.BigNumber.from(s.checkpoint).add(1)),
+ signers: [
+ {
+ address: signer3a.address,
+ weight: 2
+ },
+ {
+ address: signer3b.address,
+ weight: 2
+ },
+ {
+ address: signer3c.address,
+ weight: 1
+ }
+ ]
+ }
+
+ config3 = v2.config.ConfigCoder.fromSimple(simpleConfig3)
+
+ await account.updateConfig(config3)
+ account.setOrchestrator(new Orchestrator([signer3a, signer3b, signer3c]))
+ })
+
+ it('Should update account status', async () => {
+ const status = await account.status(networks[0].chainId)
+ expect(status.fullyMigrated).to.be.true
+ expect(status.onChain.deployed).to.be.false
+ expect(status.imageHash).to.equal(v2.config.ConfigCoder.imageHashOf(config3))
+ expect(status.presignedConfigurations.length).to.equal(2)
+ })
+
+ it('Should send a transaction', async () => {
+ const tx = await account.sendTransaction([defaultTx], networks[0].chainId)
+ expect(tx).to.not.be.undefined
+
+ const status = await account.status(networks[0].chainId)
+ expect(status.fullyMigrated).to.be.true
+ expect(status.onChain.deployed).to.be.true
+ expect(status.onChain.imageHash).to.equal(status.imageHash)
+ })
+
+ it('Should sign a message', async () => {
+ const msg = ethers.utils.toUtf8Bytes('Hello World')
+ const sig = await account.signMessage(msg, networks[0].chainId)
+
+ const canOnchainValidate = await account.status(networks[0].chainId).then(s => s.canOnchainValidate)
+ expect(canOnchainValidate).to.be.false
+ await account.doBootstrap(networks[0].chainId)
+
+ const status = await account.status(networks[0].chainId)
+ expect(status.onChain.imageHash).to.not.equal(status.imageHash)
+
+ const valid = await commons.EIP1271.isValidEIP1271Signature(
+ account.address,
+ ethers.utils.keccak256(msg),
+ sig,
+ networks[0].provider!
+ )
+
+ expect(valid).to.be.true
+ })
+ })
+
+ describe('After sending a transaction', () => {
+ beforeEach(async () => {
+ await account.sendTransaction([defaultTx], networks[0].chainId)
+ })
+
+ it('Should send a transaction in a different network', async () => {
+ const tx = await account.sendTransaction([defaultTx], networks[1].chainId)
+ expect(tx).to.not.be.undefined
+
+ const status = await account.status(networks[1].chainId)
+ expect(status.fullyMigrated).to.be.true
+ expect(status.onChain.deployed).to.be.true
+ expect(status.onChain.imageHash).to.equal(status.imageHash)
+ })
+
+ it('Should send a second transaction', async () => {
+ const tx = await account.sendTransaction([defaultTx], networks[0].chainId)
+ expect(tx).to.not.be.undefined
+ })
+
+ let signerIndex = 1
+ it('Should update the configuration again', async () => {
+ const signer2a = randomWallet(`Should update the configuration again ${signerIndex++}`)
+ const signer2b = randomWallet(`Should update the configuration again ${signerIndex++}`)
+ const signer2c = randomWallet(`Should update the configuration again ${signerIndex++}`)
+
+ const simpleConfig2 = {
+ threshold: 6,
+ checkpoint: await account.status(0).then(s => ethers.BigNumber.from(s.checkpoint).add(1)),
+ signers: [
+ {
+ address: signer2a.address,
+ weight: 3
+ },
+ {
+ address: signer2b.address,
+ weight: 3
+ },
+ {
+ address: signer2c.address,
+ weight: 3
+ }
+ ]
+ }
+
+ const ogOnchainImageHash = await account.status(0).then(s => s.onChain.imageHash)
+ const imageHash1 = await account.status(0).then(s => s.imageHash)
+
+ const config2 = v2.config.ConfigCoder.fromSimple(simpleConfig2)
+ await account.updateConfig(config2)
+
+ const status1 = await account.status(networks[0].chainId)
+ const status2 = await account.status(networks[1].chainId)
+
+ expect(status1.fullyMigrated).to.be.true
+ expect(status1.onChain.deployed).to.be.true
+ expect(status1.onChain.imageHash).to.equal(imageHash1)
+ expect(status1.imageHash).to.equal(v2.config.ConfigCoder.imageHashOf(config2))
+ expect(status1.presignedConfigurations.length).to.equal(1)
+
+ expect(status2.fullyMigrated).to.be.true
+ expect(status2.onChain.deployed).to.be.false
+ expect(status2.onChain.imageHash).to.equal(ogOnchainImageHash)
+ expect(status2.imageHash).to.equal(v2.config.ConfigCoder.imageHashOf(config2))
+ expect(status2.presignedConfigurations.length).to.equal(2)
+ })
+ })
+ })
+ })
+
+ describe('Migrated wallet', () => {
+ it('Should migrate undeployed account', async () => {
+ // Old account may be an address that's not even deployed
+ const signer1 = randomWallet('Should migrate undeployed account')
+
+ const simpleConfig = {
+ threshold: 1,
+ checkpoint: 0,
+ signers: [
+ {
+ address: signer1.address,
+ weight: 1
+ }
+ ]
+ }
+
+ const config = v1.config.ConfigCoder.fromSimple(simpleConfig)
+ const configv2 = v2.config.ConfigCoder.fromSimple(simpleConfig)
+
+ const imageHash = v1.config.ConfigCoder.imageHashOf(config)
+ const address = commons.context.addressOf(contexts[1], imageHash)
+
+ // Sessions server MUST have information about the old wallet
+ // in production this is retrieved from SequenceUtils contract
+ await tracker.saveCounterfactualWallet({ config, context: [contexts[1]] })
+
+ // Importing the account should work!
+ const account = new Account({ ...defaultArgs, address, orchestrator: new Orchestrator([signer1]) })
+
+ const status = await account.status(0)
+ expect(status.fullyMigrated).to.be.false
+ expect(status.onChain.deployed).to.be.false
+ expect(status.onChain.imageHash).to.equal(imageHash)
+ expect(status.imageHash).to.equal(imageHash)
+ expect(status.version).to.equal(1)
+
+ // Sending a transaction should fail (not fully migrated)
+ await getEth(account.address)
+ await expect(account.sendTransaction([defaultTx], networks[0].chainId)).to.be.rejected
+
+ // Should sign migration using the account
+ await account.signAllMigrations(c => c)
+
+ const status2 = await account.status(networks[0].chainId)
+ expect(status2.fullyMigrated).to.be.true
+ expect(status2.onChain.deployed).to.be.false
+ expect(status2.onChain.imageHash).to.equal(imageHash)
+ expect(status2.onChain.version).to.equal(1)
+ expect(status2.imageHash).to.equal(v2.config.ConfigCoder.imageHashOf(configv2))
+ expect(status2.version).to.equal(2)
+
+ // Send a transaction
+ const tx = await account.sendTransaction([defaultTx], networks[0].chainId)
+ expect(tx).to.not.be.undefined
+
+ const status3 = await account.status(networks[0].chainId)
+ expect(status3.fullyMigrated).to.be.true
+ expect(status3.onChain.deployed).to.be.true
+ expect(status3.onChain.imageHash).to.equal(v2.config.ConfigCoder.imageHashOf(configv2))
+ expect(status3.onChain.version).to.equal(2)
+ expect(status3.imageHash).to.equal(v2.config.ConfigCoder.imageHashOf(configv2))
+ expect(status3.version).to.equal(2)
+
+ // Send another transaction on another chain
+ const tx2 = await account.sendTransaction([defaultTx], networks[1].chainId)
+ expect(tx2).to.not.be.undefined
+
+ const status4 = await account.status(networks[1].chainId)
+ expect(status4.fullyMigrated).to.be.true
+ expect(status4.onChain.deployed).to.be.true
+ expect(status4.onChain.imageHash).to.equal(v2.config.ConfigCoder.imageHashOf(configv2))
+ expect(status4.onChain.version).to.equal(2)
+ expect(status4.imageHash).to.equal(v2.config.ConfigCoder.imageHashOf(configv2))
+ expect(status4.version).to.equal(2)
+ })
+
+ it('Should migrate a half-deployed account', async () => {
+ // Old account created with 3 signers, and already deployed
+ // in one of the chains
+ const signer1 = randomWallet('Should migrate a half-deployed account')
+ const signer2 = randomWallet('Should migrate a half-deployed account 2')
+ const signer3 = randomWallet('Should migrate a half-deployed account 3')
+
+ const simpleConfig = {
+ threshold: 2,
+ checkpoint: 0,
+ signers: [
+ {
+ address: signer1.address,
+ weight: 1
+ },
+ {
+ address: signer2.address,
+ weight: 1
+ },
+ {
+ address: signer3.address,
+ weight: 1
+ }
+ ]
+ }
+
+ const config = v1.config.ConfigCoder.fromSimple(simpleConfig)
+ const imageHash = v1.config.ConfigCoder.imageHashOf(config)
+ const address = commons.context.addressOf(contexts[1], imageHash)
+
+ // Deploy the wallet on network 0
+ const deployTx = Wallet.buildDeployTransaction(contexts[1], imageHash)
+ await (networks[0].relayer! as Relayer).relay({
+ ...deployTx,
+ chainId: networks[0].chainId,
+ intent: {
+ id: '0x00',
+ wallet: address
+ }
+ })
+
+ // Feed all information to sequence-sessions
+ // (on prod this would be imported from SequenceUtils)
+ await tracker.saveCounterfactualWallet({ config, context: Object.values(contexts) })
+
+ // Importing the account should work!
+ const account = new Account({
+ ...defaultArgs,
+ address,
+ orchestrator: new Orchestrator([signer1, signer3])
+ })
+
+ // Status on network 0 should be deployed, network 1 not
+ // both should not be migrated, and use the original imageHash
+ const status1 = await account.status(networks[0].chainId)
+ expect(status1.fullyMigrated).to.be.false
+ expect(status1.onChain.deployed).to.be.true
+ expect(status1.onChain.imageHash).to.equal(imageHash)
+ expect(status1.onChain.version).to.equal(1)
+ expect(status1.imageHash).to.equal(imageHash)
+ expect(status1.version).to.equal(1)
+
+ const status2 = await account.status(networks[1].chainId)
+ expect(status2.fullyMigrated).to.be.false
+ expect(status2.onChain.deployed).to.be.false
+ expect(status2.onChain.imageHash).to.equal(imageHash)
+ expect(status2.onChain.version).to.equal(1)
+ expect(status2.imageHash).to.equal(imageHash)
+ expect(status2.version).to.equal(1)
+
+ // Signing transactions (on both networks) and signing messages should fail
+ await getEth(account.address)
+ await expect(account.sendTransaction([defaultTx], networks[0].chainId)).to.be.rejected
+ await expect(account.sendTransaction([defaultTx], networks[1].chainId)).to.be.rejected
+ await expect(account.signMessage('0x00', networks[0].chainId)).to.be.rejected
+ await expect(account.signMessage('0x00', networks[1].chainId)).to.be.rejected
+
+ await account.signAllMigrations(c => c)
+
+ // Sign a transaction on network 0 and network 1, both should work
+ // and should take the wallet on-chain up to speed
+ const configv2 = v2.config.ConfigCoder.fromSimple(simpleConfig)
+
+ const tx1 = await account.sendTransaction([defaultTx], networks[0].chainId)
+ expect(tx1).to.not.be.undefined
+
+ const status1b = await account.status(networks[0].chainId)
+ expect(status1b.fullyMigrated).to.be.true
+ expect(status1b.onChain.deployed).to.be.true
+ expect(status1b.onChain.imageHash).to.equal(v2.config.ConfigCoder.imageHashOf(configv2))
+ expect(status1b.onChain.version).to.equal(2)
+ expect(status1b.imageHash).to.equal(v2.config.ConfigCoder.imageHashOf(configv2))
+ expect(status1b.version).to.equal(2)
+
+ const tx2 = await account.sendTransaction([defaultTx], networks[1].chainId)
+ expect(tx2).to.not.be.undefined
+
+ const status2b = await account.status(networks[1].chainId)
+ expect(status2b).to.be.deep.equal(status1b)
+ })
+
+ it('Should migrate an upgraded wallet', async () => {
+ const signer1 = randomWallet('Should migrate an upgraded wallet')
+ const signer2 = randomWallet('Should migrate an upgraded wallet 2')
+ const signer3 = randomWallet('Should migrate an upgraded wallet 3')
+ const signer4 = randomWallet('Should migrate an upgraded wallet 4')
+
+ const simpleConfig1a = {
+ threshold: 3,
+ checkpoint: 0,
+ signers: [
+ {
+ address: signer1.address,
+ weight: 2
+ },
+ {
+ address: signer2.address,
+ weight: 2
+ },
+ {
+ address: signer3.address,
+ weight: 2
+ }
+ ]
+ }
+
+ const config1a = v1.config.ConfigCoder.fromSimple(simpleConfig1a)
+ const imageHash1a = v1.config.ConfigCoder.imageHashOf(config1a)
+ const address = commons.context.addressOf(contexts[1], imageHash1a)
+
+ const simpleConfig1b = {
+ threshold: 3,
+ checkpoint: 0,
+ signers: [
+ {
+ address: signer1.address,
+ weight: 2
+ },
+ {
+ address: signer2.address,
+ weight: 2
+ },
+ {
+ address: signer4.address,
+ weight: 2
+ }
+ ]
+ }
+
+ const config1b = v1.config.ConfigCoder.fromSimple(simpleConfig1b)
+ const imageHash1b = v1.config.ConfigCoder.imageHashOf(config1b)
+
+ // Update wallet to config 1b (on network 0)
+ const wallet = new Wallet({
+ coders: {
+ signature: v1.signature.SignatureCoder,
+ config: v1.config.ConfigCoder
+ },
+ context: contexts[1],
+ config: config1a,
+ chainId: networks[0].chainId,
+ address,
+ orchestrator: new Orchestrator([signer1, signer3]),
+ relayer: (networks[0].relayer as Relayer)!,
+ provider: networks[0].provider!
+ })
+
+ const utx = await wallet.buildUpdateConfigurationTransaction(config1b)
+ const signed = await wallet.signTransactionBundle(utx)
+ const decorated = await wallet.decorateTransactions(signed)
+ await (networks[0].relayer as Relayer).relay(decorated)
+
+ // Importing the account should work!
+ const account = new Account({
+ ...defaultArgs,
+ address,
+ orchestrator: new Orchestrator([signer1, signer3])
+ })
+
+ // Feed the tracker with all the data
+ await tracker.saveCounterfactualWallet({ config: config1a, context: [contexts[1]] })
+ await tracker.saveWalletConfig({ config: config1b })
+
+ // Status on network 0 should be deployed, network 1 not
+ // and the configuration on network 0 should be the B one
+ const status1 = await account.status(networks[0].chainId)
+ expect(status1.fullyMigrated).to.be.false
+ expect(status1.onChain.deployed).to.be.true
+ expect(status1.onChain.imageHash).to.equal(imageHash1b)
+ expect(status1.onChain.version).to.equal(1)
+ expect(status1.imageHash).to.equal(imageHash1b)
+
+ const status2 = await account.status(networks[1].chainId)
+ expect(status2.fullyMigrated).to.be.false
+ expect(status2.onChain.deployed).to.be.false
+ expect(status2.onChain.imageHash).to.equal(imageHash1a)
+ expect(status2.onChain.version).to.equal(1)
+ expect(status2.imageHash).to.equal(imageHash1a)
+
+ // Signing transactions (on both networks) and signing messages should fail
+ await getEth(account.address)
+ await expect(account.sendTransaction([defaultTx], networks[0].chainId)).to.be.rejected
+ await expect(account.sendTransaction([defaultTx], networks[1].chainId)).to.be.rejected
+ await expect(account.signMessage('0x00', networks[0].chainId)).to.be.rejected
+ await expect(account.signMessage('0x00', networks[1].chainId)).to.be.rejected
+
+ // Sign all migrations should only have signers1 and 2
+ // so the migration should only be available on network 1 (the one not updated)
+ await account.signAllMigrations(c => c)
+
+ const config2a = v2.config.ConfigCoder.fromSimple(simpleConfig1a)
+ const config2b = v2.config.ConfigCoder.fromSimple(simpleConfig1b)
+ const imageHash2a = v2.config.ConfigCoder.imageHashOf(config2a)
+
+ const status1b = await account.status(networks[0].chainId)
+ expect(status1b.fullyMigrated).to.be.false
+ expect(status1b.onChain.deployed).to.be.true
+ expect(status1b.onChain.imageHash).to.equal(imageHash1b)
+ expect(status1b.onChain.version).to.equal(1)
+ expect(status1b.imageHash).to.equal(imageHash1b)
+ expect(status1b.version).to.equal(1)
+
+ const status2b = await account.status(networks[1].chainId)
+ expect(status2b.fullyMigrated).to.be.true
+ expect(status2b.onChain.deployed).to.be.false
+ expect(status2b.onChain.imageHash).to.equal(imageHash1a)
+ expect(status2b.onChain.version).to.equal(1)
+ expect(status2b.imageHash).to.equal(imageHash2a)
+ expect(status2b.version).to.equal(2)
+
+ // Sending a transaction should work for network 1
+ // but fail for network 0, same with signing messages
+ await expect(account.sendTransaction([defaultTx], networks[0].chainId)).to.be.rejected
+ await expect(account.sendTransaction([defaultTx], networks[1].chainId)).to.be.fulfilled
+
+ await expect(account.signMessage('0x00', networks[0].chainId)).to.be.rejected
+ await expect(account.signMessage('0x00', networks[1].chainId)).to.be.fulfilled
+
+ // Signing another migration with signers1 and 2 should put both in sync
+ account.setOrchestrator(new Orchestrator([signer1, signer2]))
+ await account.signAllMigrations(c => c)
+
+ await expect(account.sendTransaction([defaultTx], networks[0].chainId)).to.be.fulfilled
+ await expect(account.sendTransaction([defaultTx], networks[1].chainId)).to.be.fulfilled
+
+ await expect(account.signMessage('0x00', networks[0].chainId)).to.be.fulfilled
+ await expect(account.signMessage('0x00', networks[1].chainId)).to.be.fulfilled
+
+ const status1c = await account.status(networks[0].chainId)
+ const status2c = await account.status(networks[1].chainId)
+
+ expect(status1c.fullyMigrated).to.be.true
+ expect(status2c.fullyMigrated).to.be.true
+
+ // Configs are still different!
+ expect(status1c.imageHash).to.not.equal(status2c.imageHash)
+
+ const simpleConfig4 = {
+ threshold: 2,
+ checkpoint: 1,
+ signers: [
+ {
+ address: signer1.address,
+ weight: 1
+ },
+ {
+ address: signer2.address,
+ weight: 1
+ },
+ {
+ address: signer4.address,
+ weight: 1
+ }
+ ]
+ }
+
+ const config4 = v2.config.ConfigCoder.fromSimple(simpleConfig4)
+
+ await account.updateConfig(config4)
+
+ const status1d = await account.status(networks[0].chainId)
+ const status2d = await account.status(networks[1].chainId)
+
+ // Configs are now the same!
+ expect(status1d.imageHash).to.be.equal(status2d.imageHash)
+ })
+
+ it('Should edit the configuration during the migration', async () => {
+ // Old account may be an address that's not even deployed
+ const signer1 = randomWallet('Should edit the configuration during the migration')
+ const signer2 = randomWallet('Should edit the configuration during the migration 2')
+
+ const simpleConfig1 = {
+ threshold: 1,
+ checkpoint: 0,
+ signers: [
+ {
+ address: signer1.address,
+ weight: 1
+ }
+ ]
+ }
+
+ const simpleConfig2 = {
+ threshold: 1,
+ checkpoint: 0,
+ signers: [
+ {
+ address: signer2.address,
+ weight: 1
+ }
+ ]
+ }
+
+ const config = v1.config.ConfigCoder.fromSimple(simpleConfig1)
+ const configv2 = v2.config.ConfigCoder.fromSimple(simpleConfig2)
+
+ const imageHash = v1.config.ConfigCoder.imageHashOf(config)
+ const address = commons.context.addressOf(contexts[1], imageHash)
+
+ // Sessions server MUST have information about the old wallet
+ // in production this is retrieved from SequenceUtils contract
+ await tracker.saveCounterfactualWallet({ config, context: [contexts[1]] })
+
+ // Importing the account should work!
+ const orchestrator = new Orchestrator([signer1])
+ const account = new Account({ ...defaultArgs, address, orchestrator: orchestrator })
+
+ const status = await account.status(0)
+ expect(status.fullyMigrated).to.be.false
+ expect(status.onChain.deployed).to.be.false
+ expect(status.onChain.imageHash).to.equal(imageHash)
+ expect(status.imageHash).to.equal(imageHash)
+ expect(status.version).to.equal(1)
+
+ // Sending a transaction should fail (not fully migrated)
+ await getEth(account.address)
+ await expect(account.sendTransaction([defaultTx], networks[0].chainId)).to.be.rejected
+
+ // Should sign migration using the account
+ await account.signAllMigrations(c => {
+ expect(v1.config.ConfigCoder.imageHashOf(c as any)).to.equal(v1.config.ConfigCoder.imageHashOf(config))
+ return configv2
+ })
+
+ const status2 = await account.status(networks[0].chainId)
+ expect(status2.fullyMigrated).to.be.true
+ expect(status2.onChain.deployed).to.be.false
+ expect(status2.onChain.imageHash).to.equal(imageHash)
+ expect(status2.onChain.version).to.equal(1)
+ expect(status2.imageHash).to.equal(v2.config.ConfigCoder.imageHashOf(configv2))
+ expect(status2.version).to.equal(2)
+
+ // Send a transaction
+ orchestrator.setSigners([signer2])
+ const tx = await account.sendTransaction([defaultTx], networks[0].chainId)
+ expect(tx).to.not.be.undefined
+
+ const status3 = await account.status(networks[0].chainId)
+ expect(status3.fullyMigrated).to.be.true
+ expect(status3.onChain.deployed).to.be.true
+ expect(status3.onChain.imageHash).to.equal(v2.config.ConfigCoder.imageHashOf(configv2))
+ expect(status3.onChain.version).to.equal(2)
+ expect(status3.imageHash).to.equal(v2.config.ConfigCoder.imageHashOf(configv2))
+ expect(status3.version).to.equal(2)
+
+ // Send another transaction on another chain
+ const tx2 = await account.sendTransaction([defaultTx], networks[1].chainId)
+ expect(tx2).to.not.be.undefined
+
+ const status4 = await account.status(networks[1].chainId)
+ expect(status4.fullyMigrated).to.be.true
+ expect(status4.onChain.deployed).to.be.true
+ expect(status4.onChain.imageHash).to.equal(v2.config.ConfigCoder.imageHashOf(configv2))
+ expect(status4.onChain.version).to.equal(2)
+ expect(status4.imageHash).to.equal(v2.config.ConfigCoder.imageHashOf(configv2))
+ expect(status4.version).to.equal(2)
+ })
+
+ context('Signing messages', async () => {
+ context('After migrating', async () => {
+ let account: Account
+ let imageHash: string
+
+ beforeEach(async () => {
+ // Old account may be an address that's not even deployed
+ const signer1 = randomWallet(
+ 'Signing messages - After migrating' + account?.address ?? '' // Append prev address to entropy to avoid collisions
+ )
+
+ const simpleConfig = {
+ threshold: 1,
+ checkpoint: 0,
+ signers: [
+ {
+ address: signer1.address,
+ weight: 1
+ }
+ ]
+ }
+
+ const config = v1.config.ConfigCoder.fromSimple(simpleConfig)
+ imageHash = v1.config.ConfigCoder.imageHashOf(config)
+ const address = commons.context.addressOf(contexts[1], imageHash)
+
+ // Sessions server MUST have information about the old wallet
+ // in production this is retrieved from SequenceUtils contract
+ await tracker.saveCounterfactualWallet({ config, context: [contexts[1]] })
+
+ account = new Account({ ...defaultArgs, address, orchestrator: new Orchestrator([signer1]) })
+
+ // Should sign migration using the account
+ await account.signAllMigrations(c => c)
+ })
+
+ it('Should validate a message signed by undeployed migrated wallet', async () => {
+ const msg = ethers.utils.toUtf8Bytes('I like that you are reading our tests')
+ const sig = await account.signMessage(msg, networks[0].chainId, 'eip6492')
+
+ const valid = await account
+ .reader(networks[0].chainId)
+ .isValidSignature(account.address, ethers.utils.keccak256(msg), sig)
+
+ expect(valid).to.be.true
+ })
+
+ it('Should reject a message signed by undeployed migrated wallet (if set the throw)', async () => {
+ const msg = ethers.utils.toUtf8Bytes('I do not know what to write here anymore')
+ const sig = account.signMessage(msg, networks[0].chainId, 'throw')
+
+ await expect(sig).to.be.rejected
+ })
+
+ it('Should return an invalid signature by undeployed migrated wallet (if set to ignore)', async () => {
+ const msg = ethers.utils.toUtf8Bytes('Sending a hug')
+ const sig = await account.signMessage(msg, networks[0].chainId, 'ignore')
+
+ const valid = await account
+ .reader(networks[0].chainId)
+ .isValidSignature(account.address, ethers.utils.keccak256(msg), sig)
+
+ expect(valid).to.be.false
+ })
+
+ it('Should validate a message signed by deployed migrated wallet (deployed with v1)', async () => {
+ const deployTx = Wallet.buildDeployTransaction(contexts[1], imageHash)
+ await signer1.sendTransaction({
+ to: deployTx.entrypoint,
+ data: commons.transaction.encodeBundleExecData(deployTx)
+ })
+
+ expect(await networks[0].provider!.getCode(account.address).then(c => ethers.utils.arrayify(c).length)).to.not.equal(0)
+
+ const msg = ethers.utils.toUtf8Bytes('Everything seems to be working fine so far')
+ const sig = await account.signMessage(msg, networks[0].chainId, 'eip6492')
+
+ const valid = await account
+ .reader(networks[0].chainId)
+ .isValidSignature(account.address, ethers.utils.keccak256(msg), sig)
+
+ expect(valid).to.be.true
+ })
+
+ it('Should fail to sign a message signed by deployed migrated wallet (deployed with v1) if throw', async () => {
+ const deployTx = Wallet.buildDeployTransaction(contexts[1], imageHash)
+ await signer1.sendTransaction({
+ to: deployTx.entrypoint,
+ data: commons.transaction.encodeBundleExecData(deployTx)
+ })
+
+ expect(await networks[0].provider!.getCode(account.address).then(c => ethers.utils.arrayify(c).length)).to.not.equal(0)
+
+ const msg = ethers.utils.toUtf8Bytes('Everything seems to be working fine so far')
+ const sig = account.signMessage(msg, networks[0].chainId, 'throw')
+ expect(sig).to.be.rejected
+ })
+
+ it('Should return an invalid signature by deployed migrated wallet (deployed with v1) if ignore', async () => {
+ const deployTx = Wallet.buildDeployTransaction(contexts[1], imageHash)
+ await signer1.sendTransaction({
+ to: deployTx.entrypoint,
+ data: commons.transaction.encodeBundleExecData(deployTx)
+ })
+
+ expect(await networks[0].provider!.getCode(account.address).then(c => ethers.utils.arrayify(c).length)).to.not.equal(0)
+
+ const msg = ethers.utils.toUtf8Bytes('Everything seems to be working fine so far')
+ const sig = await account.signMessage(msg, networks[0].chainId, 'ignore')
+ const valid = await account
+ .reader(networks[0].chainId)
+ .isValidSignature(account.address, ethers.utils.keccak256(msg), sig)
+
+ expect(valid).to.be.false
+ })
+ })
+ })
+ })
+
+ describe('Nonce selection', async () => {
+ let signer: ethers.Wallet
+ let account: Account
+
+ let getNonce: (response: ethers.providers.TransactionResponse) => { space: ethers.BigNumber; nonce: ethers.BigNumber }
+
+ before(async () => {
+ const mainModule = new ethers.utils.Interface(walletContracts.mainModule.abi)
+
+ getNonce = ({ data }) => {
+ const [_, encoded] = mainModule.decodeFunctionData('execute', data)
+ const [space, nonce] = commons.transaction.decodeNonce(encoded)
+ return { space, nonce }
+ }
+
+ signer = randomWallet('Nonce selection')
+
+ const config = {
+ threshold: 1,
+ checkpoint: Math.floor(now() / 1000),
+ signers: [{ address: signer.address, weight: 1 }]
+ }
+
+ account = await Account.new({
+ ...defaultArgs,
+ config,
+ orchestrator: new Orchestrator([signer])
+ })
+
+ // use a deployed account, otherwise we end up testing the decorated bundle nonce
+ const response = await account.sendTransaction([], networks[0].chainId)
+ await response?.wait()
+
+ await getEth(account.address, signer1)
+ await getEth(account.address, signer2)
+ })
+
+ it('Should use explicitly set nonces', async () => {
+ let response = await account.sendTransaction(
+ { to: await signer1.getAddress(), value: 1 },
+ networks[0].chainId,
+ undefined,
+ undefined,
+ undefined,
+ { nonceSpace: 6492 }
+ )
+ if (!response) {
+ throw new Error('expected response')
+ }
+
+ let { space, nonce } = getNonce(response)
+
+ expect(space.eq(6492)).to.be.true
+ expect(nonce.eq(0)).to.be.true
+
+ await response.wait()
+
+ response = await account.sendTransaction(
+ { to: await signer1.getAddress(), value: 1 },
+ networks[0].chainId,
+ undefined,
+ undefined,
+ undefined,
+ { nonceSpace: 6492 }
+ )
+ if (!response) {
+ throw new Error('expected response')
+ }
+
+ const encoded = getNonce(response)
+ space = encoded.space
+ nonce = encoded.nonce
+
+ expect(space.eq(6492)).to.be.true
+ expect(nonce.eq(1)).to.be.true
+ })
+
+ it('Should select random nonces by default', async () => {
+ let response = await account.sendTransaction({ to: await signer1.getAddress(), value: 1 }, networks[0].chainId)
+ if (!response) {
+ throw new Error('expected response')
+ }
+
+ const { space: firstSpace, nonce: firstNonce } = getNonce(response)
+
+ expect(firstSpace.eq(0)).to.be.false
+ expect(firstNonce.eq(0)).to.be.true
+
+ // not necessary, parallel execution is ok:
+ // await response.wait()
+
+ response = await account.sendTransaction({ to: await signer1.getAddress(), value: 1 }, networks[0].chainId)
+ if (!response) {
+ throw new Error('expected response')
+ }
+
+ const { space: secondSpace, nonce: secondNonce } = getNonce(response)
+
+ expect(secondSpace.eq(0)).to.be.false
+ expect(secondNonce.eq(0)).to.be.true
+
+ expect(secondSpace.eq(firstSpace)).to.be.false
+ })
+
+ it('Should respect the serial option', async () => {
+ let response = await account.sendTransaction(
+ { to: await signer1.getAddress(), value: 1 },
+ networks[0].chainId,
+ undefined,
+ undefined,
+ undefined,
+ { serial: true }
+ )
+ if (!response) {
+ throw new Error('expected response')
+ }
+
+ let { space, nonce } = getNonce(response)
+
+ expect(space.eq(0)).to.be.true
+ expect(nonce.eq(0)).to.be.true
+
+ await response.wait()
+
+ response = await account.sendTransaction(
+ { to: await signer1.getAddress(), value: 1 },
+ networks[0].chainId,
+ undefined,
+ undefined,
+ undefined,
+ { serial: true }
+ )
+ if (!response) {
+ throw new Error('expected response')
+ }
+
+ const encoded = getNonce(response)
+ space = encoded.space
+ nonce = encoded.nonce
+
+ expect(space.eq(0)).to.be.true
+ expect(nonce.eq(1)).to.be.true
+ })
+ })
+})
+
+let nowCalls = 0
+export function now(): number {
+ if (deterministic) {
+ return Date.parse('2023-02-14T00:00:00.000Z') + 1000 * nowCalls++
+ } else {
+ return Date.now()
+ }
+}
+
+export function randomWallet(entropy: number | string): ethers.Wallet {
+ return new ethers.Wallet(randomBytes(32, entropy))
+}
+
+export function randomFraction(entropy: number | string): number {
+ const bytes = randomBytes(7, entropy)
+ bytes[0] &= 0x1f
+ return bytes.reduce((sum, byte) => 256 * sum + byte) / Number.MAX_SAFE_INTEGER
+}
+
+export function randomBytes(length: number, entropy: number | string): Uint8Array {
+ if (deterministic) {
+ let bytes = ''
+ while (bytes.length < 2 * length) {
+ bytes += ethers.utils.id(`${bytes}${entropy}`).slice(2)
+ }
+ return ethers.utils.arrayify(`0x${bytes.slice(0, 2 * length)}`)
+ } else {
+ return ethers.utils.randomBytes(length)
+ }
+}
diff --git a/packages/account/tests/signer.spec.ts b/packages/account/tests/signer.spec.ts
new file mode 100644
index 0000000000..cdc8aede44
--- /dev/null
+++ b/packages/account/tests/signer.spec.ts
@@ -0,0 +1,896 @@
+import { commons, v1, v2 } from '@0xsequence/core'
+import { migrator } from '@0xsequence/migration'
+import { NetworkConfig } from '@0xsequence/network'
+import { FeeOption, FeeQuote, LocalRelayer, LocalRelayerOptions, Relayer, proto } from '@0xsequence/relayer'
+import { tracker, trackers } from '@0xsequence/sessions'
+import { Orchestrator } from '@0xsequence/signhub'
+import * as utils from '@0xsequence/tests'
+import { Wallet } from '@0xsequence/wallet'
+import * as chai from 'chai'
+import chaiAsPromised from 'chai-as-promised'
+import { ethers } from 'ethers'
+import hardhat from 'hardhat'
+
+import { Account } from '../src/account'
+import { now, randomWallet } from './account.spec'
+import { createERC20 } from '@0xsequence/tests/src/tokens/erc20'
+
+const { expect } = chai.use(chaiAsPromised)
+
+describe('Account signer', () => {
+ let provider1: ethers.providers.JsonRpcProvider
+ let provider2: ethers.providers.JsonRpcProvider
+
+ let signer1: ethers.Signer
+ let signer2: ethers.Signer
+
+ let contexts: commons.context.VersionedContext
+ let networks: NetworkConfig[]
+
+ let tracker: tracker.ConfigTracker & migrator.PresignedMigrationTracker
+
+ let defaultArgs: {
+ contexts: commons.context.VersionedContext
+ networks: NetworkConfig[]
+ tracker: tracker.ConfigTracker & migrator.PresignedMigrationTracker
+ }
+
+ before(async () => {
+ provider1 = new ethers.providers.Web3Provider(hardhat.network.provider as any)
+ provider2 = new ethers.providers.JsonRpcProvider('http://127.0.0.1:7048')
+
+ // TODO: Implement migrations on local config tracker
+ tracker = new trackers.local.LocalConfigTracker(provider1) as any
+
+ networks = [
+ {
+ chainId: 31337,
+ name: 'hardhat',
+ provider: provider1,
+ rpcUrl: '',
+ relayer: new LocalRelayer(provider1.getSigner()),
+ nativeToken: {
+ symbol: 'ETH',
+ name: 'Ether',
+ decimals: 18
+ }
+ },
+ {
+ chainId: 31338,
+ name: 'hardhat2',
+ provider: provider2,
+ rpcUrl: 'http://127.0.0.1:7048',
+ relayer: new LocalRelayer(provider2.getSigner()),
+ nativeToken: {
+ symbol: 'ETH',
+ name: 'Ether',
+ decimals: 18
+ }
+ }
+ ]
+
+ signer1 = provider1.getSigner()
+ signer2 = provider2.getSigner()
+
+ contexts = await utils.context.deploySequenceContexts(signer1)
+ const context2 = await utils.context.deploySequenceContexts(signer2)
+
+ expect(contexts).to.deep.equal(context2)
+
+ defaultArgs = {
+ contexts,
+ networks,
+ tracker
+ }
+ })
+
+ describe('with new account', () => {
+ var account: Account
+ var config: any
+ var accountSigner: ethers.Wallet
+
+ beforeEach(async () => {
+ accountSigner = randomWallet('Should create a new account')
+ config = {
+ threshold: 1,
+ checkpoint: Math.floor(now() / 1000),
+ signers: [{ address: accountSigner.address, weight: 1 }]
+ }
+
+ account = await Account.new({
+ ...defaultArgs,
+ config,
+ orchestrator: new Orchestrator([accountSigner])
+ })
+ })
+ ;[31337, 31338].map((chainId: number) => {
+ context(`for chain ${chainId}`, () => {
+ it('should send transaction', async () => {
+ const signer = account.getSigner(chainId)
+
+ const res = await signer.sendTransaction({
+ to: ethers.Wallet.createRandom().address
+ })
+
+ expect(res).to.exist
+ expect(res.hash).to.exist
+
+ expect(await signer.provider.getTransaction(res.hash)).to.exist
+ })
+
+ it('should send batch transaction', async () => {
+ const signer = account.getSigner(chainId)
+
+ const res = await signer.sendTransaction([
+ {
+ to: ethers.Wallet.createRandom().address
+ },
+ {
+ to: ethers.Wallet.createRandom().address
+ }
+ ])
+
+ expect(res).to.exist
+ expect(res.hash).to.exist
+
+ expect(await signer.provider.getTransaction(res.hash)).to.exist
+ })
+
+ it('should send two transactions (one has deploy)', async () => {
+ const signer = account.getSigner(chainId)
+
+ expect(await signer.provider.getCode(account.address)).to.equal('0x')
+
+ await signer.sendTransaction({
+ to: ethers.Wallet.createRandom().address
+ })
+
+ expect(await signer.provider.getCode(account.address)).to.not.equal('0x')
+
+ const res = await signer.sendTransaction({
+ to: ethers.Wallet.createRandom().address
+ })
+
+ expect(res).to.exist
+ expect(res.hash).to.exist
+
+ expect(await signer.provider.getTransaction(res.hash)).to.exist
+ })
+
+ it('should fail to sign message because not deployed', async () => {
+ const signer = account.getSigner(chainId)
+
+ await expect(signer.signMessage(ethers.utils.randomBytes(32))).to.be.rejectedWith('Wallet cannot validate onchain')
+ })
+
+ it('should sign message after deployment', async () => {
+ const signer = account.getSigner(chainId)
+
+ await signer.sendTransaction({
+ to: ethers.Wallet.createRandom().address
+ })
+
+ expect(await signer.provider.getCode(account.address)).to.not.equal('0x')
+
+ const signature = await signer.signMessage(ethers.utils.randomBytes(32))
+ expect(signature).to.exist
+ expect(signature).to.not.equal('0x')
+ })
+
+ it('should sign a message (undeployed) when using EIP6492', async () => {
+ const signer = account.getSigner(chainId, { cantValidateBehavior: 'eip6492' })
+
+ const signature = await signer.signMessage(ethers.utils.randomBytes(32))
+ expect(signature).to.exist
+ expect(signature).to.not.equal('0x')
+ })
+
+ it('should return account address', async () => {
+ expect(account.address).to.equal(await account.getSigner(chainId).getAddress())
+ })
+
+ it('should return chainId', async () => {
+ expect(chainId).to.equal(await account.getSigner(chainId).getChainId())
+ })
+
+ it('should call select fee even if there is no fee', async () => {
+ let callsToSelectFee = 0
+
+ const tx = {
+ to: ethers.Wallet.createRandom().address
+ }
+
+ const signer = account.getSigner(chainId, {
+ selectFee: async (txs: any, options: FeeOption[]) => {
+ callsToSelectFee++
+ expect(txs).to.deep.equal(tx)
+ expect(options).to.deep.equal([])
+ return undefined
+ }
+ })
+
+ const res = await signer.sendTransaction(tx)
+
+ expect(callsToSelectFee).to.equal(1)
+
+ expect(res).to.exist
+ expect(res.hash).to.exist
+
+ expect(await signer.provider.getTransaction(res.hash)).to.exist
+ })
+
+ describe('select fee', () => {
+ var account: never
+ var getAccount: (feeOptions: FeeOption[], feeQuote: FeeQuote) => Promise
+
+ beforeEach(async () => {
+ class LocalRelayerWithFee extends LocalRelayer {
+ constructor(
+ options: LocalRelayerOptions | ethers.Signer,
+ public feeOptions: FeeOption[],
+ public quote: FeeQuote
+ ) {
+ super(options)
+ }
+
+ async getFeeOptions(
+ _address: string,
+ ..._transactions: commons.transaction.Transaction[]
+ ): Promise<{ options: FeeOption[] }> {
+ return { options: this.feeOptions, quote: this.quote } as any
+ }
+
+ async getFeeOptionsRaw(
+ _entrypoint: string,
+ _data: ethers.utils.BytesLike,
+ _options?: { simulate?: boolean }
+ ): Promise<{ options: FeeOption[] }> {
+ return { options: this.feeOptions, quote: this.quote } as any
+ }
+
+ async gasRefundOptions(
+ _address: string,
+ ..._transactions: commons.transaction.Transaction[]
+ ): Promise {
+ return this.feeOptions
+ }
+
+ async relay(
+ signedTxs: commons.transaction.IntendedTransactionBundle,
+ quote?: FeeQuote | undefined,
+ waitForReceipt?: boolean | undefined
+ ): Promise> {
+ expect(quote).to.equal(this.quote)
+ return super.relay(signedTxs, quote, waitForReceipt)
+ }
+ }
+
+ getAccount = async (feeOptions: FeeOption[], feeQuote: FeeQuote) => {
+ return Account.new({
+ ...defaultArgs,
+ networks: defaultArgs.networks.map(n => {
+ return {
+ ...n,
+ relayer: new LocalRelayerWithFee(chainId === 31337 ? signer1 : signer2, feeOptions, feeQuote)
+ }
+ }),
+ config,
+ orchestrator: new Orchestrator([accountSigner])
+ })
+ }
+ })
+
+ it('should automatically select native fee', async () => {
+ const feeOptions: FeeOption[] = [
+ {
+ token: {
+ chainId,
+ name: 'native',
+ symbol: 'ETH',
+ type: proto.FeeTokenType.UNKNOWN,
+ logoURL: ''
+ },
+ to: ethers.Wallet.createRandom().address,
+ value: '12',
+ gasLimit: 100000
+ }
+ ]
+
+ const feeQuote: FeeQuote = {
+ _tag: 'FeeQuote',
+ _quote: ethers.utils.randomBytes(99)
+ }
+
+ const account = await getAccount(feeOptions, feeQuote)
+ const signer = account.getSigner(chainId)
+
+ await (chainId === 31337 ? signer1 : signer2).sendTransaction({
+ to: account.address,
+ value: 12
+ })
+
+ const res = await signer.sendTransaction({
+ to: ethers.Wallet.createRandom().address
+ })
+
+ expect(res).to.exist
+ expect(res.hash).to.exist
+
+ expect(await signer.provider.getTransaction(res.hash)).to.exist
+ })
+
+ it('should reject if balance is not enough', async () => {
+ const feeOptions: FeeOption[] = [
+ {
+ token: {
+ chainId,
+ name: 'native',
+ symbol: 'ETH',
+ type: proto.FeeTokenType.UNKNOWN,
+ logoURL: ''
+ },
+ to: ethers.Wallet.createRandom().address,
+ value: ethers.utils.parseEther('12').toString(),
+ gasLimit: 100000
+ }
+ ]
+
+ const feeQuote: FeeQuote = {
+ _tag: 'FeeQuote',
+ _quote: ethers.utils.randomBytes(99)
+ }
+
+ const account = await getAccount(feeOptions, feeQuote)
+ const signer = account.getSigner(chainId)
+
+ await (chainId === 31337 ? signer1 : signer2).sendTransaction({
+ to: account.address,
+ value: 11
+ })
+
+ const res = signer.sendTransaction({
+ to: ethers.Wallet.createRandom().address
+ })
+
+ expect(res).to.be.rejectedWith('No fee option available - not enough balance')
+ })
+
+ it('should automatically select ERC20 fee', async () => {
+ const token = await createERC20(chainId === 31337 ? signer1 : signer2, 'Test Token', 'TEST', 18)
+
+ const recipient = ethers.Wallet.createRandom().address
+ const feeOptions: FeeOption[] = [
+ {
+ token: {
+ chainId,
+ name: 'TEST',
+ symbol: 'TEST',
+ type: proto.FeeTokenType.ERC20_TOKEN,
+ logoURL: '',
+ contractAddress: token.address
+ },
+ to: recipient,
+ value: ethers.utils.parseEther('250').toString(),
+ gasLimit: 400000
+ }
+ ]
+
+ const feeQuote: FeeQuote = {
+ _tag: 'FeeQuote',
+ _quote: ethers.utils.randomBytes(99)
+ }
+
+ const account = await getAccount(feeOptions, feeQuote)
+ const signer = account.getSigner(chainId)
+
+ await token.mint(account.address, ethers.utils.parseEther('6000'))
+
+ const res = await signer.sendTransaction({
+ to: ethers.Wallet.createRandom().address
+ })
+
+ expect(res).to.exist
+ expect(res.hash).to.exist
+
+ expect(await signer.provider.getTransaction(res.hash)).to.exist
+ expect(await token.balanceOf(recipient)).to.deep.equal(ethers.utils.parseEther('250'))
+ })
+
+ it('should reject ERC20 fee if not enough balance', async () => {
+ const token = await createERC20(chainId === 31337 ? signer1 : signer2, 'Test Token', 'TEST', 18)
+
+ const recipient = ethers.Wallet.createRandom().address
+ const feeOptions: FeeOption[] = [
+ {
+ token: {
+ chainId,
+ name: 'TEST',
+ symbol: 'TEST',
+ type: proto.FeeTokenType.ERC20_TOKEN,
+ logoURL: '',
+ contractAddress: token.address
+ },
+ to: recipient,
+ value: ethers.utils.parseEther('250').toString(),
+ gasLimit: 400000
+ }
+ ]
+
+ const feeQuote: FeeQuote = {
+ _tag: 'FeeQuote',
+ _quote: ethers.utils.randomBytes(99)
+ }
+
+ const account = await getAccount(feeOptions, feeQuote)
+ const signer = account.getSigner(chainId)
+
+ const res = signer.sendTransaction({
+ to: ethers.Wallet.createRandom().address
+ })
+
+ expect(res).to.be.rejectedWith('No fee option available - not enough balance')
+ })
+
+ it('should automatically select ERC20 fee if user has no ETH', async () => {
+ const token = await createERC20(chainId === 31337 ? signer1 : signer2, 'Test Token', 'TEST', 18)
+
+ const recipient = ethers.Wallet.createRandom().address
+ const feeOptions: FeeOption[] = [
+ {
+ token: {
+ chainId,
+ name: 'native',
+ symbol: 'ETH',
+ type: proto.FeeTokenType.UNKNOWN,
+ logoURL: ''
+ },
+ to: recipient,
+ value: ethers.utils.parseEther('12').toString(),
+ gasLimit: 100000
+ },
+ {
+ token: {
+ chainId,
+ name: 'TEST',
+ symbol: 'TEST',
+ type: proto.FeeTokenType.ERC20_TOKEN,
+ logoURL: '',
+ contractAddress: token.address
+ },
+ to: recipient,
+ value: ethers.utils.parseEther('11').toString(),
+ gasLimit: 400000
+ }
+ ]
+
+ const feeQuote: FeeQuote = {
+ _tag: 'FeeQuote',
+ _quote: ethers.utils.randomBytes(99)
+ }
+
+ const account = await getAccount(feeOptions, feeQuote)
+ const signer = account.getSigner(chainId)
+
+ await token.mint(account.address, ethers.utils.parseEther('11'))
+
+ const res = await signer.sendTransaction({
+ to: ethers.Wallet.createRandom().address
+ })
+
+ expect(res).to.exist
+ expect(res.hash).to.exist
+
+ expect(await signer.provider.getTransaction(res.hash)).to.exist
+ expect(await token.balanceOf(recipient)).to.deep.equal(ethers.utils.parseEther('11'))
+ })
+
+ it('should select fee using callback (first option)', async () => {
+ const recipient = ethers.Wallet.createRandom().address
+
+ const token = await createERC20(chainId === 31337 ? signer1 : signer2, 'Test Token', 'TEST', 18)
+
+ const feeOptions: FeeOption[] = [
+ {
+ token: {
+ chainId,
+ name: 'native',
+ symbol: 'ETH',
+ type: proto.FeeTokenType.UNKNOWN,
+ logoURL: ''
+ },
+ to: recipient,
+ value: '5',
+ gasLimit: 100000
+ },
+ {
+ token: {
+ chainId,
+ name: 'TEST',
+ symbol: 'TEST',
+ type: proto.FeeTokenType.ERC20_TOKEN,
+ logoURL: '',
+ contractAddress: token.address
+ },
+ to: recipient,
+ value: ethers.utils.parseEther('11').toString(),
+ gasLimit: 400000
+ }
+ ]
+
+ const feeQuote: FeeQuote = {
+ _tag: 'FeeQuote',
+ _quote: ethers.utils.randomBytes(99)
+ }
+
+ const account = await getAccount(feeOptions, feeQuote)
+ const signer = account.getSigner(chainId, {
+ selectFee: async (_txs: any, options: FeeOption[]) => {
+ expect(options).to.deep.equal(feeOptions)
+ return options[0]
+ }
+ })
+
+ await (chainId === 31337 ? signer1 : signer2).sendTransaction({
+ to: account.address,
+ value: 5
+ })
+
+ const res = await signer.sendTransaction({
+ to: ethers.Wallet.createRandom().address
+ })
+
+ expect(res).to.exist
+ expect(res.hash).to.exist
+
+ expect(await signer.provider.getTransaction(res.hash)).to.exist
+ expect(await signer.provider.getBalance(recipient)).to.deep.equal(ethers.BigNumber.from('5'))
+ expect(await token.balanceOf(recipient)).to.deep.equal(ethers.utils.parseEther('0'))
+ })
+
+ it('should select fee using callback (second option)', async () => {
+ const recipient = ethers.Wallet.createRandom().address
+
+ const token = await createERC20(chainId === 31337 ? signer1 : signer2, 'Test Token', 'TEST', 18)
+
+ const feeOptions: FeeOption[] = [
+ {
+ token: {
+ chainId,
+ name: 'native',
+ symbol: 'ETH',
+ type: proto.FeeTokenType.UNKNOWN,
+ logoURL: ''
+ },
+ to: recipient,
+ value: '5',
+ gasLimit: 100000
+ },
+ {
+ token: {
+ chainId,
+ name: 'TEST',
+ symbol: 'TEST',
+ type: proto.FeeTokenType.ERC20_TOKEN,
+ logoURL: '',
+ contractAddress: token.address
+ },
+ to: recipient,
+ value: ethers.utils.parseEther('11').toString(),
+ gasLimit: 400000
+ }
+ ]
+
+ const feeQuote: FeeQuote = {
+ _tag: 'FeeQuote',
+ _quote: ethers.utils.randomBytes(99)
+ }
+
+ const account = await getAccount(feeOptions, feeQuote)
+ const signer = account.getSigner(chainId, {
+ selectFee: async (_txs: any, options: FeeOption[]) => {
+ expect(options).to.deep.equal(feeOptions)
+ return options[1]
+ }
+ })
+
+ await token.mint(account.address, ethers.utils.parseEther('11'))
+
+ const res = await signer.sendTransaction({
+ to: ethers.Wallet.createRandom().address
+ })
+
+ expect(res).to.exist
+ expect(res.hash).to.exist
+
+ expect(await signer.provider.getTransaction(res.hash)).to.exist
+ expect(await signer.provider.getBalance(recipient)).to.deep.equal(ethers.BigNumber.from('0'))
+ expect(await token.balanceOf(recipient)).to.deep.equal(ethers.utils.parseEther('11'))
+ })
+ })
+ })
+
+ it('should send transactions on multiple nonce spaces one by one', async () => {
+ const signer1 = account.getSigner(chainId, { nonceSpace: '0x01' })
+ const signer2 = account.getSigner(chainId, { nonceSpace: 2 })
+ const randomSpace = ethers.BigNumber.from(ethers.utils.hexlify(ethers.utils.randomBytes(12)))
+ const signer3 = account.getSigner(chainId, {
+ nonceSpace: randomSpace
+ })
+ const signer4 = account.getSigner(chainId, { nonceSpace: '0x04' })
+ const signer5 = account.getSigner(chainId, { nonceSpace: '0xffffffffffffffffffffffffffffffffffffffff' })
+
+ await signer1.sendTransaction({
+ to: ethers.Wallet.createRandom().address
+ })
+
+ await signer2.sendTransaction({
+ to: ethers.Wallet.createRandom().address
+ })
+
+ await signer3.sendTransaction({
+ to: ethers.Wallet.createRandom().address
+ })
+
+ await signer4.sendTransaction({
+ to: ethers.Wallet.createRandom().address
+ })
+
+ await signer5.sendTransaction({
+ to: ethers.Wallet.createRandom().address
+ })
+
+ // Should have used all spaces
+ const wallet = account.walletForStatus(chainId, await account.status(chainId))
+
+ const nonceSpace1 = await wallet.getNonce('0x01').then(r => ethers.BigNumber.from(r))
+ expect(nonceSpace1.toString()).to.equal('1')
+
+ const nonceSpace2 = await wallet.getNonce(2).then(r => ethers.BigNumber.from(r))
+ expect(nonceSpace2.toString()).to.equal('1')
+
+ const nonceSpace3 = await wallet.getNonce(randomSpace).then(r => ethers.BigNumber.from(r))
+ expect(nonceSpace3.toString()).to.equal('1')
+
+ const nonceSpace4 = await wallet.getNonce('0x04').then(r => ethers.BigNumber.from(r))
+ expect(nonceSpace4.toString()).to.equal('1')
+
+ const nonceSpace5 = await wallet
+ .getNonce('0xffffffffffffffffffffffffffffffffffffffff')
+ .then(r => ethers.BigNumber.from(r))
+ expect(nonceSpace5.toString()).to.equal('1')
+
+ // Unused space should have nonce 0
+ const nonceSpace6 = await wallet.getNonce('0x06').then(r => ethers.BigNumber.from(r))
+ expect(nonceSpace6.toString()).to.equal('0')
+
+ // Using a space should consume it
+ await signer1.sendTransaction({
+ to: ethers.Wallet.createRandom().address
+ })
+
+ const nonceSpace1b = await wallet.getNonce('0x01').then(r => ethers.BigNumber.from(r))
+ expect(nonceSpace1b.toString()).to.equal('2')
+ })
+
+ // Skip if using external network (chainId 31338)
+ // it randomly fails using node 20, it does not seem to be a bug
+ // on sequence.js, instead the external node returns empty data when calling
+ // `getNonce()`, when it should return a value
+ ;(chainId === 31338 ? describe.skip : describe)('multiple nonce spaces', async () => {
+ it('should send transactions on multiple nonce spaces at once', async () => {
+ const signer1 = account.getSigner(chainId, { nonceSpace: '0x01' })
+ const signer2 = account.getSigner(chainId, { nonceSpace: 2 })
+ const randomSpace = ethers.BigNumber.from(ethers.utils.hexlify(ethers.utils.randomBytes(12)))
+ const signer3 = account.getSigner(chainId, {
+ nonceSpace: randomSpace
+ })
+ const signer4 = account.getSigner(chainId, { nonceSpace: '0x04' })
+ const signer5 = account.getSigner(chainId, { nonceSpace: '0xffffffffffffffffffffffffffffffffffffffff' })
+
+ const results = await Promise.all([
+ signer1.sendTransaction({
+ to: ethers.Wallet.createRandom().address
+ }),
+ signer2.sendTransaction({
+ to: ethers.Wallet.createRandom().address
+ }),
+ signer3.sendTransaction({
+ to: ethers.Wallet.createRandom().address
+ }),
+ signer4.sendTransaction({
+ to: ethers.Wallet.createRandom().address
+ }),
+ signer5.sendTransaction({
+ to: ethers.Wallet.createRandom().address
+ })
+ ])
+
+ expect(results).to.have.lengthOf(5)
+ expect(results[0]).to.exist
+ expect(results[0].hash).to.exist
+ expect(results[1]).to.exist
+ expect(results[1].hash).to.exist
+ expect(results[2]).to.exist
+ expect(results[2].hash).to.exist
+ expect(results[3]).to.exist
+ expect(results[3].hash).to.exist
+ expect(results[4]).to.exist
+ expect(results[4].hash).to.exist
+
+ // hashes should be different
+ for (let i = 0; i < results.length; i++) {
+ for (let j = i + 1; j < results.length; j++) {
+ expect(results[i].hash).to.not.equal(results[j].hash)
+ }
+ }
+
+ // Should have used all spaces
+ const wallet = account.walletForStatus(chainId, await account.status(chainId))
+
+ const nonceSpace1 = await wallet.getNonce('0x01').then(r => ethers.BigNumber.from(r))
+ expect(nonceSpace1.toString()).to.equal('1')
+
+ const nonceSpace2 = await wallet.getNonce(2).then(r => ethers.BigNumber.from(r))
+ expect(nonceSpace2.toString()).to.equal('1')
+
+ const nonceSpace3 = await wallet.getNonce(randomSpace).then(r => ethers.BigNumber.from(r))
+ expect(nonceSpace3.toString()).to.equal('1')
+
+ const nonceSpace4 = await wallet.getNonce('0x04').then(r => ethers.BigNumber.from(r))
+ expect(nonceSpace4.toString()).to.equal('1')
+
+ const nonceSpace5 = await wallet
+ .getNonce('0xffffffffffffffffffffffffffffffffffffffff')
+ .then(r => ethers.BigNumber.from(r))
+ expect(nonceSpace5.toString()).to.equal('1')
+
+ // Unused space should have nonce 0
+ const nonceSpace6 = await wallet.getNonce('0x06').then(r => ethers.BigNumber.from(r))
+ expect(nonceSpace6.toString()).to.equal('0')
+
+ // Using a space should consume it
+ await signer1.sendTransaction({
+ to: ethers.Wallet.createRandom().address
+ })
+
+ const nonceSpace1b = await wallet.getNonce('0x01').then(r => ethers.BigNumber.from(r))
+ expect(nonceSpace1b.toString()).to.equal('2')
+ })
+
+ it('should send 100 parallel transactions using different spaces', async () => {
+ const signers = new Array(100).fill(0).map(() =>
+ account.getSigner(chainId, {
+ nonceSpace: ethers.BigNumber.from(ethers.utils.hexlify(ethers.utils.randomBytes(12)))
+ })
+ )
+
+ // Send a random transaction on each one of them
+ await Promise.all(
+ signers.map(signer =>
+ signer.sendTransaction({
+ to: ethers.Wallet.createRandom().address
+ })
+ )
+ )
+
+ // Send another
+ await Promise.all(
+ signers.map(signer =>
+ signer.sendTransaction({
+ to: ethers.Wallet.createRandom().address
+ })
+ )
+ )
+
+ /// ... and another
+ await Promise.all(
+ signers.map(signer =>
+ signer.sendTransaction({
+ to: ethers.Wallet.createRandom().address
+ })
+ )
+ )
+ })
+
+ it('should send multiple transactions on multiple nonce spaces at once', async () => {
+ const signer1 = account.getSigner(chainId, { nonceSpace: '0x01' })
+ const signer2 = account.getSigner(chainId, { nonceSpace: 2 })
+ const randomSpace = ethers.BigNumber.from(ethers.utils.hexlify(ethers.utils.randomBytes(12)))
+
+ const signer3 = account.getSigner(chainId, {
+ nonceSpace: randomSpace
+ })
+ const signer4 = account.getSigner(chainId, { nonceSpace: '0x04' })
+ const signer5 = account.getSigner(chainId, { nonceSpace: '0xffffffffffffffffffffffffffffffffffffffff' })
+
+ await Promise.all([
+ signer1.sendTransaction({
+ to: ethers.Wallet.createRandom().address
+ }),
+ signer2.sendTransaction({
+ to: ethers.Wallet.createRandom().address
+ }),
+ signer3.sendTransaction({
+ to: ethers.Wallet.createRandom().address
+ }),
+ signer4.sendTransaction({
+ to: ethers.Wallet.createRandom().address
+ }),
+ signer5.sendTransaction({
+ to: ethers.Wallet.createRandom().address
+ })
+ ])
+
+ const results = await Promise.all([
+ signer1.sendTransaction({
+ to: ethers.Wallet.createRandom().address
+ }),
+ signer2.sendTransaction({
+ to: ethers.Wallet.createRandom().address
+ }),
+ signer3.sendTransaction({
+ to: ethers.Wallet.createRandom().address
+ }),
+ signer4.sendTransaction({
+ to: ethers.Wallet.createRandom().address
+ }),
+ signer5.sendTransaction({
+ to: ethers.Wallet.createRandom().address
+ })
+ ])
+
+ expect(results).to.have.lengthOf(5)
+ expect(results[0]).to.exist
+ expect(results[0].hash).to.exist
+ expect(results[1]).to.exist
+ expect(results[1].hash).to.exist
+ expect(results[2]).to.exist
+ expect(results[2].hash).to.exist
+ expect(results[3]).to.exist
+ expect(results[3].hash).to.exist
+ expect(results[4]).to.exist
+ expect(results[4].hash).to.exist
+
+ // hashes should be different
+ for (let i = 0; i < results.length; i++) {
+ for (let j = i + 1; j < results.length; j++) {
+ expect(results[i].hash).to.not.equal(results[j].hash)
+ }
+ }
+
+ // Should have used all spaces
+ const wallet = account.walletForStatus(chainId, await account.status(chainId))
+
+ const nonceSpace2 = await wallet.getNonce(2).then(r => ethers.BigNumber.from(r))
+ expect(nonceSpace2.toString()).to.equal('2')
+
+ const nonceSpace1 = await wallet.getNonce('0x01').then(r => ethers.BigNumber.from(r))
+ expect(nonceSpace1.toString()).to.equal('2')
+
+ const nonceSpace3 = await wallet.getNonce(randomSpace).then(r => ethers.BigNumber.from(r))
+ expect(nonceSpace3.toString()).to.equal('2')
+
+ const nonceSpace4 = await wallet.getNonce('0x04').then(r => ethers.BigNumber.from(r))
+ expect(nonceSpace4.toString()).to.equal('2')
+
+ const nonceSpace5 = await wallet
+ .getNonce('0xffffffffffffffffffffffffffffffffffffffff')
+ .then(r => ethers.BigNumber.from(r))
+ expect(nonceSpace5.toString()).to.equal('2')
+
+ // Unused space should have nonce 0
+ const nonceSpace6 = await wallet.getNonce('0x06').then(r => ethers.BigNumber.from(r))
+ expect(nonceSpace6.toString()).to.equal('0')
+
+ // Using a space should consume it
+ await signer1.sendTransaction({
+ to: ethers.Wallet.createRandom().address
+ })
+
+ const nonceSpace1b = await wallet.getNonce('0x01').then(r => ethers.BigNumber.from(r))
+ expect(nonceSpace1b.toString()).to.equal('3')
+ })
+ })
+ })
+ })
+})
diff --git a/packages/api/CHANGELOG.md b/packages/api/CHANGELOG.md
new file mode 100644
index 0000000000..abd71e7933
--- /dev/null
+++ b/packages/api/CHANGELOG.md
@@ -0,0 +1,1733 @@
+# @0xsequence/api
+
+## 1.10.8
+
+### Patch Changes
+
+- update metadata bindings
+
+## 1.10.7
+
+### Patch Changes
+
+- minor fixes to waas client
+
+## 1.10.6
+
+### Patch Changes
+
+- metadata: update bindings
+
+## 1.10.5
+
+### Patch Changes
+
+- network: ape-chain-testnet -> apechain-testnet
+
+## 1.10.4
+
+### Patch Changes
+
+- network: add b3-sepolia, ape-chain-testnet, blast, blast-sepolia
+
+## 1.10.3
+
+### Patch Changes
+
+- typing fix
+
+## 1.10.2
+
+### Patch Changes
+
+- - waas: add getIdToken method
+ - indexer: update api client
+
+## 1.10.1
+
+### Patch Changes
+
+- metadata: update bindings
+
+## 1.10.0
+
+### Minor Changes
+
+- waas release v1.3.0
+
+## 1.9.37
+
+### Patch Changes
+
+- network: adds nativeToken data to NetworkMetadata constants
+
+## 1.9.36
+
+### Patch Changes
+
+- guard: export client
+
+## 1.9.35
+
+### Patch Changes
+
+- guard: update bindings
+
+## 1.9.34
+
+### Patch Changes
+
+- waas: always use lowercase email
+
+## 1.9.33
+
+### Patch Changes
+
+- waas: umd build
+
+## 1.9.32
+
+### Patch Changes
+
+- indexer: update bindings
+
+## 1.9.31
+
+### Patch Changes
+
+- metadata: token directory changes
+
+## 1.9.30
+
+### Patch Changes
+
+- update
+
+## 1.9.29
+
+### Patch Changes
+
+- disable gnosis chain
+
+## 1.9.28
+
+### Patch Changes
+
+- add utils/merkletree
+
+## 1.9.27
+
+### Patch Changes
+
+- network: optimistic -> optimism
+- waas: remove defaults
+- api, sessions: update bindings
+
+## 1.9.26
+
+### Patch Changes
+
+- - add backend interfaces for pluggable interfaces
+ - introduce @0xsequence/react-native
+ - update pnpm to lockfile v9
+
+## 1.9.25
+
+### Patch Changes
+
+- update webrpc clients with new error types
+
+## 1.9.24
+
+### Patch Changes
+
+- waas: add memoryStore backend to localStore
+
+## 1.9.23
+
+### Patch Changes
+
+- update api client bindings
+
+## 1.9.22
+
+### Patch Changes
+
+- update metadata client bindings
+
+## 1.9.21
+
+### Patch Changes
+
+- api client bindings
+
+## 1.9.20
+
+### Patch Changes
+
+- api client bindings update
+
+## 1.9.19
+
+### Patch Changes
+
+- waas update
+
+## 1.9.18
+
+### Patch Changes
+
+- provider: prohibit dangerous functions
+
+## 1.9.17
+
+### Patch Changes
+
+- network: add xr-sepolia
+
+## 1.9.16
+
+### Patch Changes
+
+- waas: sequence.feeOptions
+
+## 1.9.15
+
+### Patch Changes
+
+- metadata: collection external_link field name fix
+
+## 1.9.14
+
+### Patch Changes
+
+- network: astar-zkatana -> astar-zkyoto
+- network: deprecate polygon mumbai network
+- network: add xai and polygon amoy
+
+## 1.9.13
+
+### Patch Changes
+
+- waas: fix @0xsequence/network dependency
+
+## 1.9.12
+
+### Patch Changes
+
+- indexer: update rpc bindings
+- provider: signMessage: Serialize the BytesLike or string message into hexstring before sending
+- waas: SessionAuthProof
+
+## 1.9.11
+
+### Patch Changes
+
+- metdata, update rpc bindings
+
+## 1.9.10
+
+### Patch Changes
+
+- update metadata rpc bindings
+
+## 1.9.9
+
+### Patch Changes
+
+- metadata, add SequenceCollections rpc client
+
+## 1.9.8
+
+### Patch Changes
+
+- waas client update
+
+## 1.9.7
+
+### Patch Changes
+
+- update rpc client bindings for api, metadata and relayer
+
+## 1.9.6
+
+### Patch Changes
+
+- waas package update
+
+## 1.9.5
+
+### Patch Changes
+
+- RpcRelayer prioritize project access key
+
+## 1.9.4
+
+### Patch Changes
+
+- waas: fix network dependency
+
+## 1.9.3
+
+### Patch Changes
+
+- provider: don't append access key to RPC url if user has already provided it
+
+## 1.9.2
+
+### Patch Changes
+
+- network: add xai-sepolia
+
+## 1.9.1
+
+### Patch Changes
+
+- analytics fix
+
+## 1.9.0
+
+### Minor Changes
+
+- waas release
+
+## 1.8.8
+
+### Patch Changes
+
+- update metadata bindings
+
+## 1.8.7
+
+### Patch Changes
+
+- provider: update databeat to 0.9.1
+
+## 1.8.6
+
+### Patch Changes
+
+- guard: SignedOwnershipProof
+
+## 1.8.5
+
+### Patch Changes
+
+- guard: signOwnershipProof and isSignedOwnershipProof
+
+## 1.8.4
+
+### Patch Changes
+
+- network: add homeverse to networks list
+
+## 1.8.3
+
+### Patch Changes
+
+- api: introduce basic linked wallet support
+
+## 1.8.2
+
+### Patch Changes
+
+- provider: don't initialize analytics unless explicitly requested
+
+## 1.8.1
+
+### Patch Changes
+
+- update to analytics provider
+
+## 1.8.0
+
+### Minor Changes
+
+- provider: project analytics
+
+## 1.7.2
+
+### Patch Changes
+
+- 0xsequence: ChainId should not be exported as a type
+- account, wallet: fix nonce selection
+
+## 1.7.1
+
+### Patch Changes
+
+- network: add missing avalanche logoURI
+
+## 1.7.0
+
+### Minor Changes
+
+- provider: projectAccessKey is now required
+
+### Patch Changes
+
+- network: add NetworkMetadata.logoURI property for all networks
+
+## 1.6.3
+
+### Patch Changes
+
+- network list update
+
+## 1.6.2
+
+### Patch Changes
+
+- auth: projectAccessKey option
+- wallet: use 12 bytes for random space
+
+## 1.6.1
+
+### Patch Changes
+
+- core: add simple config from subdigest support
+- core: fix encode tree with subdigest
+- account: implement buildOnChainSignature on Account
+
+## 1.6.0
+
+### Minor Changes
+
+- account, wallet: parallel transactions by default
+
+### Patch Changes
+
+- provider: emit disconnect on sign out
+
+## 1.5.0
+
+### Minor Changes
+
+- signhub: add 'signing' signer status
+
+### Patch Changes
+
+- auth: Session.open: onAccountAddress callback
+- account: allow empty transaction bundles
+
+## 1.4.9
+
+### Patch Changes
+
+- rename SequenceMetadataClient to SequenceMetadata
+
+## 1.4.8
+
+### Patch Changes
+
+- account: Account.getSigners
+
+## 1.4.7
+
+### Patch Changes
+
+- update indexer client bindings
+
+## 1.4.6
+
+### Patch Changes
+
+- - add sepolia networks, mark goerli as deprecated
+ - update indexer client bindings
+
+## 1.4.5
+
+### Patch Changes
+
+- indexer/metadata: update client bindings
+- auth: selectWallet with new address
+
+## 1.4.4
+
+### Patch Changes
+
+- indexer: update bindings
+- auth: handle jwt expiry
+
+## 1.4.3
+
+### Patch Changes
+
+- guard: return active status from GuardSigner.getAuthMethods
+
+## 1.4.2
+
+### Patch Changes
+
+- guard: update bindings
+
+## 1.4.1
+
+### Patch Changes
+
+- network: remove unused networks
+- signhub: orchestrator interface
+- guard: auth methods interface
+- guard: update bindings for pin and totp
+- guard: no more retry logic
+
+## 1.4.0
+
+### Minor Changes
+
+- project access key support
+
+## 1.3.0
+
+### Minor Changes
+
+- signhub: account children
+
+### Patch Changes
+
+- guard: do not throw when building deploy transaction
+- network: snowtrace.io -> subnets.avax.network/c-chain
+
+## 1.2.9
+
+### Patch Changes
+
+- account: AccountSigner.sendTransaction simulateForFeeOptions
+- relayer: update bindings
+
+## 1.2.8
+
+### Patch Changes
+
+- rename X-Sequence-Token-Key header to X-Access-Key
+
+## 1.2.7
+
+### Patch Changes
+
+- add x-sequence-token-key to clients
+
+## 1.2.6
+
+### Patch Changes
+
+- Fix bind multicall provider
+
+## 1.2.5
+
+### Patch Changes
+
+- Multicall default configuration fixes
+
+## 1.2.4
+
+### Patch Changes
+
+- provider: Adding missing payment provider types to PaymentProviderOption
+- provider: WalletRequestHandler.notifyChainChanged
+
+## 1.2.3
+
+### Patch Changes
+
+- auth, provider: connect to accept optional authorizeNonce
+
+## 1.2.2
+
+### Patch Changes
+
+- provider: allow createContract calls
+- core: check for explicit zero address in contract deployments
+
+## 1.2.1
+
+### Patch Changes
+
+- auth: use sequence api chain id as reference chain id if available
+
+## 1.2.0
+
+### Minor Changes
+
+- split services from session, better local support
+
+## 1.1.15
+
+### Patch Changes
+
+- guard: remove error filtering
+
+## 1.1.14
+
+### Patch Changes
+
+- guard: add GuardSigner.onError
+
+## 1.1.13
+
+### Patch Changes
+
+- provider: pass client version with connect options
+- provider: removing large from BannerSize
+
+## 1.1.12
+
+### Patch Changes
+
+- provider: adding bannerSize to ConnectOptions
+
+## 1.1.11
+
+### Patch Changes
+
+- add homeverse configs
+
+## 1.1.10
+
+### Patch Changes
+
+- handle default EIP6492 on send
+
+## 1.1.9
+
+### Patch Changes
+
+- Custom default EIP6492 on client
+
+## 1.1.8
+
+### Patch Changes
+
+- metadata: searchMetadata: add types filter
+
+## 1.1.7
+
+### Patch Changes
+
+- adding signInWith connect settings option to allow dapps to automatically login their users with a certain provider optimizing the normal authentication flow
+
+## 1.1.6
+
+### Patch Changes
+
+- metadata: searchMetadata: add chainID and excludeTokenMetadata filters
+
+## 1.1.5
+
+### Patch Changes
+
+- account: re-compute meta-transaction id for wallet deployment transactions
+
+## 1.1.4
+
+### Patch Changes
+
+- network: rename base-mainnet to base
+- provider: override isDefaultChain with ConnectOptions.networkId if provided
+
+## 1.1.3
+
+### Patch Changes
+
+- provider: use network id from transport session
+- provider: sign authorization using ConnectOptions.networkId if provided
+
+## 1.1.2
+
+### Patch Changes
+
+- provider: jsonrpc chain id fixes
+
+## 1.1.1
+
+### Patch Changes
+
+- network: add base mainnet and sepolia
+- provider: reject toxic transaction requests
+
+## 1.1.0
+
+### Minor Changes
+
+- Refactor dapp facing provider
+
+## 1.0.5
+
+### Patch Changes
+
+- network: export network constants
+- guard: use the correct global for fetch
+- network: nova-explorer.arbitrum.io -> nova.arbiscan.io
+
+## 1.0.4
+
+### Patch Changes
+
+- provider: accept name or number for networkId
+
+## 1.0.3
+
+### Patch Changes
+
+- Simpler isValidSignature helpers
+
+## 1.0.2
+
+### Patch Changes
+
+- add extra signature validation utils methods
+
+## 1.0.1
+
+### Patch Changes
+
+- add homeverse testnet
+
+## 1.0.0
+
+### Major Changes
+
+- https://sequence.xyz/blog/sequence-wallet-light-state-sync-full-merkle-wallets
+
+## 0.43.34
+
+### Patch Changes
+
+- auth: no jwt for indexer
+
+## 0.43.33
+
+### Patch Changes
+
+- Adding onConnectOptionsChange handler to WalletRequestHandler
+
+## 0.43.32
+
+### Patch Changes
+
+- add Base Goerli network
+
+## 0.43.31
+
+### Patch Changes
+
+- remove AuxDataProvider, add promptSignInConnect
+
+## 0.43.30
+
+### Patch Changes
+
+- add arbitrum goerli testnet
+
+## 0.43.29
+
+### Patch Changes
+
+- provider: check availability of window object
+
+## 0.43.28
+
+### Patch Changes
+
+- update api bindings
+
+## 0.43.27
+
+### Patch Changes
+
+- Add rpc is sequence method
+
+## 0.43.26
+
+### Patch Changes
+
+- add zkevm url to enum
+
+## 0.43.25
+
+### Patch Changes
+
+- added polygon zkevm to mainnet networks
+
+## 0.43.24
+
+### Patch Changes
+
+- name change from zkevm to polygon-zkevm
+
+## 0.43.23
+
+### Patch Changes
+
+- update zkEVM name to Polygon zkEVM
+
+## 0.43.22
+
+### Patch Changes
+
+- add zkevm chain
+
+## 0.43.21
+
+### Patch Changes
+
+- api: update client bindings
+
+## 0.43.20
+
+### Patch Changes
+
+- indexer: update bindings
+
+## 0.43.19
+
+### Patch Changes
+
+- session proof update
+
+## 0.43.18
+
+### Patch Changes
+
+- rpc client global check, hardening
+
+## 0.43.17
+
+### Patch Changes
+
+- rpc clients, check of 'global' is defined
+
+## 0.43.16
+
+### Patch Changes
+
+- ethers peerDep to v5, update rpc client global use
+
+## 0.43.15
+
+### Patch Changes
+
+- - provider: expand receiver type on some util methods
+
+## 0.43.14
+
+### Patch Changes
+
+- bump
+
+## 0.43.13
+
+### Patch Changes
+
+- update rpc bindings
+
+## 0.43.12
+
+### Patch Changes
+
+- provider: single wallet init, and add new unregisterWallet() method
+
+## 0.43.11
+
+### Patch Changes
+
+- fix lockfiles
+- re-add mocha type deleter
+
+## 0.43.10
+
+### Patch Changes
+
+- various improvements
+
+## 0.43.9
+
+### Patch Changes
+
+- update deps
+
+## 0.43.8
+
+### Patch Changes
+
+- network: JsonRpcProvider with caching
+
+## 0.43.7
+
+### Patch Changes
+
+- provider: fix wallet network init
+
+## 0.43.6
+
+### Patch Changes
+
+- metadatata: update rpc bindings
+
+## 0.43.5
+
+### Patch Changes
+
+- provider: do not set default network for connect messages
+- provider: forward missing error message
+
+## 0.43.4
+
+### Patch Changes
+
+- no-change version bump to fix incorrectly tagged snapshot build
+
+## 0.43.3
+
+### Patch Changes
+
+- metadata: update bindings
+
+## 0.43.2
+
+### Patch Changes
+
+- provider: implement connectUnchecked
+
+## 0.43.1
+
+### Patch Changes
+
+- update to latest ethauth dep
+
+## 0.43.0
+
+### Minor Changes
+
+- move ethers to a peer dependency
+
+## 0.42.10
+
+### Patch Changes
+
+- add auxDataProvider
+
+## 0.42.9
+
+### Patch Changes
+
+- provider: add eip-191 exceptions
+
+## 0.42.8
+
+### Patch Changes
+
+- provider: skip setting intent origin if we're unity plugin
+
+## 0.42.7
+
+### Patch Changes
+
+- Add sign in options to connection settings
+
+## 0.42.6
+
+### Patch Changes
+
+- api bindings update
+
+## 0.42.5
+
+### Patch Changes
+
+- relayer: don't treat missing receipt as hard failure
+
+## 0.42.4
+
+### Patch Changes
+
+- provider: add custom app protocol to connect options
+
+## 0.42.3
+
+### Patch Changes
+
+- update api bindings
+
+## 0.42.2
+
+### Patch Changes
+
+- disable rinkeby network
+
+## 0.42.1
+
+### Patch Changes
+
+- wallet: optional waitForReceipt parameter
+
+## 0.42.0
+
+### Minor Changes
+
+- relayer: estimateGasLimits -> simulate
+- add simulator package
+
+### Patch Changes
+
+- transactions: fix flattenAuxTransactions
+- provider: only filter nullish values
+- provider: re-map transaction 'gas' back to 'gasLimit'
+
+## 0.41.3
+
+### Patch Changes
+
+- api bindings update
+
+## 0.41.2
+
+### Patch Changes
+
+- api bindings update
+
+## 0.41.1
+
+### Patch Changes
+
+- update default networks
+
+## 0.41.0
+
+### Minor Changes
+
+- relayer: fix Relayer.wait() interface
+
+ The interface for calling Relayer.wait() has changed. Instead of a single optional ill-defined timeout/delay parameter, there are three optional parameters, in order:
+
+ - timeout: the maximum time to wait for the transaction receipt
+ - delay: the polling interval, i.e. the time to wait between requests
+ - maxFails: the maximum number of hard failures to tolerate before giving up
+
+ Please update your codebase accordingly.
+
+- relayer: add optional waitForReceipt parameter to Relayer.relay
+
+ The behaviour of Relayer.relay() was not well-defined with respect to whether or not it waited for a receipt.
+ This change allows the caller to specify whether to wait or not, with the default behaviour being to wait.
+
+### Patch Changes
+
+- relayer: wait receipt retry logic
+- fix wrapped object error
+- provider: forward delegateCall and revertOnError transaction fields
+
+## 0.40.6
+
+### Patch Changes
+
+- add arbitrum-nova chain
+
+## 0.40.5
+
+### Patch Changes
+
+- api: update bindings
+
+## 0.40.4
+
+### Patch Changes
+
+- add unreal transport
+
+## 0.40.3
+
+### Patch Changes
+
+- provider: fix MessageToSign message type
+
+## 0.40.2
+
+### Patch Changes
+
+- Wallet provider, loadSession method
+
+## 0.40.1
+
+### Patch Changes
+
+- export sequence.initWallet and sequence.getWallet
+
+## 0.40.0
+
+### Minor Changes
+
+- add sequence.initWallet(network, config) and sequence.getWallet() helper methods
+
+## 0.39.6
+
+### Patch Changes
+
+- indexer: update client bindings
+
+## 0.39.5
+
+### Patch Changes
+
+- provider: fix networkRpcUrl config option
+
+## 0.39.4
+
+### Patch Changes
+
+- api: update client bindings
+
+## 0.39.3
+
+### Patch Changes
+
+- add request method on Web3Provider
+
+## 0.39.2
+
+### Patch Changes
+
+- update umd name
+
+## 0.39.1
+
+### Patch Changes
+
+- add Aurora network
+- add origin info for accountsChanged event to handle it per dapp
+
+## 0.39.0
+
+### Minor Changes
+
+- abstract window.localStorage to interface type
+
+## 0.38.2
+
+### Patch Changes
+
+- provider: add Settings.defaultPurchaseAmount
+
+## 0.38.1
+
+### Patch Changes
+
+- update api and metadata rpc bindings
+
+## 0.38.0
+
+### Minor Changes
+
+- api: update bindings, change TokenPrice interface
+- bridge: remove @0xsequence/bridge package
+- api: update bindings, rename ContractCallArg to TupleComponent
+
+## 0.37.1
+
+### Patch Changes
+
+- Add back sortNetworks - Removing sorting was a breaking change for dapps on older versions which directly integrate sequence.
+
+## 0.37.0
+
+### Minor Changes
+
+- network related fixes and improvements
+- api: bindings: exchange rate lookups
+
+## 0.36.13
+
+### Patch Changes
+
+- api: update bindings with new price endpoints
+
+## 0.36.12
+
+### Patch Changes
+
+- wallet: skip remote signers if not needed
+- auth: check that signature meets threshold before requesting auth token
+
+## 0.36.11
+
+### Patch Changes
+
+- Prefix EIP191 message on wallet-request-handler
+
+## 0.36.10
+
+### Patch Changes
+
+- support bannerUrl on connect
+
+## 0.36.9
+
+### Patch Changes
+
+- minor dev xp improvements
+
+## 0.36.8
+
+### Patch Changes
+
+- more connect options (theme, payment providers, funding currencies)
+
+## 0.36.7
+
+### Patch Changes
+
+- fix missing break
+
+## 0.36.6
+
+### Patch Changes
+
+- wallet_switchEthereumChain support
+
+## 0.36.5
+
+### Patch Changes
+
+- auth: bump ethauth to 0.7.0
+ network, wallet: don't assume position of auth network in list
+ api/indexer/metadata: trim trailing slash on hostname, and add endpoint urls
+ relayer: Allow to specify local relayer transaction parameters like gas price or gas limit
+
+## 0.36.4
+
+### Patch Changes
+
+- Updating list of chain ids to include other ethereum compatible chains
+
+## 0.36.3
+
+### Patch Changes
+
+- provider: pass connect options to prompter methods
+
+## 0.36.2
+
+### Patch Changes
+
+- transactions: Setting target to 0x0 when empty to during SequenceTxAbiEncode
+
+## 0.36.1
+
+### Patch Changes
+
+- metadata: update client with more fields
+
+## 0.36.0
+
+### Minor Changes
+
+- relayer, wallet: fee quote support
+
+## 0.35.12
+
+### Patch Changes
+
+- provider: rename wallet.commands to wallet.utils
+
+## 0.35.11
+
+### Patch Changes
+
+- provider/utils: smoother message validation
+
+## 0.35.10
+
+### Patch Changes
+
+- upgrade deps
+
+## 0.35.9
+
+### Patch Changes
+
+- provider: window-transport override event handlers with new wallet instance
+
+## 0.35.8
+
+### Patch Changes
+
+- provider: async wallet sign in improvements
+
+## 0.35.7
+
+### Patch Changes
+
+- config: cache wallet configs
+
+## 0.35.6
+
+### Patch Changes
+
+- provider: support async signin of wallet request handler
+
+## 0.35.5
+
+### Patch Changes
+
+- wallet: skip threshold check during fee estimation
+
+## 0.35.4
+
+### Patch Changes
+
+- - browser extension mode, center window
+
+## 0.35.3
+
+### Patch Changes
+
+- - update window position when in browser extension mode
+
+## 0.35.2
+
+### Patch Changes
+
+- - provider: WindowMessageHandler accept optional windowHref
+
+## 0.35.1
+
+### Patch Changes
+
+- wallet: update config on undeployed too
+
+## 0.35.0
+
+### Minor Changes
+
+- - config: add buildStubSignature
+ - provider: add checks to signing cases for wallet deployment and config statuses
+ - provider: add prompt for wallet deployment
+ - relayer: add BaseRelayer.prependWalletDeploy
+ - relayer: add Relayer.feeOptions
+ - relayer: account for wallet deployment in fee estimation
+ - transactions: add fromTransactionish
+ - wallet: add Account.prependConfigUpdate
+ - wallet: add Account.getFeeOptions
+
+## 0.34.0
+
+### Minor Changes
+
+- - upgrade deps
+
+## 0.33.1
+
+### Patch Changes
+
+- update bindings
+
+## 0.31.0
+
+### Minor Changes
+
+- - upgrading to ethers v5.5
+
+## 0.30.0
+
+### Minor Changes
+
+- - upgrade most deps
+
+## 0.29.9
+
+### Patch Changes
+
+- update client
+
+## 0.29.8
+
+### Patch Changes
+
+- update api
+
+## 0.29.4
+
+### Patch Changes
+
+- api: update rpc bindings
+
+## 0.29.1
+
+### Patch Changes
+
+- metadata: ContractInfo.decimals is now optional, i.e. may be undefined
+
+ api: new APIs for user storage and isUsingGoogleMail
+
+## 0.29.0
+
+### Minor Changes
+
+- major architectural changes in Sequence design
+
+ - only one API instance, API is no longer a per-chain service
+ - separate per-chain indexer service, API no longer handles indexing
+ - single contract metadata service, API no longer serves metadata
+
+ chaind package has been removed, indexer and metadata packages have been added
+
+ stronger typing with new explicit ChainId type
+
+ multicall fixes and improvements
+
+ forbid "wait" transactions in sendTransactionBatch calls
+
+## 0.28.0
+
+### Minor Changes
+
+- extension provider
+
+## 0.27.0
+
+### Minor Changes
+
+- Add requireFreshSigner lib to sessions
+
+## 0.25.1
+
+### Patch Changes
+
+- Fix build typescrypt issue
+
+## 0.25.0
+
+### Minor Changes
+
+- 10c8af8: Add estimator package
+ Fix multicall few calls bug
+
+## 0.24.0
+
+### Minor Changes
+
+- pass wallet config and nonce to GetMetaTxnNetworkFeeOptions
+
+## 0.23.0
+
+### Minor Changes
+
+- - relayer: offer variety of gas fee options from the relayer service"
+
+## 0.22.2
+
+### Patch Changes
+
+- e1c109e: Fix authProof on expired sessions
+
+## 0.22.1
+
+### Patch Changes
+
+- transport session cache
+
+## 0.22.0
+
+### Minor Changes
+
+- e667b65: Expose all relayer options on networks
+
+## 0.21.5
+
+### Patch Changes
+
+- Give priority to metaTxnId returned by relayer
+
+## 0.21.4
+
+### Patch Changes
+
+- Add has enough signers method
+
+## 0.21.3
+
+### Patch Changes
+
+- add window session cache
+
+## 0.21.2
+
+### Patch Changes
+
+- exception handlind in relayer
+
+## 0.21.0
+
+### Minor Changes
+
+- - fix gas estimation on wallets with large number of signers
+ - update to session handling and wallet config construction upon auth
+
+## 0.20.0
+
+### Minor Changes
+
+- revert JWT request piggybacking
+
+## 0.19.3
+
+### Patch Changes
+
+- jwtAuth visibility, package version sync
+
+## 0.19.0
+
+### Minor Changes
+
+- - provider, improve dapp / wallet transport io
+
+## 0.18.0
+
+### Minor Changes
+
+- relayer improvements and pending transaction handling
+
+## 0.17.0
+
+### Minor Changes
+
+- ArcadeumAPIClient no longer exposes jwtAuth
+
+## 0.16.1
+
+### Patch Changes
+
+- api: add legacy types for bw compat
+
+## 0.16.0
+
+### Minor Changes
+
+- relayer as its own service separate from chaind
+
+## 0.15.1
+
+### Patch Changes
+
+- update api clients
+
+## 0.15.0
+
+### Patch Changes
+
+- - update chaind and api bindings
+ - replace EstimateMetaTxnGasReceipt with UpdateMetaTxnGasLimits and GetMetaTxnNetworkFeeOptions
+
+## 0.14.3
+
+### Patch Changes
+
+- Fix 0xSequence relayer dependencies
+
+## 0.14.2
+
+### Patch Changes
+
+- Add debug logs to rpc-relayer
+
+## 0.14.1
+
+### Patch Changes
+
+- update api client
+
+## 0.14.0
+
+### Minor Changes
+
+- update sequence utils finder which includes optimization
+
+## 0.13.0
+
+### Minor Changes
+
+- Update SequenceUtils deployed contract
+
+## 0.12.1
+
+### Patch Changes
+
+- npm bump
+
+## 0.12.0
+
+### Minor Changes
+
+- provider: improvements to window transport
+
+## 0.11.4
+
+### Patch Changes
+
+- update api client
+
+## 0.11.3
+
+### Patch Changes
+
+- improve openWindow state options handling
+
+## 0.11.2
+
+### Patch Changes
+
+- Fix multicall proxy scopes
+
+## 0.11.1
+
+### Patch Changes
+
+- Add support for dynamic and nested signatures
+
+## 0.11.0
+
+### Minor Changes
+
+- Update wallet context to 1.7 contracts
+
+## 0.10.9
+
+### Patch Changes
+
+- add support for public addresses as signers in session.open
+
+## 0.10.8
+
+### Patch Changes
+
+- Multicall production configuration
+
+## 0.10.7
+
+### Patch Changes
+
+- allow provider transport to force disconnect
+
+## 0.10.6
+
+### Patch Changes
+
+- - fix getWalletState method
+
+## 0.10.5
+
+### Patch Changes
+
+- update relayer gas refund options
+
+## 0.10.4
+
+### Patch Changes
+
+- Update api proto
+
+## 0.10.3
+
+### Patch Changes
+
+- Fix loading config cross-chain
+
+## 0.10.2
+
+### Patch Changes
+
+- - message digest fix
+
+## 0.10.1
+
+### Patch Changes
+
+- upgrade deps
+
+## 0.10.0
+
+### Minor Changes
+
+- Deployed new contracts with ERC1271 signer support
+
+## 0.9.6
+
+### Patch Changes
+
+- Update ABIs for latest sequence contracts
+
+## 0.9.5
+
+### Patch Changes
+
+- Implemented session class
+
+## 0.9.3
+
+### Patch Changes
+
+- - minor improvements
+
+## 0.9.2
+
+### Patch Changes
+
+- - Update api client
+
+## 0.9.1
+
+### Patch Changes
+
+- - patch bump
+
+## 0.9.0
+
+### Minor Changes
+
+- - provider transport hardening
+
+## 0.8.5
+
+### Patch Changes
+
+- - use latest wallet-contracts
+
+## 0.8.4
+
+### Patch Changes
+
+- - minor improvements, name updates and comments
+
+## 0.8.3
+
+### Patch Changes
+
+- - refinements
+
+ - normalize signer address in config
+
+ - provider: getWalletState() method to WalletProvider
+
+## 0.8.2
+
+### Patch Changes
+
+- - field rename and ethauth dependency bump
+
+## 0.8.1
+
+### Patch Changes
+
+- - variety of optimizations
+
+## 0.8.0
+
+### Minor Changes
+
+- - changeset fix
+
+## 0.7.0
+
+### Patch Changes
+
+- 6f11ed7: sequence.js, init release
diff --git a/packages/api/README.md b/packages/api/README.md
new file mode 100644
index 0000000000..6ac423e4d9
--- /dev/null
+++ b/packages/api/README.md
@@ -0,0 +1,4 @@
+@0xsequence/api
+===============
+
+See [0xsequence project page](https://github.com/0xsequence/sequence.js).
diff --git a/packages/services/userdata/eslint.config.js b/packages/api/eslint.config.js
similarity index 100%
rename from packages/services/userdata/eslint.config.js
rename to packages/api/eslint.config.js
diff --git a/packages/api/package.json b/packages/api/package.json
new file mode 100644
index 0000000000..e46e1fe230
--- /dev/null
+++ b/packages/api/package.json
@@ -0,0 +1,22 @@
+{
+ "name": "@0xsequence/api",
+ "version": "2.0.0",
+ "description": "api sub-package for Sequence",
+ "repository": "https://github.com/0xsequence/sequence.js/tree/master/packages/api",
+ "source": "src/index.ts",
+ "main": "dist/0xsequence-api.cjs.js",
+ "module": "dist/0xsequence-api.esm.js",
+ "author": "Horizon Blockchain Games",
+ "license": "Apache-2.0",
+ "scripts": {
+ "test": "echo",
+ "typecheck": "tsc --noEmit"
+ },
+ "dependencies": {},
+ "peerDependencies": {},
+ "devDependencies": {},
+ "files": [
+ "src",
+ "dist"
+ ]
+}
diff --git a/packages/api/src/api.gen.ts b/packages/api/src/api.gen.ts
new file mode 100644
index 0000000000..09dc0423b6
--- /dev/null
+++ b/packages/api/src/api.gen.ts
@@ -0,0 +1,1745 @@
+/* eslint-disable */
+// sequence-api v0.4.0 da72de09959c34a964bb84662ed6bd510f78f5cb
+// --
+// Code generated by webrpc-gen@v0.18.6 with typescript generator. DO NOT EDIT.
+//
+// webrpc-gen -schema=api.ridl -target=typescript -client -out=./clients/api.gen.ts
+
+// WebRPC description and code-gen version
+export const WebRPCVersion = 'v1'
+
+// Schema version of your RIDL schema
+export const WebRPCSchemaVersion = 'v0.4.0'
+
+// Schema hash generated from your RIDL schema
+export const WebRPCSchemaHash = 'da72de09959c34a964bb84662ed6bd510f78f5cb'
+
+//
+// Types
+//
+
+export enum SortOrder {
+ DESC = 'DESC',
+ ASC = 'ASC'
+}
+
+export interface Version {
+ webrpcVersion: string
+ schemaVersion: string
+ schemaHash: string
+ appVersion: string
+}
+
+export interface RuntimeStatus {
+ healthOK: boolean
+ startTime: string
+ uptime: number
+ ver: string
+ branch: string
+ commitHash: string
+ checks: RuntimeChecks
+ numTxnsRelayed: { [key: string]: NumTxnsRelayed }
+}
+
+export interface NumTxnsRelayed {
+ chainID: number
+ prev: number
+ current: number
+ period: number
+}
+
+export interface RuntimeChecks {}
+
+export interface SequenceContext {
+ factory: string
+ mainModule: string
+ mainModuleUpgradable: string
+ guestModule: string
+ utils: string
+}
+
+export interface User {
+ address: string
+ username: string
+ avatar: string
+ bio: string
+ location: string
+ locale: string
+ backup?: boolean
+ backupConfirmed?: boolean
+ maxInvites?: number
+ updatedAt?: string
+ createdAt?: string
+}
+
+export interface WalletBackup {
+ accountAddress: string
+ secretHash: string
+ encryptedWallet: string
+ userConfirmed: boolean
+ updatedAt?: string
+ createdAt?: string
+}
+
+export interface Friend {
+ id: number
+ userAddress: string
+ friendAddress: string
+ nickname: string
+ user?: User
+ createdAt?: string
+}
+
+export interface InviteCode {
+ usesLeft: number
+ ownerAccount: string
+ email?: string
+ url: string
+ createdAt?: string
+ expiresAt?: string
+}
+
+export interface InviteCodeAccount {
+ claimedByUserAddress: string
+ claimedAt?: string
+}
+
+export interface InviteInfo {
+ expiryInHours: number
+ max: number
+ invites: Array
+}
+
+export interface ContractCall {
+ signature: string
+ function: string
+ args: Array
+}
+
+export interface TupleComponent {
+ name?: string
+ type: string
+ value: any
+}
+
+export interface Transaction {
+ delegateCall: boolean
+ revertOnError: boolean
+ gasLimit: string
+ target: string
+ value: string
+ data: string
+ call?: ContractCall
+}
+
+export interface UserStorage {
+ userAddress: string
+ key: string
+ value: any
+}
+
+export interface Token {
+ chainId: number
+ contractAddress: string
+ tokenId?: string
+}
+
+export interface Price {
+ value: number
+ currency: string
+}
+
+export interface TokenPrice {
+ token: Token
+ price?: Price
+ price24hChange?: Price
+ floorPrice: Price
+ buyPrice: Price
+ sellPrice: Price
+ updatedAt: string
+}
+
+export interface ExchangeRate {
+ name: string
+ symbol: string
+ value: number
+ vsCurrency: string
+ currencyType: string
+}
+
+export interface LinkedWallet {
+ id: number
+ walletAddress: string
+ linkedWalletAddress: string
+ createdAt?: string
+}
+
+export interface Page {
+ pageSize?: number
+ page?: number
+ totalRecords?: number
+ column?: string
+ before?: any
+ after?: any
+ sort?: Array
+ more?: boolean
+}
+
+export interface SortBy {
+ column: string
+ order: SortOrder
+}
+
+export interface NftCheckoutParams {
+ name: string
+ imageUrl: string
+ network: string
+ recipientAddress: string
+ blockchainNftId: string
+ contractAddress: string
+ quantity: number
+ decimals?: number
+}
+
+export interface NftCheckout {
+ token: string
+ expiresAt: string
+ orderId: string
+}
+
+export interface SardineOrder {
+ id: string
+ createdAt?: string
+ referenceId: string
+ status: string
+ fiatCurrency: string
+ fiatExchangeRateUSD: number
+ transactionId: string
+ expiresAt?: string
+ total: number
+ subTotal: number
+ transactionFee: number
+ networkFee: number
+ paymentCurrency?: string
+ paymentMethodType?: string
+ transactionType: string
+ name: string
+ price: number
+ imageUrl: string
+ contractAddress?: string
+ transactionHash?: string
+ recipientAddress: string
+}
+
+export interface API {
+ ping(headers?: object, signal?: AbortSignal): Promise
+ version(headers?: object, signal?: AbortSignal): Promise
+ runtimeStatus(headers?: object, signal?: AbortSignal): Promise
+ clock(headers?: object, signal?: AbortSignal): Promise
+ getSequenceContext(headers?: object, signal?: AbortSignal): Promise
+ getAuthToken(args: GetAuthTokenArgs, headers?: object, signal?: AbortSignal): Promise
+ getAuthToken2(args: GetAuthToken2Args, headers?: object, signal?: AbortSignal): Promise
+ sendPasswordlessLink(
+ args: SendPasswordlessLinkArgs,
+ headers?: object,
+ signal?: AbortSignal
+ ): Promise
+ friendList(args: FriendListArgs, headers?: object, signal?: AbortSignal): Promise
+ getFriendByAddress(args: GetFriendByAddressArgs, headers?: object, signal?: AbortSignal): Promise
+ searchFriends(args: SearchFriendsArgs, headers?: object, signal?: AbortSignal): Promise
+ addFriend(args: AddFriendArgs, headers?: object, signal?: AbortSignal): Promise
+ updateFriendNickname(
+ args: UpdateFriendNicknameArgs,
+ headers?: object,
+ signal?: AbortSignal
+ ): Promise
+ removeFriend(args: RemoveFriendArgs, headers?: object, signal?: AbortSignal): Promise
+ contractCall(args: ContractCallArgs, headers?: object, signal?: AbortSignal): Promise
+ decodeContractCall(args: DecodeContractCallArgs, headers?: object, signal?: AbortSignal): Promise
+ lookupContractCallSelectors(
+ args: LookupContractCallSelectorsArgs,
+ headers?: object,
+ signal?: AbortSignal
+ ): Promise
+ userStorageFetch(args: UserStorageFetchArgs, headers?: object, signal?: AbortSignal): Promise
+ userStorageSave(args: UserStorageSaveArgs, headers?: object, signal?: AbortSignal): Promise
+ userStorageDelete(args: UserStorageDeleteArgs, headers?: object, signal?: AbortSignal): Promise
+ userStorageFetchAll(args: UserStorageFetchAllArgs, headers?: object, signal?: AbortSignal): Promise
+ getMoonpayLink(args: GetMoonpayLinkArgs, headers?: object, signal?: AbortSignal): Promise
+ getSardineClientToken(headers?: object, signal?: AbortSignal): Promise
+ getSardineNFTCheckoutToken(
+ args: GetSardineNFTCheckoutTokenArgs,
+ headers?: object,
+ signal?: AbortSignal
+ ): Promise
+ getSardineNFTCheckoutOrderStatus(
+ args: GetSardineNFTCheckoutOrderStatusArgs,
+ headers?: object,
+ signal?: AbortSignal
+ ): Promise
+ resolveENSAddress(args: ResolveENSAddressArgs, headers?: object, signal?: AbortSignal): Promise
+ isValidSignature(args: IsValidSignatureArgs, headers?: object, signal?: AbortSignal): Promise
+ isValidMessageSignature(
+ args: IsValidMessageSignatureArgs,
+ headers?: object,
+ signal?: AbortSignal
+ ): Promise
+ isValidTypedDataSignature(
+ args: IsValidTypedDataSignatureArgs,
+ headers?: object,
+ signal?: AbortSignal
+ ): Promise
+ isValidETHAuthProof(args: IsValidETHAuthProofArgs, headers?: object, signal?: AbortSignal): Promise
+ getCoinPrices(args: GetCoinPricesArgs, headers?: object, signal?: AbortSignal): Promise
+ getCollectiblePrices(
+ args: GetCollectiblePricesArgs,
+ headers?: object,
+ signal?: AbortSignal
+ ): Promise
+ getExchangeRate(args: GetExchangeRateArgs, headers?: object, signal?: AbortSignal): Promise
+ memoryStore(args: MemoryStoreArgs, headers?: object, signal?: AbortSignal): Promise
+ memoryLoad(args: MemoryLoadArgs, headers?: object, signal?: AbortSignal): Promise
+ getInviteInfo(headers?: object, signal?: AbortSignal): Promise
+ isValidAccessCode(args: IsValidAccessCodeArgs, headers?: object, signal?: AbortSignal): Promise
+ internalClaimAccessCode(
+ args: InternalClaimAccessCodeArgs,
+ headers?: object,
+ signal?: AbortSignal
+ ): Promise
+ blockNumberAtTime(args: BlockNumberAtTimeArgs, headers?: object, signal?: AbortSignal): Promise
+ paperSessionSecret(args: PaperSessionSecretArgs, headers?: object, signal?: AbortSignal): Promise
+ paperSessionSecret2(args: PaperSessionSecret2Args, headers?: object, signal?: AbortSignal): Promise
+ linkWallet(args: LinkWalletArgs, headers?: object, signal?: AbortSignal): Promise
+ getLinkedWallets(args: GetLinkedWalletsArgs, headers?: object, signal?: AbortSignal): Promise
+}
+
+export interface PingArgs {}
+
+export interface PingReturn {
+ status: boolean
+}
+export interface VersionArgs {}
+
+export interface VersionReturn {
+ version: Version
+}
+export interface RuntimeStatusArgs {}
+
+export interface RuntimeStatusReturn {
+ status: RuntimeStatus
+}
+export interface ClockArgs {}
+
+export interface ClockReturn {
+ serverTime: string
+}
+export interface GetSequenceContextArgs {}
+
+export interface GetSequenceContextReturn {
+ data: SequenceContext
+}
+export interface GetAuthTokenArgs {
+ ewtString: string
+ testnetMode?: boolean
+}
+
+export interface GetAuthTokenReturn {
+ status: boolean
+ jwtToken: string
+ address: string
+ user?: User
+}
+export interface GetAuthToken2Args {
+ ewtString: string
+ chainID: string
+}
+
+export interface GetAuthToken2Return {
+ status: boolean
+ jwtToken: string
+ address: string
+ user?: User
+}
+export interface SendPasswordlessLinkArgs {
+ email: string
+ redirectUri: string
+ intent: string
+}
+
+export interface SendPasswordlessLinkReturn {
+ status: boolean
+}
+export interface FriendListArgs {
+ nickname?: string
+ page?: Page
+}
+
+export interface FriendListReturn {
+ page: Page
+ friends: Array
+}
+export interface GetFriendByAddressArgs {
+ friendAddress: string
+}
+
+export interface GetFriendByAddressReturn {
+ status: boolean
+ friend: Friend
+}
+export interface SearchFriendsArgs {
+ filterUsername: string
+ page?: Page
+}
+
+export interface SearchFriendsReturn {
+ friends: Array
+}
+export interface AddFriendArgs {
+ friendAddress: string
+ optionalNickname?: string
+}
+
+export interface AddFriendReturn {
+ status: boolean
+ friend?: Friend
+}
+export interface UpdateFriendNicknameArgs {
+ friendAddress: string
+ nickname: string
+}
+
+export interface UpdateFriendNicknameReturn {
+ status: boolean
+ friend?: Friend
+}
+export interface RemoveFriendArgs {
+ friendAddress: string
+}
+
+export interface RemoveFriendReturn {
+ status: boolean
+}
+export interface ContractCallArgs {
+ chainID: string
+ contract: string
+ inputExpr: string
+ outputExpr: string
+ args: Array
+}
+
+export interface ContractCallReturn {
+ returns: Array
+}
+export interface DecodeContractCallArgs {
+ callData: string
+}
+
+export interface DecodeContractCallReturn {
+ call: ContractCall
+}
+export interface LookupContractCallSelectorsArgs {
+ selectors: Array
+}
+
+export interface LookupContractCallSelectorsReturn {
+ signatures: Array>
+}
+export interface UserStorageFetchArgs {
+ key: string
+}
+
+export interface UserStorageFetchReturn {
+ object: any
+}
+export interface UserStorageSaveArgs {
+ key: string
+ object: any
+}
+
+export interface UserStorageSaveReturn {
+ ok: boolean
+}
+export interface UserStorageDeleteArgs {
+ key: string
+}
+
+export interface UserStorageDeleteReturn {
+ ok: boolean
+}
+export interface UserStorageFetchAllArgs {
+ keys?: Array
+}
+
+export interface UserStorageFetchAllReturn {
+ objects: { [key: string]: any }
+}
+export interface GetMoonpayLinkArgs {
+ url: string
+}
+
+export interface GetMoonpayLinkReturn {
+ signedUrl: string
+}
+export interface GetSardineClientTokenArgs {}
+
+export interface GetSardineClientTokenReturn {
+ token: string
+}
+export interface GetSardineNFTCheckoutTokenArgs {
+ params: NftCheckoutParams
+}
+
+export interface GetSardineNFTCheckoutTokenReturn {
+ resp: NftCheckout
+}
+export interface GetSardineNFTCheckoutOrderStatusArgs {
+ orderId: string
+}
+
+export interface GetSardineNFTCheckoutOrderStatusReturn {
+ resp: SardineOrder
+}
+export interface ResolveENSAddressArgs {
+ ens: string
+}
+
+export interface ResolveENSAddressReturn {
+ address: string
+ ok: boolean
+}
+export interface IsValidSignatureArgs {
+ chainId: string
+ walletAddress: string
+ digest: string
+ signature: string
+}
+
+export interface IsValidSignatureReturn {
+ isValid: boolean
+}
+export interface IsValidMessageSignatureArgs {
+ chainId: string
+ walletAddress: string
+ message: string
+ signature: string
+}
+
+export interface IsValidMessageSignatureReturn {
+ isValid: boolean
+}
+export interface IsValidTypedDataSignatureArgs {
+ chainId: string
+ walletAddress: string
+ typedData: any
+ signature: string
+}
+
+export interface IsValidTypedDataSignatureReturn {
+ isValid: boolean
+}
+export interface IsValidETHAuthProofArgs {
+ chainId: string
+ walletAddress: string
+ ethAuthProofString: string
+}
+
+export interface IsValidETHAuthProofReturn {
+ isValid: boolean
+}
+export interface GetCoinPricesArgs {
+ tokens: Array
+}
+
+export interface GetCoinPricesReturn {
+ tokenPrices: Array
+}
+export interface GetCollectiblePricesArgs {
+ tokens: Array
+}
+
+export interface GetCollectiblePricesReturn {
+ tokenPrices: Array
+}
+export interface GetExchangeRateArgs {
+ toCurrency: string
+}
+
+export interface GetExchangeRateReturn {
+ exchangeRate: ExchangeRate
+}
+export interface MemoryStoreArgs {
+ key: string
+ value: string
+}
+
+export interface MemoryStoreReturn {
+ ok: boolean
+}
+export interface MemoryLoadArgs {
+ key: string
+}
+
+export interface MemoryLoadReturn {
+ value: string
+}
+export interface GetInviteInfoArgs {}
+
+export interface GetInviteInfoReturn {
+ inviteInfo: InviteInfo
+}
+export interface IsValidAccessCodeArgs {
+ accessCode: string
+}
+
+export interface IsValidAccessCodeReturn {
+ status: boolean
+}
+export interface InternalClaimAccessCodeArgs {
+ address: string
+ accessCode: string
+}
+
+export interface InternalClaimAccessCodeReturn {
+ status: boolean
+}
+export interface BlockNumberAtTimeArgs {
+ chainId: number
+ timestamps: Array
+}
+
+export interface BlockNumberAtTimeReturn {
+ blocks: Array
+}
+export interface PaperSessionSecretArgs {
+ chainName: string
+ contractAddress: string
+ paramsJson: string
+ contractType: string
+}
+
+export interface PaperSessionSecretReturn {
+ secret: string
+}
+export interface PaperSessionSecret2Args {
+ chainName: string
+ contractAddress: string
+ paramsJson: string
+ abi: string
+}
+
+export interface PaperSessionSecret2Return {
+ secret: string
+}
+export interface LinkWalletArgs {
+ chainId: string
+ walletAddress: string
+ ethAuthProofString: string
+ linkedWalletMessage: string
+ linkedWalletSignature: string
+}
+
+export interface LinkWalletReturn {
+ status: boolean
+ linkedWalletAddress: string
+}
+export interface GetLinkedWalletsArgs {
+ walletAddress: string
+}
+
+export interface GetLinkedWalletsReturn {
+ linkedWallets: Array
+}
+
+//
+// Client
+//
+export class API implements API {
+ protected hostname: string
+ protected fetch: Fetch
+ protected path = '/rpc/API/'
+
+ constructor(hostname: string, fetch: Fetch) {
+ this.hostname = hostname
+ this.fetch = (input: RequestInfo, init?: RequestInit) => fetch(input, init)
+ }
+
+ private url(name: string): string {
+ return this.hostname + this.path + name
+ }
+
+ ping = (headers?: object, signal?: AbortSignal): Promise => {
+ return this.fetch(this.url('Ping'), createHTTPRequest({}, headers, signal)).then(
+ res => {
+ return buildResponse(res).then(_data => {
+ return {
+ status: _data.status
+ }
+ })
+ },
+ error => {
+ throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` })
+ }
+ )
+ }
+
+ version = (headers?: object, signal?: AbortSignal): Promise => {
+ return this.fetch(this.url('Version'), createHTTPRequest({}, headers, signal)).then(
+ res => {
+ return buildResponse(res).then(_data => {
+ return {
+ version: _data.version
+ }
+ })
+ },
+ error => {
+ throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` })
+ }
+ )
+ }
+
+ runtimeStatus = (headers?: object, signal?: AbortSignal): Promise => {
+ return this.fetch(this.url('RuntimeStatus'), createHTTPRequest({}, headers, signal)).then(
+ res => {
+ return buildResponse(res).then(_data => {
+ return {
+ status: _data.status
+ }
+ })
+ },
+ error => {
+ throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` })
+ }
+ )
+ }
+
+ clock = (headers?: object, signal?: AbortSignal): Promise => {
+ return this.fetch(this.url('Clock'), createHTTPRequest({}, headers, signal)).then(
+ res => {
+ return buildResponse(res).then(_data => {
+ return {
+ serverTime: _data.serverTime
+ }
+ })
+ },
+ error => {
+ throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` })
+ }
+ )
+ }
+
+ getSequenceContext = (headers?: object, signal?: AbortSignal): Promise => {
+ return this.fetch(this.url('GetSequenceContext'), createHTTPRequest({}, headers, signal)).then(
+ res => {
+ return buildResponse(res).then(_data => {
+ return {
+ data: _data.data
+ }
+ })
+ },
+ error => {
+ throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` })
+ }
+ )
+ }
+
+ getAuthToken = (args: GetAuthTokenArgs, headers?: object, signal?: AbortSignal): Promise => {
+ return this.fetch(this.url('GetAuthToken'), createHTTPRequest(args, headers, signal)).then(
+ res => {
+ return buildResponse(res).then(_data => {
+ return {
+ status: _data.status,
+ jwtToken: _data.jwtToken,
+ address: _data.address,
+ user: _data.user
+ }
+ })
+ },
+ error => {
+ throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` })
+ }
+ )
+ }
+
+ getAuthToken2 = (args: GetAuthToken2Args, headers?: object, signal?: AbortSignal): Promise => {
+ return this.fetch(this.url('GetAuthToken2'), createHTTPRequest(args, headers, signal)).then(
+ res => {
+ return buildResponse(res).then(_data => {
+ return {
+ status: _data.status,
+ jwtToken: _data.jwtToken,
+ address: _data.address,
+ user: _data.user
+ }
+ })
+ },
+ error => {
+ throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` })
+ }
+ )
+ }
+
+ sendPasswordlessLink = (
+ args: SendPasswordlessLinkArgs,
+ headers?: object,
+ signal?: AbortSignal
+ ): Promise => {
+ return this.fetch(this.url('SendPasswordlessLink'), createHTTPRequest(args, headers, signal)).then(
+ res => {
+ return buildResponse(res).then(_data => {
+ return {
+ status: _data.status
+ }
+ })
+ },
+ error => {
+ throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` })
+ }
+ )
+ }
+
+ friendList = (args: FriendListArgs, headers?: object, signal?: AbortSignal): Promise => {
+ return this.fetch(this.url('FriendList'), createHTTPRequest(args, headers, signal)).then(
+ res => {
+ return buildResponse(res).then(_data => {
+ return {
+ page: _data.page,
+ friends: >_data.friends
+ }
+ })
+ },
+ error => {
+ throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` })
+ }
+ )
+ }
+
+ getFriendByAddress = (
+ args: GetFriendByAddressArgs,
+ headers?: object,
+ signal?: AbortSignal
+ ): Promise => {
+ return this.fetch(this.url('GetFriendByAddress'), createHTTPRequest(args, headers, signal)).then(
+ res => {
+ return buildResponse(res).then(_data => {
+ return {
+ status: _data.status,
+ friend: _data.friend
+ }
+ })
+ },
+ error => {
+ throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` })
+ }
+ )
+ }
+
+ searchFriends = (args: SearchFriendsArgs, headers?: object, signal?: AbortSignal): Promise => {
+ return this.fetch(this.url('SearchFriends'), createHTTPRequest(args, headers, signal)).then(
+ res => {
+ return buildResponse(res).then(_data => {
+ return {
+ friends: >_data.friends
+ }
+ })
+ },
+ error => {
+ throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` })
+ }
+ )
+ }
+
+ addFriend = (args: AddFriendArgs, headers?: object, signal?: AbortSignal): Promise => {
+ return this.fetch(this.url('AddFriend'), createHTTPRequest(args, headers, signal)).then(
+ res => {
+ return buildResponse(res).then(_data => {
+ return {
+ status: _data.status,
+ friend: _data.friend
+ }
+ })
+ },
+ error => {
+ throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` })
+ }
+ )
+ }
+
+ updateFriendNickname = (
+ args: UpdateFriendNicknameArgs,
+ headers?: object,
+ signal?: AbortSignal
+ ): Promise => {
+ return this.fetch(this.url('UpdateFriendNickname'), createHTTPRequest(args, headers, signal)).then(
+ res => {
+ return buildResponse(res).then(_data => {
+ return {
+ status: _data.status,
+ friend: _data.friend
+ }
+ })
+ },
+ error => {
+ throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` })
+ }
+ )
+ }
+
+ removeFriend = (args: RemoveFriendArgs, headers?: object, signal?: AbortSignal): Promise => {
+ return this.fetch(this.url('RemoveFriend'), createHTTPRequest(args, headers, signal)).then(
+ res => {
+ return buildResponse(res).then(_data => {
+ return {
+ status: _data.status
+ }
+ })
+ },
+ error => {
+ throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` })
+ }
+ )
+ }
+
+ contractCall = (args: ContractCallArgs, headers?: object, signal?: AbortSignal): Promise => {
+ return this.fetch(this.url('ContractCall'), createHTTPRequest(args, headers, signal)).then(
+ res => {
+ return buildResponse(res).then(_data => {
+ return {
+ returns: >_data.returns
+ }
+ })
+ },
+ error => {
+ throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` })
+ }
+ )
+ }
+
+ decodeContractCall = (
+ args: DecodeContractCallArgs,
+ headers?: object,
+ signal?: AbortSignal
+ ): Promise => {
+ return this.fetch(this.url('DecodeContractCall'), createHTTPRequest(args, headers, signal)).then(
+ res => {
+ return buildResponse(res).then(_data => {
+ return {
+ call: _data.call
+ }
+ })
+ },
+ error => {
+ throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` })
+ }
+ )
+ }
+
+ lookupContractCallSelectors = (
+ args: LookupContractCallSelectorsArgs,
+ headers?: object,
+ signal?: AbortSignal
+ ): Promise => {
+ return this.fetch(this.url('LookupContractCallSelectors'), createHTTPRequest(args, headers, signal)).then(
+ res => {
+ return buildResponse(res).then(_data => {
+ return {
+ signatures: >>_data.signatures
+ }
+ })
+ },
+ error => {
+ throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` })
+ }
+ )
+ }
+
+ userStorageFetch = (args: UserStorageFetchArgs, headers?: object, signal?: AbortSignal): Promise => {
+ return this.fetch(this.url('UserStorageFetch'), createHTTPRequest(args, headers, signal)).then(
+ res => {
+ return buildResponse(res).then(_data => {
+ return {
+ object: _data.object
+ }
+ })
+ },
+ error => {
+ throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` })
+ }
+ )
+ }
+
+ userStorageSave = (args: UserStorageSaveArgs, headers?: object, signal?: AbortSignal): Promise => {
+ return this.fetch(this.url('UserStorageSave'), createHTTPRequest(args, headers, signal)).then(
+ res => {
+ return buildResponse(res).then(_data => {
+ return {
+ ok: _data.ok
+ }
+ })
+ },
+ error => {
+ throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` })
+ }
+ )
+ }
+
+ userStorageDelete = (args: UserStorageDeleteArgs, headers?: object, signal?: AbortSignal): Promise => {
+ return this.fetch(this.url('UserStorageDelete'), createHTTPRequest(args, headers, signal)).then(
+ res => {
+ return buildResponse(res).then(_data => {
+ return {
+ ok: _data.ok
+ }
+ })
+ },
+ error => {
+ throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` })
+ }
+ )
+ }
+
+ userStorageFetchAll = (
+ args: UserStorageFetchAllArgs,
+ headers?: object,
+ signal?: AbortSignal
+ ): Promise => {
+ return this.fetch(this.url('UserStorageFetchAll'), createHTTPRequest(args, headers, signal)).then(
+ res => {
+ return buildResponse(res).then(_data => {
+ return {
+ objects: <{ [key: string]: any }>_data.objects
+ }
+ })
+ },
+ error => {
+ throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` })
+ }
+ )
+ }
+
+ getMoonpayLink = (args: GetMoonpayLinkArgs, headers?: object, signal?: AbortSignal): Promise => {
+ return this.fetch(this.url('GetMoonpayLink'), createHTTPRequest(args, headers, signal)).then(
+ res => {
+ return buildResponse(res).then(_data => {
+ return {
+ signedUrl: _data.signedUrl
+ }
+ })
+ },
+ error => {
+ throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` })
+ }
+ )
+ }
+
+ getSardineClientToken = (headers?: object, signal?: AbortSignal): Promise => {
+ return this.fetch(this.url('GetSardineClientToken'), createHTTPRequest({}, headers, signal)).then(
+ res => {
+ return buildResponse(res).then(_data => {
+ return {
+ token: _data.token
+ }
+ })
+ },
+ error => {
+ throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` })
+ }
+ )
+ }
+
+ getSardineNFTCheckoutToken = (
+ args: GetSardineNFTCheckoutTokenArgs,
+ headers?: object,
+ signal?: AbortSignal
+ ): Promise => {
+ return this.fetch(this.url('GetSardineNFTCheckoutToken'), createHTTPRequest(args, headers, signal)).then(
+ res => {
+ return buildResponse(res).then(_data => {
+ return {
+ resp: _data.resp
+ }
+ })
+ },
+ error => {
+ throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` })
+ }
+ )
+ }
+
+ getSardineNFTCheckoutOrderStatus = (
+ args: GetSardineNFTCheckoutOrderStatusArgs,
+ headers?: object,
+ signal?: AbortSignal
+ ): Promise => {
+ return this.fetch(this.url('GetSardineNFTCheckoutOrderStatus'), createHTTPRequest(args, headers, signal)).then(
+ res => {
+ return buildResponse(res).then(_data => {
+ return {
+ resp: _data.resp
+ }
+ })
+ },
+ error => {
+ throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` })
+ }
+ )
+ }
+
+ resolveENSAddress = (args: ResolveENSAddressArgs, headers?: object, signal?: AbortSignal): Promise => {
+ return this.fetch(this.url('ResolveENSAddress'), createHTTPRequest(args, headers, signal)).then(
+ res => {
+ return buildResponse(res).then(_data => {
+ return {
+ address: _data.address,
+ ok: _data.ok
+ }
+ })
+ },
+ error => {
+ throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` })
+ }
+ )
+ }
+
+ isValidSignature = (args: IsValidSignatureArgs, headers?: object, signal?: AbortSignal): Promise => {
+ return this.fetch(this.url('IsValidSignature'), createHTTPRequest(args, headers, signal)).then(
+ res => {
+ return buildResponse(res).then(_data => {
+ return {
+ isValid: _data.isValid
+ }
+ })
+ },
+ error => {
+ throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` })
+ }
+ )
+ }
+
+ isValidMessageSignature = (
+ args: IsValidMessageSignatureArgs,
+ headers?: object,
+ signal?: AbortSignal
+ ): Promise => {
+ return this.fetch(this.url('IsValidMessageSignature'), createHTTPRequest(args, headers, signal)).then(
+ res => {
+ return buildResponse(res).then(_data => {
+ return {
+ isValid: _data.isValid
+ }
+ })
+ },
+ error => {
+ throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` })
+ }
+ )
+ }
+
+ isValidTypedDataSignature = (
+ args: IsValidTypedDataSignatureArgs,
+ headers?: object,
+ signal?: AbortSignal
+ ): Promise => {
+ return this.fetch(this.url('IsValidTypedDataSignature'), createHTTPRequest(args, headers, signal)).then(
+ res => {
+ return buildResponse(res).then(_data => {
+ return {
+ isValid: _data.isValid
+ }
+ })
+ },
+ error => {
+ throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` })
+ }
+ )
+ }
+
+ isValidETHAuthProof = (
+ args: IsValidETHAuthProofArgs,
+ headers?: object,
+ signal?: AbortSignal
+ ): Promise => {
+ return this.fetch(this.url('IsValidETHAuthProof'), createHTTPRequest(args, headers, signal)).then(
+ res => {
+ return buildResponse(res).then(_data => {
+ return {
+ isValid: _data.isValid
+ }
+ })
+ },
+ error => {
+ throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` })
+ }
+ )
+ }
+
+ getCoinPrices = (args: GetCoinPricesArgs, headers?: object, signal?: AbortSignal): Promise => {
+ return this.fetch(this.url('GetCoinPrices'), createHTTPRequest(args, headers, signal)).then(
+ res => {
+ return buildResponse(res).then(_data => {
+ return {
+ tokenPrices: >_data.tokenPrices
+ }
+ })
+ },
+ error => {
+ throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` })
+ }
+ )
+ }
+
+ getCollectiblePrices = (
+ args: GetCollectiblePricesArgs,
+ headers?: object,
+ signal?: AbortSignal
+ ): Promise => {
+ return this.fetch(this.url('GetCollectiblePrices'), createHTTPRequest(args, headers, signal)).then(
+ res => {
+ return buildResponse(res).then(_data => {
+ return {
+ tokenPrices: >_data.tokenPrices
+ }
+ })
+ },
+ error => {
+ throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` })
+ }
+ )
+ }
+
+ getExchangeRate = (args: GetExchangeRateArgs, headers?: object, signal?: AbortSignal): Promise => {
+ return this.fetch(this.url('GetExchangeRate'), createHTTPRequest(args, headers, signal)).then(
+ res => {
+ return buildResponse(res).then(_data => {
+ return {
+ exchangeRate: _data.exchangeRate
+ }
+ })
+ },
+ error => {
+ throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` })
+ }
+ )
+ }
+
+ memoryStore = (args: MemoryStoreArgs, headers?: object, signal?: AbortSignal): Promise => {
+ return this.fetch(this.url('MemoryStore'), createHTTPRequest(args, headers, signal)).then(
+ res => {
+ return buildResponse(res).then(_data => {
+ return {
+ ok: _data.ok
+ }
+ })
+ },
+ error => {
+ throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` })
+ }
+ )
+ }
+
+ memoryLoad = (args: MemoryLoadArgs, headers?: object, signal?: AbortSignal): Promise => {
+ return this.fetch(this.url('MemoryLoad'), createHTTPRequest(args, headers, signal)).then(
+ res => {
+ return buildResponse(res).then(_data => {
+ return {
+ value: _data.value
+ }
+ })
+ },
+ error => {
+ throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` })
+ }
+ )
+ }
+
+ getInviteInfo = (headers?: object, signal?: AbortSignal): Promise => {
+ return this.fetch(this.url('GetInviteInfo'), createHTTPRequest({}, headers, signal)).then(
+ res => {
+ return buildResponse(res).then(_data => {
+ return {
+ inviteInfo: _data.inviteInfo
+ }
+ })
+ },
+ error => {
+ throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` })
+ }
+ )
+ }
+
+ isValidAccessCode = (args: IsValidAccessCodeArgs, headers?: object, signal?: AbortSignal): Promise => {
+ return this.fetch(this.url('IsValidAccessCode'), createHTTPRequest(args, headers, signal)).then(
+ res => {
+ return buildResponse(res).then(_data => {
+ return {
+ status: _data.status
+ }
+ })
+ },
+ error => {
+ throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` })
+ }
+ )
+ }
+
+ internalClaimAccessCode = (
+ args: InternalClaimAccessCodeArgs,
+ headers?: object,
+ signal?: AbortSignal
+ ): Promise => {
+ return this.fetch(this.url('InternalClaimAccessCode'), createHTTPRequest(args, headers, signal)).then(
+ res => {
+ return buildResponse(res).then(_data => {
+ return {
+ status: _data.status
+ }
+ })
+ },
+ error => {
+ throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` })
+ }
+ )
+ }
+
+ blockNumberAtTime = (args: BlockNumberAtTimeArgs, headers?: object, signal?: AbortSignal): Promise => {
+ return this.fetch(this.url('BlockNumberAtTime'), createHTTPRequest(args, headers, signal)).then(
+ res => {
+ return buildResponse(res).then(_data => {
+ return {
+ blocks: >_data.blocks
+ }
+ })
+ },
+ error => {
+ throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` })
+ }
+ )
+ }
+
+ paperSessionSecret = (
+ args: PaperSessionSecretArgs,
+ headers?: object,
+ signal?: AbortSignal
+ ): Promise => {
+ return this.fetch(this.url('PaperSessionSecret'), createHTTPRequest(args, headers, signal)).then(
+ res => {
+ return buildResponse(res).then(_data => {
+ return {
+ secret: _data.secret
+ }
+ })
+ },
+ error => {
+ throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` })
+ }
+ )
+ }
+
+ paperSessionSecret2 = (
+ args: PaperSessionSecret2Args,
+ headers?: object,
+ signal?: AbortSignal
+ ): Promise => {
+ return this.fetch(this.url('PaperSessionSecret2'), createHTTPRequest(args, headers, signal)).then(
+ res => {
+ return buildResponse(res).then(_data => {
+ return {
+ secret: _data.secret
+ }
+ })
+ },
+ error => {
+ throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` })
+ }
+ )
+ }
+
+ linkWallet = (args: LinkWalletArgs, headers?: object, signal?: AbortSignal): Promise => {
+ return this.fetch(this.url('LinkWallet'), createHTTPRequest(args, headers, signal)).then(
+ res => {
+ return buildResponse(res).then(_data => {
+ return {
+ status: _data.status,
+ linkedWalletAddress: _data.linkedWalletAddress
+ }
+ })
+ },
+ error => {
+ throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` })
+ }
+ )
+ }
+
+ getLinkedWallets = (args: GetLinkedWalletsArgs, headers?: object, signal?: AbortSignal): Promise => {
+ return this.fetch(this.url('GetLinkedWallets'), createHTTPRequest(args, headers, signal)).then(
+ res => {
+ return buildResponse(res).then(_data => {
+ return {
+ linkedWallets: >_data.linkedWallets
+ }
+ })
+ },
+ error => {
+ throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` })
+ }
+ )
+ }
+}
+
+const createHTTPRequest = (body: object = {}, headers: object = {}, signal: AbortSignal | null = null): object => {
+ return {
+ method: 'POST',
+ headers: { ...headers, 'Content-Type': 'application/json' },
+ body: JSON.stringify(body || {}),
+ signal
+ }
+}
+
+const buildResponse = (res: Response): Promise => {
+ return res.text().then(text => {
+ let data
+ try {
+ data = JSON.parse(text)
+ } catch (error) {
+ let message = ''
+ if (error instanceof Error) {
+ message = error.message
+ }
+ throw WebrpcBadResponseError.new({
+ status: res.status,
+ cause: `JSON.parse(): ${message}: response text: ${text}`
+ })
+ }
+ if (!res.ok) {
+ const code: number = typeof data.code === 'number' ? data.code : 0
+ throw (webrpcErrorByCode[code] || WebrpcError).new(data)
+ }
+ return data
+ })
+}
+
+//
+// Errors
+//
+
+export class WebrpcError extends Error {
+ name: string
+ code: number
+ message: string
+ status: number
+ cause?: string
+
+ /** @deprecated Use message instead of msg. Deprecated in webrpc v0.11.0. */
+ msg: string
+
+ constructor(name: string, code: number, message: string, status: number, cause?: string) {
+ super(message)
+ this.name = name || 'WebrpcError'
+ this.code = typeof code === 'number' ? code : 0
+ this.message = message || `endpoint error ${this.code}`
+ this.msg = this.message
+ this.status = typeof status === 'number' ? status : 0
+ this.cause = cause
+ Object.setPrototypeOf(this, WebrpcError.prototype)
+ }
+
+ static new(payload: any): WebrpcError {
+ return new this(payload.error, payload.code, payload.message || payload.msg, payload.status, payload.cause)
+ }
+}
+
+// Webrpc errors
+
+export class WebrpcEndpointError extends WebrpcError {
+ constructor(
+ name: string = 'WebrpcEndpoint',
+ code: number = 0,
+ message: string = 'endpoint error',
+ status: number = 0,
+ cause?: string
+ ) {
+ super(name, code, message, status, cause)
+ Object.setPrototypeOf(this, WebrpcEndpointError.prototype)
+ }
+}
+
+export class WebrpcRequestFailedError extends WebrpcError {
+ constructor(
+ name: string = 'WebrpcRequestFailed',
+ code: number = -1,
+ message: string = 'request failed',
+ status: number = 0,
+ cause?: string
+ ) {
+ super(name, code, message, status, cause)
+ Object.setPrototypeOf(this, WebrpcRequestFailedError.prototype)
+ }
+}
+
+export class WebrpcBadRouteError extends WebrpcError {
+ constructor(
+ name: string = 'WebrpcBadRoute',
+ code: number = -2,
+ message: string = 'bad route',
+ status: number = 0,
+ cause?: string
+ ) {
+ super(name, code, message, status, cause)
+ Object.setPrototypeOf(this, WebrpcBadRouteError.prototype)
+ }
+}
+
+export class WebrpcBadMethodError extends WebrpcError {
+ constructor(
+ name: string = 'WebrpcBadMethod',
+ code: number = -3,
+ message: string = 'bad method',
+ status: number = 0,
+ cause?: string
+ ) {
+ super(name, code, message, status, cause)
+ Object.setPrototypeOf(this, WebrpcBadMethodError.prototype)
+ }
+}
+
+export class WebrpcBadRequestError extends WebrpcError {
+ constructor(
+ name: string = 'WebrpcBadRequest',
+ code: number = -4,
+ message: string = 'bad request',
+ status: number = 0,
+ cause?: string
+ ) {
+ super(name, code, message, status, cause)
+ Object.setPrototypeOf(this, WebrpcBadRequestError.prototype)
+ }
+}
+
+export class WebrpcBadResponseError extends WebrpcError {
+ constructor(
+ name: string = 'WebrpcBadResponse',
+ code: number = -5,
+ message: string = 'bad response',
+ status: number = 0,
+ cause?: string
+ ) {
+ super(name, code, message, status, cause)
+ Object.setPrototypeOf(this, WebrpcBadResponseError.prototype)
+ }
+}
+
+export class WebrpcServerPanicError extends WebrpcError {
+ constructor(
+ name: string = 'WebrpcServerPanic',
+ code: number = -6,
+ message: string = 'server panic',
+ status: number = 0,
+ cause?: string
+ ) {
+ super(name, code, message, status, cause)
+ Object.setPrototypeOf(this, WebrpcServerPanicError.prototype)
+ }
+}
+
+export class WebrpcInternalErrorError extends WebrpcError {
+ constructor(
+ name: string = 'WebrpcInternalError',
+ code: number = -7,
+ message: string = 'internal error',
+ status: number = 0,
+ cause?: string
+ ) {
+ super(name, code, message, status, cause)
+ Object.setPrototypeOf(this, WebrpcInternalErrorError.prototype)
+ }
+}
+
+export class WebrpcClientDisconnectedError extends WebrpcError {
+ constructor(
+ name: string = 'WebrpcClientDisconnected',
+ code: number = -8,
+ message: string = 'client disconnected',
+ status: number = 0,
+ cause?: string
+ ) {
+ super(name, code, message, status, cause)
+ Object.setPrototypeOf(this, WebrpcClientDisconnectedError.prototype)
+ }
+}
+
+export class WebrpcStreamLostError extends WebrpcError {
+ constructor(
+ name: string = 'WebrpcStreamLost',
+ code: number = -9,
+ message: string = 'stream lost',
+ status: number = 0,
+ cause?: string
+ ) {
+ super(name, code, message, status, cause)
+ Object.setPrototypeOf(this, WebrpcStreamLostError.prototype)
+ }
+}
+
+export class WebrpcStreamFinishedError extends WebrpcError {
+ constructor(
+ name: string = 'WebrpcStreamFinished',
+ code: number = -10,
+ message: string = 'stream finished',
+ status: number = 0,
+ cause?: string
+ ) {
+ super(name, code, message, status, cause)
+ Object.setPrototypeOf(this, WebrpcStreamFinishedError.prototype)
+ }
+}
+
+// Schema errors
+
+export class UnauthorizedError extends WebrpcError {
+ constructor(
+ name: string = 'Unauthorized',
+ code: number = 1000,
+ message: string = 'Unauthorized access',
+ status: number = 0,
+ cause?: string
+ ) {
+ super(name, code, message, status, cause)
+ Object.setPrototypeOf(this, UnauthorizedError.prototype)
+ }
+}
+
+export class PermissionDeniedError extends WebrpcError {
+ constructor(
+ name: string = 'PermissionDenied',
+ code: number = 1001,
+ message: string = 'Permission denied',
+ status: number = 0,
+ cause?: string
+ ) {
+ super(name, code, message, status, cause)
+ Object.setPrototypeOf(this, PermissionDeniedError.prototype)
+ }
+}
+
+export class SessionExpiredError extends WebrpcError {
+ constructor(
+ name: string = 'SessionExpired',
+ code: number = 1002,
+ message: string = 'Session expired',
+ status: number = 0,
+ cause?: string
+ ) {
+ super(name, code, message, status, cause)
+ Object.setPrototypeOf(this, SessionExpiredError.prototype)
+ }
+}
+
+export class AbortedError extends WebrpcError {
+ constructor(
+ name: string = 'Aborted',
+ code: number = 1005,
+ message: string = 'Request aborted',
+ status: number = 0,
+ cause?: string
+ ) {
+ super(name, code, message, status, cause)
+ Object.setPrototypeOf(this, AbortedError.prototype)
+ }
+}
+
+export class InvalidArgumentError extends WebrpcError {
+ constructor(
+ name: string = 'InvalidArgument',
+ code: number = 2000,
+ message: string = 'Invalid argument',
+ status: number = 0,
+ cause?: string
+ ) {
+ super(name, code, message, status, cause)
+ Object.setPrototypeOf(this, InvalidArgumentError.prototype)
+ }
+}
+
+export class UnavailableError extends WebrpcError {
+ constructor(
+ name: string = 'Unavailable',
+ code: number = 2002,
+ message: string = 'Unavailable resource',
+ status: number = 0,
+ cause?: string
+ ) {
+ super(name, code, message, status, cause)
+ Object.setPrototypeOf(this, UnavailableError.prototype)
+ }
+}
+
+export class QueryFailedError extends WebrpcError {
+ constructor(
+ name: string = 'QueryFailed',
+ code: number = 2003,
+ message: string = 'Query failed',
+ status: number = 0,
+ cause?: string
+ ) {
+ super(name, code, message, status, cause)
+ Object.setPrototypeOf(this, QueryFailedError.prototype)
+ }
+}
+
+export class NotFoundError extends WebrpcError {
+ constructor(
+ name: string = 'NotFound',
+ code: number = 3000,
+ message: string = 'Resource not found',
+ status: number = 0,
+ cause?: string
+ ) {
+ super(name, code, message, status, cause)
+ Object.setPrototypeOf(this, NotFoundError.prototype)
+ }
+}
+
+export enum errors {
+ WebrpcEndpoint = 'WebrpcEndpoint',
+ WebrpcRequestFailed = 'WebrpcRequestFailed',
+ WebrpcBadRoute = 'WebrpcBadRoute',
+ WebrpcBadMethod = 'WebrpcBadMethod',
+ WebrpcBadRequest = 'WebrpcBadRequest',
+ WebrpcBadResponse = 'WebrpcBadResponse',
+ WebrpcServerPanic = 'WebrpcServerPanic',
+ WebrpcInternalError = 'WebrpcInternalError',
+ WebrpcClientDisconnected = 'WebrpcClientDisconnected',
+ WebrpcStreamLost = 'WebrpcStreamLost',
+ WebrpcStreamFinished = 'WebrpcStreamFinished',
+ Unauthorized = 'Unauthorized',
+ PermissionDenied = 'PermissionDenied',
+ SessionExpired = 'SessionExpired',
+ Aborted = 'Aborted',
+ InvalidArgument = 'InvalidArgument',
+ Unavailable = 'Unavailable',
+ QueryFailed = 'QueryFailed',
+ NotFound = 'NotFound'
+}
+
+const webrpcErrorByCode: { [code: number]: any } = {
+ [0]: WebrpcEndpointError,
+ [-1]: WebrpcRequestFailedError,
+ [-2]: WebrpcBadRouteError,
+ [-3]: WebrpcBadMethodError,
+ [-4]: WebrpcBadRequestError,
+ [-5]: WebrpcBadResponseError,
+ [-6]: WebrpcServerPanicError,
+ [-7]: WebrpcInternalErrorError,
+ [-8]: WebrpcClientDisconnectedError,
+ [-9]: WebrpcStreamLostError,
+ [-10]: WebrpcStreamFinishedError,
+ [1000]: UnauthorizedError,
+ [1001]: PermissionDeniedError,
+ [1002]: SessionExpiredError,
+ [1005]: AbortedError,
+ [2000]: InvalidArgumentError,
+ [2002]: UnavailableError,
+ [2003]: QueryFailedError,
+ [3000]: NotFoundError
+}
+
+export type Fetch = (input: RequestInfo, init?: RequestInit) => Promise
diff --git a/packages/api/src/index.ts b/packages/api/src/index.ts
new file mode 100644
index 0000000000..63b8559678
--- /dev/null
+++ b/packages/api/src/index.ts
@@ -0,0 +1,36 @@
+export * from './userdata.gen.js'
+
+import { UserData as UserdataRpc } from './userdata.gen.js'
+
+export class SequenceUserdataClient extends UserdataRpc {
+ constructor(
+ hostname: string,
+ public projectAccessKey?: string,
+ public jwtAuth?: string,
+ ) {
+ super(hostname.endsWith('/') ? hostname.slice(0, -1) : hostname, fetch)
+ this.fetch = this._fetch
+ }
+
+ _fetch = (input: RequestInfo, init?: RequestInit): Promise => {
+ // automatically include jwt and access key auth header to requests
+ // if its been set on the api client
+ const headers: Record = {}
+
+ const jwtAuth = this.jwtAuth
+ const projectAccessKey = this.projectAccessKey
+
+ if (jwtAuth && jwtAuth.length > 0) {
+ headers['Authorization'] = `BEARER ${jwtAuth}`
+ }
+
+ if (projectAccessKey && projectAccessKey.length > 0) {
+ headers['X-Access-Key'] = projectAccessKey
+ }
+
+ // before the request is made
+ init!.headers = { ...init!.headers, ...headers }
+
+ return fetch(input, init)
+ }
+}
diff --git a/packages/auth/CHANGELOG.md b/packages/auth/CHANGELOG.md
new file mode 100644
index 0000000000..37751e73a0
--- /dev/null
+++ b/packages/auth/CHANGELOG.md
@@ -0,0 +1,4782 @@
+# @0xsequence/auth
+
+## 2.0.0
+
+### Major Changes
+
+- changeset
+
+### Patch Changes
+
+- Updated dependencies
+ - @0xsequence/abi@2.0.0
+ - @0xsequence/account@2.0.0
+ - @0xsequence/api@2.0.0
+ - @0xsequence/core@2.0.0
+ - @0xsequence/indexer@2.0.0
+ - @0xsequence/metadata@2.0.0
+ - @0xsequence/migration@2.0.0
+ - @0xsequence/network@2.0.0
+ - @0xsequence/sessions@2.0.0
+ - @0xsequence/signhub@2.0.0
+ - @0xsequence/utils@2.0.0
+ - @0xsequence/wallet@2.0.0
+
+## 1.10.14
+
+### Patch Changes
+
+- network: add borne-testnet to allNetworks
+- Updated dependencies
+ - @0xsequence/abi@1.10.14
+ - @0xsequence/account@1.10.14
+ - @0xsequence/api@1.10.14
+ - @0xsequence/core@1.10.14
+ - @0xsequence/indexer@1.10.14
+ - @0xsequence/metadata@1.10.14
+ - @0xsequence/migration@1.10.14
+ - @0xsequence/network@1.10.14
+ - @0xsequence/sessions@1.10.14
+ - @0xsequence/signhub@1.10.14
+ - @0xsequence/utils@1.10.14
+ - @0xsequence/wallet@1.10.14
+
+## 1.10.13
+
+### Patch Changes
+
+- network: add borne testnet
+- Updated dependencies
+ - @0xsequence/abi@1.10.13
+ - @0xsequence/account@1.10.13
+ - @0xsequence/api@1.10.13
+ - @0xsequence/core@1.10.13
+ - @0xsequence/indexer@1.10.13
+ - @0xsequence/metadata@1.10.13
+ - @0xsequence/migration@1.10.13
+ - @0xsequence/network@1.10.13
+ - @0xsequence/sessions@1.10.13
+ - @0xsequence/signhub@1.10.13
+ - @0xsequence/utils@1.10.13
+ - @0xsequence/wallet@1.10.13
+
+## 1.10.12
+
+### Patch Changes
+
+- api: update bindings
+- global/window -> globalThis
+- Updated dependencies
+- Updated dependencies
+ - @0xsequence/abi@1.10.12
+ - @0xsequence/account@1.10.12
+ - @0xsequence/api@1.10.12
+ - @0xsequence/core@1.10.12
+ - @0xsequence/indexer@1.10.12
+ - @0xsequence/metadata@1.10.12
+ - @0xsequence/migration@1.10.12
+ - @0xsequence/network@1.10.12
+ - @0xsequence/sessions@1.10.12
+ - @0xsequence/signhub@1.10.12
+ - @0xsequence/utils@1.10.12
+ - @0xsequence/wallet@1.10.12
+
+## 1.10.11
+
+### Patch Changes
+
+- waas: updated intent.gen without webrpc types, errors exported from authenticator.gen
+- Updated dependencies
+ - @0xsequence/abi@1.10.11
+ - @0xsequence/account@1.10.11
+ - @0xsequence/api@1.10.11
+ - @0xsequence/core@1.10.11
+ - @0xsequence/indexer@1.10.11
+ - @0xsequence/metadata@1.10.11
+ - @0xsequence/migration@1.10.11
+ - @0xsequence/network@1.10.11
+ - @0xsequence/sessions@1.10.11
+ - @0xsequence/signhub@1.10.11
+ - @0xsequence/utils@1.10.11
+ - @0xsequence/wallet@1.10.11
+
+## 1.10.10
+
+### Patch Changes
+
+- metadata: update bindings with new contract collections api
+- Updated dependencies
+ - @0xsequence/abi@1.10.10
+ - @0xsequence/account@1.10.10
+ - @0xsequence/api@1.10.10
+ - @0xsequence/core@1.10.10
+ - @0xsequence/indexer@1.10.10
+ - @0xsequence/metadata@1.10.10
+ - @0xsequence/migration@1.10.10
+ - @0xsequence/network@1.10.10
+ - @0xsequence/sessions@1.10.10
+ - @0xsequence/signhub@1.10.10
+ - @0xsequence/utils@1.10.10
+ - @0xsequence/wallet@1.10.10
+
+## 1.10.9
+
+### Patch Changes
+
+- waas minor update
+- Updated dependencies
+ - @0xsequence/abi@1.10.9
+ - @0xsequence/account@1.10.9
+ - @0xsequence/api@1.10.9
+ - @0xsequence/core@1.10.9
+ - @0xsequence/indexer@1.10.9
+ - @0xsequence/metadata@1.10.9
+ - @0xsequence/migration@1.10.9
+ - @0xsequence/network@1.10.9
+ - @0xsequence/sessions@1.10.9
+ - @0xsequence/signhub@1.10.9
+ - @0xsequence/utils@1.10.9
+ - @0xsequence/wallet@1.10.9
+
+## 1.10.8
+
+### Patch Changes
+
+- update metadata bindings
+- Updated dependencies
+ - @0xsequence/abi@1.10.8
+ - @0xsequence/account@1.10.8
+ - @0xsequence/api@1.10.8
+ - @0xsequence/core@1.10.8
+ - @0xsequence/indexer@1.10.8
+ - @0xsequence/metadata@1.10.8
+ - @0xsequence/migration@1.10.8
+ - @0xsequence/network@1.10.8
+ - @0xsequence/sessions@1.10.8
+ - @0xsequence/signhub@1.10.8
+ - @0xsequence/utils@1.10.8
+ - @0xsequence/wallet@1.10.8
+
+## 1.10.7
+
+### Patch Changes
+
+- minor fixes to waas client
+- Updated dependencies
+ - @0xsequence/abi@1.10.7
+ - @0xsequence/account@1.10.7
+ - @0xsequence/api@1.10.7
+ - @0xsequence/core@1.10.7
+ - @0xsequence/indexer@1.10.7
+ - @0xsequence/metadata@1.10.7
+ - @0xsequence/migration@1.10.7
+ - @0xsequence/network@1.10.7
+ - @0xsequence/sessions@1.10.7
+ - @0xsequence/signhub@1.10.7
+ - @0xsequence/utils@1.10.7
+ - @0xsequence/wallet@1.10.7
+
+## 1.10.6
+
+### Patch Changes
+
+- metadata: update bindings
+- Updated dependencies
+ - @0xsequence/abi@1.10.6
+ - @0xsequence/account@1.10.6
+ - @0xsequence/api@1.10.6
+ - @0xsequence/core@1.10.6
+ - @0xsequence/indexer@1.10.6
+ - @0xsequence/metadata@1.10.6
+ - @0xsequence/migration@1.10.6
+ - @0xsequence/network@1.10.6
+ - @0xsequence/sessions@1.10.6
+ - @0xsequence/signhub@1.10.6
+ - @0xsequence/utils@1.10.6
+ - @0xsequence/wallet@1.10.6
+
+## 1.10.5
+
+### Patch Changes
+
+- network: ape-chain-testnet -> apechain-testnet
+- Updated dependencies
+ - @0xsequence/abi@1.10.5
+ - @0xsequence/account@1.10.5
+ - @0xsequence/api@1.10.5
+ - @0xsequence/core@1.10.5
+ - @0xsequence/indexer@1.10.5
+ - @0xsequence/metadata@1.10.5
+ - @0xsequence/migration@1.10.5
+ - @0xsequence/network@1.10.5
+ - @0xsequence/sessions@1.10.5
+ - @0xsequence/signhub@1.10.5
+ - @0xsequence/utils@1.10.5
+ - @0xsequence/wallet@1.10.5
+
+## 1.10.4
+
+### Patch Changes
+
+- network: add b3-sepolia, ape-chain-testnet, blast, blast-sepolia
+- Updated dependencies
+ - @0xsequence/abi@1.10.4
+ - @0xsequence/account@1.10.4
+ - @0xsequence/api@1.10.4
+ - @0xsequence/core@1.10.4
+ - @0xsequence/indexer@1.10.4
+ - @0xsequence/metadata@1.10.4
+ - @0xsequence/migration@1.10.4
+ - @0xsequence/network@1.10.4
+ - @0xsequence/sessions@1.10.4
+ - @0xsequence/signhub@1.10.4
+ - @0xsequence/utils@1.10.4
+ - @0xsequence/wallet@1.10.4
+
+## 1.10.3
+
+### Patch Changes
+
+- typing fix
+- Updated dependencies
+ - @0xsequence/abi@1.10.3
+ - @0xsequence/account@1.10.3
+ - @0xsequence/api@1.10.3
+ - @0xsequence/core@1.10.3
+ - @0xsequence/indexer@1.10.3
+ - @0xsequence/metadata@1.10.3
+ - @0xsequence/migration@1.10.3
+ - @0xsequence/network@1.10.3
+ - @0xsequence/sessions@1.10.3
+ - @0xsequence/signhub@1.10.3
+ - @0xsequence/utils@1.10.3
+ - @0xsequence/wallet@1.10.3
+
+## 1.10.2
+
+### Patch Changes
+
+- - waas: add getIdToken method
+ - indexer: update api client
+- Updated dependencies
+ - @0xsequence/abi@1.10.2
+ - @0xsequence/account@1.10.2
+ - @0xsequence/api@1.10.2
+ - @0xsequence/core@1.10.2
+ - @0xsequence/indexer@1.10.2
+ - @0xsequence/metadata@1.10.2
+ - @0xsequence/migration@1.10.2
+ - @0xsequence/network@1.10.2
+ - @0xsequence/sessions@1.10.2
+ - @0xsequence/signhub@1.10.2
+ - @0xsequence/utils@1.10.2
+ - @0xsequence/wallet@1.10.2
+
+## 1.10.1
+
+### Patch Changes
+
+- metadata: update bindings
+- Updated dependencies
+ - @0xsequence/abi@1.10.1
+ - @0xsequence/account@1.10.1
+ - @0xsequence/api@1.10.1
+ - @0xsequence/core@1.10.1
+ - @0xsequence/indexer@1.10.1
+ - @0xsequence/metadata@1.10.1
+ - @0xsequence/migration@1.10.1
+ - @0xsequence/network@1.10.1
+ - @0xsequence/sessions@1.10.1
+ - @0xsequence/signhub@1.10.1
+ - @0xsequence/utils@1.10.1
+ - @0xsequence/wallet@1.10.1
+
+## 1.10.0
+
+### Minor Changes
+
+- waas release v1.3.0
+
+### Patch Changes
+
+- Updated dependencies
+ - @0xsequence/abi@1.10.0
+ - @0xsequence/account@1.10.0
+ - @0xsequence/api@1.10.0
+ - @0xsequence/core@1.10.0
+ - @0xsequence/indexer@1.10.0
+ - @0xsequence/metadata@1.10.0
+ - @0xsequence/migration@1.10.0
+ - @0xsequence/network@1.10.0
+ - @0xsequence/sessions@1.10.0
+ - @0xsequence/signhub@1.10.0
+ - @0xsequence/utils@1.10.0
+ - @0xsequence/wallet@1.10.0
+
+## 1.9.37
+
+### Patch Changes
+
+- network: adds nativeToken data to NetworkMetadata constants
+- Updated dependencies
+ - @0xsequence/abi@1.9.37
+ - @0xsequence/account@1.9.37
+ - @0xsequence/api@1.9.37
+ - @0xsequence/core@1.9.37
+ - @0xsequence/indexer@1.9.37
+ - @0xsequence/metadata@1.9.37
+ - @0xsequence/migration@1.9.37
+ - @0xsequence/network@1.9.37
+ - @0xsequence/sessions@1.9.37
+ - @0xsequence/signhub@1.9.37
+ - @0xsequence/utils@1.9.37
+ - @0xsequence/wallet@1.9.37
+
+## 1.9.36
+
+### Patch Changes
+
+- guard: export client
+- Updated dependencies
+ - @0xsequence/abi@1.9.36
+ - @0xsequence/account@1.9.36
+ - @0xsequence/api@1.9.36
+ - @0xsequence/core@1.9.36
+ - @0xsequence/indexer@1.9.36
+ - @0xsequence/metadata@1.9.36
+ - @0xsequence/migration@1.9.36
+ - @0xsequence/network@1.9.36
+ - @0xsequence/sessions@1.9.36
+ - @0xsequence/signhub@1.9.36
+ - @0xsequence/utils@1.9.36
+ - @0xsequence/wallet@1.9.36
+
+## 1.9.35
+
+### Patch Changes
+
+- guard: update bindings
+- Updated dependencies
+ - @0xsequence/abi@1.9.35
+ - @0xsequence/account@1.9.35
+ - @0xsequence/api@1.9.35
+ - @0xsequence/core@1.9.35
+ - @0xsequence/indexer@1.9.35
+ - @0xsequence/metadata@1.9.35
+ - @0xsequence/migration@1.9.35
+ - @0xsequence/network@1.9.35
+ - @0xsequence/sessions@1.9.35
+ - @0xsequence/signhub@1.9.35
+ - @0xsequence/utils@1.9.35
+ - @0xsequence/wallet@1.9.35
+
+## 1.9.34
+
+### Patch Changes
+
+- waas: always use lowercase email
+- Updated dependencies
+ - @0xsequence/abi@1.9.34
+ - @0xsequence/account@1.9.34
+ - @0xsequence/api@1.9.34
+ - @0xsequence/core@1.9.34
+ - @0xsequence/indexer@1.9.34
+ - @0xsequence/metadata@1.9.34
+ - @0xsequence/migration@1.9.34
+ - @0xsequence/network@1.9.34
+ - @0xsequence/sessions@1.9.34
+ - @0xsequence/signhub@1.9.34
+ - @0xsequence/utils@1.9.34
+ - @0xsequence/wallet@1.9.34
+
+## 1.9.33
+
+### Patch Changes
+
+- waas: umd build
+- Updated dependencies
+ - @0xsequence/abi@1.9.33
+ - @0xsequence/account@1.9.33
+ - @0xsequence/api@1.9.33
+ - @0xsequence/core@1.9.33
+ - @0xsequence/indexer@1.9.33
+ - @0xsequence/metadata@1.9.33
+ - @0xsequence/migration@1.9.33
+ - @0xsequence/network@1.9.33
+ - @0xsequence/sessions@1.9.33
+ - @0xsequence/signhub@1.9.33
+ - @0xsequence/utils@1.9.33
+ - @0xsequence/wallet@1.9.33
+
+## 1.9.32
+
+### Patch Changes
+
+- indexer: update bindings
+- Updated dependencies
+ - @0xsequence/abi@1.9.32
+ - @0xsequence/account@1.9.32
+ - @0xsequence/api@1.9.32
+ - @0xsequence/core@1.9.32
+ - @0xsequence/indexer@1.9.32
+ - @0xsequence/metadata@1.9.32
+ - @0xsequence/migration@1.9.32
+ - @0xsequence/network@1.9.32
+ - @0xsequence/sessions@1.9.32
+ - @0xsequence/signhub@1.9.32
+ - @0xsequence/utils@1.9.32
+ - @0xsequence/wallet@1.9.32
+
+## 1.9.31
+
+### Patch Changes
+
+- metadata: token directory changes
+- Updated dependencies
+ - @0xsequence/abi@1.9.31
+ - @0xsequence/account@1.9.31
+ - @0xsequence/api@1.9.31
+ - @0xsequence/core@1.9.31
+ - @0xsequence/indexer@1.9.31
+ - @0xsequence/metadata@1.9.31
+ - @0xsequence/migration@1.9.31
+ - @0xsequence/network@1.9.31
+ - @0xsequence/sessions@1.9.31
+ - @0xsequence/signhub@1.9.31
+ - @0xsequence/utils@1.9.31
+ - @0xsequence/wallet@1.9.31
+
+## 1.9.30
+
+### Patch Changes
+
+- update
+- Updated dependencies
+ - @0xsequence/abi@1.9.30
+ - @0xsequence/account@1.9.30
+ - @0xsequence/api@1.9.30
+ - @0xsequence/core@1.9.30
+ - @0xsequence/indexer@1.9.30
+ - @0xsequence/metadata@1.9.30
+ - @0xsequence/migration@1.9.30
+ - @0xsequence/network@1.9.30
+ - @0xsequence/sessions@1.9.30
+ - @0xsequence/signhub@1.9.30
+ - @0xsequence/utils@1.9.30
+ - @0xsequence/wallet@1.9.30
+
+## 1.9.29
+
+### Patch Changes
+
+- disable gnosis chain
+- Updated dependencies
+ - @0xsequence/abi@1.9.29
+ - @0xsequence/account@1.9.29
+ - @0xsequence/api@1.9.29
+ - @0xsequence/core@1.9.29
+ - @0xsequence/indexer@1.9.29
+ - @0xsequence/metadata@1.9.29
+ - @0xsequence/migration@1.9.29
+ - @0xsequence/network@1.9.29
+ - @0xsequence/sessions@1.9.29
+ - @0xsequence/signhub@1.9.29
+ - @0xsequence/utils@1.9.29
+ - @0xsequence/wallet@1.9.29
+
+## 1.9.28
+
+### Patch Changes
+
+- add utils/merkletree
+- Updated dependencies
+ - @0xsequence/abi@1.9.28
+ - @0xsequence/account@1.9.28
+ - @0xsequence/api@1.9.28
+ - @0xsequence/core@1.9.28
+ - @0xsequence/indexer@1.9.28
+ - @0xsequence/metadata@1.9.28
+ - @0xsequence/migration@1.9.28
+ - @0xsequence/network@1.9.28
+ - @0xsequence/sessions@1.9.28
+ - @0xsequence/signhub@1.9.28
+ - @0xsequence/utils@1.9.28
+ - @0xsequence/wallet@1.9.28
+
+## 1.9.27
+
+### Patch Changes
+
+- network: optimistic -> optimism
+- waas: remove defaults
+- api, sessions: update bindings
+- Updated dependencies
+- Updated dependencies
+- Updated dependencies
+ - @0xsequence/abi@1.9.27
+ - @0xsequence/account@1.9.27
+ - @0xsequence/api@1.9.27
+ - @0xsequence/core@1.9.27
+ - @0xsequence/indexer@1.9.27
+ - @0xsequence/metadata@1.9.27
+ - @0xsequence/migration@1.9.27
+ - @0xsequence/network@1.9.27
+ - @0xsequence/sessions@1.9.27
+ - @0xsequence/signhub@1.9.27
+ - @0xsequence/utils@1.9.27
+ - @0xsequence/wallet@1.9.27
+
+## 1.9.26
+
+### Patch Changes
+
+- - add backend interfaces for pluggable interfaces
+ - introduce @0xsequence/react-native
+ - update pnpm to lockfile v9
+- Updated dependencies
+ - @0xsequence/abi@1.9.26
+ - @0xsequence/account@1.9.26
+ - @0xsequence/api@1.9.26
+ - @0xsequence/core@1.9.26
+ - @0xsequence/indexer@1.9.26
+ - @0xsequence/metadata@1.9.26
+ - @0xsequence/migration@1.9.26
+ - @0xsequence/network@1.9.26
+ - @0xsequence/sessions@1.9.26
+ - @0xsequence/signhub@1.9.26
+ - @0xsequence/utils@1.9.26
+ - @0xsequence/wallet@1.9.26
+
+## 1.9.25
+
+### Patch Changes
+
+- update webrpc clients with new error types
+- Updated dependencies
+ - @0xsequence/abi@1.9.25
+ - @0xsequence/account@1.9.25
+ - @0xsequence/api@1.9.25
+ - @0xsequence/core@1.9.25
+ - @0xsequence/indexer@1.9.25
+ - @0xsequence/metadata@1.9.25
+ - @0xsequence/migration@1.9.25
+ - @0xsequence/network@1.9.25
+ - @0xsequence/sessions@1.9.25
+ - @0xsequence/signhub@1.9.25
+ - @0xsequence/utils@1.9.25
+ - @0xsequence/wallet@1.9.25
+
+## 1.9.24
+
+### Patch Changes
+
+- waas: add memoryStore backend to localStore
+- Updated dependencies
+ - @0xsequence/abi@1.9.24
+ - @0xsequence/account@1.9.24
+ - @0xsequence/api@1.9.24
+ - @0xsequence/core@1.9.24
+ - @0xsequence/indexer@1.9.24
+ - @0xsequence/metadata@1.9.24
+ - @0xsequence/migration@1.9.24
+ - @0xsequence/network@1.9.24
+ - @0xsequence/sessions@1.9.24
+ - @0xsequence/signhub@1.9.24
+ - @0xsequence/utils@1.9.24
+ - @0xsequence/wallet@1.9.24
+
+## 1.9.23
+
+### Patch Changes
+
+- update api client bindings
+- Updated dependencies
+ - @0xsequence/abi@1.9.23
+ - @0xsequence/account@1.9.23
+ - @0xsequence/api@1.9.23
+ - @0xsequence/core@1.9.23
+ - @0xsequence/indexer@1.9.23
+ - @0xsequence/metadata@1.9.23
+ - @0xsequence/migration@1.9.23
+ - @0xsequence/network@1.9.23
+ - @0xsequence/sessions@1.9.23
+ - @0xsequence/signhub@1.9.23
+ - @0xsequence/utils@1.9.23
+ - @0xsequence/wallet@1.9.23
+
+## 1.9.22
+
+### Patch Changes
+
+- update metadata client bindings
+- Updated dependencies
+ - @0xsequence/abi@1.9.22
+ - @0xsequence/account@1.9.22
+ - @0xsequence/api@1.9.22
+ - @0xsequence/core@1.9.22
+ - @0xsequence/indexer@1.9.22
+ - @0xsequence/metadata@1.9.22
+ - @0xsequence/migration@1.9.22
+ - @0xsequence/network@1.9.22
+ - @0xsequence/sessions@1.9.22
+ - @0xsequence/signhub@1.9.22
+ - @0xsequence/utils@1.9.22
+ - @0xsequence/wallet@1.9.22
+
+## 1.9.21
+
+### Patch Changes
+
+- api client bindings
+- Updated dependencies
+ - @0xsequence/abi@1.9.21
+ - @0xsequence/account@1.9.21
+ - @0xsequence/api@1.9.21
+ - @0xsequence/core@1.9.21
+ - @0xsequence/indexer@1.9.21
+ - @0xsequence/metadata@1.9.21
+ - @0xsequence/migration@1.9.21
+ - @0xsequence/network@1.9.21
+ - @0xsequence/sessions@1.9.21
+ - @0xsequence/signhub@1.9.21
+ - @0xsequence/utils@1.9.21
+ - @0xsequence/wallet@1.9.21
+
+## 1.9.20
+
+### Patch Changes
+
+- api client bindings update
+- Updated dependencies
+ - @0xsequence/abi@1.9.20
+ - @0xsequence/account@1.9.20
+ - @0xsequence/api@1.9.20
+ - @0xsequence/core@1.9.20
+ - @0xsequence/indexer@1.9.20
+ - @0xsequence/metadata@1.9.20
+ - @0xsequence/migration@1.9.20
+ - @0xsequence/network@1.9.20
+ - @0xsequence/sessions@1.9.20
+ - @0xsequence/signhub@1.9.20
+ - @0xsequence/utils@1.9.20
+ - @0xsequence/wallet@1.9.20
+
+## 1.9.19
+
+### Patch Changes
+
+- waas update
+- Updated dependencies
+ - @0xsequence/abi@1.9.19
+ - @0xsequence/account@1.9.19
+ - @0xsequence/api@1.9.19
+ - @0xsequence/core@1.9.19
+ - @0xsequence/indexer@1.9.19
+ - @0xsequence/metadata@1.9.19
+ - @0xsequence/migration@1.9.19
+ - @0xsequence/network@1.9.19
+ - @0xsequence/sessions@1.9.19
+ - @0xsequence/signhub@1.9.19
+ - @0xsequence/utils@1.9.19
+ - @0xsequence/wallet@1.9.19
+
+## 1.9.18
+
+### Patch Changes
+
+- provider: prohibit dangerous functions
+- Updated dependencies
+ - @0xsequence/abi@1.9.18
+ - @0xsequence/account@1.9.18
+ - @0xsequence/api@1.9.18
+ - @0xsequence/core@1.9.18
+ - @0xsequence/indexer@1.9.18
+ - @0xsequence/metadata@1.9.18
+ - @0xsequence/migration@1.9.18
+ - @0xsequence/network@1.9.18
+ - @0xsequence/sessions@1.9.18
+ - @0xsequence/signhub@1.9.18
+ - @0xsequence/utils@1.9.18
+ - @0xsequence/wallet@1.9.18
+
+## 1.9.17
+
+### Patch Changes
+
+- network: add xr-sepolia
+- Updated dependencies
+ - @0xsequence/network@1.9.17
+ - @0xsequence/abi@1.9.17
+ - @0xsequence/account@1.9.17
+ - @0xsequence/api@1.9.17
+ - @0xsequence/core@1.9.17
+ - @0xsequence/indexer@1.9.17
+ - @0xsequence/metadata@1.9.17
+ - @0xsequence/migration@1.9.17
+ - @0xsequence/sessions@1.9.17
+ - @0xsequence/signhub@1.9.17
+ - @0xsequence/utils@1.9.17
+ - @0xsequence/wallet@1.9.17
+
+## 1.9.16
+
+### Patch Changes
+
+- waas: sequence.feeOptions
+- Updated dependencies
+ - @0xsequence/abi@1.9.16
+ - @0xsequence/account@1.9.16
+ - @0xsequence/api@1.9.16
+ - @0xsequence/core@1.9.16
+ - @0xsequence/indexer@1.9.16
+ - @0xsequence/metadata@1.9.16
+ - @0xsequence/migration@1.9.16
+ - @0xsequence/network@1.9.16
+ - @0xsequence/sessions@1.9.16
+ - @0xsequence/signhub@1.9.16
+ - @0xsequence/utils@1.9.16
+ - @0xsequence/wallet@1.9.16
+
+## 1.9.15
+
+### Patch Changes
+
+- metadata: collection external_link field name fix
+- Updated dependencies
+ - @0xsequence/abi@1.9.15
+ - @0xsequence/account@1.9.15
+ - @0xsequence/api@1.9.15
+ - @0xsequence/core@1.9.15
+ - @0xsequence/indexer@1.9.15
+ - @0xsequence/metadata@1.9.15
+ - @0xsequence/migration@1.9.15
+ - @0xsequence/network@1.9.15
+ - @0xsequence/sessions@1.9.15
+ - @0xsequence/signhub@1.9.15
+ - @0xsequence/utils@1.9.15
+ - @0xsequence/wallet@1.9.15
+
+## 1.9.14
+
+### Patch Changes
+
+- network: astar-zkatana -> astar-zkyoto
+- network: deprecate polygon mumbai network
+- network: add xai and polygon amoy
+- Updated dependencies
+- Updated dependencies
+- Updated dependencies
+ - @0xsequence/abi@1.9.14
+ - @0xsequence/account@1.9.14
+ - @0xsequence/api@1.9.14
+ - @0xsequence/core@1.9.14
+ - @0xsequence/indexer@1.9.14
+ - @0xsequence/metadata@1.9.14
+ - @0xsequence/migration@1.9.14
+ - @0xsequence/network@1.9.14
+ - @0xsequence/sessions@1.9.14
+ - @0xsequence/signhub@1.9.14
+ - @0xsequence/utils@1.9.14
+ - @0xsequence/wallet@1.9.14
+
+## 1.9.13
+
+### Patch Changes
+
+- waas: fix @0xsequence/network dependency
+- Updated dependencies
+ - @0xsequence/abi@1.9.13
+ - @0xsequence/account@1.9.13
+ - @0xsequence/api@1.9.13
+ - @0xsequence/core@1.9.13
+ - @0xsequence/indexer@1.9.13
+ - @0xsequence/metadata@1.9.13
+ - @0xsequence/migration@1.9.13
+ - @0xsequence/network@1.9.13
+ - @0xsequence/sessions@1.9.13
+ - @0xsequence/signhub@1.9.13
+ - @0xsequence/utils@1.9.13
+ - @0xsequence/wallet@1.9.13
+
+## 1.9.12
+
+### Patch Changes
+
+- indexer: update rpc bindings
+- provider: signMessage: Serialize the BytesLike or string message into hexstring before sending
+- waas: SessionAuthProof
+- Updated dependencies
+- Updated dependencies
+- Updated dependencies
+ - @0xsequence/abi@1.9.12
+ - @0xsequence/account@1.9.12
+ - @0xsequence/api@1.9.12
+ - @0xsequence/core@1.9.12
+ - @0xsequence/indexer@1.9.12
+ - @0xsequence/metadata@1.9.12
+ - @0xsequence/migration@1.9.12
+ - @0xsequence/network@1.9.12
+ - @0xsequence/sessions@1.9.12
+ - @0xsequence/signhub@1.9.12
+ - @0xsequence/utils@1.9.12
+ - @0xsequence/wallet@1.9.12
+
+## 1.9.11
+
+### Patch Changes
+
+- metdata, update rpc bindings
+- Updated dependencies
+ - @0xsequence/abi@1.9.11
+ - @0xsequence/account@1.9.11
+ - @0xsequence/api@1.9.11
+ - @0xsequence/core@1.9.11
+ - @0xsequence/indexer@1.9.11
+ - @0xsequence/metadata@1.9.11
+ - @0xsequence/migration@1.9.11
+ - @0xsequence/network@1.9.11
+ - @0xsequence/sessions@1.9.11
+ - @0xsequence/signhub@1.9.11
+ - @0xsequence/utils@1.9.11
+ - @0xsequence/wallet@1.9.11
+
+## 1.9.10
+
+### Patch Changes
+
+- update metadata rpc bindings
+- Updated dependencies
+ - @0xsequence/abi@1.9.10
+ - @0xsequence/account@1.9.10
+ - @0xsequence/api@1.9.10
+ - @0xsequence/core@1.9.10
+ - @0xsequence/indexer@1.9.10
+ - @0xsequence/metadata@1.9.10
+ - @0xsequence/migration@1.9.10
+ - @0xsequence/network@1.9.10
+ - @0xsequence/sessions@1.9.10
+ - @0xsequence/signhub@1.9.10
+ - @0xsequence/utils@1.9.10
+ - @0xsequence/wallet@1.9.10
+
+## 1.9.9
+
+### Patch Changes
+
+- metadata, add SequenceCollections rpc client
+- Updated dependencies
+ - @0xsequence/abi@1.9.9
+ - @0xsequence/account@1.9.9
+ - @0xsequence/api@1.9.9
+ - @0xsequence/core@1.9.9
+ - @0xsequence/indexer@1.9.9
+ - @0xsequence/metadata@1.9.9
+ - @0xsequence/migration@1.9.9
+ - @0xsequence/network@1.9.9
+ - @0xsequence/sessions@1.9.9
+ - @0xsequence/signhub@1.9.9
+ - @0xsequence/utils@1.9.9
+ - @0xsequence/wallet@1.9.9
+
+## 1.9.8
+
+### Patch Changes
+
+- waas client update
+- Updated dependencies
+ - @0xsequence/abi@1.9.8
+ - @0xsequence/account@1.9.8
+ - @0xsequence/api@1.9.8
+ - @0xsequence/core@1.9.8
+ - @0xsequence/indexer@1.9.8
+ - @0xsequence/metadata@1.9.8
+ - @0xsequence/migration@1.9.8
+ - @0xsequence/network@1.9.8
+ - @0xsequence/sessions@1.9.8
+ - @0xsequence/signhub@1.9.8
+ - @0xsequence/utils@1.9.8
+ - @0xsequence/wallet@1.9.8
+
+## 1.9.7
+
+### Patch Changes
+
+- update rpc client bindings for api, metadata and relayer
+- Updated dependencies
+ - @0xsequence/abi@1.9.7
+ - @0xsequence/account@1.9.7
+ - @0xsequence/api@1.9.7
+ - @0xsequence/core@1.9.7
+ - @0xsequence/indexer@1.9.7
+ - @0xsequence/metadata@1.9.7
+ - @0xsequence/migration@1.9.7
+ - @0xsequence/network@1.9.7
+ - @0xsequence/sessions@1.9.7
+ - @0xsequence/signhub@1.9.7
+ - @0xsequence/utils@1.9.7
+ - @0xsequence/wallet@1.9.7
+
+## 1.9.6
+
+### Patch Changes
+
+- waas package update
+- Updated dependencies
+ - @0xsequence/abi@1.9.6
+ - @0xsequence/account@1.9.6
+ - @0xsequence/api@1.9.6
+ - @0xsequence/core@1.9.6
+ - @0xsequence/indexer@1.9.6
+ - @0xsequence/metadata@1.9.6
+ - @0xsequence/migration@1.9.6
+ - @0xsequence/network@1.9.6
+ - @0xsequence/sessions@1.9.6
+ - @0xsequence/signhub@1.9.6
+ - @0xsequence/utils@1.9.6
+ - @0xsequence/wallet@1.9.6
+
+## 1.9.5
+
+### Patch Changes
+
+- RpcRelayer prioritize project access key
+- Updated dependencies
+ - @0xsequence/abi@1.9.5
+ - @0xsequence/account@1.9.5
+ - @0xsequence/api@1.9.5
+ - @0xsequence/core@1.9.5
+ - @0xsequence/indexer@1.9.5
+ - @0xsequence/metadata@1.9.5
+ - @0xsequence/migration@1.9.5
+ - @0xsequence/network@1.9.5
+ - @0xsequence/sessions@1.9.5
+ - @0xsequence/signhub@1.9.5
+ - @0xsequence/utils@1.9.5
+ - @0xsequence/wallet@1.9.5
+
+## 1.9.4
+
+### Patch Changes
+
+- waas: fix network dependency
+- Updated dependencies
+ - @0xsequence/abi@1.9.4
+ - @0xsequence/account@1.9.4
+ - @0xsequence/api@1.9.4
+ - @0xsequence/core@1.9.4
+ - @0xsequence/indexer@1.9.4
+ - @0xsequence/metadata@1.9.4
+ - @0xsequence/migration@1.9.4
+ - @0xsequence/network@1.9.4
+ - @0xsequence/sessions@1.9.4
+ - @0xsequence/signhub@1.9.4
+ - @0xsequence/utils@1.9.4
+ - @0xsequence/wallet@1.9.4
+
+## 1.9.3
+
+### Patch Changes
+
+- provider: don't append access key to RPC url if user has already provided it
+- Updated dependencies
+ - @0xsequence/abi@1.9.3
+ - @0xsequence/account@1.9.3
+ - @0xsequence/api@1.9.3
+ - @0xsequence/core@1.9.3
+ - @0xsequence/indexer@1.9.3
+ - @0xsequence/metadata@1.9.3
+ - @0xsequence/migration@1.9.3
+ - @0xsequence/network@1.9.3
+ - @0xsequence/sessions@1.9.3
+ - @0xsequence/signhub@1.9.3
+ - @0xsequence/utils@1.9.3
+ - @0xsequence/wallet@1.9.3
+
+## 1.9.2
+
+### Patch Changes
+
+- network: add xai-sepolia
+- Updated dependencies
+ - @0xsequence/abi@1.9.2
+ - @0xsequence/account@1.9.2
+ - @0xsequence/api@1.9.2
+ - @0xsequence/core@1.9.2
+ - @0xsequence/indexer@1.9.2
+ - @0xsequence/metadata@1.9.2
+ - @0xsequence/migration@1.9.2
+ - @0xsequence/network@1.9.2
+ - @0xsequence/sessions@1.9.2
+ - @0xsequence/signhub@1.9.2
+ - @0xsequence/utils@1.9.2
+ - @0xsequence/wallet@1.9.2
+
+## 1.9.1
+
+### Patch Changes
+
+- analytics fix
+- Updated dependencies
+ - @0xsequence/abi@1.9.1
+ - @0xsequence/account@1.9.1
+ - @0xsequence/api@1.9.1
+ - @0xsequence/core@1.9.1
+ - @0xsequence/indexer@1.9.1
+ - @0xsequence/metadata@1.9.1
+ - @0xsequence/migration@1.9.1
+ - @0xsequence/network@1.9.1
+ - @0xsequence/sessions@1.9.1
+ - @0xsequence/signhub@1.9.1
+ - @0xsequence/utils@1.9.1
+ - @0xsequence/wallet@1.9.1
+
+## 1.9.0
+
+### Minor Changes
+
+- waas release
+
+### Patch Changes
+
+- Updated dependencies
+ - @0xsequence/abi@1.9.0
+ - @0xsequence/account@1.9.0
+ - @0xsequence/api@1.9.0
+ - @0xsequence/core@1.9.0
+ - @0xsequence/indexer@1.9.0
+ - @0xsequence/metadata@1.9.0
+ - @0xsequence/migration@1.9.0
+ - @0xsequence/network@1.9.0
+ - @0xsequence/sessions@1.9.0
+ - @0xsequence/signhub@1.9.0
+ - @0xsequence/utils@1.9.0
+ - @0xsequence/wallet@1.9.0
+
+## 1.8.8
+
+### Patch Changes
+
+- update metadata bindings
+- Updated dependencies
+ - @0xsequence/abi@1.8.8
+ - @0xsequence/account@1.8.8
+ - @0xsequence/api@1.8.8
+ - @0xsequence/core@1.8.8
+ - @0xsequence/indexer@1.8.8
+ - @0xsequence/metadata@1.8.8
+ - @0xsequence/migration@1.8.8
+ - @0xsequence/network@1.8.8
+ - @0xsequence/sessions@1.8.8
+ - @0xsequence/signhub@1.8.8
+ - @0xsequence/utils@1.8.8
+ - @0xsequence/wallet@1.8.8
+
+## 1.8.7
+
+### Patch Changes
+
+- provider: update databeat to 0.9.1
+- Updated dependencies
+ - @0xsequence/abi@1.8.7
+ - @0xsequence/account@1.8.7
+ - @0xsequence/api@1.8.7
+ - @0xsequence/core@1.8.7
+ - @0xsequence/indexer@1.8.7
+ - @0xsequence/metadata@1.8.7
+ - @0xsequence/migration@1.8.7
+ - @0xsequence/network@1.8.7
+ - @0xsequence/sessions@1.8.7
+ - @0xsequence/signhub@1.8.7
+ - @0xsequence/utils@1.8.7
+ - @0xsequence/wallet@1.8.7
+
+## 1.8.6
+
+### Patch Changes
+
+- guard: SignedOwnershipProof
+- Updated dependencies
+ - @0xsequence/abi@1.8.6
+ - @0xsequence/account@1.8.6
+ - @0xsequence/api@1.8.6
+ - @0xsequence/core@1.8.6
+ - @0xsequence/indexer@1.8.6
+ - @0xsequence/metadata@1.8.6
+ - @0xsequence/migration@1.8.6
+ - @0xsequence/network@1.8.6
+ - @0xsequence/sessions@1.8.6
+ - @0xsequence/signhub@1.8.6
+ - @0xsequence/utils@1.8.6
+ - @0xsequence/wallet@1.8.6
+
+## 1.8.5
+
+### Patch Changes
+
+- guard: signOwnershipProof and isSignedOwnershipProof
+- Updated dependencies
+ - @0xsequence/abi@1.8.5
+ - @0xsequence/account@1.8.5
+ - @0xsequence/api@1.8.5
+ - @0xsequence/core@1.8.5
+ - @0xsequence/indexer@1.8.5
+ - @0xsequence/metadata@1.8.5
+ - @0xsequence/migration@1.8.5
+ - @0xsequence/network@1.8.5
+ - @0xsequence/sessions@1.8.5
+ - @0xsequence/signhub@1.8.5
+ - @0xsequence/utils@1.8.5
+ - @0xsequence/wallet@1.8.5
+
+## 1.8.4
+
+### Patch Changes
+
+- network: add homeverse to networks list
+- Updated dependencies
+ - @0xsequence/abi@1.8.4
+ - @0xsequence/account@1.8.4
+ - @0xsequence/api@1.8.4
+ - @0xsequence/core@1.8.4
+ - @0xsequence/indexer@1.8.4
+ - @0xsequence/metadata@1.8.4
+ - @0xsequence/migration@1.8.4
+ - @0xsequence/network@1.8.4
+ - @0xsequence/sessions@1.8.4
+ - @0xsequence/signhub@1.8.4
+ - @0xsequence/utils@1.8.4
+ - @0xsequence/wallet@1.8.4
+
+## 1.8.3
+
+### Patch Changes
+
+- api: introduce basic linked wallet support
+- Updated dependencies
+ - @0xsequence/abi@1.8.3
+ - @0xsequence/account@1.8.3
+ - @0xsequence/api@1.8.3
+ - @0xsequence/core@1.8.3
+ - @0xsequence/indexer@1.8.3
+ - @0xsequence/metadata@1.8.3
+ - @0xsequence/migration@1.8.3
+ - @0xsequence/network@1.8.3
+ - @0xsequence/sessions@1.8.3
+ - @0xsequence/signhub@1.8.3
+ - @0xsequence/utils@1.8.3
+ - @0xsequence/wallet@1.8.3
+
+## 1.8.2
+
+### Patch Changes
+
+- provider: don't initialize analytics unless explicitly requested
+- Updated dependencies
+ - @0xsequence/abi@1.8.2
+ - @0xsequence/account@1.8.2
+ - @0xsequence/api@1.8.2
+ - @0xsequence/core@1.8.2
+ - @0xsequence/indexer@1.8.2
+ - @0xsequence/metadata@1.8.2
+ - @0xsequence/migration@1.8.2
+ - @0xsequence/network@1.8.2
+ - @0xsequence/sessions@1.8.2
+ - @0xsequence/signhub@1.8.2
+ - @0xsequence/utils@1.8.2
+ - @0xsequence/wallet@1.8.2
+
+## 1.8.1
+
+### Patch Changes
+
+- update to analytics provider
+- Updated dependencies
+ - @0xsequence/abi@1.8.1
+ - @0xsequence/account@1.8.1
+ - @0xsequence/api@1.8.1
+ - @0xsequence/core@1.8.1
+ - @0xsequence/indexer@1.8.1
+ - @0xsequence/metadata@1.8.1
+ - @0xsequence/migration@1.8.1
+ - @0xsequence/network@1.8.1
+ - @0xsequence/sessions@1.8.1
+ - @0xsequence/signhub@1.8.1
+ - @0xsequence/utils@1.8.1
+ - @0xsequence/wallet@1.8.1
+
+## 1.8.0
+
+### Minor Changes
+
+- provider: project analytics
+
+### Patch Changes
+
+- Updated dependencies
+ - @0xsequence/abi@1.8.0
+ - @0xsequence/account@1.8.0
+ - @0xsequence/api@1.8.0
+ - @0xsequence/core@1.8.0
+ - @0xsequence/indexer@1.8.0
+ - @0xsequence/metadata@1.8.0
+ - @0xsequence/migration@1.8.0
+ - @0xsequence/network@1.8.0
+ - @0xsequence/sessions@1.8.0
+ - @0xsequence/signhub@1.8.0
+ - @0xsequence/utils@1.8.0
+ - @0xsequence/wallet@1.8.0
+
+## 1.7.2
+
+### Patch Changes
+
+- 0xsequence: ChainId should not be exported as a type
+- account, wallet: fix nonce selection
+- Updated dependencies
+- Updated dependencies
+ - @0xsequence/abi@1.7.2
+ - @0xsequence/account@1.7.2
+ - @0xsequence/api@1.7.2
+ - @0xsequence/core@1.7.2
+ - @0xsequence/indexer@1.7.2
+ - @0xsequence/metadata@1.7.2
+ - @0xsequence/migration@1.7.2
+ - @0xsequence/network@1.7.2
+ - @0xsequence/sessions@1.7.2
+ - @0xsequence/signhub@1.7.2
+ - @0xsequence/utils@1.7.2
+ - @0xsequence/wallet@1.7.2
+
+## 1.7.1
+
+### Patch Changes
+
+- network: add missing avalanche logoURI
+- Updated dependencies
+ - @0xsequence/abi@1.7.1
+ - @0xsequence/account@1.7.1
+ - @0xsequence/api@1.7.1
+ - @0xsequence/core@1.7.1
+ - @0xsequence/indexer@1.7.1
+ - @0xsequence/metadata@1.7.1
+ - @0xsequence/migration@1.7.1
+ - @0xsequence/network@1.7.1
+ - @0xsequence/sessions@1.7.1
+ - @0xsequence/signhub@1.7.1
+ - @0xsequence/utils@1.7.1
+ - @0xsequence/wallet@1.7.1
+
+## 1.7.0
+
+### Minor Changes
+
+- provider: projectAccessKey is now required
+
+### Patch Changes
+
+- network: add NetworkMetadata.logoURI property for all networks
+- Updated dependencies
+- Updated dependencies
+ - @0xsequence/abi@1.7.0
+ - @0xsequence/account@1.7.0
+ - @0xsequence/api@1.7.0
+ - @0xsequence/core@1.7.0
+ - @0xsequence/indexer@1.7.0
+ - @0xsequence/metadata@1.7.0
+ - @0xsequence/migration@1.7.0
+ - @0xsequence/network@1.7.0
+ - @0xsequence/sessions@1.7.0
+ - @0xsequence/signhub@1.7.0
+ - @0xsequence/utils@1.7.0
+ - @0xsequence/wallet@1.7.0
+
+## 1.6.3
+
+### Patch Changes
+
+- network list update
+- Updated dependencies
+ - @0xsequence/abi@1.6.3
+ - @0xsequence/account@1.6.3
+ - @0xsequence/api@1.6.3
+ - @0xsequence/core@1.6.3
+ - @0xsequence/indexer@1.6.3
+ - @0xsequence/metadata@1.6.3
+ - @0xsequence/migration@1.6.3
+ - @0xsequence/network@1.6.3
+ - @0xsequence/sessions@1.6.3
+ - @0xsequence/signhub@1.6.3
+ - @0xsequence/utils@1.6.3
+ - @0xsequence/wallet@1.6.3
+
+## 1.6.2
+
+### Patch Changes
+
+- auth: projectAccessKey option
+- wallet: use 12 bytes for random space
+- Updated dependencies
+- Updated dependencies
+ - @0xsequence/abi@1.6.2
+ - @0xsequence/account@1.6.2
+ - @0xsequence/api@1.6.2
+ - @0xsequence/core@1.6.2
+ - @0xsequence/indexer@1.6.2
+ - @0xsequence/metadata@1.6.2
+ - @0xsequence/migration@1.6.2
+ - @0xsequence/network@1.6.2
+ - @0xsequence/sessions@1.6.2
+ - @0xsequence/signhub@1.6.2
+ - @0xsequence/utils@1.6.2
+ - @0xsequence/wallet@1.6.2
+
+## 1.6.1
+
+### Patch Changes
+
+- core: add simple config from subdigest support
+- core: fix encode tree with subdigest
+- account: implement buildOnChainSignature on Account
+- Updated dependencies
+- Updated dependencies
+- Updated dependencies
+ - @0xsequence/abi@1.6.1
+ - @0xsequence/account@1.6.1
+ - @0xsequence/api@1.6.1
+ - @0xsequence/core@1.6.1
+ - @0xsequence/indexer@1.6.1
+ - @0xsequence/metadata@1.6.1
+ - @0xsequence/migration@1.6.1
+ - @0xsequence/network@1.6.1
+ - @0xsequence/sessions@1.6.1
+ - @0xsequence/signhub@1.6.1
+ - @0xsequence/utils@1.6.1
+ - @0xsequence/wallet@1.6.1
+
+## 1.6.0
+
+### Minor Changes
+
+- account, wallet: parallel transactions by default
+
+### Patch Changes
+
+- provider: emit disconnect on sign out
+- Updated dependencies
+- Updated dependencies
+ - @0xsequence/abi@1.6.0
+ - @0xsequence/account@1.6.0
+ - @0xsequence/api@1.6.0
+ - @0xsequence/core@1.6.0
+ - @0xsequence/indexer@1.6.0
+ - @0xsequence/metadata@1.6.0
+ - @0xsequence/migration@1.6.0
+ - @0xsequence/network@1.6.0
+ - @0xsequence/sessions@1.6.0
+ - @0xsequence/signhub@1.6.0
+ - @0xsequence/utils@1.6.0
+ - @0xsequence/wallet@1.6.0
+
+## 1.5.0
+
+### Minor Changes
+
+- signhub: add 'signing' signer status
+
+### Patch Changes
+
+- auth: Session.open: onAccountAddress callback
+- account: allow empty transaction bundles
+- Updated dependencies
+- Updated dependencies
+- Updated dependencies
+ - @0xsequence/abi@1.5.0
+ - @0xsequence/account@1.5.0
+ - @0xsequence/api@1.5.0
+ - @0xsequence/core@1.5.0
+ - @0xsequence/indexer@1.5.0
+ - @0xsequence/metadata@1.5.0
+ - @0xsequence/migration@1.5.0
+ - @0xsequence/network@1.5.0
+ - @0xsequence/sessions@1.5.0
+ - @0xsequence/signhub@1.5.0
+ - @0xsequence/utils@1.5.0
+ - @0xsequence/wallet@1.5.0
+
+## 1.4.9
+
+### Patch Changes
+
+- rename SequenceMetadataClient to SequenceMetadata
+- Updated dependencies
+ - @0xsequence/abi@1.4.9
+ - @0xsequence/account@1.4.9
+ - @0xsequence/api@1.4.9
+ - @0xsequence/core@1.4.9
+ - @0xsequence/indexer@1.4.9
+ - @0xsequence/metadata@1.4.9
+ - @0xsequence/migration@1.4.9
+ - @0xsequence/network@1.4.9
+ - @0xsequence/sessions@1.4.9
+ - @0xsequence/signhub@1.4.9
+ - @0xsequence/utils@1.4.9
+ - @0xsequence/wallet@1.4.9
+
+## 1.4.8
+
+### Patch Changes
+
+- account: Account.getSigners
+- Updated dependencies
+ - @0xsequence/abi@1.4.8
+ - @0xsequence/account@1.4.8
+ - @0xsequence/api@1.4.8
+ - @0xsequence/core@1.4.8
+ - @0xsequence/indexer@1.4.8
+ - @0xsequence/metadata@1.4.8
+ - @0xsequence/migration@1.4.8
+ - @0xsequence/network@1.4.8
+ - @0xsequence/sessions@1.4.8
+ - @0xsequence/signhub@1.4.8
+ - @0xsequence/utils@1.4.8
+ - @0xsequence/wallet@1.4.8
+
+## 1.4.7
+
+### Patch Changes
+
+- update indexer client bindings
+- Updated dependencies
+ - @0xsequence/abi@1.4.7
+ - @0xsequence/account@1.4.7
+ - @0xsequence/api@1.4.7
+ - @0xsequence/core@1.4.7
+ - @0xsequence/indexer@1.4.7
+ - @0xsequence/metadata@1.4.7
+ - @0xsequence/migration@1.4.7
+ - @0xsequence/network@1.4.7
+ - @0xsequence/sessions@1.4.7
+ - @0xsequence/signhub@1.4.7
+ - @0xsequence/utils@1.4.7
+ - @0xsequence/wallet@1.4.7
+
+## 1.4.6
+
+### Patch Changes
+
+- - add sepolia networks, mark goerli as deprecated
+ - update indexer client bindings
+- Updated dependencies
+ - @0xsequence/abi@1.4.6
+ - @0xsequence/account@1.4.6
+ - @0xsequence/api@1.4.6
+ - @0xsequence/core@1.4.6
+ - @0xsequence/indexer@1.4.6
+ - @0xsequence/metadata@1.4.6
+ - @0xsequence/migration@1.4.6
+ - @0xsequence/network@1.4.6
+ - @0xsequence/sessions@1.4.6
+ - @0xsequence/signhub@1.4.6
+ - @0xsequence/utils@1.4.6
+ - @0xsequence/wallet@1.4.6
+
+## 1.4.5
+
+### Patch Changes
+
+- indexer/metadata: update client bindings
+- auth: selectWallet with new address
+- Updated dependencies
+- Updated dependencies
+ - @0xsequence/abi@1.4.5
+ - @0xsequence/account@1.4.5
+ - @0xsequence/api@1.4.5
+ - @0xsequence/core@1.4.5
+ - @0xsequence/indexer@1.4.5
+ - @0xsequence/metadata@1.4.5
+ - @0xsequence/migration@1.4.5
+ - @0xsequence/network@1.4.5
+ - @0xsequence/sessions@1.4.5
+ - @0xsequence/signhub@1.4.5
+ - @0xsequence/utils@1.4.5
+ - @0xsequence/wallet@1.4.5
+
+## 1.4.4
+
+### Patch Changes
+
+- indexer: update bindings
+- auth: handle jwt expiry
+- Updated dependencies
+- Updated dependencies
+ - @0xsequence/abi@1.4.4
+ - @0xsequence/account@1.4.4
+ - @0xsequence/api@1.4.4
+ - @0xsequence/core@1.4.4
+ - @0xsequence/indexer@1.4.4
+ - @0xsequence/metadata@1.4.4
+ - @0xsequence/migration@1.4.4
+ - @0xsequence/network@1.4.4
+ - @0xsequence/sessions@1.4.4
+ - @0xsequence/signhub@1.4.4
+ - @0xsequence/utils@1.4.4
+ - @0xsequence/wallet@1.4.4
+
+## 1.4.3
+
+### Patch Changes
+
+- guard: return active status from GuardSigner.getAuthMethods
+- Updated dependencies
+ - @0xsequence/abi@1.4.3
+ - @0xsequence/account@1.4.3
+ - @0xsequence/api@1.4.3
+ - @0xsequence/core@1.4.3
+ - @0xsequence/indexer@1.4.3
+ - @0xsequence/metadata@1.4.3
+ - @0xsequence/migration@1.4.3
+ - @0xsequence/network@1.4.3
+ - @0xsequence/sessions@1.4.3
+ - @0xsequence/signhub@1.4.3
+ - @0xsequence/utils@1.4.3
+ - @0xsequence/wallet@1.4.3
+
+## 1.4.2
+
+### Patch Changes
+
+- guard: update bindings
+- Updated dependencies
+ - @0xsequence/abi@1.4.2
+ - @0xsequence/account@1.4.2
+ - @0xsequence/api@1.4.2
+ - @0xsequence/core@1.4.2
+ - @0xsequence/indexer@1.4.2
+ - @0xsequence/metadata@1.4.2
+ - @0xsequence/migration@1.4.2
+ - @0xsequence/network@1.4.2
+ - @0xsequence/sessions@1.4.2
+ - @0xsequence/signhub@1.4.2
+ - @0xsequence/utils@1.4.2
+ - @0xsequence/wallet@1.4.2
+
+## 1.4.1
+
+### Patch Changes
+
+- network: remove unused networks
+- signhub: orchestrator interface
+- guard: auth methods interface
+- guard: update bindings for pin and totp
+- guard: no more retry logic
+- Updated dependencies
+- Updated dependencies
+- Updated dependencies
+- Updated dependencies
+- Updated dependencies
+ - @0xsequence/abi@1.4.1
+ - @0xsequence/account@1.4.1
+ - @0xsequence/api@1.4.1
+ - @0xsequence/core@1.4.1
+ - @0xsequence/indexer@1.4.1
+ - @0xsequence/metadata@1.4.1
+ - @0xsequence/migration@1.4.1
+ - @0xsequence/network@1.4.1
+ - @0xsequence/sessions@1.4.1
+ - @0xsequence/signhub@1.4.1
+ - @0xsequence/utils@1.4.1
+ - @0xsequence/wallet@1.4.1
+
+## 1.4.0
+
+### Minor Changes
+
+- project access key support
+
+### Patch Changes
+
+- Updated dependencies
+ - @0xsequence/abi@1.4.0
+ - @0xsequence/account@1.4.0
+ - @0xsequence/api@1.4.0
+ - @0xsequence/core@1.4.0
+ - @0xsequence/indexer@1.4.0
+ - @0xsequence/metadata@1.4.0
+ - @0xsequence/migration@1.4.0
+ - @0xsequence/network@1.4.0
+ - @0xsequence/sessions@1.4.0
+ - @0xsequence/signhub@1.4.0
+ - @0xsequence/utils@1.4.0
+ - @0xsequence/wallet@1.4.0
+
+## 1.3.0
+
+### Minor Changes
+
+- signhub: account children
+
+### Patch Changes
+
+- guard: do not throw when building deploy transaction
+- network: snowtrace.io -> subnets.avax.network/c-chain
+- Updated dependencies
+- Updated dependencies
+- Updated dependencies
+ - @0xsequence/abi@1.3.0
+ - @0xsequence/account@1.3.0
+ - @0xsequence/api@1.3.0
+ - @0xsequence/core@1.3.0
+ - @0xsequence/indexer@1.3.0
+ - @0xsequence/metadata@1.3.0
+ - @0xsequence/migration@1.3.0
+ - @0xsequence/network@1.3.0
+ - @0xsequence/sessions@1.3.0
+ - @0xsequence/signhub@1.3.0
+ - @0xsequence/utils@1.3.0
+ - @0xsequence/wallet@1.3.0
+
+## 1.2.9
+
+### Patch Changes
+
+- account: AccountSigner.sendTransaction simulateForFeeOptions
+- relayer: update bindings
+- Updated dependencies
+- Updated dependencies
+ - @0xsequence/abi@1.2.9
+ - @0xsequence/account@1.2.9
+ - @0xsequence/api@1.2.9
+ - @0xsequence/core@1.2.9
+ - @0xsequence/indexer@1.2.9
+ - @0xsequence/metadata@1.2.9
+ - @0xsequence/migration@1.2.9
+ - @0xsequence/network@1.2.9
+ - @0xsequence/sessions@1.2.9
+ - @0xsequence/signhub@1.2.9
+ - @0xsequence/utils@1.2.9
+ - @0xsequence/wallet@1.2.9
+
+## 1.2.8
+
+### Patch Changes
+
+- rename X-Sequence-Token-Key header to X-Access-Key
+- Updated dependencies
+ - @0xsequence/abi@1.2.8
+ - @0xsequence/account@1.2.8
+ - @0xsequence/api@1.2.8
+ - @0xsequence/core@1.2.8
+ - @0xsequence/indexer@1.2.8
+ - @0xsequence/metadata@1.2.8
+ - @0xsequence/migration@1.2.8
+ - @0xsequence/network@1.2.8
+ - @0xsequence/sessions@1.2.8
+ - @0xsequence/signhub@1.2.8
+ - @0xsequence/utils@1.2.8
+ - @0xsequence/wallet@1.2.8
+
+## 1.2.7
+
+### Patch Changes
+
+- add x-sequence-token-key to clients
+- Updated dependencies
+ - @0xsequence/abi@1.2.7
+ - @0xsequence/account@1.2.7
+ - @0xsequence/api@1.2.7
+ - @0xsequence/core@1.2.7
+ - @0xsequence/indexer@1.2.7
+ - @0xsequence/metadata@1.2.7
+ - @0xsequence/migration@1.2.7
+ - @0xsequence/network@1.2.7
+ - @0xsequence/sessions@1.2.7
+ - @0xsequence/signhub@1.2.7
+ - @0xsequence/utils@1.2.7
+ - @0xsequence/wallet@1.2.7
+
+## 1.2.6
+
+### Patch Changes
+
+- Fix bind multicall provider
+- Updated dependencies
+ - @0xsequence/abi@1.2.6
+ - @0xsequence/account@1.2.6
+ - @0xsequence/api@1.2.6
+ - @0xsequence/core@1.2.6
+ - @0xsequence/indexer@1.2.6
+ - @0xsequence/metadata@1.2.6
+ - @0xsequence/migration@1.2.6
+ - @0xsequence/network@1.2.6
+ - @0xsequence/sessions@1.2.6
+ - @0xsequence/signhub@1.2.6
+ - @0xsequence/utils@1.2.6
+ - @0xsequence/wallet@1.2.6
+
+## 1.2.5
+
+### Patch Changes
+
+- Multicall default configuration fixes
+- Updated dependencies
+ - @0xsequence/abi@1.2.5
+ - @0xsequence/account@1.2.5
+ - @0xsequence/api@1.2.5
+ - @0xsequence/core@1.2.5
+ - @0xsequence/indexer@1.2.5
+ - @0xsequence/metadata@1.2.5
+ - @0xsequence/migration@1.2.5
+ - @0xsequence/network@1.2.5
+ - @0xsequence/sessions@1.2.5
+ - @0xsequence/signhub@1.2.5
+ - @0xsequence/utils@1.2.5
+ - @0xsequence/wallet@1.2.5
+
+## 1.2.4
+
+### Patch Changes
+
+- provider: Adding missing payment provider types to PaymentProviderOption
+- provider: WalletRequestHandler.notifyChainChanged
+- Updated dependencies
+- Updated dependencies
+ - @0xsequence/abi@1.2.4
+ - @0xsequence/account@1.2.4
+ - @0xsequence/api@1.2.4
+ - @0xsequence/core@1.2.4
+ - @0xsequence/indexer@1.2.4
+ - @0xsequence/metadata@1.2.4
+ - @0xsequence/migration@1.2.4
+ - @0xsequence/network@1.2.4
+ - @0xsequence/sessions@1.2.4
+ - @0xsequence/signhub@1.2.4
+ - @0xsequence/utils@1.2.4
+ - @0xsequence/wallet@1.2.4
+
+## 1.2.3
+
+### Patch Changes
+
+- auth, provider: connect to accept optional authorizeNonce
+- Updated dependencies
+ - @0xsequence/abi@1.2.3
+ - @0xsequence/account@1.2.3
+ - @0xsequence/api@1.2.3
+ - @0xsequence/core@1.2.3
+ - @0xsequence/indexer@1.2.3
+ - @0xsequence/metadata@1.2.3
+ - @0xsequence/migration@1.2.3
+ - @0xsequence/network@1.2.3
+ - @0xsequence/sessions@1.2.3
+ - @0xsequence/signhub@1.2.3
+ - @0xsequence/utils@1.2.3
+ - @0xsequence/wallet@1.2.3
+
+## 1.2.2
+
+### Patch Changes
+
+- provider: allow createContract calls
+- core: check for explicit zero address in contract deployments
+- Updated dependencies
+- Updated dependencies
+ - @0xsequence/abi@1.2.2
+ - @0xsequence/account@1.2.2
+ - @0xsequence/api@1.2.2
+ - @0xsequence/core@1.2.2
+ - @0xsequence/indexer@1.2.2
+ - @0xsequence/metadata@1.2.2
+ - @0xsequence/migration@1.2.2
+ - @0xsequence/network@1.2.2
+ - @0xsequence/sessions@1.2.2
+ - @0xsequence/signhub@1.2.2
+ - @0xsequence/utils@1.2.2
+ - @0xsequence/wallet@1.2.2
+
+## 1.2.1
+
+### Patch Changes
+
+- auth: use sequence api chain id as reference chain id if available
+- Updated dependencies
+ - @0xsequence/abi@1.2.1
+ - @0xsequence/account@1.2.1
+ - @0xsequence/api@1.2.1
+ - @0xsequence/core@1.2.1
+ - @0xsequence/indexer@1.2.1
+ - @0xsequence/metadata@1.2.1
+ - @0xsequence/migration@1.2.1
+ - @0xsequence/network@1.2.1
+ - @0xsequence/sessions@1.2.1
+ - @0xsequence/signhub@1.2.1
+ - @0xsequence/utils@1.2.1
+ - @0xsequence/wallet@1.2.1
+
+## 1.2.0
+
+### Minor Changes
+
+- split services from session, better local support
+
+### Patch Changes
+
+- Updated dependencies
+ - @0xsequence/abi@1.2.0
+ - @0xsequence/account@1.2.0
+ - @0xsequence/api@1.2.0
+ - @0xsequence/core@1.2.0
+ - @0xsequence/indexer@1.2.0
+ - @0xsequence/metadata@1.2.0
+ - @0xsequence/migration@1.2.0
+ - @0xsequence/network@1.2.0
+ - @0xsequence/sessions@1.2.0
+ - @0xsequence/signhub@1.2.0
+ - @0xsequence/utils@1.2.0
+ - @0xsequence/wallet@1.2.0
+
+## 1.1.15
+
+### Patch Changes
+
+- guard: remove error filtering
+- Updated dependencies
+ - @0xsequence/abi@1.1.15
+ - @0xsequence/account@1.1.15
+ - @0xsequence/api@1.1.15
+ - @0xsequence/core@1.1.15
+ - @0xsequence/indexer@1.1.15
+ - @0xsequence/metadata@1.1.15
+ - @0xsequence/migration@1.1.15
+ - @0xsequence/network@1.1.15
+ - @0xsequence/sessions@1.1.15
+ - @0xsequence/signhub@1.1.15
+ - @0xsequence/utils@1.1.15
+ - @0xsequence/wallet@1.1.15
+
+## 1.1.14
+
+### Patch Changes
+
+- guard: add GuardSigner.onError
+- Updated dependencies
+ - @0xsequence/abi@1.1.14
+ - @0xsequence/account@1.1.14
+ - @0xsequence/api@1.1.14
+ - @0xsequence/core@1.1.14
+ - @0xsequence/indexer@1.1.14
+ - @0xsequence/metadata@1.1.14
+ - @0xsequence/migration@1.1.14
+ - @0xsequence/network@1.1.14
+ - @0xsequence/sessions@1.1.14
+ - @0xsequence/signhub@1.1.14
+ - @0xsequence/utils@1.1.14
+ - @0xsequence/wallet@1.1.14
+
+## 1.1.13
+
+### Patch Changes
+
+- provider: pass client version with connect options
+- provider: removing large from BannerSize
+- Updated dependencies
+- Updated dependencies
+ - @0xsequence/abi@1.1.13
+ - @0xsequence/account@1.1.13
+ - @0xsequence/api@1.1.13
+ - @0xsequence/core@1.1.13
+ - @0xsequence/indexer@1.1.13
+ - @0xsequence/metadata@1.1.13
+ - @0xsequence/migration@1.1.13
+ - @0xsequence/network@1.1.13
+ - @0xsequence/sessions@1.1.13
+ - @0xsequence/signhub@1.1.13
+ - @0xsequence/utils@1.1.13
+ - @0xsequence/wallet@1.1.13
+
+## 1.1.12
+
+### Patch Changes
+
+- provider: adding bannerSize to ConnectOptions
+- Updated dependencies
+ - @0xsequence/abi@1.1.12
+ - @0xsequence/account@1.1.12
+ - @0xsequence/api@1.1.12
+ - @0xsequence/core@1.1.12
+ - @0xsequence/indexer@1.1.12
+ - @0xsequence/metadata@1.1.12
+ - @0xsequence/migration@1.1.12
+ - @0xsequence/network@1.1.12
+ - @0xsequence/sessions@1.1.12
+ - @0xsequence/signhub@1.1.12
+ - @0xsequence/utils@1.1.12
+ - @0xsequence/wallet@1.1.12
+
+## 1.1.11
+
+### Patch Changes
+
+- add homeverse configs
+- Updated dependencies
+ - @0xsequence/abi@1.1.11
+ - @0xsequence/account@1.1.11
+ - @0xsequence/api@1.1.11
+ - @0xsequence/core@1.1.11
+ - @0xsequence/indexer@1.1.11
+ - @0xsequence/metadata@1.1.11
+ - @0xsequence/migration@1.1.11
+ - @0xsequence/network@1.1.11
+ - @0xsequence/sessions@1.1.11
+ - @0xsequence/signhub@1.1.11
+ - @0xsequence/utils@1.1.11
+ - @0xsequence/wallet@1.1.11
+
+## 1.1.10
+
+### Patch Changes
+
+- handle default EIP6492 on send
+- Updated dependencies
+ - @0xsequence/abi@1.1.10
+ - @0xsequence/account@1.1.10
+ - @0xsequence/api@1.1.10
+ - @0xsequence/core@1.1.10
+ - @0xsequence/indexer@1.1.10
+ - @0xsequence/metadata@1.1.10
+ - @0xsequence/migration@1.1.10
+ - @0xsequence/network@1.1.10
+ - @0xsequence/sessions@1.1.10
+ - @0xsequence/signhub@1.1.10
+ - @0xsequence/utils@1.1.10
+ - @0xsequence/wallet@1.1.10
+
+## 1.1.9
+
+### Patch Changes
+
+- Custom default EIP6492 on client
+- Updated dependencies
+ - @0xsequence/abi@1.1.9
+ - @0xsequence/account@1.1.9
+ - @0xsequence/api@1.1.9
+ - @0xsequence/core@1.1.9
+ - @0xsequence/indexer@1.1.9
+ - @0xsequence/metadata@1.1.9
+ - @0xsequence/migration@1.1.9
+ - @0xsequence/network@1.1.9
+ - @0xsequence/sessions@1.1.9
+ - @0xsequence/signhub@1.1.9
+ - @0xsequence/utils@1.1.9
+ - @0xsequence/wallet@1.1.9
+
+## 1.1.8
+
+### Patch Changes
+
+- metadata: searchMetadata: add types filter
+- Updated dependencies
+ - @0xsequence/abi@1.1.8
+ - @0xsequence/account@1.1.8
+ - @0xsequence/api@1.1.8
+ - @0xsequence/core@1.1.8
+ - @0xsequence/indexer@1.1.8
+ - @0xsequence/metadata@1.1.8
+ - @0xsequence/migration@1.1.8
+ - @0xsequence/network@1.1.8
+ - @0xsequence/sessions@1.1.8
+ - @0xsequence/signhub@1.1.8
+ - @0xsequence/utils@1.1.8
+ - @0xsequence/wallet@1.1.8
+
+## 1.1.7
+
+### Patch Changes
+
+- adding signInWith connect settings option to allow dapps to automatically login their users with a certain provider optimizing the normal authentication flow
+- Updated dependencies
+ - @0xsequence/abi@1.1.7
+ - @0xsequence/account@1.1.7
+ - @0xsequence/api@1.1.7
+ - @0xsequence/core@1.1.7
+ - @0xsequence/indexer@1.1.7
+ - @0xsequence/metadata@1.1.7
+ - @0xsequence/migration@1.1.7
+ - @0xsequence/network@1.1.7
+ - @0xsequence/sessions@1.1.7
+ - @0xsequence/signhub@1.1.7
+ - @0xsequence/utils@1.1.7
+ - @0xsequence/wallet@1.1.7
+
+## 1.1.6
+
+### Patch Changes
+
+- metadata: searchMetadata: add chainID and excludeTokenMetadata filters
+- Updated dependencies
+ - @0xsequence/abi@1.1.6
+ - @0xsequence/account@1.1.6
+ - @0xsequence/api@1.1.6
+ - @0xsequence/core@1.1.6
+ - @0xsequence/indexer@1.1.6
+ - @0xsequence/metadata@1.1.6
+ - @0xsequence/migration@1.1.6
+ - @0xsequence/network@1.1.6
+ - @0xsequence/sessions@1.1.6
+ - @0xsequence/signhub@1.1.6
+ - @0xsequence/utils@1.1.6
+ - @0xsequence/wallet@1.1.6
+
+## 1.1.5
+
+### Patch Changes
+
+- account: re-compute meta-transaction id for wallet deployment transactions
+- Updated dependencies
+ - @0xsequence/abi@1.1.5
+ - @0xsequence/account@1.1.5
+ - @0xsequence/api@1.1.5
+ - @0xsequence/core@1.1.5
+ - @0xsequence/indexer@1.1.5
+ - @0xsequence/metadata@1.1.5
+ - @0xsequence/migration@1.1.5
+ - @0xsequence/network@1.1.5
+ - @0xsequence/sessions@1.1.5
+ - @0xsequence/signhub@1.1.5
+ - @0xsequence/utils@1.1.5
+ - @0xsequence/wallet@1.1.5
+
+## 1.1.4
+
+### Patch Changes
+
+- network: rename base-mainnet to base
+- provider: override isDefaultChain with ConnectOptions.networkId if provided
+- Updated dependencies
+- Updated dependencies
+ - @0xsequence/abi@1.1.4
+ - @0xsequence/account@1.1.4
+ - @0xsequence/api@1.1.4
+ - @0xsequence/core@1.1.4
+ - @0xsequence/indexer@1.1.4
+ - @0xsequence/metadata@1.1.4
+ - @0xsequence/migration@1.1.4
+ - @0xsequence/network@1.1.4
+ - @0xsequence/sessions@1.1.4
+ - @0xsequence/signhub@1.1.4
+ - @0xsequence/utils@1.1.4
+ - @0xsequence/wallet@1.1.4
+
+## 1.1.3
+
+### Patch Changes
+
+- provider: use network id from transport session
+- provider: sign authorization using ConnectOptions.networkId if provided
+- Updated dependencies
+- Updated dependencies
+ - @0xsequence/abi@1.1.3
+ - @0xsequence/account@1.1.3
+ - @0xsequence/api@1.1.3
+ - @0xsequence/core@1.1.3
+ - @0xsequence/indexer@1.1.3
+ - @0xsequence/metadata@1.1.3
+ - @0xsequence/migration@1.1.3
+ - @0xsequence/network@1.1.3
+ - @0xsequence/sessions@1.1.3
+ - @0xsequence/signhub@1.1.3
+ - @0xsequence/utils@1.1.3
+ - @0xsequence/wallet@1.1.3
+
+## 1.1.2
+
+### Patch Changes
+
+- provider: jsonrpc chain id fixes
+- Updated dependencies
+ - @0xsequence/abi@1.1.2
+ - @0xsequence/account@1.1.2
+ - @0xsequence/api@1.1.2
+ - @0xsequence/core@1.1.2
+ - @0xsequence/indexer@1.1.2
+ - @0xsequence/metadata@1.1.2
+ - @0xsequence/migration@1.1.2
+ - @0xsequence/network@1.1.2
+ - @0xsequence/sessions@1.1.2
+ - @0xsequence/signhub@1.1.2
+ - @0xsequence/utils@1.1.2
+ - @0xsequence/wallet@1.1.2
+
+## 1.1.1
+
+### Patch Changes
+
+- network: add base mainnet and sepolia
+- provider: reject toxic transaction requests
+- Updated dependencies
+- Updated dependencies
+ - @0xsequence/abi@1.1.1
+ - @0xsequence/account@1.1.1
+ - @0xsequence/api@1.1.1
+ - @0xsequence/core@1.1.1
+ - @0xsequence/indexer@1.1.1
+ - @0xsequence/metadata@1.1.1
+ - @0xsequence/migration@1.1.1
+ - @0xsequence/network@1.1.1
+ - @0xsequence/sessions@1.1.1
+ - @0xsequence/signhub@1.1.1
+ - @0xsequence/utils@1.1.1
+ - @0xsequence/wallet@1.1.1
+
+## 1.1.0
+
+### Minor Changes
+
+- Refactor dapp facing provider
+
+### Patch Changes
+
+- Updated dependencies
+ - @0xsequence/abi@1.1.0
+ - @0xsequence/account@1.1.0
+ - @0xsequence/api@1.1.0
+ - @0xsequence/core@1.1.0
+ - @0xsequence/indexer@1.1.0
+ - @0xsequence/metadata@1.1.0
+ - @0xsequence/migration@1.1.0
+ - @0xsequence/network@1.1.0
+ - @0xsequence/sessions@1.1.0
+ - @0xsequence/signhub@1.1.0
+ - @0xsequence/utils@1.1.0
+ - @0xsequence/wallet@1.1.0
+
+## 1.0.5
+
+### Patch Changes
+
+- network: export network constants
+- guard: use the correct global for fetch
+- network: nova-explorer.arbitrum.io -> nova.arbiscan.io
+- Updated dependencies
+- Updated dependencies
+- Updated dependencies
+ - @0xsequence/abi@1.0.5
+ - @0xsequence/account@1.0.5
+ - @0xsequence/api@1.0.5
+ - @0xsequence/core@1.0.5
+ - @0xsequence/indexer@1.0.5
+ - @0xsequence/metadata@1.0.5
+ - @0xsequence/migration@1.0.5
+ - @0xsequence/network@1.0.5
+ - @0xsequence/sessions@1.0.5
+ - @0xsequence/signhub@1.0.5
+ - @0xsequence/utils@1.0.5
+ - @0xsequence/wallet@1.0.5
+
+## 1.0.4
+
+### Patch Changes
+
+- provider: accept name or number for networkId
+- Updated dependencies
+ - @0xsequence/abi@1.0.4
+ - @0xsequence/account@1.0.4
+ - @0xsequence/api@1.0.4
+ - @0xsequence/core@1.0.4
+ - @0xsequence/indexer@1.0.4
+ - @0xsequence/metadata@1.0.4
+ - @0xsequence/migration@1.0.4
+ - @0xsequence/network@1.0.4
+ - @0xsequence/sessions@1.0.4
+ - @0xsequence/signhub@1.0.4
+ - @0xsequence/utils@1.0.4
+ - @0xsequence/wallet@1.0.4
+
+## 1.0.3
+
+### Patch Changes
+
+- Simpler isValidSignature helpers
+- Updated dependencies
+ - @0xsequence/abi@1.0.3
+ - @0xsequence/account@1.0.3
+ - @0xsequence/api@1.0.3
+ - @0xsequence/core@1.0.3
+ - @0xsequence/indexer@1.0.3
+ - @0xsequence/metadata@1.0.3
+ - @0xsequence/migration@1.0.3
+ - @0xsequence/network@1.0.3
+ - @0xsequence/sessions@1.0.3
+ - @0xsequence/signhub@1.0.3
+ - @0xsequence/utils@1.0.3
+ - @0xsequence/wallet@1.0.3
+
+## 1.0.2
+
+### Patch Changes
+
+- add extra signature validation utils methods
+- Updated dependencies
+ - @0xsequence/abi@1.0.2
+ - @0xsequence/account@1.0.2
+ - @0xsequence/api@1.0.2
+ - @0xsequence/core@1.0.2
+ - @0xsequence/indexer@1.0.2
+ - @0xsequence/metadata@1.0.2
+ - @0xsequence/migration@1.0.2
+ - @0xsequence/network@1.0.2
+ - @0xsequence/sessions@1.0.2
+ - @0xsequence/signhub@1.0.2
+ - @0xsequence/utils@1.0.2
+ - @0xsequence/wallet@1.0.2
+
+## 1.0.1
+
+### Patch Changes
+
+- add homeverse testnet
+- Updated dependencies
+ - @0xsequence/abi@1.0.1
+ - @0xsequence/account@1.0.1
+ - @0xsequence/api@1.0.1
+ - @0xsequence/core@1.0.1
+ - @0xsequence/indexer@1.0.1
+ - @0xsequence/metadata@1.0.1
+ - @0xsequence/migration@1.0.1
+ - @0xsequence/network@1.0.1
+ - @0xsequence/sessions@1.0.1
+ - @0xsequence/signhub@1.0.1
+ - @0xsequence/utils@1.0.1
+ - @0xsequence/wallet@1.0.1
+
+## 1.0.0
+
+### Major Changes
+
+- https://sequence.xyz/blog/sequence-wallet-light-state-sync-full-merkle-wallets
+
+### Patch Changes
+
+- Updated dependencies
+ - @0xsequence/abi@1.0.0
+ - @0xsequence/account@1.0.0
+ - @0xsequence/api@1.0.0
+ - @0xsequence/core@1.0.0
+ - @0xsequence/indexer@1.0.0
+ - @0xsequence/metadata@1.0.0
+ - @0xsequence/migration@1.0.0
+ - @0xsequence/network@1.0.0
+ - @0xsequence/sessions@1.0.0
+ - @0xsequence/signhub@1.0.0
+ - @0xsequence/utils@1.0.0
+ - @0xsequence/wallet@1.0.0
+
+## 0.43.34
+
+### Patch Changes
+
+- auth: no jwt for indexer
+- Updated dependencies
+ - @0xsequence/abi@0.43.34
+ - @0xsequence/api@0.43.34
+ - @0xsequence/config@0.43.34
+ - @0xsequence/indexer@0.43.34
+ - @0xsequence/metadata@0.43.34
+ - @0xsequence/network@0.43.34
+ - @0xsequence/provider@0.43.34
+ - @0xsequence/utils@0.43.34
+ - @0xsequence/wallet@0.43.34
+
+## 0.43.33
+
+### Patch Changes
+
+- Adding onConnectOptionsChange handler to WalletRequestHandler
+- Updated dependencies
+ - @0xsequence/abi@0.43.33
+ - @0xsequence/api@0.43.33
+ - @0xsequence/config@0.43.33
+ - @0xsequence/indexer@0.43.33
+ - @0xsequence/metadata@0.43.33
+ - @0xsequence/network@0.43.33
+ - @0xsequence/provider@0.43.33
+ - @0xsequence/utils@0.43.33
+ - @0xsequence/wallet@0.43.33
+
+## 0.43.32
+
+### Patch Changes
+
+- add Base Goerli network
+- Updated dependencies
+ - @0xsequence/abi@0.43.32
+ - @0xsequence/api@0.43.32
+ - @0xsequence/config@0.43.32
+ - @0xsequence/indexer@0.43.32
+ - @0xsequence/metadata@0.43.32
+ - @0xsequence/network@0.43.32
+ - @0xsequence/provider@0.43.32
+ - @0xsequence/utils@0.43.32
+ - @0xsequence/wallet@0.43.32
+
+## 0.43.31
+
+### Patch Changes
+
+- remove AuxDataProvider, add promptSignInConnect
+- Updated dependencies
+ - @0xsequence/abi@0.43.31
+ - @0xsequence/api@0.43.31
+ - @0xsequence/config@0.43.31
+ - @0xsequence/indexer@0.43.31
+ - @0xsequence/metadata@0.43.31
+ - @0xsequence/network@0.43.31
+ - @0xsequence/provider@0.43.31
+ - @0xsequence/utils@0.43.31
+ - @0xsequence/wallet@0.43.31
+
+## 0.43.30
+
+### Patch Changes
+
+- add arbitrum goerli testnet
+- Updated dependencies
+ - @0xsequence/abi@0.43.30
+ - @0xsequence/api@0.43.30
+ - @0xsequence/config@0.43.30
+ - @0xsequence/indexer@0.43.30
+ - @0xsequence/metadata@0.43.30
+ - @0xsequence/network@0.43.30
+ - @0xsequence/provider@0.43.30
+ - @0xsequence/utils@0.43.30
+ - @0xsequence/wallet@0.43.30
+
+## 0.43.29
+
+### Patch Changes
+
+- provider: check availability of window object
+- Updated dependencies
+ - @0xsequence/abi@0.43.29
+ - @0xsequence/api@0.43.29
+ - @0xsequence/config@0.43.29
+ - @0xsequence/indexer@0.43.29
+ - @0xsequence/metadata@0.43.29
+ - @0xsequence/network@0.43.29
+ - @0xsequence/provider@0.43.29
+ - @0xsequence/utils@0.43.29
+ - @0xsequence/wallet@0.43.29
+
+## 0.43.28
+
+### Patch Changes
+
+- update api bindings
+- Updated dependencies
+ - @0xsequence/abi@0.43.28
+ - @0xsequence/api@0.43.28
+ - @0xsequence/config@0.43.28
+ - @0xsequence/indexer@0.43.28
+ - @0xsequence/metadata@0.43.28
+ - @0xsequence/network@0.43.28
+ - @0xsequence/provider@0.43.28
+ - @0xsequence/utils@0.43.28
+ - @0xsequence/wallet@0.43.28
+
+## 0.43.27
+
+### Patch Changes
+
+- Add rpc is sequence method
+- Updated dependencies
+ - @0xsequence/abi@0.43.27
+ - @0xsequence/api@0.43.27
+ - @0xsequence/config@0.43.27
+ - @0xsequence/indexer@0.43.27
+ - @0xsequence/metadata@0.43.27
+ - @0xsequence/network@0.43.27
+ - @0xsequence/provider@0.43.27
+ - @0xsequence/utils@0.43.27
+ - @0xsequence/wallet@0.43.27
+
+## 0.43.26
+
+### Patch Changes
+
+- add zkevm url to enum
+- Updated dependencies
+ - @0xsequence/abi@0.43.26
+ - @0xsequence/api@0.43.26
+ - @0xsequence/config@0.43.26
+ - @0xsequence/indexer@0.43.26
+ - @0xsequence/metadata@0.43.26
+ - @0xsequence/network@0.43.26
+ - @0xsequence/provider@0.43.26
+ - @0xsequence/utils@0.43.26
+ - @0xsequence/wallet@0.43.26
+
+## 0.43.25
+
+### Patch Changes
+
+- added polygon zkevm to mainnet networks
+- Updated dependencies
+ - @0xsequence/abi@0.43.25
+ - @0xsequence/api@0.43.25
+ - @0xsequence/config@0.43.25
+ - @0xsequence/indexer@0.43.25
+ - @0xsequence/metadata@0.43.25
+ - @0xsequence/network@0.43.25
+ - @0xsequence/provider@0.43.25
+ - @0xsequence/utils@0.43.25
+ - @0xsequence/wallet@0.43.25
+
+## 0.43.24
+
+### Patch Changes
+
+- name change from zkevm to polygon-zkevm
+- Updated dependencies
+ - @0xsequence/abi@0.43.24
+ - @0xsequence/api@0.43.24
+ - @0xsequence/config@0.43.24
+ - @0xsequence/indexer@0.43.24
+ - @0xsequence/metadata@0.43.24
+ - @0xsequence/network@0.43.24
+ - @0xsequence/provider@0.43.24
+ - @0xsequence/utils@0.43.24
+ - @0xsequence/wallet@0.43.24
+
+## 0.43.23
+
+### Patch Changes
+
+- update zkEVM name to Polygon zkEVM
+- Updated dependencies
+ - @0xsequence/abi@0.43.23
+ - @0xsequence/api@0.43.23
+ - @0xsequence/config@0.43.23
+ - @0xsequence/indexer@0.43.23
+ - @0xsequence/metadata@0.43.23
+ - @0xsequence/network@0.43.23
+ - @0xsequence/provider@0.43.23
+ - @0xsequence/utils@0.43.23
+ - @0xsequence/wallet@0.43.23
+
+## 0.43.22
+
+### Patch Changes
+
+- add zkevm chain
+- Updated dependencies
+ - @0xsequence/abi@0.43.22
+ - @0xsequence/api@0.43.22
+ - @0xsequence/config@0.43.22
+ - @0xsequence/indexer@0.43.22
+ - @0xsequence/metadata@0.43.22
+ - @0xsequence/network@0.43.22
+ - @0xsequence/provider@0.43.22
+ - @0xsequence/utils@0.43.22
+ - @0xsequence/wallet@0.43.22
+
+## 0.43.21
+
+### Patch Changes
+
+- api: update client bindings
+- Updated dependencies
+ - @0xsequence/abi@0.43.21
+ - @0xsequence/api@0.43.21
+ - @0xsequence/config@0.43.21
+ - @0xsequence/indexer@0.43.21
+ - @0xsequence/metadata@0.43.21
+ - @0xsequence/network@0.43.21
+ - @0xsequence/provider@0.43.21
+ - @0xsequence/utils@0.43.21
+ - @0xsequence/wallet@0.43.21
+
+## 0.43.20
+
+### Patch Changes
+
+- indexer: update bindings
+- Updated dependencies
+ - @0xsequence/abi@0.43.20
+ - @0xsequence/api@0.43.20
+ - @0xsequence/config@0.43.20
+ - @0xsequence/indexer@0.43.20
+ - @0xsequence/metadata@0.43.20
+ - @0xsequence/network@0.43.20
+ - @0xsequence/provider@0.43.20
+ - @0xsequence/utils@0.43.20
+ - @0xsequence/wallet@0.43.20
+
+## 0.43.19
+
+### Patch Changes
+
+- session proof update
+- Updated dependencies
+ - @0xsequence/abi@0.43.19
+ - @0xsequence/api@0.43.19
+ - @0xsequence/config@0.43.19
+ - @0xsequence/indexer@0.43.19
+ - @0xsequence/metadata@0.43.19
+ - @0xsequence/network@0.43.19
+ - @0xsequence/provider@0.43.19
+ - @0xsequence/utils@0.43.19
+ - @0xsequence/wallet@0.43.19
+
+## 0.43.18
+
+### Patch Changes
+
+- rpc client global check, hardening
+- Updated dependencies
+ - @0xsequence/abi@0.43.18
+ - @0xsequence/api@0.43.18
+ - @0xsequence/config@0.43.18
+ - @0xsequence/indexer@0.43.18
+ - @0xsequence/metadata@0.43.18
+ - @0xsequence/network@0.43.18
+ - @0xsequence/provider@0.43.18
+ - @0xsequence/utils@0.43.18
+ - @0xsequence/wallet@0.43.18
+
+## 0.43.17
+
+### Patch Changes
+
+- rpc clients, check of 'global' is defined
+- Updated dependencies
+ - @0xsequence/abi@0.43.17
+ - @0xsequence/api@0.43.17
+ - @0xsequence/config@0.43.17
+ - @0xsequence/indexer@0.43.17
+ - @0xsequence/metadata@0.43.17
+ - @0xsequence/network@0.43.17
+ - @0xsequence/provider@0.43.17
+ - @0xsequence/utils@0.43.17
+ - @0xsequence/wallet@0.43.17
+
+## 0.43.16
+
+### Patch Changes
+
+- ethers peerDep to v5, update rpc client global use
+- Updated dependencies
+ - @0xsequence/abi@0.43.16
+ - @0xsequence/api@0.43.16
+ - @0xsequence/config@0.43.16
+ - @0xsequence/indexer@0.43.16
+ - @0xsequence/metadata@0.43.16
+ - @0xsequence/network@0.43.16
+ - @0xsequence/provider@0.43.16
+ - @0xsequence/utils@0.43.16
+ - @0xsequence/wallet@0.43.16
+
+## 0.43.15
+
+### Patch Changes
+
+- - provider: expand receiver type on some util methods
+- Updated dependencies
+ - @0xsequence/abi@0.43.15
+ - @0xsequence/api@0.43.15
+ - @0xsequence/config@0.43.15
+ - @0xsequence/indexer@0.43.15
+ - @0xsequence/metadata@0.43.15
+ - @0xsequence/network@0.43.15
+ - @0xsequence/provider@0.43.15
+ - @0xsequence/utils@0.43.15
+ - @0xsequence/wallet@0.43.15
+
+## 0.43.14
+
+### Patch Changes
+
+- bump
+- Updated dependencies
+ - @0xsequence/abi@0.43.14
+ - @0xsequence/api@0.43.14
+ - @0xsequence/config@0.43.14
+ - @0xsequence/indexer@0.43.14
+ - @0xsequence/metadata@0.43.14
+ - @0xsequence/network@0.43.14
+ - @0xsequence/provider@0.43.14
+ - @0xsequence/utils@0.43.14
+ - @0xsequence/wallet@0.43.14
+
+## 0.43.13
+
+### Patch Changes
+
+- update rpc bindings
+- Updated dependencies
+ - @0xsequence/abi@0.43.13
+ - @0xsequence/api@0.43.13
+ - @0xsequence/config@0.43.13
+ - @0xsequence/indexer@0.43.13
+ - @0xsequence/metadata@0.43.13
+ - @0xsequence/network@0.43.13
+ - @0xsequence/provider@0.43.13
+ - @0xsequence/utils@0.43.13
+ - @0xsequence/wallet@0.43.13
+
+## 0.43.12
+
+### Patch Changes
+
+- provider: single wallet init, and add new unregisterWallet() method
+- Updated dependencies
+ - @0xsequence/abi@0.43.12
+ - @0xsequence/api@0.43.12
+ - @0xsequence/config@0.43.12
+ - @0xsequence/indexer@0.43.12
+ - @0xsequence/metadata@0.43.12
+ - @0xsequence/network@0.43.12
+ - @0xsequence/provider@0.43.12
+ - @0xsequence/utils@0.43.12
+ - @0xsequence/wallet@0.43.12
+
+## 0.43.11
+
+### Patch Changes
+
+- fix lockfiles
+- re-add mocha type deleter
+- Updated dependencies
+- Updated dependencies
+ - @0xsequence/abi@0.43.11
+ - @0xsequence/api@0.43.11
+ - @0xsequence/config@0.43.11
+ - @0xsequence/indexer@0.43.11
+ - @0xsequence/metadata@0.43.11
+ - @0xsequence/network@0.43.11
+ - @0xsequence/provider@0.43.11
+ - @0xsequence/utils@0.43.11
+ - @0xsequence/wallet@0.43.11
+
+## 0.43.10
+
+### Patch Changes
+
+- various improvements
+- Updated dependencies
+ - @0xsequence/abi@0.43.10
+ - @0xsequence/api@0.43.10
+ - @0xsequence/config@0.43.10
+ - @0xsequence/indexer@0.43.10
+ - @0xsequence/metadata@0.43.10
+ - @0xsequence/network@0.43.10
+ - @0xsequence/provider@0.43.10
+ - @0xsequence/utils@0.43.10
+ - @0xsequence/wallet@0.43.10
+
+## 0.43.9
+
+### Patch Changes
+
+- update deps
+- Updated dependencies
+ - @0xsequence/abi@0.43.9
+ - @0xsequence/api@0.43.9
+ - @0xsequence/config@0.43.9
+ - @0xsequence/indexer@0.43.9
+ - @0xsequence/metadata@0.43.9
+ - @0xsequence/network@0.43.9
+ - @0xsequence/provider@0.43.9
+ - @0xsequence/utils@0.43.9
+ - @0xsequence/wallet@0.43.9
+
+## 0.43.8
+
+### Patch Changes
+
+- network: JsonRpcProvider with caching
+- Updated dependencies
+ - @0xsequence/abi@0.43.8
+ - @0xsequence/api@0.43.8
+ - @0xsequence/config@0.43.8
+ - @0xsequence/indexer@0.43.8
+ - @0xsequence/metadata@0.43.8
+ - @0xsequence/network@0.43.8
+ - @0xsequence/provider@0.43.8
+ - @0xsequence/utils@0.43.8
+ - @0xsequence/wallet@0.43.8
+
+## 0.43.7
+
+### Patch Changes
+
+- provider: fix wallet network init
+- Updated dependencies
+ - @0xsequence/abi@0.43.7
+ - @0xsequence/api@0.43.7
+ - @0xsequence/config@0.43.7
+ - @0xsequence/indexer@0.43.7
+ - @0xsequence/metadata@0.43.7
+ - @0xsequence/network@0.43.7
+ - @0xsequence/utils@0.43.7
+ - @0xsequence/wallet@0.43.7
+
+## 0.43.6
+
+### Patch Changes
+
+- metadatata: update rpc bindings
+- Updated dependencies
+ - @0xsequence/abi@0.43.6
+ - @0xsequence/api@0.43.6
+ - @0xsequence/config@0.43.6
+ - @0xsequence/indexer@0.43.6
+ - @0xsequence/metadata@0.43.6
+ - @0xsequence/network@0.43.6
+ - @0xsequence/utils@0.43.6
+ - @0xsequence/wallet@0.43.6
+
+## 0.43.5
+
+### Patch Changes
+
+- provider: do not set default network for connect messages
+- provider: forward missing error message
+- Updated dependencies
+- Updated dependencies
+ - @0xsequence/abi@0.43.5
+ - @0xsequence/api@0.43.5
+ - @0xsequence/config@0.43.5
+ - @0xsequence/indexer@0.43.5
+ - @0xsequence/metadata@0.43.5
+ - @0xsequence/network@0.43.5
+ - @0xsequence/utils@0.43.5
+ - @0xsequence/wallet@0.43.5
+
+## 0.43.4
+
+### Patch Changes
+
+- no-change version bump to fix incorrectly tagged snapshot build
+- Updated dependencies
+ - @0xsequence/abi@0.43.4
+ - @0xsequence/api@0.43.4
+ - @0xsequence/config@0.43.4
+ - @0xsequence/indexer@0.43.4
+ - @0xsequence/metadata@0.43.4
+ - @0xsequence/network@0.43.4
+ - @0xsequence/utils@0.43.4
+ - @0xsequence/wallet@0.43.4
+
+## 0.43.3
+
+### Patch Changes
+
+- metadata: update bindings
+- Updated dependencies
+ - @0xsequence/abi@0.43.3
+ - @0xsequence/api@0.43.3
+ - @0xsequence/config@0.43.3
+ - @0xsequence/indexer@0.43.3
+ - @0xsequence/metadata@0.43.3
+ - @0xsequence/network@0.43.3
+ - @0xsequence/utils@0.43.3
+ - @0xsequence/wallet@0.43.3
+
+## 0.43.2
+
+### Patch Changes
+
+- provider: implement connectUnchecked
+- Updated dependencies
+ - @0xsequence/abi@0.43.2
+ - @0xsequence/api@0.43.2
+ - @0xsequence/config@0.43.2
+ - @0xsequence/indexer@0.43.2
+ - @0xsequence/metadata@0.43.2
+ - @0xsequence/network@0.43.2
+ - @0xsequence/utils@0.43.2
+ - @0xsequence/wallet@0.43.2
+
+## 0.43.1
+
+### Patch Changes
+
+- update to latest ethauth dep
+- Updated dependencies
+ - @0xsequence/abi@0.43.1
+ - @0xsequence/api@0.43.1
+ - @0xsequence/config@0.43.1
+ - @0xsequence/indexer@0.43.1
+ - @0xsequence/metadata@0.43.1
+ - @0xsequence/network@0.43.1
+ - @0xsequence/utils@0.43.1
+ - @0xsequence/wallet@0.43.1
+
+## 0.43.0
+
+### Minor Changes
+
+- move ethers to a peer dependency
+
+### Patch Changes
+
+- Updated dependencies
+ - @0xsequence/abi@0.43.0
+ - @0xsequence/api@0.43.0
+ - @0xsequence/config@0.43.0
+ - @0xsequence/indexer@0.43.0
+ - @0xsequence/metadata@0.43.0
+ - @0xsequence/network@0.43.0
+ - @0xsequence/utils@0.43.0
+ - @0xsequence/wallet@0.43.0
+
+## 0.42.10
+
+### Patch Changes
+
+- add auxDataProvider
+- Updated dependencies
+ - @0xsequence/abi@0.42.10
+ - @0xsequence/api@0.42.10
+ - @0xsequence/config@0.42.10
+ - @0xsequence/indexer@0.42.10
+ - @0xsequence/metadata@0.42.10
+ - @0xsequence/network@0.42.10
+ - @0xsequence/utils@0.42.10
+ - @0xsequence/wallet@0.42.10
+
+## 0.42.9
+
+### Patch Changes
+
+- provider: add eip-191 exceptions
+- Updated dependencies
+ - @0xsequence/abi@0.42.9
+ - @0xsequence/api@0.42.9
+ - @0xsequence/config@0.42.9
+ - @0xsequence/indexer@0.42.9
+ - @0xsequence/metadata@0.42.9
+ - @0xsequence/network@0.42.9
+ - @0xsequence/utils@0.42.9
+ - @0xsequence/wallet@0.42.9
+
+## 0.42.8
+
+### Patch Changes
+
+- provider: skip setting intent origin if we're unity plugin
+- Updated dependencies
+ - @0xsequence/abi@0.42.8
+ - @0xsequence/api@0.42.8
+ - @0xsequence/config@0.42.8
+ - @0xsequence/indexer@0.42.8
+ - @0xsequence/metadata@0.42.8
+ - @0xsequence/network@0.42.8
+ - @0xsequence/utils@0.42.8
+ - @0xsequence/wallet@0.42.8
+
+## 0.42.7
+
+### Patch Changes
+
+- Add sign in options to connection settings
+- Updated dependencies
+ - @0xsequence/abi@0.42.7
+ - @0xsequence/api@0.42.7
+ - @0xsequence/config@0.42.7
+ - @0xsequence/indexer@0.42.7
+ - @0xsequence/metadata@0.42.7
+ - @0xsequence/network@0.42.7
+ - @0xsequence/utils@0.42.7
+ - @0xsequence/wallet@0.42.7
+
+## 0.42.6
+
+### Patch Changes
+
+- api bindings update
+- Updated dependencies
+ - @0xsequence/abi@0.42.6
+ - @0xsequence/api@0.42.6
+ - @0xsequence/config@0.42.6
+ - @0xsequence/indexer@0.42.6
+ - @0xsequence/metadata@0.42.6
+ - @0xsequence/network@0.42.6
+ - @0xsequence/utils@0.42.6
+ - @0xsequence/wallet@0.42.6
+
+## 0.42.5
+
+### Patch Changes
+
+- relayer: don't treat missing receipt as hard failure
+- Updated dependencies
+ - @0xsequence/abi@0.42.5
+ - @0xsequence/api@0.42.5
+ - @0xsequence/config@0.42.5
+ - @0xsequence/indexer@0.42.5
+ - @0xsequence/metadata@0.42.5
+ - @0xsequence/network@0.42.5
+ - @0xsequence/utils@0.42.5
+ - @0xsequence/wallet@0.42.5
+
+## 0.42.4
+
+### Patch Changes
+
+- provider: add custom app protocol to connect options
+- Updated dependencies
+ - @0xsequence/abi@0.42.4
+ - @0xsequence/api@0.42.4
+ - @0xsequence/config@0.42.4
+ - @0xsequence/indexer@0.42.4
+ - @0xsequence/metadata@0.42.4
+ - @0xsequence/network@0.42.4
+ - @0xsequence/utils@0.42.4
+ - @0xsequence/wallet@0.42.4
+
+## 0.42.3
+
+### Patch Changes
+
+- update api bindings
+- Updated dependencies
+ - @0xsequence/abi@0.42.3
+ - @0xsequence/api@0.42.3
+ - @0xsequence/config@0.42.3
+ - @0xsequence/indexer@0.42.3
+ - @0xsequence/metadata@0.42.3
+ - @0xsequence/network@0.42.3
+ - @0xsequence/utils@0.42.3
+ - @0xsequence/wallet@0.42.3
+
+## 0.42.2
+
+### Patch Changes
+
+- disable rinkeby network
+- Updated dependencies
+ - @0xsequence/abi@0.42.2
+ - @0xsequence/api@0.42.2
+ - @0xsequence/config@0.42.2
+ - @0xsequence/indexer@0.42.2
+ - @0xsequence/metadata@0.42.2
+ - @0xsequence/network@0.42.2
+ - @0xsequence/utils@0.42.2
+ - @0xsequence/wallet@0.42.2
+
+## 0.42.1
+
+### Patch Changes
+
+- wallet: optional waitForReceipt parameter
+- Updated dependencies
+ - @0xsequence/abi@0.42.1
+ - @0xsequence/api@0.42.1
+ - @0xsequence/config@0.42.1
+ - @0xsequence/indexer@0.42.1
+ - @0xsequence/metadata@0.42.1
+ - @0xsequence/network@0.42.1
+ - @0xsequence/utils@0.42.1
+ - @0xsequence/wallet@0.42.1
+
+## 0.42.0
+
+### Minor Changes
+
+- relayer: estimateGasLimits -> simulate
+- add simulator package
+
+### Patch Changes
+
+- transactions: fix flattenAuxTransactions
+- provider: only filter nullish values
+- provider: re-map transaction 'gas' back to 'gasLimit'
+- Updated dependencies
+- Updated dependencies
+- Updated dependencies
+- Updated dependencies
+- Updated dependencies
+ - @0xsequence/abi@0.42.0
+ - @0xsequence/api@0.42.0
+ - @0xsequence/config@0.42.0
+ - @0xsequence/indexer@0.42.0
+ - @0xsequence/metadata@0.42.0
+ - @0xsequence/network@0.42.0
+ - @0xsequence/utils@0.42.0
+ - @0xsequence/wallet@0.42.0
+
+## 0.41.3
+
+### Patch Changes
+
+- api bindings update
+- Updated dependencies
+ - @0xsequence/abi@0.41.3
+ - @0xsequence/api@0.41.3
+ - @0xsequence/config@0.41.3
+ - @0xsequence/indexer@0.41.3
+ - @0xsequence/metadata@0.41.3
+ - @0xsequence/network@0.41.3
+ - @0xsequence/utils@0.41.3
+ - @0xsequence/wallet@0.41.3
+
+## 0.41.2
+
+### Patch Changes
+
+- api bindings update
+- Updated dependencies
+ - @0xsequence/abi@0.41.2
+ - @0xsequence/api@0.41.2
+ - @0xsequence/config@0.41.2
+ - @0xsequence/indexer@0.41.2
+ - @0xsequence/metadata@0.41.2
+ - @0xsequence/network@0.41.2
+ - @0xsequence/utils@0.41.2
+ - @0xsequence/wallet@0.41.2
+
+## 0.41.1
+
+### Patch Changes
+
+- update default networks
+- Updated dependencies
+ - @0xsequence/abi@0.41.1
+ - @0xsequence/api@0.41.1
+ - @0xsequence/config@0.41.1
+ - @0xsequence/indexer@0.41.1
+ - @0xsequence/metadata@0.41.1
+ - @0xsequence/network@0.41.1
+ - @0xsequence/utils@0.41.1
+ - @0xsequence/wallet@0.41.1
+
+## 0.41.0
+
+### Minor Changes
+
+- relayer: fix Relayer.wait() interface
+
+ The interface for calling Relayer.wait() has changed. Instead of a single optional ill-defined timeout/delay parameter, there are three optional parameters, in order:
+
+ - timeout: the maximum time to wait for the transaction receipt
+ - delay: the polling interval, i.e. the time to wait between requests
+ - maxFails: the maximum number of hard failures to tolerate before giving up
+
+ Please update your codebase accordingly.
+
+- relayer: add optional waitForReceipt parameter to Relayer.relay
+
+ The behaviour of Relayer.relay() was not well-defined with respect to whether or not it waited for a receipt.
+ This change allows the caller to specify whether to wait or not, with the default behaviour being to wait.
+
+### Patch Changes
+
+- relayer: wait receipt retry logic
+- fix wrapped object error
+- provider: forward delegateCall and revertOnError transaction fields
+- Updated dependencies
+- Updated dependencies
+- Updated dependencies
+- Updated dependencies
+- Updated dependencies
+ - @0xsequence/abi@0.41.0
+ - @0xsequence/api@0.41.0
+ - @0xsequence/config@0.41.0
+ - @0xsequence/indexer@0.41.0
+ - @0xsequence/metadata@0.41.0
+ - @0xsequence/network@0.41.0
+ - @0xsequence/utils@0.41.0
+ - @0xsequence/wallet@0.41.0
+
+## 0.40.6
+
+### Patch Changes
+
+- add arbitrum-nova chain
+- Updated dependencies
+ - @0xsequence/abi@0.40.6
+ - @0xsequence/api@0.40.6
+ - @0xsequence/config@0.40.6
+ - @0xsequence/indexer@0.40.6
+ - @0xsequence/metadata@0.40.6
+ - @0xsequence/network@0.40.6
+ - @0xsequence/utils@0.40.6
+ - @0xsequence/wallet@0.40.6
+
+## 0.40.5
+
+### Patch Changes
+
+- api: update bindings
+- Updated dependencies
+ - @0xsequence/abi@0.40.5
+ - @0xsequence/api@0.40.5
+ - @0xsequence/config@0.40.5
+ - @0xsequence/indexer@0.40.5
+ - @0xsequence/metadata@0.40.5
+ - @0xsequence/network@0.40.5
+ - @0xsequence/utils@0.40.5
+ - @0xsequence/wallet@0.40.5
+
+## 0.40.4
+
+### Patch Changes
+
+- add unreal transport
+- Updated dependencies
+ - @0xsequence/abi@0.40.4
+ - @0xsequence/api@0.40.4
+ - @0xsequence/config@0.40.4
+ - @0xsequence/indexer@0.40.4
+ - @0xsequence/metadata@0.40.4
+ - @0xsequence/network@0.40.4
+ - @0xsequence/utils@0.40.4
+ - @0xsequence/wallet@0.40.4
+
+## 0.40.3
+
+### Patch Changes
+
+- provider: fix MessageToSign message type
+- Updated dependencies
+ - @0xsequence/abi@0.40.3
+ - @0xsequence/api@0.40.3
+ - @0xsequence/config@0.40.3
+ - @0xsequence/indexer@0.40.3
+ - @0xsequence/metadata@0.40.3
+ - @0xsequence/network@0.40.3
+ - @0xsequence/utils@0.40.3
+ - @0xsequence/wallet@0.40.3
+
+## 0.40.2
+
+### Patch Changes
+
+- Wallet provider, loadSession method
+- Updated dependencies
+ - @0xsequence/abi@0.40.2
+ - @0xsequence/api@0.40.2
+ - @0xsequence/config@0.40.2
+ - @0xsequence/indexer@0.40.2
+ - @0xsequence/metadata@0.40.2
+ - @0xsequence/network@0.40.2
+ - @0xsequence/utils@0.40.2
+ - @0xsequence/wallet@0.40.2
+
+## 0.40.1
+
+### Patch Changes
+
+- export sequence.initWallet and sequence.getWallet
+- Updated dependencies
+ - @0xsequence/abi@0.40.1
+ - @0xsequence/api@0.40.1
+ - @0xsequence/config@0.40.1
+ - @0xsequence/indexer@0.40.1
+ - @0xsequence/metadata@0.40.1
+ - @0xsequence/network@0.40.1
+ - @0xsequence/utils@0.40.1
+ - @0xsequence/wallet@0.40.1
+
+## 0.40.0
+
+### Minor Changes
+
+- add sequence.initWallet(network, config) and sequence.getWallet() helper methods
+
+### Patch Changes
+
+- Updated dependencies
+ - @0xsequence/abi@0.40.0
+ - @0xsequence/api@0.40.0
+ - @0xsequence/config@0.40.0
+ - @0xsequence/indexer@0.40.0
+ - @0xsequence/metadata@0.40.0
+ - @0xsequence/network@0.40.0
+ - @0xsequence/utils@0.40.0
+ - @0xsequence/wallet@0.40.0
+
+## 0.39.6
+
+### Patch Changes
+
+- indexer: update client bindings
+- Updated dependencies
+ - @0xsequence/abi@0.39.6
+ - @0xsequence/api@0.39.6
+ - @0xsequence/config@0.39.6
+ - @0xsequence/indexer@0.39.6
+ - @0xsequence/metadata@0.39.6
+ - @0xsequence/network@0.39.6
+ - @0xsequence/utils@0.39.6
+ - @0xsequence/wallet@0.39.6
+
+## 0.39.5
+
+### Patch Changes
+
+- provider: fix networkRpcUrl config option
+- Updated dependencies
+ - @0xsequence/abi@0.39.5
+ - @0xsequence/api@0.39.5
+ - @0xsequence/config@0.39.5
+ - @0xsequence/indexer@0.39.5
+ - @0xsequence/metadata@0.39.5
+ - @0xsequence/network@0.39.5
+ - @0xsequence/utils@0.39.5
+ - @0xsequence/wallet@0.39.5
+
+## 0.39.4
+
+### Patch Changes
+
+- api: update client bindings
+- Updated dependencies
+ - @0xsequence/abi@0.39.4
+ - @0xsequence/api@0.39.4
+ - @0xsequence/config@0.39.4
+ - @0xsequence/indexer@0.39.4
+ - @0xsequence/metadata@0.39.4
+ - @0xsequence/network@0.39.4
+ - @0xsequence/utils@0.39.4
+ - @0xsequence/wallet@0.39.4
+
+## 0.39.3
+
+### Patch Changes
+
+- add request method on Web3Provider
+- Updated dependencies
+ - @0xsequence/abi@0.39.3
+ - @0xsequence/api@0.39.3
+ - @0xsequence/config@0.39.3
+ - @0xsequence/indexer@0.39.3
+ - @0xsequence/metadata@0.39.3
+ - @0xsequence/network@0.39.3
+ - @0xsequence/utils@0.39.3
+ - @0xsequence/wallet@0.39.3
+
+## 0.39.2
+
+### Patch Changes
+
+- update umd name
+- Updated dependencies
+ - @0xsequence/abi@0.39.2
+ - @0xsequence/api@0.39.2
+ - @0xsequence/config@0.39.2
+ - @0xsequence/indexer@0.39.2
+ - @0xsequence/metadata@0.39.2
+ - @0xsequence/network@0.39.2
+ - @0xsequence/utils@0.39.2
+ - @0xsequence/wallet@0.39.2
+
+## 0.39.1
+
+### Patch Changes
+
+- add Aurora network
+- add origin info for accountsChanged event to handle it per dapp
+- Updated dependencies
+- Updated dependencies
+ - @0xsequence/abi@0.39.1
+ - @0xsequence/api@0.39.1
+ - @0xsequence/config@0.39.1
+ - @0xsequence/indexer@0.39.1
+ - @0xsequence/metadata@0.39.1
+ - @0xsequence/network@0.39.1
+ - @0xsequence/utils@0.39.1
+ - @0xsequence/wallet@0.39.1
+
+## 0.39.0
+
+### Minor Changes
+
+- abstract window.localStorage to interface type
+
+### Patch Changes
+
+- Updated dependencies
+ - @0xsequence/abi@0.39.0
+ - @0xsequence/api@0.39.0
+ - @0xsequence/config@0.39.0
+ - @0xsequence/indexer@0.39.0
+ - @0xsequence/metadata@0.39.0
+ - @0xsequence/network@0.39.0
+ - @0xsequence/utils@0.39.0
+ - @0xsequence/wallet@0.39.0
+
+## 0.38.2
+
+### Patch Changes
+
+- provider: add Settings.defaultPurchaseAmount
+- Updated dependencies
+ - @0xsequence/abi@0.38.2
+ - @0xsequence/api@0.38.2
+ - @0xsequence/config@0.38.2
+ - @0xsequence/indexer@0.38.2
+ - @0xsequence/metadata@0.38.2
+ - @0xsequence/network@0.38.2
+ - @0xsequence/utils@0.38.2
+ - @0xsequence/wallet@0.38.2
+
+## 0.38.1
+
+### Patch Changes
+
+- update api and metadata rpc bindings
+- Updated dependencies
+ - @0xsequence/abi@0.38.1
+ - @0xsequence/api@0.38.1
+ - @0xsequence/config@0.38.1
+ - @0xsequence/indexer@0.38.1
+ - @0xsequence/metadata@0.38.1
+ - @0xsequence/network@0.38.1
+ - @0xsequence/utils@0.38.1
+ - @0xsequence/wallet@0.38.1
+
+## 0.38.0
+
+### Minor Changes
+
+- api: update bindings, change TokenPrice interface
+- bridge: remove @0xsequence/bridge package
+- api: update bindings, rename ContractCallArg to TupleComponent
+
+### Patch Changes
+
+- Updated dependencies
+- Updated dependencies
+- Updated dependencies
+ - @0xsequence/abi@0.38.0
+ - @0xsequence/api@0.38.0
+ - @0xsequence/config@0.38.0
+ - @0xsequence/indexer@0.38.0
+ - @0xsequence/metadata@0.38.0
+ - @0xsequence/network@0.38.0
+ - @0xsequence/utils@0.38.0
+ - @0xsequence/wallet@0.38.0
+
+## 0.37.1
+
+### Patch Changes
+
+- Add back sortNetworks - Removing sorting was a breaking change for dapps on older versions which directly integrate sequence.
+- Updated dependencies
+ - @0xsequence/abi@0.37.1
+ - @0xsequence/api@0.37.1
+ - @0xsequence/config@0.37.1
+ - @0xsequence/indexer@0.37.1
+ - @0xsequence/metadata@0.37.1
+ - @0xsequence/network@0.37.1
+ - @0xsequence/utils@0.37.1
+ - @0xsequence/wallet@0.37.1
+
+## 0.37.0
+
+### Minor Changes
+
+- network related fixes and improvements
+- api: bindings: exchange rate lookups
+
+### Patch Changes
+
+- Updated dependencies
+- Updated dependencies
+ - @0xsequence/abi@0.37.0
+ - @0xsequence/api@0.37.0
+ - @0xsequence/config@0.37.0
+ - @0xsequence/indexer@0.37.0
+ - @0xsequence/metadata@0.37.0
+ - @0xsequence/network@0.37.0
+ - @0xsequence/utils@0.37.0
+ - @0xsequence/wallet@0.37.0
+
+## 0.36.13
+
+### Patch Changes
+
+- api: update bindings with new price endpoints
+- Updated dependencies
+ - @0xsequence/abi@0.36.13
+ - @0xsequence/api@0.36.13
+ - @0xsequence/config@0.36.13
+ - @0xsequence/indexer@0.36.13
+ - @0xsequence/metadata@0.36.13
+ - @0xsequence/network@0.36.13
+ - @0xsequence/utils@0.36.13
+ - @0xsequence/wallet@0.36.13
+
+## 0.36.12
+
+### Patch Changes
+
+- wallet: skip remote signers if not needed
+- auth: check that signature meets threshold before requesting auth token
+- Updated dependencies
+- Updated dependencies
+ - @0xsequence/abi@0.36.12
+ - @0xsequence/api@0.36.12
+ - @0xsequence/config@0.36.12
+ - @0xsequence/indexer@0.36.12
+ - @0xsequence/metadata@0.36.12
+ - @0xsequence/network@0.36.12
+ - @0xsequence/utils@0.36.12
+ - @0xsequence/wallet@0.36.12
+
+## 0.36.11
+
+### Patch Changes
+
+- Prefix EIP191 message on wallet-request-handler
+- Updated dependencies
+ - @0xsequence/abi@0.36.11
+ - @0xsequence/api@0.36.11
+ - @0xsequence/config@0.36.11
+ - @0xsequence/indexer@0.36.11
+ - @0xsequence/metadata@0.36.11
+ - @0xsequence/network@0.36.11
+ - @0xsequence/utils@0.36.11
+ - @0xsequence/wallet@0.36.11
+
+## 0.36.10
+
+### Patch Changes
+
+- support bannerUrl on connect
+- Updated dependencies
+ - @0xsequence/abi@0.36.10
+ - @0xsequence/api@0.36.10
+ - @0xsequence/config@0.36.10
+ - @0xsequence/indexer@0.36.10
+ - @0xsequence/metadata@0.36.10
+ - @0xsequence/network@0.36.10
+ - @0xsequence/utils@0.36.10
+ - @0xsequence/wallet@0.36.10
+
+## 0.36.9
+
+### Patch Changes
+
+- minor dev xp improvements
+- Updated dependencies
+ - @0xsequence/abi@0.36.9
+ - @0xsequence/api@0.36.9
+ - @0xsequence/config@0.36.9
+ - @0xsequence/indexer@0.36.9
+ - @0xsequence/metadata@0.36.9
+ - @0xsequence/network@0.36.9
+ - @0xsequence/utils@0.36.9
+ - @0xsequence/wallet@0.36.9
+
+## 0.36.8
+
+### Patch Changes
+
+- more connect options (theme, payment providers, funding currencies)
+- Updated dependencies
+ - @0xsequence/abi@0.36.8
+ - @0xsequence/api@0.36.8
+ - @0xsequence/config@0.36.8
+ - @0xsequence/indexer@0.36.8
+ - @0xsequence/metadata@0.36.8
+ - @0xsequence/network@0.36.8
+ - @0xsequence/utils@0.36.8
+ - @0xsequence/wallet@0.36.8
+
+## 0.36.7
+
+### Patch Changes
+
+- fix missing break
+- Updated dependencies
+ - @0xsequence/abi@0.36.7
+ - @0xsequence/api@0.36.7
+ - @0xsequence/config@0.36.7
+ - @0xsequence/indexer@0.36.7
+ - @0xsequence/metadata@0.36.7
+ - @0xsequence/network@0.36.7
+ - @0xsequence/utils@0.36.7
+ - @0xsequence/wallet@0.36.7
+
+## 0.36.6
+
+### Patch Changes
+
+- wallet_switchEthereumChain support
+- Updated dependencies
+ - @0xsequence/abi@0.36.6
+ - @0xsequence/api@0.36.6
+ - @0xsequence/config@0.36.6
+ - @0xsequence/indexer@0.36.6
+ - @0xsequence/metadata@0.36.6
+ - @0xsequence/network@0.36.6
+ - @0xsequence/utils@0.36.6
+ - @0xsequence/wallet@0.36.6
+
+## 0.36.5
+
+### Patch Changes
+
+- auth: bump ethauth to 0.7.0
+ network, wallet: don't assume position of auth network in list
+ api/indexer/metadata: trim trailing slash on hostname, and add endpoint urls
+ relayer: Allow to specify local relayer transaction parameters like gas price or gas limit
+- Updated dependencies
+ - @0xsequence/abi@0.36.5
+ - @0xsequence/api@0.36.5
+ - @0xsequence/config@0.36.5
+ - @0xsequence/indexer@0.36.5
+ - @0xsequence/metadata@0.36.5
+ - @0xsequence/network@0.36.5
+ - @0xsequence/utils@0.36.5
+ - @0xsequence/wallet@0.36.5
+
+## 0.36.4
+
+### Patch Changes
+
+- Updating list of chain ids to include other ethereum compatible chains
+- Updated dependencies
+ - @0xsequence/abi@0.36.4
+ - @0xsequence/api@0.36.4
+ - @0xsequence/config@0.36.4
+ - @0xsequence/indexer@0.36.4
+ - @0xsequence/metadata@0.36.4
+ - @0xsequence/network@0.36.4
+ - @0xsequence/utils@0.36.4
+ - @0xsequence/wallet@0.36.4
+
+## 0.36.3
+
+### Patch Changes
+
+- provider: pass connect options to prompter methods
+- Updated dependencies
+ - @0xsequence/abi@0.36.3
+ - @0xsequence/api@0.36.3
+ - @0xsequence/config@0.36.3
+ - @0xsequence/indexer@0.36.3
+ - @0xsequence/metadata@0.36.3
+ - @0xsequence/network@0.36.3
+ - @0xsequence/utils@0.36.3
+ - @0xsequence/wallet@0.36.3
+
+## 0.36.2
+
+### Patch Changes
+
+- transactions: Setting target to 0x0 when empty to during SequenceTxAbiEncode
+- Updated dependencies
+ - @0xsequence/abi@0.36.2
+ - @0xsequence/api@0.36.2
+ - @0xsequence/config@0.36.2
+ - @0xsequence/indexer@0.36.2
+ - @0xsequence/metadata@0.36.2
+ - @0xsequence/network@0.36.2
+ - @0xsequence/utils@0.36.2
+ - @0xsequence/wallet@0.36.2
+
+## 0.36.1
+
+### Patch Changes
+
+- metadata: update client with more fields
+- Updated dependencies
+ - @0xsequence/abi@0.36.1
+ - @0xsequence/api@0.36.1
+ - @0xsequence/config@0.36.1
+ - @0xsequence/indexer@0.36.1
+ - @0xsequence/metadata@0.36.1
+ - @0xsequence/network@0.36.1
+ - @0xsequence/utils@0.36.1
+ - @0xsequence/wallet@0.36.1
+
+## 0.36.0
+
+### Minor Changes
+
+- relayer, wallet: fee quote support
+
+### Patch Changes
+
+- Updated dependencies
+ - @0xsequence/abi@0.36.0
+ - @0xsequence/api@0.36.0
+ - @0xsequence/config@0.36.0
+ - @0xsequence/indexer@0.36.0
+ - @0xsequence/metadata@0.36.0
+ - @0xsequence/network@0.36.0
+ - @0xsequence/utils@0.36.0
+ - @0xsequence/wallet@0.36.0
+
+## 0.35.12
+
+### Patch Changes
+
+- provider: rename wallet.commands to wallet.utils
+- Updated dependencies
+ - @0xsequence/abi@0.35.12
+ - @0xsequence/api@0.35.12
+ - @0xsequence/config@0.35.12
+ - @0xsequence/indexer@0.35.12
+ - @0xsequence/metadata@0.35.12
+ - @0xsequence/network@0.35.12
+ - @0xsequence/utils@0.35.12
+ - @0xsequence/wallet@0.35.12
+
+## 0.35.11
+
+### Patch Changes
+
+- provider/utils: smoother message validation
+- Updated dependencies
+ - @0xsequence/abi@0.35.11
+ - @0xsequence/api@0.35.11
+ - @0xsequence/config@0.35.11
+ - @0xsequence/indexer@0.35.11
+ - @0xsequence/metadata@0.35.11
+ - @0xsequence/network@0.35.11
+ - @0xsequence/utils@0.35.11
+ - @0xsequence/wallet@0.35.11
+
+## 0.35.10
+
+### Patch Changes
+
+- upgrade deps
+- Updated dependencies
+ - @0xsequence/abi@0.35.10
+ - @0xsequence/api@0.35.10
+ - @0xsequence/config@0.35.10
+ - @0xsequence/indexer@0.35.10
+ - @0xsequence/metadata@0.35.10
+ - @0xsequence/network@0.35.10
+ - @0xsequence/utils@0.35.10
+ - @0xsequence/wallet@0.35.10
+
+## 0.35.9
+
+### Patch Changes
+
+- provider: window-transport override event handlers with new wallet instance
+- Updated dependencies
+ - @0xsequence/abi@0.35.9
+ - @0xsequence/api@0.35.9
+ - @0xsequence/config@0.35.9
+ - @0xsequence/indexer@0.35.9
+ - @0xsequence/metadata@0.35.9
+ - @0xsequence/network@0.35.9
+ - @0xsequence/utils@0.35.9
+ - @0xsequence/wallet@0.35.9
+
+## 0.35.8
+
+### Patch Changes
+
+- provider: async wallet sign in improvements
+- Updated dependencies
+ - @0xsequence/abi@0.35.8
+ - @0xsequence/api@0.35.8
+ - @0xsequence/config@0.35.8
+ - @0xsequence/indexer@0.35.8
+ - @0xsequence/metadata@0.35.8
+ - @0xsequence/network@0.35.8
+ - @0xsequence/utils@0.35.8
+ - @0xsequence/wallet@0.35.8
+
+## 0.35.7
+
+### Patch Changes
+
+- config: cache wallet configs
+- Updated dependencies
+ - @0xsequence/abi@0.35.7
+ - @0xsequence/api@0.35.7
+ - @0xsequence/config@0.35.7
+ - @0xsequence/indexer@0.35.7
+ - @0xsequence/metadata@0.35.7
+ - @0xsequence/network@0.35.7
+ - @0xsequence/utils@0.35.7
+ - @0xsequence/wallet@0.35.7
+
+## 0.35.6
+
+### Patch Changes
+
+- provider: support async signin of wallet request handler
+- Updated dependencies
+ - @0xsequence/abi@0.35.6
+ - @0xsequence/api@0.35.6
+ - @0xsequence/config@0.35.6
+ - @0xsequence/indexer@0.35.6
+ - @0xsequence/metadata@0.35.6
+ - @0xsequence/network@0.35.6
+ - @0xsequence/utils@0.35.6
+ - @0xsequence/wallet@0.35.6
+
+## 0.35.5
+
+### Patch Changes
+
+- wallet: skip threshold check during fee estimation
+- Updated dependencies
+ - @0xsequence/abi@0.35.5
+ - @0xsequence/api@0.35.5
+ - @0xsequence/config@0.35.5
+ - @0xsequence/indexer@0.35.5
+ - @0xsequence/metadata@0.35.5
+ - @0xsequence/network@0.35.5
+ - @0xsequence/utils@0.35.5
+ - @0xsequence/wallet@0.35.5
+
+## 0.35.4
+
+### Patch Changes
+
+- - browser extension mode, center window
+- Updated dependencies
+ - @0xsequence/abi@0.35.4
+ - @0xsequence/api@0.35.4
+ - @0xsequence/config@0.35.4
+ - @0xsequence/indexer@0.35.4
+ - @0xsequence/metadata@0.35.4
+ - @0xsequence/network@0.35.4
+ - @0xsequence/utils@0.35.4
+ - @0xsequence/wallet@0.35.4
+
+## 0.35.3
+
+### Patch Changes
+
+- - update window position when in browser extension mode
+- Updated dependencies
+ - @0xsequence/abi@0.35.3
+ - @0xsequence/api@0.35.3
+ - @0xsequence/config@0.35.3
+ - @0xsequence/indexer@0.35.3
+ - @0xsequence/metadata@0.35.3
+ - @0xsequence/network@0.35.3
+ - @0xsequence/utils@0.35.3
+ - @0xsequence/wallet@0.35.3
+
+## 0.35.2
+
+### Patch Changes
+
+- - provider: WindowMessageHandler accept optional windowHref
+- Updated dependencies
+ - @0xsequence/abi@0.35.2
+ - @0xsequence/api@0.35.2
+ - @0xsequence/config@0.35.2
+ - @0xsequence/indexer@0.35.2
+ - @0xsequence/metadata@0.35.2
+ - @0xsequence/network@0.35.2
+ - @0xsequence/utils@0.35.2
+ - @0xsequence/wallet@0.35.2
+
+## 0.35.1
+
+### Patch Changes
+
+- wallet: update config on undeployed too
+- Updated dependencies
+ - @0xsequence/abi@0.35.1
+ - @0xsequence/api@0.35.1
+ - @0xsequence/config@0.35.1
+ - @0xsequence/indexer@0.35.1
+ - @0xsequence/metadata@0.35.1
+ - @0xsequence/network@0.35.1
+ - @0xsequence/utils@0.35.1
+ - @0xsequence/wallet@0.35.1
+
+## 0.35.0
+
+### Minor Changes
+
+- - config: add buildStubSignature
+ - provider: add checks to signing cases for wallet deployment and config statuses
+ - provider: add prompt for wallet deployment
+ - relayer: add BaseRelayer.prependWalletDeploy
+ - relayer: add Relayer.feeOptions
+ - relayer: account for wallet deployment in fee estimation
+ - transactions: add fromTransactionish
+ - wallet: add Account.prependConfigUpdate
+ - wallet: add Account.getFeeOptions
+
+### Patch Changes
+
+- Updated dependencies
+ - @0xsequence/abi@0.35.0
+ - @0xsequence/api@0.35.0
+ - @0xsequence/config@0.35.0
+ - @0xsequence/indexer@0.35.0
+ - @0xsequence/metadata@0.35.0
+ - @0xsequence/network@0.35.0
+ - @0xsequence/utils@0.35.0
+ - @0xsequence/wallet@0.35.0
+
+## 0.34.1
+
+### Patch Changes
+
+- upgrade ethauth dep
+
+## 0.34.0
+
+### Minor Changes
+
+- - upgrade deps
+
+### Patch Changes
+
+- Updated dependencies
+ - @0xsequence/abi@0.34.0
+ - @0xsequence/api@0.34.0
+ - @0xsequence/config@0.34.0
+ - @0xsequence/indexer@0.34.0
+ - @0xsequence/metadata@0.34.0
+ - @0xsequence/network@0.34.0
+ - @0xsequence/utils@0.34.0
+ - @0xsequence/wallet@0.34.0
+
+## 0.33.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @0xsequence/wallet@0.33.3
+
+## 0.33.2
+
+### Patch Changes
+
+- @0xsequence/wallet@0.33.2
+
+## 0.33.1
+
+### Patch Changes
+
+- Updated dependencies
+ - @0xsequence/api@0.33.1
+
+## 0.33.0
+
+### Minor Changes
+
+- auth: fix spelling of 'thershold' to 'threshold'
+
+## 0.31.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @0xsequence/metadata@0.31.3
+
+## 0.31.1
+
+### Patch Changes
+
+- @0xsequence/wallet@0.31.1
+
+## 0.31.0
+
+### Minor Changes
+
+- - upgrading to ethers v5.5
+
+### Patch Changes
+
+- Updated dependencies
+ - @0xsequence/abi@0.31.0
+ - @0xsequence/api@0.31.0
+ - @0xsequence/config@0.31.0
+ - @0xsequence/indexer@0.31.0
+ - @0xsequence/metadata@0.31.0
+ - @0xsequence/network@0.31.0
+ - @0xsequence/utils@0.31.0
+ - @0xsequence/wallet@0.31.0
+
+## 0.30.0
+
+### Minor Changes
+
+- - upgrade most deps
+
+### Patch Changes
+
+- Updated dependencies
+ - @0xsequence/abi@0.30.0
+ - @0xsequence/api@0.30.0
+ - @0xsequence/config@0.30.0
+ - @0xsequence/indexer@0.30.0
+ - @0xsequence/metadata@0.30.0
+ - @0xsequence/network@0.30.0
+ - @0xsequence/utils@0.30.0
+ - @0xsequence/wallet@0.30.0
+
+## 0.29.9
+
+### Patch Changes
+
+- Updated dependencies [undefined]
+ - @0xsequence/api@0.29.9
+
+## 0.29.8
+
+### Patch Changes
+
+- update api
+- Updated dependencies [undefined]
+ - @0xsequence/abi@0.29.8
+ - @0xsequence/api@0.29.8
+ - @0xsequence/config@0.29.8
+ - @0xsequence/indexer@0.29.8
+ - @0xsequence/metadata@0.29.8
+ - @0xsequence/network@0.29.8
+ - @0xsequence/utils@0.29.8
+ - @0xsequence/wallet@0.29.8
+
+## 0.29.7
+
+### Patch Changes
+
+- Updated dependencies [undefined]
+ - @0xsequence/wallet@0.29.7
+
+## 0.29.6
+
+### Patch Changes
+
+- Updated dependencies [undefined]
+ - @0xsequence/network@0.29.6
+ - @0xsequence/config@0.29.6
+ - @0xsequence/wallet@0.29.6
+
+## 0.29.5
+
+### Patch Changes
+
+- auth: pass testnetMode flag depending on network
+- Updated dependencies [undefined]
+ - @0xsequence/config@0.29.5
+ - @0xsequence/wallet@0.29.5
+
+## 0.29.4
+
+### Patch Changes
+
+- Updated dependencies [undefined]
+ - @0xsequence/api@0.29.4
+
+## 0.29.3
+
+### Patch Changes
+
+- Updated dependencies [undefined]
+ - @0xsequence/indexer@0.29.3
+
+## 0.29.2
+
+### Patch Changes
+
+- @0xsequence/wallet@0.29.2
+
+## 0.29.1
+
+### Patch Changes
+
+- Updated dependencies [undefined]
+ - @0xsequence/api@0.29.1
+ - @0xsequence/metadata@0.29.1
+
+## 0.29.0
+
+### Minor Changes
+
+- major architectural changes in Sequence design
+
+ - only one API instance, API is no longer a per-chain service
+ - separate per-chain indexer service, API no longer handles indexing
+ - single contract metadata service, API no longer serves metadata
+
+ chaind package has been removed, indexer and metadata packages have been added
+
+ stronger typing with new explicit ChainId type
+
+ multicall fixes and improvements
+
+ forbid "wait" transactions in sendTransactionBatch calls
+
+### Patch Changes
+
+- Updated dependencies [undefined]
+ - @0xsequence/api@0.29.0
+ - @0xsequence/config@0.29.0
+ - @0xsequence/indexer@0.29.0
+ - @0xsequence/metadata@0.29.0
+ - @0xsequence/network@0.29.0
+ - @0xsequence/abi@0.29.0
+ - @0xsequence/utils@0.29.0
+ - @0xsequence/wallet@0.29.0
+
+## 0.28.0
+
+### Minor Changes
+
+- extension provider
+
+### Patch Changes
+
+- Updated dependencies [undefined]
+ - @0xsequence/abi@0.28.0
+ - @0xsequence/api@0.28.0
+ - @0xsequence/config@0.28.0
+ - @0xsequence/network@0.28.0
+ - @0xsequence/utils@0.28.0
+ - @0xsequence/wallet@0.28.0
+
+## 0.27.2
+
+### Patch Changes
+
+- Updated dependencies [undefined]
+ - @0xsequence/wallet@0.27.2
+
+## 0.27.1
+
+### Patch Changes
+
+- @0xsequence/wallet@0.27.1
+
+## 0.27.0
+
+### Minor Changes
+
+- Add requireFreshSigner lib to sessions
+
+### Patch Changes
+
+- Updated dependencies [undefined]
+ - @0xsequence/abi@0.27.0
+ - @0xsequence/api@0.27.0
+ - @0xsequence/config@0.27.0
+ - @0xsequence/network@0.27.0
+ - @0xsequence/utils@0.27.0
+ - @0xsequence/wallet@0.27.0
+
+## 0.26.0
+
+### Minor Changes
+
+- update relayer client bindings
+ provide the wallet's address for calls to SendMetaTxn
+ modify the semantics of Relayer.getNonce() to allow relayers to select nonce spaces for clients
+
+### Patch Changes
+
+- Updated dependencies [undefined]
+ - @0xsequence/wallet@0.26.0
+
+## 0.25.1
+
+### Patch Changes
+
+- Fix build typescrypt issue
+- Updated dependencies [undefined]
+ - @0xsequence/abi@0.25.1
+ - @0xsequence/api@0.25.1
+ - @0xsequence/config@0.25.1
+ - @0xsequence/network@0.25.1
+ - @0xsequence/utils@0.25.1
+ - @0xsequence/wallet@0.25.1
+
+## 0.25.0
+
+### Minor Changes
+
+- 10c8af8: Add estimator package
+ Fix multicall few calls bug
+
+### Patch Changes
+
+- Updated dependencies [10c8af8]
+ - @0xsequence/abi@0.25.0
+ - @0xsequence/api@0.25.0
+ - @0xsequence/config@0.25.0
+ - @0xsequence/network@0.25.0
+ - @0xsequence/utils@0.25.0
+ - @0xsequence/wallet@0.25.0
+
+## 0.24.1
+
+### Patch Changes
+
+- @0xsequence/wallet@0.24.1
+
+## 0.24.0
+
+### Patch Changes
+
+- Updated dependencies [undefined]
+ - @0xsequence/api@0.24.0
+ - @0xsequence/wallet@0.24.0
+
+## 0.23.0
+
+### Minor Changes
+
+- - relayer: offer variety of gas fee options from the relayer service"
+
+### Patch Changes
+
+- Updated dependencies [undefined]
+ - @0xsequence/abi@0.23.0
+ - @0xsequence/api@0.23.0
+ - @0xsequence/config@0.23.0
+ - @0xsequence/network@0.23.0
+ - @0xsequence/utils@0.23.0
+ - @0xsequence/wallet@0.23.0
+
+## 0.22.2
+
+### Patch Changes
+
+- e1c109e: Fix authProof on expired sessions
+- Updated dependencies [e1c109e]
+ - @0xsequence/abi@0.22.2
+ - @0xsequence/api@0.22.2
+ - @0xsequence/config@0.22.2
+ - @0xsequence/network@0.22.2
+ - @0xsequence/utils@0.22.2
+ - @0xsequence/wallet@0.22.2
+
+## 0.22.1
+
+### Patch Changes
+
+- transport session cache
+- Updated dependencies [undefined]
+ - @0xsequence/abi@0.22.1
+ - @0xsequence/api@0.22.1
+ - @0xsequence/config@0.22.1
+ - @0xsequence/network@0.22.1
+ - @0xsequence/utils@0.22.1
+ - @0xsequence/wallet@0.22.1
+
+## 0.22.0
+
+### Minor Changes
+
+- e667b65: Expose all relayer options on networks
+
+### Patch Changes
+
+- Updated dependencies [e667b65]
+ - @0xsequence/abi@0.22.0
+ - @0xsequence/network@0.22.0
+ - @0xsequence/utils@0.22.0
+ - @0xsequence/wallet@0.22.0
+ - @0xsequence/api@0.22.0
+ - @0xsequence/config@0.22.0
+
+## 0.21.5
+
+### Patch Changes
+
+- Give priority to metaTxnId returned by relayer
+- Updated dependencies [undefined]
+ - @0xsequence/abi@0.21.5
+ - @0xsequence/api@0.21.5
+ - @0xsequence/config@0.21.5
+ - @0xsequence/network@0.21.5
+ - @0xsequence/utils@0.21.5
+ - @0xsequence/wallet@0.21.5
+
+## 0.21.4
+
+### Patch Changes
+
+- Add has enough signers method
+- Updated dependencies [undefined]
+ - @0xsequence/abi@0.21.4
+ - @0xsequence/api@0.21.4
+ - @0xsequence/config@0.21.4
+ - @0xsequence/network@0.21.4
+ - @0xsequence/utils@0.21.4
+ - @0xsequence/wallet@0.21.4
+
+## 0.21.3
+
+### Patch Changes
+
+- add window session cache
+- Updated dependencies [undefined]
+ - @0xsequence/abi@0.21.3
+ - @0xsequence/api@0.21.3
+ - @0xsequence/config@0.21.3
+ - @0xsequence/network@0.21.3
+ - @0xsequence/utils@0.21.3
+ - @0xsequence/wallet@0.21.3
+
+## 0.21.2
+
+### Patch Changes
+
+- exception handlind in relayer
+- Updated dependencies [undefined]
+ - @0xsequence/abi@0.21.2
+ - @0xsequence/api@0.21.2
+ - @0xsequence/config@0.21.2
+ - @0xsequence/network@0.21.2
+ - @0xsequence/utils@0.21.2
+ - @0xsequence/wallet@0.21.2
+
+## 0.21.1
+
+### Patch Changes
+
+- Updated dependencies [undefined]
+ - @0xsequence/wallet@0.21.1
+
+## 0.21.0
+
+### Minor Changes
+
+- - fix gas estimation on wallets with large number of signers
+ - update to session handling and wallet config construction upon auth
+
+### Patch Changes
+
+- Updated dependencies [undefined]
+ - @0xsequence/abi@0.21.0
+ - @0xsequence/api@0.21.0
+ - @0xsequence/config@0.21.0
+ - @0xsequence/network@0.21.0
+ - @0xsequence/utils@0.21.0
+ - @0xsequence/wallet@0.21.0
+
+## 0.20.0
+
+### Minor Changes
+
+- revert JWT request piggybacking
+
+### Patch Changes
+
+- Updated dependencies [undefined]
+ - @0xsequence/api@0.20.0
+
+## 0.19.3
+
+### Patch Changes
+
+- jwtAuth visibility, package version sync
+- Updated dependencies [undefined]
+ - @0xsequence/abi@0.19.3
+ - @0xsequence/api@0.19.3
+ - @0xsequence/config@0.19.3
+ - @0xsequence/network@0.19.3
+ - @0xsequence/utils@0.19.3
+ - @0xsequence/wallet@0.19.3
+
+## 0.19.2
+
+### Patch Changes
+
+- Updated dependencies [undefined]
+ - @0xsequence/abi@0.19.2
+ - @0xsequence/config@0.19.2
+ - @0xsequence/wallet@0.19.2
+
+## 0.19.0
+
+### Minor Changes
+
+- - provider, improve dapp / wallet transport io
+
+### Patch Changes
+
+- Updated dependencies [undefined]
+ - @0xsequence/abi@0.19.0
+ - @0xsequence/api@0.19.0
+ - @0xsequence/config@0.19.0
+ - @0xsequence/network@0.19.0
+ - @0xsequence/utils@0.19.0
+ - @0xsequence/wallet@0.19.0
+
+## 0.18.0
+
+### Minor Changes
+
+- relayer improvements and pending transaction handling
+
+### Patch Changes
+
+- Updated dependencies [undefined]
+ - @0xsequence/abi@0.18.0
+ - @0xsequence/api@0.18.0
+ - @0xsequence/config@0.18.0
+ - @0xsequence/network@0.18.0
+ - @0xsequence/wallet@0.18.0
+
+## 0.17.0
+
+### Minor Changes
+
+- piggyback on already pending JWT and signing requests
+
+### Patch Changes
+
+- Updated dependencies [undefined]
+ - @0xsequence/api@0.17.0
+
+## 0.16.1
+
+### Patch Changes
+
+- Updated dependencies [undefined]
+ - @0xsequence/api@0.16.1
+
+## 0.16.0
+
+### Minor Changes
+
+- relayer as its own service separate from chaind
+
+### Patch Changes
+
+- Updated dependencies [undefined]
+ - @0xsequence/abi@0.16.0
+ - @0xsequence/api@0.16.0
+ - @0xsequence/config@0.16.0
+ - @0xsequence/network@0.16.0
+ - @0xsequence/wallet@0.16.0
+
+## 0.15.1
+
+### Patch Changes
+
+- update api clients
+- Updated dependencies [undefined]
+ - @0xsequence/abi@0.15.1
+ - @0xsequence/api@0.15.1
+ - @0xsequence/config@0.15.1
+ - @0xsequence/network@0.15.1
+ - @0xsequence/wallet@0.15.1
+
+## 0.15.0
+
+### Patch Changes
+
+- Updated dependencies [undefined]
+ - @0xsequence/api@0.15.0
+ - @0xsequence/wallet@0.15.0
+
+## 0.14.3
+
+### Patch Changes
+
+- Fix 0xSequence relayer dependencies
+- Updated dependencies [undefined]
+ - @0xsequence/abi@0.14.3
+ - @0xsequence/api@0.14.3
+ - @0xsequence/config@0.14.3
+ - @0xsequence/network@0.14.3
+ - @0xsequence/wallet@0.14.3
+
+## 0.14.2
+
+### Patch Changes
+
+- Add debug logs to rpc-relayer
+- Updated dependencies [undefined]
+ - @0xsequence/abi@0.14.2
+ - @0xsequence/api@0.14.2
+ - @0xsequence/config@0.14.2
+ - @0xsequence/network@0.14.2
+ - @0xsequence/wallet@0.14.2
+
+## 0.14.0
+
+### Minor Changes
+
+- update sequence utils finder which includes optimization
+
+### Patch Changes
+
+- Updated dependencies [undefined]
+ - @0xsequence/abi@0.14.0
+ - @0xsequence/api@0.14.0
+ - @0xsequence/config@0.14.0
+ - @0xsequence/network@0.14.0
+ - @0xsequence/wallet@0.14.0
+
+## 0.13.0
+
+### Minor Changes
+
+- Update SequenceUtils deployed contract
+
+### Patch Changes
+
+- Updated dependencies [undefined]
+ - @0xsequence/abi@0.13.0
+ - @0xsequence/api@0.13.0
+ - @0xsequence/config@0.13.0
+ - @0xsequence/network@0.13.0
+ - @0xsequence/wallet@0.13.0
+
+## 0.12.1
+
+### Patch Changes
+
+- npm bump
+- Updated dependencies [undefined]
+ - @0xsequence/abi@0.12.1
+ - @0xsequence/api@0.12.1
+ - @0xsequence/config@0.12.1
+ - @0xsequence/network@0.12.1
+ - @0xsequence/wallet@0.12.1
+
+## 0.12.0
+
+### Minor Changes
+
+- provider: improvements to window transport
+
+### Patch Changes
+
+- Updated dependencies [undefined]
+ - @0xsequence/abi@0.12.0
+ - @0xsequence/api@0.12.0
+ - @0xsequence/config@0.12.0
+ - @0xsequence/network@0.12.0
+ - @0xsequence/wallet@0.12.0
+
+## 0.11.4
+
+### Patch Changes
+
+- update api client
+- Updated dependencies [undefined]
+ - @0xsequence/api@0.11.4
+ - @0xsequence/abi@0.11.4
+ - @0xsequence/config@0.11.4
+ - @0xsequence/network@0.11.4
+ - @0xsequence/wallet@0.11.4
+
+## 0.11.3
+
+### Patch Changes
+
+- improve openWindow state options handling
+- Updated dependencies [undefined]
+ - @0xsequence/abi@0.11.3
+ - @0xsequence/api@0.11.3
+ - @0xsequence/config@0.11.3
+ - @0xsequence/network@0.11.3
+ - @0xsequence/wallet@0.11.3
+
+## 0.11.2
+
+### Patch Changes
+
+- Fix multicall proxy scopes
+- Updated dependencies [undefined]
+ - @0xsequence/abi@0.11.2
+ - @0xsequence/api@0.11.2
+ - @0xsequence/config@0.11.2
+ - @0xsequence/network@0.11.2
+ - @0xsequence/wallet@0.11.2
+
+## 0.11.1
+
+### Patch Changes
+
+- Add support for dynamic and nested signatures
+- Updated dependencies [undefined]
+ - @0xsequence/abi@0.11.1
+ - @0xsequence/api@0.11.1
+ - @0xsequence/config@0.11.1
+ - @0xsequence/network@0.11.1
+ - @0xsequence/wallet@0.11.1
+
+## 0.11.0
+
+### Minor Changes
+
+- Update wallet context to 1.7 contracts
+
+### Patch Changes
+
+- Updated dependencies [undefined]
+ - @0xsequence/abi@0.11.0
+ - @0xsequence/api@0.11.0
+ - @0xsequence/config@0.11.0
+ - @0xsequence/network@0.11.0
+ - @0xsequence/wallet@0.11.0
+
+## 0.10.9
+
+### Patch Changes
+
+- add support for public addresses as signers in session.open
+- Updated dependencies [undefined]
+ - @0xsequence/abi@0.10.9
+ - @0xsequence/api@0.10.9
+ - @0xsequence/config@0.10.9
+ - @0xsequence/network@0.10.9
+ - @0xsequence/wallet@0.10.9
+
+## 0.10.8
+
+### Patch Changes
+
+- Multicall production configuration
+- Updated dependencies [undefined]
+ - @0xsequence/abi@0.10.8
+ - @0xsequence/api@0.10.8
+ - @0xsequence/config@0.10.8
+ - @0xsequence/network@0.10.8
+ - @0xsequence/wallet@0.10.8
+
+## 0.10.7
+
+### Patch Changes
+
+- allow provider transport to force disconnect
+- Updated dependencies [undefined]
+ - @0xsequence/abi@0.10.7
+ - @0xsequence/api@0.10.7
+ - @0xsequence/config@0.10.7
+ - @0xsequence/network@0.10.7
+ - @0xsequence/wallet@0.10.7
+
+## 0.10.6
+
+### Patch Changes
+
+- - fix getWalletState method
+- Updated dependencies [undefined]
+ - @0xsequence/abi@0.10.6
+ - @0xsequence/api@0.10.6
+ - @0xsequence/config@0.10.6
+ - @0xsequence/network@0.10.6
+ - @0xsequence/wallet@0.10.6
+
+## 0.10.5
+
+### Patch Changes
+
+- update relayer gas refund options
+- Updated dependencies [undefined]
+ - @0xsequence/abi@0.10.5
+ - @0xsequence/api@0.10.5
+ - @0xsequence/config@0.10.5
+ - @0xsequence/network@0.10.5
+ - @0xsequence/wallet@0.10.5
+
+## 0.10.4
+
+### Patch Changes
+
+- Update api proto
+- Updated dependencies [undefined]
+ - @0xsequence/abi@0.10.4
+ - @0xsequence/api@0.10.4
+ - @0xsequence/config@0.10.4
+ - @0xsequence/network@0.10.4
+ - @0xsequence/wallet@0.10.4
+
+## 0.10.3
+
+### Patch Changes
+
+- Fix loading config cross-chain
+- Updated dependencies [undefined]
+ - @0xsequence/abi@0.10.3
+ - @0xsequence/api@0.10.3
+ - @0xsequence/config@0.10.3
+ - @0xsequence/network@0.10.3
+ - @0xsequence/wallet@0.10.3
+
+## 0.10.2
+
+### Patch Changes
+
+- - message digest fix
+- Updated dependencies [undefined]
+ - @0xsequence/abi@0.10.2
+ - @0xsequence/api@0.10.2
+ - @0xsequence/config@0.10.2
+ - @0xsequence/network@0.10.2
+ - @0xsequence/wallet@0.10.2
+
+## 0.10.1
+
+### Patch Changes
+
+- upgrade deps
+- Updated dependencies [undefined]
+ - @0xsequence/abi@0.10.1
+ - @0xsequence/api@0.10.1
+ - @0xsequence/config@0.10.1
+ - @0xsequence/network@0.10.1
+ - @0xsequence/wallet@0.10.1
+
+## 0.10.0
+
+### Minor Changes
+
+- Deployed new contracts with ERC1271 signer support
+
+### Patch Changes
+
+- Updated dependencies [undefined]
+ - @0xsequence/abi@0.10.0
+ - @0xsequence/api@0.10.0
+ - @0xsequence/config@0.10.0
+ - @0xsequence/network@0.10.0
+ - @0xsequence/wallet@0.10.0
+
+## 0.9.6
+
+### Patch Changes
+
+- Update ABIs for latest sequence contracts
+- Updated dependencies [undefined]
+ - @0xsequence/api@0.9.6
+ - @0xsequence/config@0.9.6
+ - @0xsequence/network@0.9.6
+ - @0xsequence/wallet@0.9.6
+ - @0xsequence/abi@0.9.6
+
+## 0.9.5
+
+### Patch Changes
+
+- Implemented session class
+- Updated dependencies [undefined]
+ - @0xsequence/api@0.9.5
+ - @0xsequence/config@0.9.5
+ - @0xsequence/network@0.9.5
+ - @0xsequence/wallet@0.9.5
+
+## 0.9.3
+
+### Patch Changes
+
+- - minor improvements
+- Updated dependencies [undefined]
+ - @0xsequence/abi@0.9.3
+ - @0xsequence/network@0.9.3
+ - @0xsequence/wallet@0.9.3
+
+## 0.9.1
+
+### Patch Changes
+
+- - patch bump
+- Updated dependencies [undefined]
+ - @0xsequence/abi@0.9.1
+ - @0xsequence/network@0.9.1
+ - @0xsequence/wallet@0.9.1
+
+## 0.9.0
+
+### Minor Changes
+
+- - provider transport hardening
+
+### Patch Changes
+
+- Updated dependencies [undefined]
+ - @0xsequence/abi@0.9.0
+ - @0xsequence/network@0.9.0
+ - @0xsequence/wallet@0.9.0
+
+## 0.8.5
+
+### Patch Changes
+
+- - use latest wallet-contracts
+- Updated dependencies [undefined]
+ - @0xsequence/abi@0.8.5
+ - @0xsequence/network@0.8.5
+ - @0xsequence/wallet@0.8.5
+
+## 0.8.4
+
+### Patch Changes
+
+- - minor improvements, name updates and comments
+- Updated dependencies [undefined]
+ - @0xsequence/abi@0.8.4
+ - @0xsequence/network@0.8.4
+ - @0xsequence/wallet@0.8.4
+
+## 0.8.3
+
+### Patch Changes
+
+- - refinements
+
+ - normalize signer address in config
+
+ - provider: getWalletState() method to WalletProvider
+
+- Updated dependencies [undefined]
+ - @0xsequence/abi@0.8.3
+ - @0xsequence/network@0.8.3
+ - @0xsequence/wallet@0.8.3
+
+## 0.8.2
+
+### Patch Changes
+
+- - field rename and ethauth dependency bump
+- Updated dependencies [undefined]
+ - @0xsequence/abi@0.8.2
+ - @0xsequence/network@0.8.2
+ - @0xsequence/wallet@0.8.2
+
+## 0.8.1
+
+### Patch Changes
+
+- - variety of optimizations
+- Updated dependencies [undefined]
+ - @0xsequence/abi@0.8.1
+ - @0xsequence/network@0.8.1
+ - @0xsequence/wallet@0.8.1
+
+## 0.8.0
+
+### Minor Changes
+
+- - changeset fix
+
+### Patch Changes
+
+- Updated dependencies [undefined]
+ - @0xsequence/abi@0.8.0
+ - @0xsequence/network@0.8.0
+ - @0xsequence/wallet@0.8.0
+
+## 0.7.2
+
+### Patch Changes
+
+- package.json fix
+
+## 0.7.0
+
+### Patch Changes
+
+- 6f11ed7: sequence.js, init release
+- Updated dependencies [6f11ed7]
+ - @0xsequence/abi@0.7.0
+ - @0xsequence/network@0.7.0
+ - @0xsequence/wallet@0.7.0
diff --git a/packages/auth/README.md b/packages/auth/README.md
new file mode 100644
index 0000000000..33f7072359
--- /dev/null
+++ b/packages/auth/README.md
@@ -0,0 +1,4 @@
+@0xsequence/auth
+================
+
+See [0xsequence project page](https://github.com/0xsequence/sequence.js).
diff --git a/packages/auth/hardhat.config.js b/packages/auth/hardhat.config.js
new file mode 100644
index 0000000000..eaca505314
--- /dev/null
+++ b/packages/auth/hardhat.config.js
@@ -0,0 +1,15 @@
+/**
+ * @type import('hardhat/config').HardhatUserConfig
+ */
+module.exports = {
+ solidity: '0.7.6',
+
+ networks: {
+ hardhat: {
+ chainId: 31337,
+ accounts: {
+ mnemonic: 'ripple axis someone ridge uniform wrist prosper there frog rate olympic knee'
+ }
+ }
+ }
+}
diff --git a/packages/auth/package.json b/packages/auth/package.json
new file mode 100644
index 0000000000..945ca4f2d8
--- /dev/null
+++ b/packages/auth/package.json
@@ -0,0 +1,49 @@
+{
+ "name": "@0xsequence/auth",
+ "version": "2.0.0",
+ "description": "auth sub-package for Sequence",
+ "repository": "https://github.com/0xsequence/sequence.js/tree/master/packages/auth",
+ "source": "src/index.ts",
+ "main": "dist/0xsequence-auth.cjs.js",
+ "module": "dist/0xsequence-auth.esm.js",
+ "author": "Horizon Blockchain Games",
+ "license": "Apache-2.0",
+ "scripts": {
+ "test": "pnpm test:concurrently 'pnpm test:run'",
+ "test:run": "pnpm test:file tests/**/*.spec.ts",
+ "test:file": "NODE_OPTIONS='--import tsx' mocha --timeout 30000",
+ "test:concurrently": "concurrently -k --success first 'pnpm start:hardhat > /dev/null' ",
+ "start:hardhat": "hardhat node --port 9546",
+ "typecheck": "tsc --noEmit"
+ },
+ "dependencies": {
+ "@0xsequence/abi": "workspace:*",
+ "@0xsequence/account": "workspace:*",
+ "@0xsequence/api": "workspace:*",
+ "@0xsequence/core": "workspace:*",
+ "@0xsequence/ethauth": "^0.8.1",
+ "@0xsequence/indexer": "workspace:*",
+ "@0xsequence/metadata": "workspace:*",
+ "@0xsequence/migration": "workspace:*",
+ "@0xsequence/network": "workspace:*",
+ "@0xsequence/sessions": "workspace:*",
+ "@0xsequence/signhub": "workspace:*",
+ "@0xsequence/wallet": "workspace:*",
+ "@0xsequence/utils": "workspace:*"
+ },
+ "peerDependencies": {
+ "ethers": ">=5.5 < 6"
+ },
+ "devDependencies": {
+ "@0xsequence/tests": "workspace:*",
+ "@0xsequence/wallet-contracts": "^1.10.0",
+ "concurrently": "^7.5.0",
+ "ethers": "^5.7.2",
+ "hardhat": "^2.20.1",
+ "mockttp": "^3.6.0"
+ },
+ "files": [
+ "src",
+ "dist"
+ ]
+}
diff --git a/packages/auth/src/authorization.ts b/packages/auth/src/authorization.ts
new file mode 100644
index 0000000000..103c2b2a79
--- /dev/null
+++ b/packages/auth/src/authorization.ts
@@ -0,0 +1,81 @@
+import { ethers } from 'ethers'
+import { ETHAuth, Proof } from '@0xsequence/ethauth'
+import { ChainIdLike, toChainIdNumber } from '@0xsequence/network'
+import { TypedData } from '@0xsequence/utils'
+import { Signer } from '@0xsequence/wallet'
+import { Account } from '@0xsequence/account'
+import { DEFAULT_SESSION_EXPIRATION } from './services'
+
+export interface AuthorizationOptions {
+ // app name string, ie 'Skyweaver'
+ app?: string
+
+ // origin hostname of encoded in the message, ie. 'play.skyweaver.net'
+ origin?: string
+
+ // expiry in seconds encoded in the message
+ expiry?: number
+
+ // nonce for the authorization request
+ nonce?: number
+}
+
+export interface ETHAuthProof {
+ // eip712 typed-data payload for ETHAuth domain as input
+ typedData: TypedData
+
+ // signature encoded in an ETHAuth proof string
+ proofString: string
+}
+
+// signAuthorization will perform an EIP712 typed-data message signing of ETHAuth domain via the provided
+// Signer and authorization options.
+export const signAuthorization = async (
+ signer: Signer | Account,
+ chainId: ChainIdLike,
+ options: AuthorizationOptions
+): Promise => {
+ const address = ethers.utils.getAddress(await signer.getAddress())
+ if (!address || address === '' || address === '0x') {
+ throw ErrAccountIsRequired
+ }
+
+ const proof = new Proof()
+ proof.address = address
+
+ if (!options || !options.app || options.app === '') {
+ throw new AuthError('authorization options requires app to be set')
+ }
+ proof.claims.app = options.app
+ proof.claims.ogn = options.origin
+ proof.claims.n = options.nonce
+
+ proof.setExpiryIn(options.expiry ? Math.max(options.expiry, 200) : DEFAULT_SESSION_EXPIRATION)
+
+ const typedData = proof.messageTypedData()
+
+ const chainIdNumber = toChainIdNumber(chainId)
+
+ proof.signature = await (signer instanceof Account
+ ? // Account can sign EIP-6492 signatures, so it doesn't require deploying the wallet
+ signer.signTypedData(typedData.domain, typedData.types, typedData.message, chainIdNumber, 'eip6492')
+ : signer.signTypedData(typedData.domain, typedData.types, typedData.message, chainIdNumber))
+
+ const ethAuth = new ETHAuth()
+ const proofString = await ethAuth.encodeProof(proof, true)
+
+ return {
+ typedData,
+ proofString
+ }
+}
+
+// TODO: review......
+export class AuthError extends Error {
+ constructor(message?: string) {
+ super(message)
+ this.name = 'AuthError'
+ }
+}
+
+export const ErrAccountIsRequired = new AuthError('auth error: account address is empty')
diff --git a/packages/auth/src/index.ts b/packages/auth/src/index.ts
new file mode 100644
index 0000000000..af64af8df0
--- /dev/null
+++ b/packages/auth/src/index.ts
@@ -0,0 +1,3 @@
+export * from './authorization'
+export * from './session'
+export * from './proof'
diff --git a/packages/auth/src/proof.ts b/packages/auth/src/proof.ts
new file mode 100644
index 0000000000..23051fde69
--- /dev/null
+++ b/packages/auth/src/proof.ts
@@ -0,0 +1,16 @@
+import { commons } from '@0xsequence/core'
+import { Proof, ValidatorFunc } from '@0xsequence/ethauth'
+import { tracker } from '@0xsequence/sessions'
+import { ethers } from 'ethers'
+
+export const ValidateSequenceWalletProof = (
+ readerFor: (chainId: number) => commons.reader.Reader,
+ tracker: tracker.ConfigTracker,
+ context: commons.context.WalletContext
+): ValidatorFunc => {
+ return async (_provider: ethers.providers.JsonRpcProvider, chainId: number, proof: Proof): Promise<{ isValid: boolean }> => {
+ const digest = proof.messageDigest()
+ const isValid = await readerFor(chainId).isValidSignature(proof.address, digest, proof.signature)
+ return { isValid }
+ }
+}
diff --git a/packages/auth/src/services.ts b/packages/auth/src/services.ts
new file mode 100644
index 0000000000..6db53a216d
--- /dev/null
+++ b/packages/auth/src/services.ts
@@ -0,0 +1,337 @@
+import { Account } from '@0xsequence/account'
+import { SequenceAPIClient } from '@0xsequence/api'
+import { ETHAuth, Proof } from '@0xsequence/ethauth'
+import { Indexer, SequenceIndexer } from '@0xsequence/indexer'
+import { SequenceMetadata } from '@0xsequence/metadata'
+import { ChainIdLike, findNetworkConfig } from '@0xsequence/network'
+import { getEthersConnectionInfo } from '@0xsequence/utils'
+import { ethers } from 'ethers'
+
+export type SessionMeta = {
+ // name of the app requesting the session, used with ETHAuth
+ name: string
+
+ // expiration in seconds for a session before it expires, used with ETHAuth
+ expiration?: number
+}
+
+export type ServicesSettings = {
+ metadata: SessionMeta
+ sequenceApiUrl: string
+ sequenceApiChainId: ethers.BigNumberish
+ sequenceMetadataUrl: string
+}
+
+export type SessionJWT = {
+ token: string
+ expiration: number
+}
+
+export type SessionJWTPromise = {
+ token: Promise
+ expiration: number
+}
+
+export type ProofStringPromise = {
+ proofString: Promise
+ expiration: number
+}
+
+// Default session expiration of ETHAuth token (1 week)
+export const DEFAULT_SESSION_EXPIRATION = 60 * 60 * 24 * 7
+
+// Long session expiration of ETHAuth token (~1 year)
+export const LONG_SESSION_EXPIRATION = 3e7
+
+const EXPIRATION_JWT_MARGIN = 60 // seconds
+
+export class Services {
+ _initialAuthRequest: Promise
+
+ // proof strings are indexed by account address and app name, see getProofStringKey()
+ private readonly proofStrings: Map = new Map()
+
+ private onAuthCallbacks: ((result: PromiseSettledResult) => void)[] = []
+
+ private apiClient: SequenceAPIClient | undefined
+ private metadataClient: SequenceMetadata | undefined
+ private indexerClients: Map = new Map()
+
+ private projectAccessKey?: string
+
+ constructor(
+ public readonly account: Account,
+ public readonly settings: ServicesSettings,
+ public readonly status: {
+ jwt?: SessionJWTPromise
+ metadata?: SessionMeta
+ } = {},
+ projectAccessKey?: string
+ ) {
+ this.projectAccessKey = projectAccessKey
+ }
+
+ private now(): number {
+ return Math.floor(Date.now() / 1000)
+ }
+
+ get expiration(): number {
+ return Math.max(this.settings.metadata.expiration ?? DEFAULT_SESSION_EXPIRATION, 120)
+ }
+
+ onAuth(cb: (result: PromiseSettledResult) => void) {
+ this.onAuthCallbacks.push(cb)
+ return () => (this.onAuthCallbacks = this.onAuthCallbacks.filter(c => c !== cb))
+ }
+
+ async dump(): Promise<{
+ jwt?: SessionJWT
+ metadata?: SessionMeta
+ }> {
+ if (!this.status.jwt) return { metadata: this.settings.metadata }
+
+ return {
+ jwt: {
+ token: await this.status.jwt.token,
+ expiration: this.status.jwt.expiration
+ },
+ metadata: this.status.metadata
+ }
+ }
+
+ auth(maxTries: number = 5): Promise {
+ if (this._initialAuthRequest) return this._initialAuthRequest
+
+ this._initialAuthRequest = (async () => {
+ const url = this.settings.sequenceApiUrl
+ if (!url) throw Error('No sequence api url')
+
+ let jwtAuth: string | undefined
+ for (let i = 1; ; i++) {
+ try {
+ jwtAuth = (await this.getJWT(true)).token
+ break
+ } catch (error) {
+ if (i === maxTries) {
+ console.error(`couldn't authenticate after ${maxTries} attempts`, error)
+ throw error
+ }
+ }
+ }
+
+ return new SequenceAPIClient(url, undefined, jwtAuth)
+ })()
+
+ return this._initialAuthRequest
+ }
+
+ private async getJWT(tryAuth: boolean): Promise {
+ const url = this.settings.sequenceApiUrl
+ if (!url) throw Error('No sequence api url')
+
+ // check if we already have or are waiting for a token
+ if (this.status.jwt) {
+ const jwt = this.status.jwt
+ const token = await jwt.token
+
+ if (this.now() < jwt.expiration) {
+ return { token, expiration: jwt.expiration }
+ }
+
+ // token expired, delete it and get a new one
+ this.status.jwt = undefined
+ }
+
+ if (!tryAuth) {
+ throw new Error('no auth token in memory')
+ }
+
+ const proofStringKey = this.getProofStringKey()
+ const { proofString, expiration } = this.getProofString(proofStringKey)
+
+ const jwt = {
+ token: proofString
+ .then(async proofString => {
+ const api = new SequenceAPIClient(url)
+
+ const authResp = await api.getAuthToken({ ewtString: proofString })
+
+ if (authResp?.status === true && authResp.jwtToken.length !== 0) {
+ return authResp.jwtToken
+ } else {
+ if (!(await this.isProofStringValid(proofString))) {
+ this.proofStrings.delete(proofStringKey)
+ }
+ throw new Error('no auth token from server')
+ }
+ })
+ .catch(reason => {
+ this.status.jwt = undefined
+ throw reason
+ }),
+ expiration
+ }
+
+ this.status.jwt = jwt
+
+ jwt.token
+ .then(token => {
+ this.onAuthCallbacks.forEach(cb => {
+ try {
+ cb({ status: 'fulfilled', value: token })
+ } catch {}
+ })
+ })
+ .catch((reason: any) => {
+ this.onAuthCallbacks.forEach(cb => {
+ try {
+ cb({ status: 'rejected', reason })
+ } catch {}
+ })
+ })
+
+ const token = await jwt.token
+ return { token, expiration }
+ }
+
+ private getProofStringKey(): string {
+ return `${this.account.address} - ${this.settings.metadata.name}`
+ }
+
+ private async isProofStringValid(proofString: string): Promise {
+ try {
+ const ethAuth = new ETHAuth()
+ const chainId = ethers.BigNumber.from(this.settings.sequenceApiChainId)
+ const network = findNetworkConfig(this.account.networks, chainId)
+ if (!network) throw Error('No network found')
+ ethAuth.chainId = chainId.toNumber()
+
+ // TODO: Modify ETHAuth so it can take a provider instead of a url
+ // -----
+ // Can't pass jwt here since this is used for getting the jwt
+ ethAuth.provider = new ethers.providers.StaticJsonRpcProvider(
+ getEthersConnectionInfo(network.rpcUrl, this.projectAccessKey),
+ {
+ name: '',
+ chainId: chainId.toNumber()
+ }
+ )
+
+ await ethAuth.decodeProof(proofString)
+
+ return true
+ } catch {
+ return false
+ }
+ }
+
+ async getAPIClient(tryAuth: boolean = true): Promise {
+ if (!this.apiClient) {
+ const url = this.settings.sequenceApiUrl
+ if (!url) throw Error('No sequence api url')
+
+ const jwtAuth = (await this.getJWT(tryAuth)).token
+ this.apiClient = new SequenceAPIClient(url, undefined, jwtAuth)
+ }
+
+ return this.apiClient
+ }
+
+ async getMetadataClient(tryAuth: boolean = true): Promise {
+ if (!this.metadataClient) {
+ const jwtAuth = (await this.getJWT(tryAuth)).token
+ this.metadataClient = new SequenceMetadata(this.settings.sequenceMetadataUrl, undefined, jwtAuth)
+ }
+
+ return this.metadataClient
+ }
+
+ async getIndexerClient(chainId: ChainIdLike, tryAuth: boolean = true): Promise