diff --git a/.changeset/config.json b/.changeset/config.json index 4f8345f464..6b372552ca 100644 --- a/.changeset/config.json +++ b/.changeset/config.json @@ -5,7 +5,7 @@ "fixed": [], "linked": [], "access": "restricted", - "baseBranch": "master", + "baseBranch": "main", "updateInternalDependencies": "patch", - "ignore": ["@0xsequence/wallet-primitives-cli", "docs", "web"] + "ignore": [] } diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000000..dd84ea7824 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,38 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: '' +assignees: '' + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Desktop (please complete the following information):** + - OS: [e.g. iOS] + - Browser [e.g. chrome, safari] + - Version [e.g. 22] + +**Smartphone (please complete the following information):** + - Device: [e.g. iPhone6] + - OS: [e.g. iOS8.1] + - Browser [e.g. stock browser, safari] + - Version [e.g. 22] + +**Additional context** +Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/custom.md b/.github/ISSUE_TEMPLATE/custom.md new file mode 100644 index 0000000000..48d5f81fa4 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/custom.md @@ -0,0 +1,10 @@ +--- +name: Custom issue template +about: Describe this issue template's purpose here. +title: '' +labels: '' +assignees: '' + +--- + + diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000000..bbcbbe7d61 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,20 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: '' +labels: '' +assignees: '' + +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. diff --git a/.github/workflows/publish-dists.yml b/.github/workflows/publish-dists.yml new file mode 100644 index 0000000000..fd4bb79054 --- /dev/null +++ b/.github/workflows/publish-dists.yml @@ -0,0 +1,88 @@ +name: Publish Dists for Packages + +on: + workflow_dispatch: + push: + branches: + - master + +jobs: + build-and-push: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - uses: ./.github/actions/install-dependencies + + - name: Build package + run: pnpm run build + + - name: Prepare dist branch + run: | + PACKAGES=("services/guard" "services/identity-instrument" "services/relayer" "wallet/core" "wallet/primitives" "wallet/wdk" "wallet/dapp-client") + + for PACKAGE in "${PACKAGES[@]}"; do + BRANCH="dists/$PACKAGE" + PKG_DIR="packages/$PACKAGE" + + echo "šŸ“¦ Publishing $PACKAGE to $BRANCH" + + mkdir -p /tmp/$PACKAGE + shopt -s dotglob + cp -r $PKG_DIR/* /tmp/$PACKAGE || true + + cd /tmp/$PACKAGE + git init + git checkout -b $BRANCH + + git config user.name "github-actions" + git config user.email "actions@github.com" + + echo "šŸ”§ Rewriting workspace: deps in package.json..." + node -e ' + const fs = require("fs"); + const path = require("path"); + const pkgPath = path.resolve("package.json"); + const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf8")); + const repo = "github:0xsequence/sequence.js"; + + const versions = { + "@0xsequence/guard": `${repo}#dists/services/guard`, + "@0xsequence/identity-instrument": `${repo}#dists/services/identity-instrument`, + "@0xsequence/relayer": `${repo}#dists/services/relayer`, + "@0xsequence/wallet-core": `${repo}#dists/wallet/core`, + "@0xsequence/wallet-primitives": `${repo}#dists/wallet/primitives`, + "@0xsequence/wallet-wdk": `${repo}#dists/wallet/wdk`, + }; + + const rewrite = (deps = {}) => { + for (const k in deps) { + if (deps[k].startsWith("workspace:")) { + const version = versions[k]; + + if (!version) { + console.warn(`No version found for ${k}, skipping...`); + continue; + } + + deps[k] = version; + console.log(`→ ${k} → ${deps[k]}`); + } + } + }; + + rewrite(pkg.dependencies); + fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2)); + ' + + git add . + git commit -m "Build: publish $PACKAGE dist" + + git remote add origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}.git + git push -f origin HEAD:$BRANCH + + cd - + done diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index bb22f4c721..1fc06bba89 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -25,17 +25,16 @@ jobs: tests: name: Run all tests runs-on: ubuntu-latest - needs: [build] + needs: [install] steps: - uses: actions/checkout@v4 - uses: ./.github/actions/install-dependencies - name: Install Foundry uses: foundry-rs/foundry-toolchain@v1 with: - version: v1.5.0 + version: nightly - name: Start Anvil in background run: anvil --fork-url https://nodes.sequence.app/arbitrum & - - run: pnpm build - run: pnpm test # NOTE: if you'd like to see example of how to run diff --git a/extras/docs/eslint.config.js b/extras/docs/eslint.config.js index 0fbeffd979..3d2c2e9d49 100644 --- a/extras/docs/eslint.config.js +++ b/extras/docs/eslint.config.js @@ -1,9 +1,4 @@ import { nextJsConfig } from '@repo/eslint-config/next-js' /** @type {import("eslint").Linter.Config} */ -export default [ - ...nextJsConfig, - { - ignores: ['next-env.d.ts'], - }, -] +export default nextJsConfig diff --git a/extras/docs/next.config.js b/extras/docs/next.config.js index 2963459c42..1d6147825a 100644 --- a/extras/docs/next.config.js +++ b/extras/docs/next.config.js @@ -1,14 +1,4 @@ -import path from 'node:path' -import { fileURLToPath } from 'node:url' - -const __dirname = path.dirname(fileURLToPath(import.meta.url)) -const workspaceRoot = path.join(__dirname, '..', '..') - /** @type {import('next').NextConfig} */ -const nextConfig = { - // Anchor output tracing to the monorepo root so Next.js doesn't pick up - // sibling lockfiles and mis-detect the workspace boundary during lint/build. - outputFileTracingRoot: workspaceRoot, -} +const nextConfig = {} export default nextConfig diff --git a/extras/web/eslint.config.js b/extras/web/eslint.config.js index 0fbeffd979..3d2c2e9d49 100644 --- a/extras/web/eslint.config.js +++ b/extras/web/eslint.config.js @@ -1,9 +1,4 @@ import { nextJsConfig } from '@repo/eslint-config/next-js' /** @type {import("eslint").Linter.Config} */ -export default [ - ...nextJsConfig, - { - ignores: ['next-env.d.ts'], - }, -] +export default nextJsConfig diff --git a/extras/web/next.config.js b/extras/web/next.config.js index 2963459c42..1d6147825a 100644 --- a/extras/web/next.config.js +++ b/extras/web/next.config.js @@ -1,14 +1,4 @@ -import path from 'node:path' -import { fileURLToPath } from 'node:url' - -const __dirname = path.dirname(fileURLToPath(import.meta.url)) -const workspaceRoot = path.join(__dirname, '..', '..') - /** @type {import('next').NextConfig} */ -const nextConfig = { - // Anchor output tracing to the monorepo root so Next.js doesn't pick up - // sibling lockfiles and mis-detect the workspace boundary during lint/build. - outputFileTracingRoot: workspaceRoot, -} +const nextConfig = {} export default nextConfig diff --git a/packages/services/api/eslint.config.js b/packages/services/api/eslint.config.js index cecf89b031..19170f88ed 100644 --- a/packages/services/api/eslint.config.js +++ b/packages/services/api/eslint.config.js @@ -1,4 +1,4 @@ -import { config as baseConfig } from "@repo/eslint-config/base" +import { config } from "@repo/eslint-config/react-internal"; /** @type {import("eslint").Linter.Config} */ -export default baseConfig +export default config; diff --git a/packages/services/builder/eslint.config.js b/packages/services/builder/eslint.config.js index cecf89b031..19170f88ed 100644 --- a/packages/services/builder/eslint.config.js +++ b/packages/services/builder/eslint.config.js @@ -1,4 +1,4 @@ -import { config as baseConfig } from "@repo/eslint-config/base" +import { config } from "@repo/eslint-config/react-internal"; /** @type {import("eslint").Linter.Config} */ -export default baseConfig +export default config; diff --git a/packages/services/guard/eslint.config.js b/packages/services/guard/eslint.config.js index cecf89b031..19170f88ed 100644 --- a/packages/services/guard/eslint.config.js +++ b/packages/services/guard/eslint.config.js @@ -1,4 +1,4 @@ -import { config as baseConfig } from "@repo/eslint-config/base" +import { config } from "@repo/eslint-config/react-internal"; /** @type {import("eslint").Linter.Config} */ -export default baseConfig +export default config; diff --git a/packages/services/guard/src/client/guard.gen.ts b/packages/services/guard/src/client/guard.gen.ts index 4eea436eeb..ec0af4487a 100644 --- a/packages/services/guard/src/client/guard.gen.ts +++ b/packages/services/guard/src/client/guard.gen.ts @@ -1,5 +1,5 @@ /* eslint-disable */ -// sequence-guard v0.5.0 910e01c32ffb24b42386d4ca6be119b0acc55c5f +// sequence-guard v0.4.0 b62e755c3f81d6b5a8e7462abc063a57a744cdef // -- // Code generated by webrpc-gen@v0.25.3 with typescript generator. DO NOT EDIT. // @@ -7,16 +7,16 @@ export const WebrpcHeader = 'Webrpc' -export const WebrpcHeaderValue = 'webrpc@v0.25.3;gen-typescript@v0.17.0;sequence-guard@v0.5.0' +export const WebrpcHeaderValue = 'webrpc@v0.25.3;gen-typescript@v0.17.0;sequence-guard@v0.4.0' // WebRPC description and code-gen version export const WebRPCVersion = 'v1' // Schema version of your RIDL schema -export const WebRPCSchemaVersion = 'v0.5.0' +export const WebRPCSchemaVersion = 'v0.4.0' // Schema hash generated from your RIDL schema -export const WebRPCSchemaHash = '910e01c32ffb24b42386d4ca6be119b0acc55c5f' +export const WebRPCSchemaHash = 'b62e755c3f81d6b5a8e7462abc063a57a744cdef' type WebrpcGenVersions = { webrpcGenVersion: string @@ -131,7 +131,6 @@ export interface OwnershipProof { export interface AuthToken { id: string token: string - resetAuth?: boolean } export interface RecoveryCode { diff --git a/packages/services/identity-instrument/CHANGELOG.md b/packages/services/identity-instrument/CHANGELOG.md deleted file mode 100644 index ff6cebf477..0000000000 --- a/packages/services/identity-instrument/CHANGELOG.md +++ /dev/null @@ -1,170 +0,0 @@ -# @0xsequence/identity-instrument - -## 3.0.5 - -### Patch Changes - -- Account federation support - -## 3.0.4 - -### Patch Changes - -- id-token login support - -## 3.0.3 - -### Patch Changes - -- 3.0.3 - -## 3.0.2 - -### Patch Changes - -- allow native self transfer - -## 3.0.1 - -### Patch Changes - -- Network and session fixes - -## 3.0.0 - -### Patch Changes - -- f68be62: ethauth support -- 49d8a2f: New chains, minor fixes -- 3411232: Beta release with dapp connector fixes -- 23cb9e9: New chains, relayer rpc fix -- f5f6a7a: dapp-client updates -- e7de3b1: Fix signer 404 error, minor fixes -- 493836f: multicall3 optimization -- 30e1f1a: 3.0.0 beta -- d5017e8: Beta release for v3 -- 24a5fab: Final RC before 3.0.0 -- e5e1a03: Apple auth fixes -- 0b63113: Apple auth fix -- a89134a: Userdata service updates -- 7c6c811: 3.0.0-beta.3 with fixes -- 3.0.0 release -- 98ce38b: 3.0.0-beta.2 with identity instrument updates -- 747e6b5: Relayer fee options fix -- 40c19ff: dapp client updates for EOA login -- 6d5de25: 3.0.0-beta.1 -- 934acd1: RC5 upgrade - -## 3.0.0-beta.19 - -### Patch Changes - -- Final RC before 3.0.0 - -## 3.0.0-beta.18 - -### Patch Changes - -- multicall3 optimization - -## 3.0.0-beta.17 - -### Patch Changes - -- New chains, relayer rpc fix - -## 3.0.0-beta.16 - -### Patch Changes - -- ethauth support - -## 3.0.0-beta.15 - -### Patch Changes - -- New chains, minor fixes - -## 3.0.0-beta.14 - -### Patch Changes - -- Relayer fee options fix - -## 3.0.0-beta.13 - -### Patch Changes - -- Userdata service updates - -## 3.0.0-beta.12 - -### Patch Changes - -- Beta release with dapp connector fixes - -## 3.0.0-beta.11 - -### Patch Changes - -- 3.0.0 beta - -## 3.0.0-beta.10 - -### Patch Changes - -- dapp-client updates - -## 3.0.0-beta.9 - -### Patch Changes - -- dapp client updates for EOA login - -## 3.0.0-beta.8 - -### Patch Changes - -- Apple auth fixes - -## 3.0.0-beta.7 - -### Patch Changes - -- Apple auth fix - -## 3.0.0-beta.6 - -### Patch Changes - -- Fix signer 404 error, minor fixes - -## 3.0.0-beta.5 - -### Patch Changes - -- Beta release for v3 - -## 3.0.0-beta.4 - -### Patch Changes - -- RC5 upgrade - -## 3.0.0-beta.3 - -### Patch Changes - -- 3.0.0-beta.3 with fixes - -## 3.0.0-beta.2 - -### Patch Changes - -- 3.0.0-beta.2 with identity instrument updates - -## 3.0.0-beta.1 - -### Patch Changes - -- 3.0.0-beta.1 diff --git a/packages/services/identity-instrument/src/index.ts b/packages/services/identity-instrument/src/index.ts index f7b477b6ce..12eb0f0ffc 100644 --- a/packages/services/identity-instrument/src/index.ts +++ b/packages/services/identity-instrument/src/index.ts @@ -65,7 +65,7 @@ export class IdentityInstrument { keyType: KeyType.Ethereum_Secp256k1, }, digest: Hex.fromBytes(digest), - nonce: Hex.fromNumber(Date.now()), + nonce: Hex.random(16), } const res = await this.rpc.sign({ params, diff --git a/packages/services/marketplace/src/marketplace.gen.ts b/packages/services/marketplace/src/marketplace.gen.ts index 6a316623df..f251bce5d3 100644 --- a/packages/services/marketplace/src/marketplace.gen.ts +++ b/packages/services/marketplace/src/marketplace.gen.ts @@ -1,14 +1,14 @@ /* eslint-disable */ -// marketplace-api 652676d9951ceb12f6846907c7c4b5160c73c57a +// marketplace-api 7ab3354385f317680dd861e82a18aa351d8579d5 // -- -// Code generated by webrpc-gen@v0.30.2 with github.com/webrpc/gen-typescript@v0.19.0 generator. DO NOT EDIT. +// Code generated by webrpc-gen@v0.25.1 with typescript generator. DO NOT EDIT. // -// webrpc-gen -schema=./schema/schema.ridl -target=github.com/webrpc/gen-typescript@v0.19.0 -client -out=./clients/marketplace.gen.ts +// webrpc-gen -schema=marketplace.ridl -target=typescript -client -out=./clients/marketplace.gen.ts export const WebrpcHeader = 'Webrpc' export const WebrpcHeaderValue = - 'webrpc@v0.30.2;gen-typescript@v0.19.0;marketplace-api@v0.0.0-652676d9951ceb12f6846907c7c4b5160c73c57a' + 'webrpc@v0.25.1;gen-typescript@v0.17.0;marketplace-api@v0.0.0-7ab3354385f317680dd861e82a18aa351d8579d5' // WebRPC description and code-gen version export const WebRPCVersion = 'v1' @@ -17,7 +17,7 @@ export const WebRPCVersion = 'v1' export const WebRPCSchemaVersion = '' // Schema hash generated from your RIDL schema -export const WebRPCSchemaHash = '652676d9951ceb12f6846907c7c4b5160c73c57a' +export const WebRPCSchemaHash = '7ab3354385f317680dd861e82a18aa351d8579d5' type WebrpcGenVersions = { webrpcGenVersion: string @@ -71,9 +71,41 @@ function parseWebrpcGenVersions(header: string): WebrpcGenVersions { // Types // +export interface TokenMetadata { + tokenId: string + name: string + description?: string + image?: string + video?: string + audio?: string + properties?: { [key: string]: any } + attributes: Array<{ [key: string]: any }> + image_data?: string + external_url?: string + background_color?: string + animation_url?: string + decimals?: number + updatedAt?: string + assets?: Array +} + +export interface Asset { + id: number + collectionId: number + tokenId: string + url?: string + metadataField: string + name?: string + filesize?: number + mimeType?: string + width?: number + height?: number + updatedAt?: string +} + export enum SortOrder { - ASC = 'ASC', DESC = 'DESC', + ASC = 'ASC', } export enum PropertyType { @@ -95,7 +127,6 @@ export enum MarketplaceKind { alienswap = 'alienswap', payment_processor = 'payment_processor', mintify = 'mintify', - magic_eden = 'magic_eden', } export enum OrderbookKind { @@ -107,7 +138,6 @@ export enum OrderbookKind { looks_rare = 'looks_rare', reservoir = 'reservoir', x2y2 = 'x2y2', - magic_eden = 'magic_eden', } export enum SourceKind { @@ -115,8 +145,6 @@ export enum SourceKind { external = 'external', sequence_marketplace_v1 = 'sequence_marketplace_v1', sequence_marketplace_v2 = 'sequence_marketplace_v2', - opensea = 'opensea', - magic_eden = 'magic_eden', } export enum OrderSide { @@ -125,12 +153,6 @@ export enum OrderSide { offer = 'offer', } -export enum OfferType { - unknown = 'unknown', - item = 'item', - collection = 'collection', -} - export enum OrderStatus { unknown = 'unknown', active = 'active', @@ -158,6 +180,12 @@ export enum CollectionPriority { export enum CollectionStatus { unknown = 'unknown', created = 'created', + syncing_contract_metadata = 'syncing_contract_metadata', + synced_contract_metadata = 'synced_contract_metadata', + syncing_metadata = 'syncing_metadata', + synced_metadata = 'synced_metadata', + syncing_tokens = 'syncing_tokens', + synced_tokens = 'synced_tokens', syncing_orders = 'syncing_orders', active = 'active', failed = 'failed', @@ -171,30 +199,12 @@ export enum ProjectStatus { inactive = 'inactive', } -export enum ItemsContractStatus { - unknown = 'unknown', - created = 'created', - syncing_contract_metadata = 'syncing_contract_metadata', - synced_contract_metadata = 'synced_contract_metadata', - syncing_tokens = 'syncing_tokens', - synced_tokens = 'synced_tokens', - active = 'active', - inactive = 'inactive', - incompatible_type = 'incompatible_type', -} - export enum CollectibleStatus { unknown = 'unknown', active = 'active', inactive = 'inactive', } -export enum CollectibleSource { - unknown = 'unknown', - indexer = 'indexer', - manual = 'manual', -} - export enum CurrencyStatus { unknown = 'unknown', created = 'created', @@ -228,27 +238,24 @@ export enum TransactionCrypto { export enum TransactionNFTCheckoutProvider { unknown = 'unknown', - transak = 'transak', sardine = 'sardine', + transak = 'transak', } export enum TransactionOnRampProvider { unknown = 'unknown', - transak = 'transak', sardine = 'sardine', + transak = 'transak', } export enum TransactionSwapProvider { unknown = 'unknown', - lifi = 'lifi', + zerox = 'zerox', } export enum ExecuteType { unknown = 'unknown', order = 'order', - createListing = 'createListing', - createItemOffer = 'createItemOffer', - createTraitOffer = 'createTraitOffer', } export enum ActivityAction { @@ -262,33 +269,6 @@ export enum ActivityAction { transfer = 'transfer', } -export enum PrimarySaleContractStatus { - unknown = 'unknown', - created = 'created', - syncing_items = 'syncing_items', - active = 'active', - inactive = 'inactive', - incompatible_type = 'incompatible_type', - failed = 'failed', -} - -export enum PrimarySaleVersion { - v0 = 'v0', - v1 = 'v1', -} - -export enum PrimarySaleItemDetailType { - unknown = 'unknown', - global = 'global', - individual = 'individual', -} - -export enum MetadataStatus { - NOT_AVAILABLE = 'NOT_AVAILABLE', - REFRESHING = 'REFRESHING', - AVAILABLE = 'AVAILABLE', -} - export interface Page { page: number pageSize: number @@ -325,26 +305,6 @@ export interface CollectiblesFilter { ordersNotCreatedBy?: Array inCurrencyAddresses?: Array notInCurrencyAddresses?: Array - prices?: Array -} - -export interface OrdersFilter { - searchText?: string - properties?: Array - marketplaces?: Array - inAccounts?: Array - notInAccounts?: Array - ordersCreatedBy?: Array - ordersNotCreatedBy?: Array - inCurrencyAddresses?: Array - notInCurrencyAddresses?: Array - prices?: Array -} - -export interface PriceFilter { - contractAddress: string - min?: string - max?: string } export interface Order { @@ -354,7 +314,6 @@ export interface Order { status: OrderStatus chainId: number originName: string - slug: string collectionContractAddress: string tokenId?: string createdBy: string @@ -427,8 +386,6 @@ export interface CollectionConfig { export interface CollectionLastSynced { allOrders: string newOrders: string - names: Array - cursors: { [key: string]: string } } export interface Project { @@ -441,22 +398,12 @@ export interface Project { deletedAt?: string } -export interface ItemsContract { - status: ItemsContractStatus +export interface Collectible { chainId: number contractAddress: string - contractType: ContractType - lastSynced: string - createdAt: string - updatedAt: string - deletedAt?: string -} - -export interface Collectible { status: CollectibleStatus tokenId: string decimals: number - source: CollectibleSource createdAt: string updatedAt: string deletedAt?: string @@ -473,8 +420,6 @@ export interface Currency { exchangeRate: number defaultChainCurrency: boolean nativeCurrency: boolean - openseaListing: boolean - openseaOffer: boolean createdAt: string updatedAt: string deletedAt?: string @@ -554,16 +499,6 @@ export interface CheckoutOptions { onRamp: Array } -export interface ExecuteInput { - chainId: string - signature: string - method: string - endpoint: string - executeType: ExecuteType - body: any - slug?: string -} - export interface Activity { chainId: number contractAddress: string @@ -585,91 +520,6 @@ export interface Activity { deletedAt?: string } -export interface PrimarySaleContract { - chainId: number - contractAddress: string - collectionAddress: string - contractType: ContractType - version: PrimarySaleVersion - currencyAddress: string - priceDecimals: number - status: PrimarySaleContractStatus - lastSynced: string - createdAt: string - updatedAt: string - deletedAt?: string -} - -export interface PrimarySaleItem { - itemAddress: string - contractType: ContractType - tokenId: string - itemType: PrimarySaleItemDetailType - startDate: string - endDate: string - currencyAddress: string - priceDecimals: number - priceAmount: string - priceAmountFormatted: string - priceUsd: number - priceUsdFormatted: string - supply: string - supplyCap: string - unlimitedSupply: boolean - createdAt: string - updatedAt: string - deletedAt?: string -} - -export interface CollectiblePrimarySaleItem { - metadata: TokenMetadata - primarySaleItem: PrimarySaleItem -} - -export interface PrimarySaleItemsFilter { - includeEmpty: boolean - searchText?: string - properties?: Array - detailTypes?: Array - startDateAfter?: string - startDateBefore?: string - endDateAfter?: string - endDateBefore?: string -} - -export interface TokenMetadata { - tokenId: string - name: string - description?: string - image?: string - video?: string - audio?: string - properties?: { [key: string]: any } - attributes: Array<{ [key: string]: any }> - image_data?: string - external_url?: string - background_color?: string - animation_url?: string - decimals?: number - updatedAt?: string - assets?: Array - status: MetadataStatus -} - -export interface Asset { - id: number - collectionId: number - tokenId: string - url?: string - metadataField: string - name?: string - filesize?: number - mimeType?: string - width?: number - height?: number - updatedAt?: string -} - export interface Admin { createCollection(args: CreateCollectionArgs, headers?: object, signal?: AbortSignal): Promise getCollection(args: GetCollectionArgs, headers?: object, signal?: AbortSignal): Promise @@ -680,29 +530,14 @@ export interface Admin { * determine what should happen here */ syncCollection(args: SyncCollectionArgs, headers?: object, signal?: AbortSignal): Promise - createPrimarySaleContract( - args: CreatePrimarySaleContractArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - deletePrimarySaleContract( - args: DeletePrimarySaleContractArgs, - headers?: object, - signal?: AbortSignal, - ): Promise createCurrency(args: CreateCurrencyArgs, headers?: object, signal?: AbortSignal): Promise createCurrencies(args: CreateCurrenciesArgs, headers?: object, signal?: AbortSignal): Promise updateCurrency(args: UpdateCurrencyArgs, headers?: object, signal?: AbortSignal): Promise - listCurrencies(args: ListCurrenciesArgs, headers?: object, signal?: AbortSignal): Promise + listCurrencies(headers?: object, signal?: AbortSignal): Promise deleteCurrency(args: DeleteCurrencyArgs, headers?: object, signal?: AbortSignal): Promise - /** - * This for manual adding of non minted ERC1155 tokens, it's used for purposes of Shop. - */ - addCollectibles(args: AddCollectiblesArgs, headers?: object, signal?: AbortSignal): Promise } export interface CreateCollectionArgs { - chainId: string projectId: number contractAddress: string } @@ -711,7 +546,6 @@ export interface CreateCollectionReturn { collection: Collection } export interface GetCollectionArgs { - chainId: string projectId: number contractAddress: string } @@ -720,7 +554,6 @@ export interface GetCollectionReturn { collection: Collection } export interface UpdateCollectionArgs { - chainId: string collection: Collection } @@ -728,7 +561,6 @@ export interface UpdateCollectionReturn { collection: Collection } export interface ListCollectionsArgs { - chainId: string projectId: number page?: Page } @@ -738,7 +570,6 @@ export interface ListCollectionsReturn { page?: Page } export interface DeleteCollectionArgs { - chainId: string projectId: number contractAddress: string } @@ -747,30 +578,14 @@ export interface DeleteCollectionReturn { collection: Collection } export interface SyncCollectionArgs { - chainId: string - contractAddress: string -} - -export interface SyncCollectionReturn {} -export interface CreatePrimarySaleContractArgs { - chainId: string projectId: number - primarySaleContractAddress: string - itemsContractAddress: string + contractAddress: string } -export interface CreatePrimarySaleContractReturn { - primarySaleContract: PrimarySaleContract -} -export interface DeletePrimarySaleContractArgs { - chainId: string - projectId: number - primarySaleContractAddress: string +export interface SyncCollectionReturn { + collection: Collection } - -export interface DeletePrimarySaleContractReturn {} export interface CreateCurrencyArgs { - chainId: string currency: Currency } @@ -778,7 +593,6 @@ export interface CreateCurrencyReturn { currency: Currency } export interface CreateCurrenciesArgs { - chainId: string currencies: Array } @@ -786,53 +600,33 @@ export interface CreateCurrenciesReturn { currency: { [key: string]: Currency } } export interface UpdateCurrencyArgs { - chainId: string currency: Currency } export interface UpdateCurrencyReturn { currency: Currency } -export interface ListCurrenciesArgs { - chainId: string -} +export interface ListCurrenciesArgs {} export interface ListCurrenciesReturn { currencies: Array } export interface DeleteCurrencyArgs { - chainId: string + chainId: number contractAddress: string } export interface DeleteCurrencyReturn { currency: Currency } -export interface AddCollectiblesArgs { - chainId: string - itemsContractAddress: string - tokenIds: Array -} - -export interface AddCollectiblesReturn {} export interface Marketplace { - listCurrencies(args: ListCurrenciesArgs, headers?: object, signal?: AbortSignal): Promise + listCurrencies(headers?: object, signal?: AbortSignal): Promise getCollectionDetail( args: GetCollectionDetailArgs, headers?: object, signal?: AbortSignal, ): Promise - getCollectionActiveListingsCurrencies( - args: GetCollectionActiveListingsCurrenciesArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - getCollectionActiveOffersCurrencies( - args: GetCollectionActiveOffersCurrenciesArgs, - headers?: object, - signal?: AbortSignal, - ): Promise getCollectible(args: GetCollectibleArgs, headers?: object, signal?: AbortSignal): Promise getLowestPriceOfferForCollectible( args: GetLowestPriceOfferForCollectibleArgs, @@ -864,23 +658,6 @@ export interface Marketplace { headers?: object, signal?: AbortSignal, ): Promise - listOrdersWithCollectibles( - args: ListOrdersWithCollectiblesArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - getCountOfAllOrders( - args: GetCountOfAllOrdersArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - getCountOfFilteredOrders( - args: GetCountOfFilteredOrdersArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - listListings(args: ListListingsArgs, headers?: object, signal?: AbortSignal): Promise - listOffers(args: ListOffersArgs, headers?: object, signal?: AbortSignal): Promise getCountOfListingsForCollectible( args: GetCountOfListingsForCollectibleArgs, headers?: object, @@ -968,7 +745,7 @@ export interface Marketplace { signal?: AbortSignal, ): Promise /** - * only used in a case of external transactions ( when we create off-chain transactions ) for instance opensea market, use only ExecuteInput params and leave other root inputs empty, they are depracated and kept only for backward compatibility + * only used in a case of external transactions ( when we create off-chain transactions ) for instance opensea market */ execute(args: ExecuteArgs, headers?: object, signal?: AbortSignal): Promise /** @@ -1019,61 +796,21 @@ export interface Marketplace { headers?: object, signal?: AbortSignal, ): Promise - supportedMarketplaces( - args: SupportedMarketplacesArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - getPrimarySaleItem( - args: GetPrimarySaleItemArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - listPrimarySaleItems( - args: ListPrimarySaleItemsArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - getCountOfPrimarySaleItems( - args: GetCountOfPrimarySaleItemsArgs, - headers?: object, - signal?: AbortSignal, - ): Promise } -export interface ListCurrenciesArgs { - chainId: string -} +export interface ListCurrenciesArgs {} export interface ListCurrenciesReturn { currencies: Array } export interface GetCollectionDetailArgs { - chainId: string contractAddress: string } export interface GetCollectionDetailReturn { collection: Collection } -export interface GetCollectionActiveListingsCurrenciesArgs { - chainId: string - contractAddress: string -} - -export interface GetCollectionActiveListingsCurrenciesReturn { - currencies: Array -} -export interface GetCollectionActiveOffersCurrenciesArgs { - chainId: string - contractAddress: string -} - -export interface GetCollectionActiveOffersCurrenciesReturn { - currencies: Array -} export interface GetCollectibleArgs { - chainId: string contractAddress: string tokenId: string } @@ -1082,7 +819,6 @@ export interface GetCollectibleReturn { metadata: TokenMetadata } export interface GetLowestPriceOfferForCollectibleArgs { - chainId: string contractAddress: string tokenId: string filter?: OrderFilter @@ -1092,7 +828,6 @@ export interface GetLowestPriceOfferForCollectibleReturn { order: Order } export interface GetHighestPriceOfferForCollectibleArgs { - chainId: string contractAddress: string tokenId: string filter?: OrderFilter @@ -1102,7 +837,6 @@ export interface GetHighestPriceOfferForCollectibleReturn { order: Order } export interface GetLowestPriceListingForCollectibleArgs { - chainId: string contractAddress: string tokenId: string filter?: OrderFilter @@ -1112,7 +846,6 @@ export interface GetLowestPriceListingForCollectibleReturn { order: Order } export interface GetHighestPriceListingForCollectibleArgs { - chainId: string contractAddress: string tokenId: string filter?: OrderFilter @@ -1122,7 +855,6 @@ export interface GetHighestPriceListingForCollectibleReturn { order: Order } export interface ListListingsForCollectibleArgs { - chainId: string contractAddress: string tokenId: string filter?: OrderFilter @@ -1134,7 +866,6 @@ export interface ListListingsForCollectibleReturn { page?: Page } export interface ListOffersForCollectibleArgs { - chainId: string contractAddress: string tokenId: string filter?: OrderFilter @@ -1145,61 +876,7 @@ export interface ListOffersForCollectibleReturn { offers: Array page?: Page } -export interface ListOrdersWithCollectiblesArgs { - chainId: string - side: OrderSide - contractAddress: string - filter?: OrdersFilter - page?: Page -} - -export interface ListOrdersWithCollectiblesReturn { - collectibles: Array - page?: Page -} -export interface GetCountOfAllOrdersArgs { - chainId: string - side: OrderSide - contractAddress: string -} - -export interface GetCountOfAllOrdersReturn { - count: number -} -export interface GetCountOfFilteredOrdersArgs { - chainId: string - side: OrderSide - contractAddress: string - filter?: OrdersFilter -} - -export interface GetCountOfFilteredOrdersReturn { - count: number -} -export interface ListListingsArgs { - chainId: string - contractAddress: string - filter?: OrderFilter - page?: Page -} - -export interface ListListingsReturn { - listings: Array - page?: Page -} -export interface ListOffersArgs { - chainId: string - contractAddress: string - filter?: OrderFilter - page?: Page -} - -export interface ListOffersReturn { - offers: Array - page?: Page -} export interface GetCountOfListingsForCollectibleArgs { - chainId: string contractAddress: string tokenId: string filter?: OrderFilter @@ -1209,7 +886,6 @@ export interface GetCountOfListingsForCollectibleReturn { count: number } export interface GetCountOfOffersForCollectibleArgs { - chainId: string contractAddress: string tokenId: string filter?: OrderFilter @@ -1219,7 +895,6 @@ export interface GetCountOfOffersForCollectibleReturn { count: number } export interface GetCollectibleLowestOfferArgs { - chainId: string contractAddress: string tokenId: string filter?: OrderFilter @@ -1229,7 +904,6 @@ export interface GetCollectibleLowestOfferReturn { order?: Order } export interface GetCollectibleHighestOfferArgs { - chainId: string contractAddress: string tokenId: string filter?: OrderFilter @@ -1239,7 +913,6 @@ export interface GetCollectibleHighestOfferReturn { order?: Order } export interface GetCollectibleLowestListingArgs { - chainId: string contractAddress: string tokenId: string filter?: OrderFilter @@ -1249,7 +922,6 @@ export interface GetCollectibleLowestListingReturn { order?: Order } export interface GetCollectibleHighestListingArgs { - chainId: string contractAddress: string tokenId: string filter?: OrderFilter @@ -1259,7 +931,6 @@ export interface GetCollectibleHighestListingReturn { order?: Order } export interface ListCollectibleListingsArgs { - chainId: string contractAddress: string tokenId: string filter?: OrderFilter @@ -1271,7 +942,6 @@ export interface ListCollectibleListingsReturn { page?: Page } export interface ListCollectibleOffersArgs { - chainId: string contractAddress: string tokenId: string filter?: OrderFilter @@ -1283,7 +953,6 @@ export interface ListCollectibleOffersReturn { page?: Page } export interface GenerateBuyTransactionArgs { - chainId: string collectionAddress: string buyer: string marketplace: MarketplaceKind @@ -1296,7 +965,6 @@ export interface GenerateBuyTransactionReturn { steps: Array } export interface GenerateSellTransactionArgs { - chainId: string collectionAddress: string seller: string marketplace: MarketplaceKind @@ -1309,13 +977,11 @@ export interface GenerateSellTransactionReturn { steps: Array } export interface GenerateListingTransactionArgs { - chainId: string collectionAddress: string owner: string contractType: ContractType orderbook: OrderbookKind listing: CreateReq - additionalFees: Array walletType?: WalletKind } @@ -1323,22 +989,18 @@ export interface GenerateListingTransactionReturn { steps: Array } export interface GenerateOfferTransactionArgs { - chainId: string collectionAddress: string maker: string contractType: ContractType orderbook: OrderbookKind offer: CreateReq - additionalFees: Array walletType?: WalletKind - offerType: OfferType } export interface GenerateOfferTransactionReturn { steps: Array } export interface GenerateCancelTransactionArgs { - chainId: string collectionAddress: string maker: string marketplace: MarketplaceKind @@ -1349,20 +1011,17 @@ export interface GenerateCancelTransactionReturn { steps: Array } export interface ExecuteArgs { - params: ExecuteInput - chainId?: string - signature?: string - method?: string - endpoint?: string - executeType?: ExecuteType - body?: any -} + signature: string + method: string + endpoint: string + executeType: ExecuteType + body: any +} export interface ExecuteReturn { orderId: string } export interface ListCollectiblesArgs { - chainId: string side: OrderSide contractAddress: string filter?: CollectiblesFilter @@ -1374,7 +1033,6 @@ export interface ListCollectiblesReturn { page?: Page } export interface GetCountOfAllCollectiblesArgs { - chainId: string contractAddress: string } @@ -1382,7 +1040,6 @@ export interface GetCountOfAllCollectiblesReturn { count: number } export interface GetCountOfFilteredCollectiblesArgs { - chainId: string side: OrderSide contractAddress: string filter?: CollectiblesFilter @@ -1392,7 +1049,6 @@ export interface GetCountOfFilteredCollectiblesReturn { count: number } export interface GetFloorOrderArgs { - chainId: string contractAddress: string filter?: CollectiblesFilter } @@ -1401,7 +1057,6 @@ export interface GetFloorOrderReturn { collectible: CollectibleOrder } export interface ListCollectionActivitiesArgs { - chainId: string contractAddress: string page?: Page } @@ -1411,7 +1066,6 @@ export interface ListCollectionActivitiesReturn { page?: Page } export interface ListCollectibleActivitiesArgs { - chainId: string contractAddress: string tokenId: string page?: Page @@ -1422,7 +1076,6 @@ export interface ListCollectibleActivitiesReturn { page?: Page } export interface ListCollectiblesWithLowestListingArgs { - chainId: string contractAddress: string filter?: CollectiblesFilter page?: Page @@ -1433,7 +1086,6 @@ export interface ListCollectiblesWithLowestListingReturn { page?: Page } export interface ListCollectiblesWithHighestOfferArgs { - chainId: string contractAddress: string filter?: CollectiblesFilter page?: Page @@ -1444,19 +1096,16 @@ export interface ListCollectiblesWithHighestOfferReturn { page?: Page } export interface SyncOrderArgs { - chainId: string order: Order } export interface SyncOrderReturn {} export interface SyncOrdersArgs { - chainId: string orders: Array } export interface SyncOrdersReturn {} export interface GetOrdersArgs { - chainId: string input: Array page?: Page } @@ -1466,7 +1115,6 @@ export interface GetOrdersReturn { page?: Page } export interface CheckoutOptionsMarketplaceArgs { - chainId: string wallet: string orders: Array additionalFee: number @@ -1476,7 +1124,6 @@ export interface CheckoutOptionsMarketplaceReturn { options: CheckoutOptions } export interface CheckoutOptionsSalesContractArgs { - chainId: string wallet: string contractAddress: string collectionAddress: string @@ -1486,42 +1133,6 @@ export interface CheckoutOptionsSalesContractArgs { export interface CheckoutOptionsSalesContractReturn { options: CheckoutOptions } -export interface SupportedMarketplacesArgs { - chainId: string -} - -export interface SupportedMarketplacesReturn { - marketplaces: Array -} -export interface GetPrimarySaleItemArgs { - chainId: string - primarySaleContractAddress: string - tokenId: string -} - -export interface GetPrimarySaleItemReturn { - item: CollectiblePrimarySaleItem -} -export interface ListPrimarySaleItemsArgs { - chainId: string - primarySaleContractAddress: string - filter?: PrimarySaleItemsFilter - page?: Page -} - -export interface ListPrimarySaleItemsReturn { - primarySaleItems: Array - page?: Page -} -export interface GetCountOfPrimarySaleItemsArgs { - chainId: string - primarySaleContractAddress: string - filter?: PrimarySaleItemsFilter -} - -export interface GetCountOfPrimarySaleItemsReturn { - count: number -} // // Client @@ -1554,9 +1165,7 @@ export class Admin implements Admin { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -1571,9 +1180,7 @@ export class Admin implements Admin { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -1592,9 +1199,7 @@ export class Admin implements Admin { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -1614,9 +1219,7 @@ export class Admin implements Admin { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -1635,9 +1238,7 @@ export class Admin implements Admin { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -1648,55 +1249,15 @@ export class Admin implements Admin { signal?: AbortSignal, ): Promise => { return this.fetch(this.url('SyncCollection'), createHTTPRequest(args, headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return {} - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - createPrimarySaleContract = ( - args: CreatePrimarySaleContractArgs, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch(this.url('CreatePrimarySaleContract'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { return { - primarySaleContract: _data.primarySaleContract, + collection: _data.collection, } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - deletePrimarySaleContract = ( - args: DeletePrimarySaleContractArgs, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch(this.url('DeletePrimarySaleContract'), createHTTPRequest(args, headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return {} - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -1715,9 +1276,7 @@ export class Admin implements Admin { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -1736,9 +1295,7 @@ export class Admin implements Admin { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -1757,19 +1314,13 @@ export class Admin implements Admin { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } - listCurrencies = ( - args: ListCurrenciesArgs, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch(this.url('ListCurrencies'), createHTTPRequest(args, headers, signal)).then( + listCurrencies = (headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('ListCurrencies'), createHTTPRequest({}, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { return { @@ -1778,9 +1329,7 @@ export class Admin implements Admin { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -1799,28 +1348,7 @@ export class Admin implements Admin { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - addCollectibles = ( - args: AddCollectiblesArgs, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch(this.url('AddCollectibles'), createHTTPRequest(args, headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return {} - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -1839,12 +1367,8 @@ export class Marketplace implements Marketplace { return this.hostname + this.path + name } - listCurrencies = ( - args: ListCurrenciesArgs, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch(this.url('ListCurrencies'), createHTTPRequest(args, headers, signal)).then( + listCurrencies = (headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('ListCurrencies'), createHTTPRequest({}, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { return { @@ -1853,9 +1377,7 @@ export class Marketplace implements Marketplace { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -1874,51 +1396,7 @@ export class Marketplace implements Marketplace { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - getCollectionActiveListingsCurrencies = ( - args: GetCollectionActiveListingsCurrenciesArgs, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch(this.url('GetCollectionActiveListingsCurrencies'), createHTTPRequest(args, headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return { - currencies: >_data.currencies, - } - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - getCollectionActiveOffersCurrencies = ( - args: GetCollectionActiveOffersCurrenciesArgs, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch(this.url('GetCollectionActiveOffersCurrencies'), createHTTPRequest(args, headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return { - currencies: >_data.currencies, - } - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -1937,9 +1415,7 @@ export class Marketplace implements Marketplace { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -1958,9 +1434,7 @@ export class Marketplace implements Marketplace { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -1979,9 +1453,7 @@ export class Marketplace implements Marketplace { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -2000,9 +1472,7 @@ export class Marketplace implements Marketplace { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -2021,9 +1491,7 @@ export class Marketplace implements Marketplace { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -2043,9 +1511,7 @@ export class Marketplace implements Marketplace { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -2065,109 +1531,7 @@ export class Marketplace implements Marketplace { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - listOrdersWithCollectibles = ( - args: ListOrdersWithCollectiblesArgs, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch(this.url('ListOrdersWithCollectibles'), createHTTPRequest(args, headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return { - collectibles: >_data.collectibles, - page: _data.page, - } - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - getCountOfAllOrders = ( - args: GetCountOfAllOrdersArgs, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch(this.url('GetCountOfAllOrders'), createHTTPRequest(args, headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return { - count: _data.count, - } - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - getCountOfFilteredOrders = ( - args: GetCountOfFilteredOrdersArgs, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch(this.url('GetCountOfFilteredOrders'), createHTTPRequest(args, headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return { - count: _data.count, - } - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - listListings = (args: ListListingsArgs, headers?: object, signal?: AbortSignal): Promise => { - return this.fetch(this.url('ListListings'), createHTTPRequest(args, headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return { - listings: >_data.listings, - page: _data.page, - } - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - listOffers = (args: ListOffersArgs, headers?: object, signal?: AbortSignal): Promise => { - return this.fetch(this.url('ListOffers'), createHTTPRequest(args, headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return { - offers: >_data.offers, - page: _data.page, - } - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -2186,9 +1550,7 @@ export class Marketplace implements Marketplace { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -2207,9 +1569,7 @@ export class Marketplace implements Marketplace { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -2228,9 +1588,7 @@ export class Marketplace implements Marketplace { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -2249,9 +1607,7 @@ export class Marketplace implements Marketplace { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -2270,9 +1626,7 @@ export class Marketplace implements Marketplace { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -2291,9 +1645,7 @@ export class Marketplace implements Marketplace { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -2313,9 +1665,7 @@ export class Marketplace implements Marketplace { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -2335,9 +1685,7 @@ export class Marketplace implements Marketplace { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -2356,9 +1704,7 @@ export class Marketplace implements Marketplace { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -2377,9 +1723,7 @@ export class Marketplace implements Marketplace { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -2398,9 +1742,7 @@ export class Marketplace implements Marketplace { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -2419,9 +1761,7 @@ export class Marketplace implements Marketplace { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -2440,9 +1780,7 @@ export class Marketplace implements Marketplace { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -2457,9 +1795,7 @@ export class Marketplace implements Marketplace { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -2479,9 +1815,7 @@ export class Marketplace implements Marketplace { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -2500,9 +1834,7 @@ export class Marketplace implements Marketplace { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -2521,9 +1853,7 @@ export class Marketplace implements Marketplace { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -2538,9 +1868,7 @@ export class Marketplace implements Marketplace { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -2560,9 +1888,7 @@ export class Marketplace implements Marketplace { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -2582,9 +1908,7 @@ export class Marketplace implements Marketplace { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -2604,9 +1928,7 @@ export class Marketplace implements Marketplace { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -2626,9 +1948,7 @@ export class Marketplace implements Marketplace { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -2641,9 +1961,7 @@ export class Marketplace implements Marketplace { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -2656,9 +1974,7 @@ export class Marketplace implements Marketplace { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -2674,9 +1990,7 @@ export class Marketplace implements Marketplace { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -2695,9 +2009,7 @@ export class Marketplace implements Marketplace { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -2716,94 +2028,7 @@ export class Marketplace implements Marketplace { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - supportedMarketplaces = ( - args: SupportedMarketplacesArgs, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch(this.url('SupportedMarketplaces'), createHTTPRequest(args, headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return { - marketplaces: >_data.marketplaces, - } - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - getPrimarySaleItem = ( - args: GetPrimarySaleItemArgs, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch(this.url('GetPrimarySaleItem'), createHTTPRequest(args, headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return { - item: _data.item, - } - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - listPrimarySaleItems = ( - args: ListPrimarySaleItemsArgs, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch(this.url('ListPrimarySaleItems'), createHTTPRequest(args, headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return { - primarySaleItems: >_data.primarySaleItems, - page: _data.page, - } - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - getCountOfPrimarySaleItems = ( - args: GetCountOfPrimarySaleItemsArgs, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch(this.url('GetCountOfPrimarySaleItems'), createHTTPRequest(args, headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return { - count: _data.count, - } - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -2827,9 +2052,13 @@ const buildResponse = (res: Response): Promise => { 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(): ${error instanceof Error ? error.message : String(error)}: response text: ${text}`, + cause: `JSON.parse(): ${message}: response text: ${text}`, }) } if (!res.ok) { @@ -2877,7 +2106,7 @@ export class WebrpcEndpointError extends WebrpcError { name: string = 'WebrpcEndpoint', code: number = 0, message: string = `endpoint error`, - status: number = 400, + status: number = 0, cause?: string, ) { super(name, code, message, status, cause) @@ -2890,7 +2119,7 @@ export class WebrpcRequestFailedError extends WebrpcError { name: string = 'WebrpcRequestFailed', code: number = -1, message: string = `request failed`, - status: number = 400, + status: number = 0, cause?: string, ) { super(name, code, message, status, cause) @@ -2903,7 +2132,7 @@ export class WebrpcBadRouteError extends WebrpcError { name: string = 'WebrpcBadRoute', code: number = -2, message: string = `bad route`, - status: number = 404, + status: number = 0, cause?: string, ) { super(name, code, message, status, cause) @@ -2916,7 +2145,7 @@ export class WebrpcBadMethodError extends WebrpcError { name: string = 'WebrpcBadMethod', code: number = -3, message: string = `bad method`, - status: number = 405, + status: number = 0, cause?: string, ) { super(name, code, message, status, cause) @@ -2929,7 +2158,7 @@ export class WebrpcBadRequestError extends WebrpcError { name: string = 'WebrpcBadRequest', code: number = -4, message: string = `bad request`, - status: number = 400, + status: number = 0, cause?: string, ) { super(name, code, message, status, cause) @@ -2942,7 +2171,7 @@ export class WebrpcBadResponseError extends WebrpcError { name: string = 'WebrpcBadResponse', code: number = -5, message: string = `bad response`, - status: number = 500, + status: number = 0, cause?: string, ) { super(name, code, message, status, cause) @@ -2955,7 +2184,7 @@ export class WebrpcServerPanicError extends WebrpcError { name: string = 'WebrpcServerPanic', code: number = -6, message: string = `server panic`, - status: number = 500, + status: number = 0, cause?: string, ) { super(name, code, message, status, cause) @@ -2968,7 +2197,7 @@ export class WebrpcInternalErrorError extends WebrpcError { name: string = 'WebrpcInternalError', code: number = -7, message: string = `internal error`, - status: number = 500, + status: number = 0, cause?: string, ) { super(name, code, message, status, cause) @@ -2976,16 +2205,16 @@ export class WebrpcInternalErrorError extends WebrpcError { } } -export class WebrpcClientAbortedError extends WebrpcError { +export class WebrpcClientDisconnectedError extends WebrpcError { constructor( - name: string = 'WebrpcClientAborted', + name: string = 'WebrpcClientDisconnected', code: number = -8, - message: string = `request aborted by client`, - status: number = 400, + message: string = `client disconnected`, + status: number = 0, cause?: string, ) { super(name, code, message, status, cause) - Object.setPrototypeOf(this, WebrpcClientAbortedError.prototype) + Object.setPrototypeOf(this, WebrpcClientDisconnectedError.prototype) } } @@ -2994,7 +2223,7 @@ export class WebrpcStreamLostError extends WebrpcError { name: string = 'WebrpcStreamLost', code: number = -9, message: string = `stream lost`, - status: number = 400, + status: number = 0, cause?: string, ) { super(name, code, message, status, cause) @@ -3007,7 +2236,7 @@ export class WebrpcStreamFinishedError extends WebrpcError { name: string = 'WebrpcStreamFinished', code: number = -10, message: string = `stream finished`, - status: number = 200, + status: number = 0, cause?: string, ) { super(name, code, message, status, cause) @@ -3022,7 +2251,7 @@ export class UnauthorizedError extends WebrpcError { name: string = 'Unauthorized', code: number = 1000, message: string = `Unauthorized access`, - status: number = 401, + status: number = 0, cause?: string, ) { super(name, code, message, status, cause) @@ -3035,7 +2264,7 @@ export class PermissionDeniedError extends WebrpcError { name: string = 'PermissionDenied', code: number = 1001, message: string = `Permission denied`, - status: number = 403, + status: number = 0, cause?: string, ) { super(name, code, message, status, cause) @@ -3048,7 +2277,7 @@ export class SessionExpiredError extends WebrpcError { name: string = 'SessionExpired', code: number = 1002, message: string = `Session expired`, - status: number = 403, + status: number = 0, cause?: string, ) { super(name, code, message, status, cause) @@ -3061,7 +2290,7 @@ export class MethodNotFoundError extends WebrpcError { name: string = 'MethodNotFound', code: number = 1003, message: string = `Method not found`, - status: number = 404, + status: number = 0, cause?: string, ) { super(name, code, message, status, cause) @@ -3069,64 +2298,64 @@ export class MethodNotFoundError extends WebrpcError { } } -export class RequestConflictError extends WebrpcError { +export class TimeoutError extends WebrpcError { constructor( - name: string = 'RequestConflict', - code: number = 1004, - message: string = `Conflict with target resource`, - status: number = 409, + name: string = 'Timeout', + code: number = 2000, + message: string = `Request timed out`, + status: number = 0, cause?: string, ) { super(name, code, message, status, cause) - Object.setPrototypeOf(this, RequestConflictError.prototype) + Object.setPrototypeOf(this, TimeoutError.prototype) } } -export class AbortedError extends WebrpcError { +export class InvalidArgumentError extends WebrpcError { constructor( - name: string = 'Aborted', - code: number = 1005, - message: string = `Request aborted`, - status: number = 400, + name: string = 'InvalidArgument', + code: number = 2001, + message: string = `Invalid argument`, + status: number = 0, cause?: string, ) { super(name, code, message, status, cause) - Object.setPrototypeOf(this, AbortedError.prototype) + Object.setPrototypeOf(this, InvalidArgumentError.prototype) } } -export class GeoblockedError extends WebrpcError { +export class NotFoundError extends WebrpcError { constructor( - name: string = 'Geoblocked', - code: number = 1006, - message: string = `Geoblocked region`, - status: number = 451, + 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, GeoblockedError.prototype) + Object.setPrototypeOf(this, NotFoundError.prototype) } } -export class RateLimitedError extends WebrpcError { +export class UserNotFoundError extends WebrpcError { constructor( - name: string = 'RateLimited', - code: number = 1007, - message: string = `Rate-limited. Please slow down.`, - status: number = 429, + name: string = 'UserNotFound', + code: number = 3001, + message: string = `User not found`, + status: number = 0, cause?: string, ) { super(name, code, message, status, cause) - Object.setPrototypeOf(this, RateLimitedError.prototype) + Object.setPrototypeOf(this, UserNotFoundError.prototype) } } export class ProjectNotFoundError extends WebrpcError { constructor( name: string = 'ProjectNotFound', - code: number = 1008, + code: number = 3002, message: string = `Project not found`, - status: number = 401, + status: number = 0, cause?: string, ) { super(name, code, message, status, cause) @@ -3134,198 +2363,29 @@ export class ProjectNotFoundError extends WebrpcError { } } -export class SecretKeyCorsDisallowedError extends WebrpcError { - constructor( - name: string = 'SecretKeyCorsDisallowed', - code: number = 1009, - message: string = `CORS disallowed. Admin API Secret Key can't be used from a web app.`, - status: number = 403, - cause?: string, - ) { - super(name, code, message, status, cause) - Object.setPrototypeOf(this, SecretKeyCorsDisallowedError.prototype) - } -} - -export class AccessKeyNotFoundError extends WebrpcError { +export class InvalidTierError extends WebrpcError { constructor( - name: string = 'AccessKeyNotFound', - code: number = 1101, - message: string = `Access key not found`, - status: number = 401, + name: string = 'InvalidTier', + code: number = 3003, + message: string = `Invalid subscription tier`, + status: number = 0, cause?: string, ) { super(name, code, message, status, cause) - Object.setPrototypeOf(this, AccessKeyNotFoundError.prototype) + Object.setPrototypeOf(this, InvalidTierError.prototype) } } -export class AccessKeyMismatchError extends WebrpcError { +export class ProjectLimitReachedError extends WebrpcError { constructor( - name: string = 'AccessKeyMismatch', - code: number = 1102, - message: string = `Access key mismatch`, - status: number = 403, + name: string = 'ProjectLimitReached', + code: number = 3005, + message: string = `Project limit reached`, + status: number = 0, cause?: string, ) { super(name, code, message, status, cause) - Object.setPrototypeOf(this, AccessKeyMismatchError.prototype) - } -} - -export class InvalidOriginError extends WebrpcError { - constructor( - name: string = 'InvalidOrigin', - code: number = 1103, - message: string = `Invalid origin for Access Key`, - status: number = 403, - cause?: string, - ) { - super(name, code, message, status, cause) - Object.setPrototypeOf(this, InvalidOriginError.prototype) - } -} - -export class InvalidServiceError extends WebrpcError { - constructor( - name: string = 'InvalidService', - code: number = 1104, - message: string = `Service not enabled for Access key`, - status: number = 403, - cause?: string, - ) { - super(name, code, message, status, cause) - Object.setPrototypeOf(this, InvalidServiceError.prototype) - } -} - -export class UnauthorizedUserError extends WebrpcError { - constructor( - name: string = 'UnauthorizedUser', - code: number = 1105, - message: string = `Unauthorized user`, - status: number = 403, - cause?: string, - ) { - super(name, code, message, status, cause) - Object.setPrototypeOf(this, UnauthorizedUserError.prototype) - } -} - -export class InvalidChainError extends WebrpcError { - constructor( - name: string = 'InvalidChain', - code: number = 1106, - message: string = `Network not enabled for Access key`, - status: number = 403, - cause?: string, - ) { - super(name, code, message, status, cause) - Object.setPrototypeOf(this, InvalidChainError.prototype) - } -} - -export class QuotaExceededError extends WebrpcError { - constructor( - name: string = 'QuotaExceeded', - code: number = 1200, - message: string = `Quota request exceeded`, - status: number = 429, - cause?: string, - ) { - super(name, code, message, status, cause) - Object.setPrototypeOf(this, QuotaExceededError.prototype) - } -} - -export class QuotaRateLimitError extends WebrpcError { - constructor( - name: string = 'QuotaRateLimit', - code: number = 1201, - message: string = `Quota rate limit exceeded`, - status: number = 429, - cause?: string, - ) { - super(name, code, message, status, cause) - Object.setPrototypeOf(this, QuotaRateLimitError.prototype) - } -} - -export class NoDefaultKeyError extends WebrpcError { - constructor( - name: string = 'NoDefaultKey', - code: number = 1300, - message: string = `No default access key found`, - status: number = 403, - cause?: string, - ) { - super(name, code, message, status, cause) - Object.setPrototypeOf(this, NoDefaultKeyError.prototype) - } -} - -export class MaxAccessKeysError extends WebrpcError { - constructor( - name: string = 'MaxAccessKeys', - code: number = 1301, - message: string = `Access keys limit reached`, - status: number = 403, - cause?: string, - ) { - super(name, code, message, status, cause) - Object.setPrototypeOf(this, MaxAccessKeysError.prototype) - } -} - -export class AtLeastOneKeyError extends WebrpcError { - constructor( - name: string = 'AtLeastOneKey', - code: number = 1302, - message: string = `You need at least one Access Key`, - status: number = 403, - cause?: string, - ) { - super(name, code, message, status, cause) - Object.setPrototypeOf(this, AtLeastOneKeyError.prototype) - } -} - -export class TimeoutError extends WebrpcError { - constructor( - name: string = 'Timeout', - code: number = 1900, - message: string = `Request timed out`, - status: number = 408, - cause?: string, - ) { - super(name, code, message, status, cause) - Object.setPrototypeOf(this, TimeoutError.prototype) - } -} - -export class NotFoundError extends WebrpcError { - constructor( - name: string = 'NotFound', - code: number = 2000, - message: string = `Resource not found`, - status: number = 400, - cause?: string, - ) { - super(name, code, message, status, cause) - Object.setPrototypeOf(this, NotFoundError.prototype) - } -} - -export class InvalidArgumentError extends WebrpcError { - constructor( - name: string = 'InvalidArgument', - code: number = 2001, - message: string = `Invalid argument`, - status: number = 400, - cause?: string, - ) { - super(name, code, message, status, cause) - Object.setPrototypeOf(this, InvalidArgumentError.prototype) + Object.setPrototypeOf(this, ProjectLimitReachedError.prototype) } } @@ -3334,7 +2394,7 @@ export class NotImplementedError extends WebrpcError { name: string = 'NotImplemented', code: number = 9999, message: string = `Not Implemented`, - status: number = 500, + status: number = 0, cause?: string, ) { super(name, code, message, status, cause) @@ -3351,33 +2411,20 @@ export enum errors { WebrpcBadResponse = 'WebrpcBadResponse', WebrpcServerPanic = 'WebrpcServerPanic', WebrpcInternalError = 'WebrpcInternalError', - WebrpcClientAborted = 'WebrpcClientAborted', + WebrpcClientDisconnected = 'WebrpcClientDisconnected', WebrpcStreamLost = 'WebrpcStreamLost', WebrpcStreamFinished = 'WebrpcStreamFinished', Unauthorized = 'Unauthorized', PermissionDenied = 'PermissionDenied', SessionExpired = 'SessionExpired', MethodNotFound = 'MethodNotFound', - RequestConflict = 'RequestConflict', - Aborted = 'Aborted', - Geoblocked = 'Geoblocked', - RateLimited = 'RateLimited', - ProjectNotFound = 'ProjectNotFound', - SecretKeyCorsDisallowed = 'SecretKeyCorsDisallowed', - AccessKeyNotFound = 'AccessKeyNotFound', - AccessKeyMismatch = 'AccessKeyMismatch', - InvalidOrigin = 'InvalidOrigin', - InvalidService = 'InvalidService', - UnauthorizedUser = 'UnauthorizedUser', - InvalidChain = 'InvalidChain', - QuotaExceeded = 'QuotaExceeded', - QuotaRateLimit = 'QuotaRateLimit', - NoDefaultKey = 'NoDefaultKey', - MaxAccessKeys = 'MaxAccessKeys', - AtLeastOneKey = 'AtLeastOneKey', Timeout = 'Timeout', - NotFound = 'NotFound', InvalidArgument = 'InvalidArgument', + NotFound = 'NotFound', + UserNotFound = 'UserNotFound', + ProjectNotFound = 'ProjectNotFound', + InvalidTier = 'InvalidTier', + ProjectLimitReached = 'ProjectLimitReached', NotImplemented = 'NotImplemented', } @@ -3390,33 +2437,20 @@ export enum WebrpcErrorCodes { WebrpcBadResponse = -5, WebrpcServerPanic = -6, WebrpcInternalError = -7, - WebrpcClientAborted = -8, + WebrpcClientDisconnected = -8, WebrpcStreamLost = -9, WebrpcStreamFinished = -10, Unauthorized = 1000, PermissionDenied = 1001, SessionExpired = 1002, MethodNotFound = 1003, - RequestConflict = 1004, - Aborted = 1005, - Geoblocked = 1006, - RateLimited = 1007, - ProjectNotFound = 1008, - SecretKeyCorsDisallowed = 1009, - AccessKeyNotFound = 1101, - AccessKeyMismatch = 1102, - InvalidOrigin = 1103, - InvalidService = 1104, - UnauthorizedUser = 1105, - InvalidChain = 1106, - QuotaExceeded = 1200, - QuotaRateLimit = 1201, - NoDefaultKey = 1300, - MaxAccessKeys = 1301, - AtLeastOneKey = 1302, - Timeout = 1900, - NotFound = 2000, + Timeout = 2000, InvalidArgument = 2001, + NotFound = 3000, + UserNotFound = 3001, + ProjectNotFound = 3002, + InvalidTier = 3003, + ProjectLimitReached = 3005, NotImplemented = 9999, } @@ -3429,33 +2463,20 @@ export const webrpcErrorByCode: { [code: number]: any } = { [-5]: WebrpcBadResponseError, [-6]: WebrpcServerPanicError, [-7]: WebrpcInternalErrorError, - [-8]: WebrpcClientAbortedError, + [-8]: WebrpcClientDisconnectedError, [-9]: WebrpcStreamLostError, [-10]: WebrpcStreamFinishedError, [1000]: UnauthorizedError, [1001]: PermissionDeniedError, [1002]: SessionExpiredError, [1003]: MethodNotFoundError, - [1004]: RequestConflictError, - [1005]: AbortedError, - [1006]: GeoblockedError, - [1007]: RateLimitedError, - [1008]: ProjectNotFoundError, - [1009]: SecretKeyCorsDisallowedError, - [1101]: AccessKeyNotFoundError, - [1102]: AccessKeyMismatchError, - [1103]: InvalidOriginError, - [1104]: InvalidServiceError, - [1105]: UnauthorizedUserError, - [1106]: InvalidChainError, - [1200]: QuotaExceededError, - [1201]: QuotaRateLimitError, - [1300]: NoDefaultKeyError, - [1301]: MaxAccessKeysError, - [1302]: AtLeastOneKeyError, - [1900]: TimeoutError, - [2000]: NotFoundError, + [2000]: TimeoutError, [2001]: InvalidArgumentError, + [3000]: NotFoundError, + [3001]: UserNotFoundError, + [3002]: ProjectNotFoundError, + [3003]: InvalidTierError, + [3005]: ProjectLimitReachedError, [9999]: NotImplementedError, } diff --git a/packages/services/metadata/src/metadata.gen.ts b/packages/services/metadata/src/metadata.gen.ts index 9390aee762..05cdfb1943 100644 --- a/packages/services/metadata/src/metadata.gen.ts +++ b/packages/services/metadata/src/metadata.gen.ts @@ -1,357 +1,73 @@ /* eslint-disable */ -// sequence-metadata v0.4.0 673a5fa528008c7f9558810fbb24aad978ed7a84 +// sequence-metadata v0.4.0 5cb74ff169ce80c2e42e65d6bbc98b1daaa0945f // -- -// Code generated by Webrpc-gen@v0.31.0 with typescript generator. DO NOT EDIT. +// Code generated by webrpc-gen@v0.25.3 with typescript generator. DO NOT EDIT. // -// webrpc-gen -schema=metadata.ridl -target=typescript -client -ignore=@deprecated -compat -out=./clients/metadata.gen.ts +// webrpc-gen -schema=metadata.ridl -target=typescript -client -ignore=@deprecated -out=./clients/metadata.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 = '673a5fa528008c7f9558810fbb24aad978ed7a84' - -// -// Client interface -// - -export interface MetadataClient { - ping(headers?: object, signal?: AbortSignal): Promise - - version(headers?: object, signal?: AbortSignal): Promise - - runtimeStatus(headers?: object, signal?: AbortSignal): Promise - - getTask(req: GetTaskArgs, headers?: object, signal?: AbortSignal): Promise - - getTaskStatus(req: GetTaskStatusArgs, headers?: object, signal?: AbortSignal): Promise - - /** - * Contract Info -- returns contract meta-info for contracts found in registered chain's token-lists - */ - getContractInfo(req: GetContractInfoArgs, headers?: object, signal?: AbortSignal): Promise - - getContractInfoBatch( - req: GetContractInfoBatchArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - - /** - * Find Contract Info across all chains token-lists. Similar to GetContractInfo above, - * but it will traverse all chains and results from all. - */ - findContractInfo(req: FindContractInfoArgs, headers?: object, signal?: AbortSignal): Promise - - /** - * map of contractAddress :: []ContractInfo - */ - findContractInfoBatch( - req: FindContractInfoBatchArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - - /** - * Refresh Contract Info -- refresh contract meta-info - */ - refreshContractInfo( - req: RefreshContractInfoArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - - refreshContractInfoBatch( - req: RefreshContractInfoBatchArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - - /** - * Search for contract infos using a query string - */ - searchContractsByQuery( - req: SearchContractsByQueryArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - - /** - * GetTokenMetadata - fetch token metadata for a particular contract and respective tokenIDs - */ - getTokenMetadata(req: GetTokenMetadataArgs, headers?: object, signal?: AbortSignal): Promise - - /** - * GetTokenMetadataBatch allows you to query the token metadata of a batch of contracts and respective tokenIDs - * where map is contractAddress::[]tokenID => contractAddress::[]TokenMetadata - * - * Note, we limit each request to 50 contracts max and 50 tokens max per contract. - */ - getTokenMetadataBatch( - req: GetTokenMetadataBatchArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - - /** - * RefreshTokenMetadata allows you to refresh a contract metadata for contract-level and token-level metadata. - */ - refreshTokenMetadata( - req: RefreshTokenMetadataArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - - /** - * Search ERC721 & ERC1155 token metadata by query string 'q' - */ - searchTokenMetadataByQuery( - req: SearchTokenMetadataByQueryArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - - /** - * Search ERC721 & ERC1155 token metadata by filter object 'filter' - * which allows to search by text or properties. - */ - searchTokenMetadata( - req: SearchTokenMetadataArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - - /** - * Search ERC721 & ERC1155 for token IDs by filter object 'filter' - * which allows to search by text or properties. - */ - searchTokenMetadataTokenIDs( - req: SearchTokenMetadataTokenIDsArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - - /** - * Get token metadata property filters for a contract address - */ - getTokenMetadataPropertyFilters( - req: GetTokenMetadataPropertyFiltersArgs, - headers?: object, - signal?: AbortSignal, - ): Promise +export const WebrpcHeader = 'Webrpc' - /** - * Gets Token Directory supported networks - */ - getTokenDirectoryNetworks( - req: GetTokenDirectoryNetworksArgs, - headers?: object, - signal?: AbortSignal, - ): Promise +export const WebrpcHeaderValue = 'webrpc@v0.25.3;gen-typescript@v0.17.0;sequence-metadata@v0.4.0' - /** - * Gets Token Directory entries - */ - getTokenDirectory( - req: GetTokenDirectoryArgs, - headers?: object, - signal?: AbortSignal, - ): Promise +// WebRPC description and code-gen version +export const WebRPCVersion = 'v1' - /** - * Search in Token Directory - */ - searchTokenDirectory( - req: SearchTokenDirectoryArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - - /** - * Niftyswap querying data - */ - getNiftyswapTokenQuantity( - req: GetNiftyswapTokenQuantityArgs, - headers?: object, - signal?: AbortSignal, - ): Promise +// Schema version of your RIDL schema +export const WebRPCSchemaVersion = 'v0.4.0' - /** - * map of tokenID :: quantity - */ - getNiftyswapUnitPrices( - req: GetNiftyswapUnitPricesArgs, - headers?: object, - signal?: AbortSignal, - ): Promise +// Schema hash generated from your RIDL schema +export const WebRPCSchemaHash = '5cb74ff169ce80c2e42e65d6bbc98b1daaa0945f' - /** - * map of tokenID :: price - */ - getNiftyswapUnitPricesWithQuantities( - req: GetNiftyswapUnitPricesWithQuantitiesArgs, - headers?: object, - signal?: AbortSignal, - ): Promise +type WebrpcGenVersions = { + webrpcGenVersion: string + codeGenName: string + codeGenVersion: string + schemaName: string + schemaVersion: string } -export interface CollectionsClient { - createCollection(req: CreateCollectionArgs, headers?: object, signal?: AbortSignal): Promise - - getCollection(req: GetCollectionArgs, headers?: object, signal?: AbortSignal): Promise - - listCollections(req: ListCollectionsArgs, headers?: object, signal?: AbortSignal): Promise - - updateCollection(req: UpdateCollectionArgs, headers?: object, signal?: AbortSignal): Promise - - deleteCollection(req: DeleteCollectionArgs, headers?: object, signal?: AbortSignal): Promise - - publishCollection( - req: PublishCollectionArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - - unpublishCollection( - req: UnpublishCollectionArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - createContractCollection( - req: CreateContractCollectionArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - - getContractCollection( - req: GetContractCollectionArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - - listContractCollections( - req: ListContractCollectionsArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - - updateContractCollection( - req: UpdateContractCollectionArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - - deleteContractCollection( - req: DeleteContractCollectionArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - - createToken(req: CreateTokenArgs, headers?: object, signal?: AbortSignal): Promise - - getToken(req: GetTokenArgs, headers?: object, signal?: AbortSignal): Promise - - listTokens(req: ListTokensArgs, headers?: object, signal?: AbortSignal): Promise - - updateToken(req: UpdateTokenArgs, headers?: object, signal?: AbortSignal): Promise - - deleteToken(req: DeleteTokenArgs, headers?: object, signal?: AbortSignal): Promise - - createAsset(req: CreateAssetArgs, headers?: object, signal?: AbortSignal): Promise - - getAsset(req: GetAssetArgs, headers?: object, signal?: AbortSignal): Promise - - updateAsset(req: UpdateAssetArgs, headers?: object, signal?: AbortSignal): Promise +export function VersionFromHeader(headers: Headers): WebrpcGenVersions { + const headerValue = headers.get(WebrpcHeader) + if (!headerValue) { + return { + webrpcGenVersion: '', + codeGenName: '', + codeGenVersion: '', + schemaName: '', + schemaVersion: '', + } + } - deleteAsset(req: DeleteAssetArgs, headers?: object, signal?: AbortSignal): Promise + return parseWebrpcGenVersions(headerValue) } -export interface AdminClient { - /** - * ContractInfo - */ - refreshContractInfoUpdatedBefore( - req: RefreshContractInfoUpdatedBeforeArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - - /** - * TokenMetadata - */ - refreshTokenMetadataUpdatedBefore( - req: RefreshTokenMetadataUpdatedBeforeArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - - /** - * Contract Info Overrides - */ - getContractInfoOverride( - req: GetContractInfoOverrideArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - - getContractInfoOverrides( - req: GetContractInfoOverridesArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - - addContractInfoOverride( - req: AddContractInfoOverrideArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - - updateContractInfoOverride( - req: UpdateContractInfoOverrideArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - - removeContractInfoOverride( - req: RemoveContractInfoOverrideArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - /** - * Token Directory - */ - isInTokenDirectory( - req: IsInTokenDirectoryArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - - setTokenDirectoryFeatureIndex( - req: SetTokenDirectoryFeatureIndexArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - - addContractToTokenDirectory( - req: AddContractToTokenDirectoryArgs, - headers?: object, - signal?: AbortSignal, - ): Promise +function parseWebrpcGenVersions(header: string): WebrpcGenVersions { + const versions = header.split(';') + if (versions.length < 3) { + return { + webrpcGenVersion: '', + codeGenName: '', + codeGenVersion: '', + schemaName: '', + schemaVersion: '', + } + } - removeContractFromTokenDirectory( - req: RemoveContractFromTokenDirectoryArgs, - headers?: object, - signal?: AbortSignal, - ): Promise + const [_, webrpcGenVersion] = versions[0]!.split('@') + const [codeGenName, codeGenVersion] = versions[1]!.split('@') + const [schemaName, schemaVersion] = versions[2]!.split('@') - refreshTokenDirectory(headers?: object, signal?: AbortSignal): Promise + return { + webrpcGenVersion: webrpcGenVersion ?? '', + codeGenName: codeGenName ?? '', + codeGenVersion: codeGenVersion ?? '', + schemaName: schemaName ?? '', + schemaVersion: schemaVersion ?? '', + } } // -// Schema types +// Types // export enum ContractType { @@ -650,24 +366,177 @@ export interface Task { result: Array } +export interface Metadata { + ping(headers?: object, signal?: AbortSignal): Promise + version(headers?: object, signal?: AbortSignal): Promise + runtimeStatus(headers?: object, signal?: AbortSignal): Promise + getTask(args: GetTaskArgs, headers?: object, signal?: AbortSignal): Promise + getTaskStatus(args: GetTaskStatusArgs, headers?: object, signal?: AbortSignal): Promise + /** + * Contract Info -- returns contract meta-info for contracts found in registered chain's token-lists + */ + getContractInfo(args: GetContractInfoArgs, headers?: object, signal?: AbortSignal): Promise + getContractInfoBatch( + args: GetContractInfoBatchArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + /** + * Find Contract Info across all chains token-lists. Similar to GetContractInfo above, + * but it will traverse all chains and results from all. + */ + findContractInfo(args: FindContractInfoArgs, headers?: object, signal?: AbortSignal): Promise + /** + * map of contractAddress :: []ContractInfo + */ + findContractInfoBatch( + args: FindContractInfoBatchArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + /** + * Refresh Contract Info -- refresh contract meta-info + */ + refreshContractInfo( + args: RefreshContractInfoArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + refreshContractInfoBatch( + args: RefreshContractInfoBatchArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + /** + * Search for contract infos using a query string + */ + searchContractsByQuery( + args: SearchContractsByQueryArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + /** + * GetTokenMetadata - fetch token metadata for a particular contract and respective tokenIDs + */ + getTokenMetadata(args: GetTokenMetadataArgs, headers?: object, signal?: AbortSignal): Promise + /** + * GetTokenMetadataBatch allows you to query the token metadata of a batch of contracts and respective tokenIDs + * where map is contractAddress::[]tokenID => contractAddress::[]TokenMetadata + * + * Note, we limit each request to 50 contracts max and 50 tokens max per contract. + */ + getTokenMetadataBatch( + args: GetTokenMetadataBatchArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + /** + * RefreshTokenMetadata allows you to refresh a contract metadata for contract-level and token-level metadata. + */ + refreshTokenMetadata( + args: RefreshTokenMetadataArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + /** + * Search ERC721 & ERC1155 token metadata by query string 'q' + */ + searchTokenMetadataByQuery( + args: SearchTokenMetadataByQueryArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + /** + * Search ERC721 & ERC1155 token metadata by filter object 'filter' + * which allows to search by text or properties. + */ + searchTokenMetadata( + args: SearchTokenMetadataArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + /** + * Search ERC721 & ERC1155 for token IDs by filter object 'filter' + * which allows to search by text or properties. + */ + searchTokenMetadataTokenIDs( + args: SearchTokenMetadataTokenIDsArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + /** + * Get token metadata property filters for a contract address + */ + getTokenMetadataPropertyFilters( + args: GetTokenMetadataPropertyFiltersArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + /** + * Gets Token Directory supported networks + */ + getTokenDirectoryNetworks( + args: GetTokenDirectoryNetworksArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + /** + * Gets Token Directory entries + */ + getTokenDirectory( + args: GetTokenDirectoryArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + /** + * Search in Token Directory + */ + searchTokenDirectory( + args: SearchTokenDirectoryArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + /** + * Niftyswap querying data + */ + getNiftyswapTokenQuantity( + args: GetNiftyswapTokenQuantityArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + /** + * map of tokenID :: quantity + */ + getNiftyswapUnitPrices( + args: GetNiftyswapUnitPricesArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + /** + * map of tokenID :: price + */ + getNiftyswapUnitPricesWithQuantities( + args: GetNiftyswapUnitPricesWithQuantitiesArgs, + 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 GetTaskArgs { taskId: number } @@ -675,7 +544,6 @@ export interface GetTaskArgs { export interface GetTaskReturn { task: Task } - export interface GetTaskStatusArgs { taskId: number } @@ -683,7 +551,6 @@ export interface GetTaskStatusArgs { export interface GetTaskStatusReturn { status?: TaskStatus } - export interface GetContractInfoArgs { chainID: string contractAddress: string @@ -693,7 +560,6 @@ export interface GetContractInfoReturn { contractInfo: ContractInfo taskID?: number } - export interface GetContractInfoBatchArgs { chainID: string contractAddresses: Array @@ -703,7 +569,6 @@ export interface GetContractInfoBatchReturn { contractInfoMap: { [key: string]: ContractInfo } taskID?: number } - export interface FindContractInfoArgs { contractAddress: string } @@ -711,7 +576,6 @@ export interface FindContractInfoArgs { export interface FindContractInfoReturn { contractInfoList: Array } - export interface FindContractInfoBatchArgs { contractAddresses: Array } @@ -719,7 +583,6 @@ export interface FindContractInfoBatchArgs { export interface FindContractInfoBatchReturn { contractInfoByChain: { [key: string]: Array } } - export interface RefreshContractInfoArgs { chainID: string contractAddress: string @@ -728,7 +591,6 @@ export interface RefreshContractInfoArgs { export interface RefreshContractInfoReturn { taskID?: number } - export interface RefreshContractInfoBatchArgs { chainID: string contractAddresses: Array @@ -737,7 +599,6 @@ export interface RefreshContractInfoBatchArgs { export interface RefreshContractInfoBatchReturn { taskID?: number } - export interface SearchContractsByQueryArgs { q: string chainID?: string @@ -750,7 +611,6 @@ export interface SearchContractsByQueryReturn { contractInfo: Array nextPage: Page } - export interface GetTokenMetadataArgs { chainID: string contractAddress: string @@ -761,7 +621,6 @@ export interface GetTokenMetadataReturn { tokenMetadata: Array taskID?: number } - export interface GetTokenMetadataBatchArgs { chainID: string contractTokenMap: { [key: string]: Array } @@ -771,18 +630,16 @@ export interface GetTokenMetadataBatchReturn { contractTokenMetadata: { [key: string]: Array } taskID?: number } - export interface RefreshTokenMetadataArgs { chainID: string contractAddress: string tokenIDs?: Array - newMints?: boolean + refreshAll?: boolean } export interface RefreshTokenMetadataReturn { taskID: number } - export interface SearchTokenMetadataByQueryArgs { q: string chainID?: string @@ -794,7 +651,6 @@ export interface SearchTokenMetadataByQueryReturn { tokenMetadata: Array nextPage: Page } - export interface SearchTokenMetadataArgs { chainID: string contractAddress: string @@ -806,7 +662,6 @@ export interface SearchTokenMetadataReturn { page: Page tokenMetadata: Array } - export interface SearchTokenMetadataTokenIDsArgs { chainID: string contractAddress: string @@ -818,7 +673,6 @@ export interface SearchTokenMetadataTokenIDsReturn { page: Page tokenIDs: Array } - export interface GetTokenMetadataPropertyFiltersArgs { chainID: string contractAddress: string @@ -829,7 +683,6 @@ export interface GetTokenMetadataPropertyFiltersArgs { export interface GetTokenMetadataPropertyFiltersReturn { filters: Array } - export interface GetTokenDirectoryNetworksArgs { includeTestnets?: boolean onlyFeatured?: boolean @@ -839,7 +692,6 @@ export interface GetTokenDirectoryNetworksReturn { chainIDs: Array networks: Array } - export interface GetTokenDirectoryArgs { chainID?: string includeTestnets?: boolean @@ -851,7 +703,6 @@ export interface GetTokenDirectoryReturn { contracts: Array page: Page } - export interface SearchTokenDirectoryArgs { query: string chainID?: number @@ -864,7 +715,6 @@ export interface SearchTokenDirectoryReturn { contracts: Array page: Page } - export interface GetNiftyswapTokenQuantityArgs { chainID: string contractAddress: string @@ -874,7 +724,6 @@ export interface GetNiftyswapTokenQuantityArgs { export interface GetNiftyswapTokenQuantityReturn { quantity: { [key: string]: string } } - export interface GetNiftyswapUnitPricesArgs { chainID: string contractAddress: string @@ -885,7 +734,6 @@ export interface GetNiftyswapUnitPricesArgs { export interface GetNiftyswapUnitPricesReturn { prices: { [key: string]: string } } - export interface GetNiftyswapUnitPricesWithQuantitiesArgs { chainID: string contractAddress: string @@ -897,6 +745,58 @@ export interface GetNiftyswapUnitPricesWithQuantitiesReturn { prices: { [key: string]: GetNiftyswapUnitPricesResponse } } +export interface Collections { + createCollection(args: CreateCollectionArgs, headers?: object, signal?: AbortSignal): Promise + getCollection(args: GetCollectionArgs, headers?: object, signal?: AbortSignal): Promise + listCollections(args: ListCollectionsArgs, headers?: object, signal?: AbortSignal): Promise + updateCollection(args: UpdateCollectionArgs, headers?: object, signal?: AbortSignal): Promise + deleteCollection(args: DeleteCollectionArgs, headers?: object, signal?: AbortSignal): Promise + publishCollection( + args: PublishCollectionArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + unpublishCollection( + args: UnpublishCollectionArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + createContractCollection( + args: CreateContractCollectionArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + getContractCollection( + args: GetContractCollectionArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + listContractCollections( + args: ListContractCollectionsArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + updateContractCollection( + args: UpdateContractCollectionArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + deleteContractCollection( + args: DeleteContractCollectionArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + createToken(args: CreateTokenArgs, headers?: object, signal?: AbortSignal): Promise + getToken(args: GetTokenArgs, headers?: object, signal?: AbortSignal): Promise + listTokens(args: ListTokensArgs, headers?: object, signal?: AbortSignal): Promise + updateToken(args: UpdateTokenArgs, headers?: object, signal?: AbortSignal): Promise + deleteToken(args: DeleteTokenArgs, headers?: object, signal?: AbortSignal): Promise + createAsset(args: CreateAssetArgs, headers?: object, signal?: AbortSignal): Promise + getAsset(args: GetAssetArgs, headers?: object, signal?: AbortSignal): Promise + updateAsset(args: UpdateAssetArgs, headers?: object, signal?: AbortSignal): Promise + deleteAsset(args: DeleteAssetArgs, headers?: object, signal?: AbortSignal): Promise +} + export interface CreateCollectionArgs { projectId?: number collection: Collection @@ -905,7 +805,6 @@ export interface CreateCollectionArgs { export interface CreateCollectionReturn { collection: Collection } - export interface GetCollectionArgs { projectId?: number collectionId: number @@ -914,7 +813,6 @@ export interface GetCollectionArgs { export interface GetCollectionReturn { collection: Collection } - export interface ListCollectionsArgs { projectId?: number page?: Page @@ -924,7 +822,6 @@ export interface ListCollectionsReturn { page: Page collections: Array } - export interface UpdateCollectionArgs { projectId?: number collection: Collection @@ -933,7 +830,6 @@ export interface UpdateCollectionArgs { export interface UpdateCollectionReturn { collection: Collection } - export interface DeleteCollectionArgs { projectId?: number collectionId: number @@ -942,7 +838,6 @@ export interface DeleteCollectionArgs { export interface DeleteCollectionReturn { status: boolean } - export interface PublishCollectionArgs { projectId?: number collectionId: number @@ -952,7 +847,6 @@ export interface PublishCollectionArgs { export interface PublishCollectionReturn { collection: Collection } - export interface UnpublishCollectionArgs { projectId?: number collectionId: number @@ -961,7 +855,6 @@ export interface UnpublishCollectionArgs { export interface UnpublishCollectionReturn { collection: Collection } - export interface CreateContractCollectionArgs { projectId: number contractCollection: ContractCollection @@ -970,7 +863,6 @@ export interface CreateContractCollectionArgs { export interface CreateContractCollectionReturn { contractCollection: ContractCollection } - export interface GetContractCollectionArgs { projectId: number chainId: number @@ -980,7 +872,6 @@ export interface GetContractCollectionArgs { export interface GetContractCollectionReturn { contractCollection: ContractCollection } - export interface ListContractCollectionsArgs { projectId: number collectionId?: number @@ -992,7 +883,6 @@ export interface ListContractCollectionsReturn { collections: Array page: Page } - export interface UpdateContractCollectionArgs { projectId: number contractCollection: ContractCollection @@ -1001,7 +891,6 @@ export interface UpdateContractCollectionArgs { export interface UpdateContractCollectionReturn { ok: boolean } - export interface DeleteContractCollectionArgs { projectId: number chainId: number @@ -1011,7 +900,6 @@ export interface DeleteContractCollectionArgs { export interface DeleteContractCollectionReturn { ok: boolean } - export interface CreateTokenArgs { projectId?: number collectionId: number @@ -1023,7 +911,6 @@ export interface CreateTokenReturn { token: TokenMetadata assets: Array } - export interface GetTokenArgs { projectId?: number collectionId: number @@ -1034,7 +921,6 @@ export interface GetTokenReturn { token: TokenMetadata assets: Array } - export interface ListTokensArgs { projectId?: number collectionId: number @@ -1045,7 +931,6 @@ export interface ListTokensReturn { page: Page tokens: Array } - export interface UpdateTokenArgs { projectId?: number collectionId: number @@ -1057,7 +942,6 @@ export interface UpdateTokenArgs { export interface UpdateTokenReturn { token: TokenMetadata } - export interface DeleteTokenArgs { projectId?: number collectionId: number @@ -1067,7 +951,6 @@ export interface DeleteTokenArgs { export interface DeleteTokenReturn { status: boolean } - export interface CreateAssetArgs { projectId?: number asset: Asset @@ -1076,7 +959,6 @@ export interface CreateAssetArgs { export interface CreateAssetReturn { asset: Asset } - export interface GetAssetArgs { projectId?: number assetId: number @@ -1085,7 +967,6 @@ export interface GetAssetArgs { export interface GetAssetReturn { asset: Asset } - export interface UpdateAssetArgs { projectId?: number asset: Asset @@ -1094,7 +975,6 @@ export interface UpdateAssetArgs { export interface UpdateAssetReturn { asset: Asset } - export interface DeleteAssetArgs { projectId?: number assetId: number @@ -1104,6 +984,77 @@ export interface DeleteAssetReturn { status: boolean } +export interface Admin { + /** + * ContractInfo + */ + refreshContractInfoUpdatedBefore( + args: RefreshContractInfoUpdatedBeforeArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + /** + * TokenMetadata + */ + refreshTokenMetadataUpdatedBefore( + args: RefreshTokenMetadataUpdatedBeforeArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + /** + * Contract Info Overrides + */ + getContractInfoOverride( + args: GetContractInfoOverrideArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + getContractInfoOverrides( + args: GetContractInfoOverridesArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + addContractInfoOverride( + args: AddContractInfoOverrideArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + updateContractInfoOverride( + args: UpdateContractInfoOverrideArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + removeContractInfoOverride( + args: RemoveContractInfoOverrideArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + /** + * Token Directory + */ + isInTokenDirectory( + args: IsInTokenDirectoryArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + setTokenDirectoryFeatureIndex( + args: SetTokenDirectoryFeatureIndexArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + addContractToTokenDirectory( + args: AddContractToTokenDirectoryArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + removeContractFromTokenDirectory( + args: RemoveContractFromTokenDirectoryArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + refreshTokenDirectory(headers?: object, signal?: AbortSignal): Promise +} + export interface RefreshContractInfoUpdatedBeforeArgs { before: string maxContractNumber: number @@ -1112,7 +1063,6 @@ export interface RefreshContractInfoUpdatedBeforeArgs { export interface RefreshContractInfoUpdatedBeforeReturn { taskIDs: Array } - export interface RefreshTokenMetadataUpdatedBeforeArgs { before: string maxTokenNumber: number @@ -1121,7 +1071,6 @@ export interface RefreshTokenMetadataUpdatedBeforeArgs { export interface RefreshTokenMetadataUpdatedBeforeReturn { taskIDs: Array } - export interface GetContractInfoOverrideArgs { chainID: string contractAddress: string @@ -1130,7 +1079,6 @@ export interface GetContractInfoOverrideArgs { export interface GetContractInfoOverrideReturn { contractInfoOverride: ContractInfoOverride } - export interface GetContractInfoOverridesArgs { chainID?: string page?: Page @@ -1140,7 +1088,6 @@ export interface GetContractInfoOverridesReturn { contractInfoOverrides: Array page: Page } - export interface AddContractInfoOverrideArgs { chainID: string contractAddress: string @@ -1150,7 +1097,6 @@ export interface AddContractInfoOverrideArgs { export interface AddContractInfoOverrideReturn { ok: boolean } - export interface UpdateContractInfoOverrideArgs { chainID: string contractAddress: string @@ -1160,7 +1106,6 @@ export interface UpdateContractInfoOverrideArgs { export interface UpdateContractInfoOverrideReturn { ok: boolean } - export interface RemoveContractInfoOverrideArgs { chainID: string contractAddress: string @@ -1169,7 +1114,6 @@ export interface RemoveContractInfoOverrideArgs { export interface RemoveContractInfoOverrideReturn { ok: boolean } - export interface IsInTokenDirectoryArgs { chainID: string contractAddress: string @@ -1179,7 +1123,6 @@ export interface IsInTokenDirectoryReturn { ok: boolean featureIndex: number } - export interface SetTokenDirectoryFeatureIndexArgs { chainID: string contractAddress: string @@ -1189,7 +1132,6 @@ export interface SetTokenDirectoryFeatureIndexArgs { export interface SetTokenDirectoryFeatureIndexReturn { ok: boolean } - export interface AddContractToTokenDirectoryArgs { chainID: string contractAddress: string @@ -1198,7 +1140,6 @@ export interface AddContractToTokenDirectoryArgs { export interface AddContractToTokenDirectoryReturn { ok: boolean } - export interface RemoveContractFromTokenDirectoryArgs { chainID: string contractAddress: string @@ -1207,7 +1148,6 @@ export interface RemoveContractFromTokenDirectoryArgs { export interface RemoveContractFromTokenDirectoryReturn { ok: boolean } - export interface RefreshTokenDirectoryArgs {} export interface RefreshTokenDirectoryReturn { @@ -1217,8 +1157,7 @@ export interface RefreshTokenDirectoryReturn { // // Client // - -export class Metadata implements MetadataClient { +export class Metadata implements Metadata { protected hostname: string protected fetch: Fetch protected path = '/rpc/Metadata/' @@ -1232,563 +1171,473 @@ export class Metadata implements MetadataClient { return this.hostname + this.path + name } - queryKey = { - ping: () => ['Metadata', 'ping'] as const, - version: () => ['Metadata', 'version'] as const, - runtimeStatus: () => ['Metadata', 'runtimeStatus'] as const, - getTask: (req: GetTaskArgs) => ['Metadata', 'getTask', req] as const, - getTaskStatus: (req: GetTaskStatusArgs) => ['Metadata', 'getTaskStatus', req] as const, - getContractInfo: (req: GetContractInfoArgs) => ['Metadata', 'getContractInfo', req] as const, - getContractInfoBatch: (req: GetContractInfoBatchArgs) => ['Metadata', 'getContractInfoBatch', req] as const, - findContractInfo: (req: FindContractInfoArgs) => ['Metadata', 'findContractInfo', req] as const, - findContractInfoBatch: (req: FindContractInfoBatchArgs) => ['Metadata', 'findContractInfoBatch', req] as const, - refreshContractInfo: (req: RefreshContractInfoArgs) => ['Metadata', 'refreshContractInfo', req] as const, - refreshContractInfoBatch: (req: RefreshContractInfoBatchArgs) => - ['Metadata', 'refreshContractInfoBatch', req] as const, - searchContractsByQuery: (req: SearchContractsByQueryArgs) => ['Metadata', 'searchContractsByQuery', req] as const, - getTokenMetadata: (req: GetTokenMetadataArgs) => ['Metadata', 'getTokenMetadata', req] as const, - getTokenMetadataBatch: (req: GetTokenMetadataBatchArgs) => ['Metadata', 'getTokenMetadataBatch', req] as const, - refreshTokenMetadata: (req: RefreshTokenMetadataArgs) => ['Metadata', 'refreshTokenMetadata', req] as const, - searchTokenMetadataByQuery: (req: SearchTokenMetadataByQueryArgs) => - ['Metadata', 'searchTokenMetadataByQuery', req] as const, - searchTokenMetadata: (req: SearchTokenMetadataArgs) => ['Metadata', 'searchTokenMetadata', req] as const, - searchTokenMetadataTokenIDs: (req: SearchTokenMetadataTokenIDsArgs) => - ['Metadata', 'searchTokenMetadataTokenIDs', req] as const, - getTokenMetadataPropertyFilters: (req: GetTokenMetadataPropertyFiltersArgs) => - ['Metadata', 'getTokenMetadataPropertyFilters', req] as const, - getTokenDirectoryNetworks: (req: GetTokenDirectoryNetworksArgs) => - ['Metadata', 'getTokenDirectoryNetworks', req] as const, - getTokenDirectory: (req: GetTokenDirectoryArgs) => ['Metadata', 'getTokenDirectory', req] as const, - searchTokenDirectory: (req: SearchTokenDirectoryArgs) => ['Metadata', 'searchTokenDirectory', req] as const, - getNiftyswapTokenQuantity: (req: GetNiftyswapTokenQuantityArgs) => - ['Metadata', 'getNiftyswapTokenQuantity', req] as const, - getNiftyswapUnitPrices: (req: GetNiftyswapUnitPricesArgs) => ['Metadata', 'getNiftyswapUnitPrices', req] as const, - getNiftyswapUnitPricesWithQuantities: (req: GetNiftyswapUnitPricesWithQuantitiesArgs) => - ['Metadata', 'getNiftyswapUnitPricesWithQuantities', req] as const, - } - ping = (headers?: object, signal?: AbortSignal): Promise => { - return this.fetch(this.url('Ping'), createHttpRequest('{}', headers, signal)).then( + return this.fetch(this.url('Ping'), createHTTPRequest({}, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'PingReturn') + return { + status: _data.status, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } version = (headers?: object, signal?: AbortSignal): Promise => { - return this.fetch(this.url('Version'), createHttpRequest('{}', headers, signal)).then( + return this.fetch(this.url('Version'), createHTTPRequest({}, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'VersionReturn') + return { + version: _data.version, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } runtimeStatus = (headers?: object, signal?: AbortSignal): Promise => { - return this.fetch(this.url('RuntimeStatus'), createHttpRequest('{}', headers, signal)).then( + return this.fetch(this.url('RuntimeStatus'), createHTTPRequest({}, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'RuntimeStatusReturn') + return { + status: _data.status, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } - getTask = (req: GetTaskArgs, headers?: object, signal?: AbortSignal): Promise => { - return this.fetch(this.url('GetTask'), createHttpRequest(JsonEncode(req, 'GetTaskArgs'), headers, signal)).then( + getTask = (args: GetTaskArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('GetTask'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'GetTaskReturn') + return { + task: _data.task, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } - getTaskStatus = (req: GetTaskStatusArgs, headers?: object, signal?: AbortSignal): Promise => { - return this.fetch( - this.url('GetTaskStatus'), - createHttpRequest(JsonEncode(req, 'GetTaskStatusArgs'), headers, signal), - ).then( + getTaskStatus = (args: GetTaskStatusArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('GetTaskStatus'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'GetTaskStatusReturn') + return { + status: _data.status, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } getContractInfo = ( - req: GetContractInfoArgs, + args: GetContractInfoArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('GetContractInfo'), - createHttpRequest(JsonEncode(req, 'GetContractInfoArgs'), headers, signal), - ).then( + return this.fetch(this.url('GetContractInfo'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'GetContractInfoReturn') + return { + contractInfo: _data.contractInfo, + taskID: _data.taskID, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } getContractInfoBatch = ( - req: GetContractInfoBatchArgs, + args: GetContractInfoBatchArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('GetContractInfoBatch'), - createHttpRequest(JsonEncode(req, 'GetContractInfoBatchArgs'), headers, signal), - ).then( + return this.fetch(this.url('GetContractInfoBatch'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'GetContractInfoBatchReturn') + return { + contractInfoMap: <{ [key: string]: ContractInfo }>_data.contractInfoMap, + taskID: _data.taskID, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } findContractInfo = ( - req: FindContractInfoArgs, + args: FindContractInfoArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('FindContractInfo'), - createHttpRequest(JsonEncode(req, 'FindContractInfoArgs'), headers, signal), - ).then( + return this.fetch(this.url('FindContractInfo'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'FindContractInfoReturn') + return { + contractInfoList: >_data.contractInfoList, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } findContractInfoBatch = ( - req: FindContractInfoBatchArgs, + args: FindContractInfoBatchArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('FindContractInfoBatch'), - createHttpRequest(JsonEncode(req, 'FindContractInfoBatchArgs'), headers, signal), - ).then( + return this.fetch(this.url('FindContractInfoBatch'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'FindContractInfoBatchReturn') + return { + contractInfoByChain: <{ [key: string]: Array }>_data.contractInfoByChain, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } refreshContractInfo = ( - req: RefreshContractInfoArgs, + args: RefreshContractInfoArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('RefreshContractInfo'), - createHttpRequest(JsonEncode(req, 'RefreshContractInfoArgs'), headers, signal), - ).then( + return this.fetch(this.url('RefreshContractInfo'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'RefreshContractInfoReturn') + return { + taskID: _data.taskID, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } refreshContractInfoBatch = ( - req: RefreshContractInfoBatchArgs, + args: RefreshContractInfoBatchArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('RefreshContractInfoBatch'), - createHttpRequest(JsonEncode(req, 'RefreshContractInfoBatchArgs'), headers, signal), - ).then( + return this.fetch(this.url('RefreshContractInfoBatch'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'RefreshContractInfoBatchReturn') + return { + taskID: _data.taskID, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } searchContractsByQuery = ( - req: SearchContractsByQueryArgs, + args: SearchContractsByQueryArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('SearchContractsByQuery'), - createHttpRequest(JsonEncode(req, 'SearchContractsByQueryArgs'), headers, signal), - ).then( + return this.fetch(this.url('SearchContractsByQuery'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'SearchContractsByQueryReturn') + return { + contractInfo: >_data.contractInfo, + nextPage: _data.nextPage, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } getTokenMetadata = ( - req: GetTokenMetadataArgs, + args: GetTokenMetadataArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('GetTokenMetadata'), - createHttpRequest(JsonEncode(req, 'GetTokenMetadataArgs'), headers, signal), - ).then( + return this.fetch(this.url('GetTokenMetadata'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'GetTokenMetadataReturn') + return { + tokenMetadata: >_data.tokenMetadata, + taskID: _data.taskID, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } getTokenMetadataBatch = ( - req: GetTokenMetadataBatchArgs, + args: GetTokenMetadataBatchArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('GetTokenMetadataBatch'), - createHttpRequest(JsonEncode(req, 'GetTokenMetadataBatchArgs'), headers, signal), - ).then( + return this.fetch(this.url('GetTokenMetadataBatch'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'GetTokenMetadataBatchReturn') + return { + contractTokenMetadata: <{ [key: string]: Array }>_data.contractTokenMetadata, + taskID: _data.taskID, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } refreshTokenMetadata = ( - req: RefreshTokenMetadataArgs, + args: RefreshTokenMetadataArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('RefreshTokenMetadata'), - createHttpRequest(JsonEncode(req, 'RefreshTokenMetadataArgs'), headers, signal), - ).then( + return this.fetch(this.url('RefreshTokenMetadata'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'RefreshTokenMetadataReturn') + return { + taskID: _data.taskID, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } searchTokenMetadataByQuery = ( - req: SearchTokenMetadataByQueryArgs, + args: SearchTokenMetadataByQueryArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('SearchTokenMetadataByQuery'), - createHttpRequest(JsonEncode(req, 'SearchTokenMetadataByQueryArgs'), headers, signal), - ).then( + return this.fetch(this.url('SearchTokenMetadataByQuery'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'SearchTokenMetadataByQueryReturn') + return { + tokenMetadata: >_data.tokenMetadata, + nextPage: _data.nextPage, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } searchTokenMetadata = ( - req: SearchTokenMetadataArgs, + args: SearchTokenMetadataArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('SearchTokenMetadata'), - createHttpRequest(JsonEncode(req, 'SearchTokenMetadataArgs'), headers, signal), - ).then( + return this.fetch(this.url('SearchTokenMetadata'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'SearchTokenMetadataReturn') + return { + page: _data.page, + tokenMetadata: >_data.tokenMetadata, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } searchTokenMetadataTokenIDs = ( - req: SearchTokenMetadataTokenIDsArgs, + args: SearchTokenMetadataTokenIDsArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('SearchTokenMetadataTokenIDs'), - createHttpRequest(JsonEncode(req, 'SearchTokenMetadataTokenIDsArgs'), headers, signal), - ).then( + return this.fetch(this.url('SearchTokenMetadataTokenIDs'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'SearchTokenMetadataTokenIDsReturn') + return { + page: _data.page, + tokenIDs: >_data.tokenIDs, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } getTokenMetadataPropertyFilters = ( - req: GetTokenMetadataPropertyFiltersArgs, + args: GetTokenMetadataPropertyFiltersArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('GetTokenMetadataPropertyFilters'), - createHttpRequest(JsonEncode(req, 'GetTokenMetadataPropertyFiltersArgs'), headers, signal), - ).then( + return this.fetch(this.url('GetTokenMetadataPropertyFilters'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'GetTokenMetadataPropertyFiltersReturn') + return { + filters: >_data.filters, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } getTokenDirectoryNetworks = ( - req: GetTokenDirectoryNetworksArgs, + args: GetTokenDirectoryNetworksArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('GetTokenDirectoryNetworks'), - createHttpRequest(JsonEncode(req, 'GetTokenDirectoryNetworksArgs'), headers, signal), - ).then( + return this.fetch(this.url('GetTokenDirectoryNetworks'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'GetTokenDirectoryNetworksReturn') + return { + chainIDs: >_data.chainIDs, + networks: >_data.networks, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } getTokenDirectory = ( - req: GetTokenDirectoryArgs, + args: GetTokenDirectoryArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('GetTokenDirectory'), - createHttpRequest(JsonEncode(req, 'GetTokenDirectoryArgs'), headers, signal), - ).then( + return this.fetch(this.url('GetTokenDirectory'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'GetTokenDirectoryReturn') + return { + contracts: >_data.contracts, + page: _data.page, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } searchTokenDirectory = ( - req: SearchTokenDirectoryArgs, + args: SearchTokenDirectoryArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('SearchTokenDirectory'), - createHttpRequest(JsonEncode(req, 'SearchTokenDirectoryArgs'), headers, signal), - ).then( + return this.fetch(this.url('SearchTokenDirectory'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'SearchTokenDirectoryReturn') + return { + contracts: >_data.contracts, + page: _data.page, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } getNiftyswapTokenQuantity = ( - req: GetNiftyswapTokenQuantityArgs, + args: GetNiftyswapTokenQuantityArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('GetNiftyswapTokenQuantity'), - createHttpRequest(JsonEncode(req, 'GetNiftyswapTokenQuantityArgs'), headers, signal), - ).then( + return this.fetch(this.url('GetNiftyswapTokenQuantity'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'GetNiftyswapTokenQuantityReturn') + return { + quantity: <{ [key: string]: string }>_data.quantity, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } getNiftyswapUnitPrices = ( - req: GetNiftyswapUnitPricesArgs, + args: GetNiftyswapUnitPricesArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('GetNiftyswapUnitPrices'), - createHttpRequest(JsonEncode(req, 'GetNiftyswapUnitPricesArgs'), headers, signal), - ).then( + return this.fetch(this.url('GetNiftyswapUnitPrices'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'GetNiftyswapUnitPricesReturn') + return { + prices: <{ [key: string]: string }>_data.prices, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } getNiftyswapUnitPricesWithQuantities = ( - req: GetNiftyswapUnitPricesWithQuantitiesArgs, + args: GetNiftyswapUnitPricesWithQuantitiesArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('GetNiftyswapUnitPricesWithQuantities'), - createHttpRequest(JsonEncode(req, 'GetNiftyswapUnitPricesWithQuantitiesArgs'), headers, signal), - ).then( + return this.fetch(this.url('GetNiftyswapUnitPricesWithQuantities'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode( - _data, - 'GetNiftyswapUnitPricesWithQuantitiesReturn', - ) + return { + prices: <{ [key: string]: GetNiftyswapUnitPricesResponse }>_data.prices, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } } -export class Collections implements CollectionsClient { +export class Collections implements Collections { protected hostname: string protected fetch: Fetch protected path = '/rpc/Collections/' @@ -1802,451 +1651,372 @@ export class Collections implements CollectionsClient { return this.hostname + this.path + name } - queryKey = { - createCollection: (req: CreateCollectionArgs) => ['Collections', 'createCollection', req] as const, - getCollection: (req: GetCollectionArgs) => ['Collections', 'getCollection', req] as const, - listCollections: (req: ListCollectionsArgs) => ['Collections', 'listCollections', req] as const, - updateCollection: (req: UpdateCollectionArgs) => ['Collections', 'updateCollection', req] as const, - deleteCollection: (req: DeleteCollectionArgs) => ['Collections', 'deleteCollection', req] as const, - publishCollection: (req: PublishCollectionArgs) => ['Collections', 'publishCollection', req] as const, - unpublishCollection: (req: UnpublishCollectionArgs) => ['Collections', 'unpublishCollection', req] as const, - createContractCollection: (req: CreateContractCollectionArgs) => - ['Collections', 'createContractCollection', req] as const, - getContractCollection: (req: GetContractCollectionArgs) => ['Collections', 'getContractCollection', req] as const, - listContractCollections: (req: ListContractCollectionsArgs) => - ['Collections', 'listContractCollections', req] as const, - updateContractCollection: (req: UpdateContractCollectionArgs) => - ['Collections', 'updateContractCollection', req] as const, - deleteContractCollection: (req: DeleteContractCollectionArgs) => - ['Collections', 'deleteContractCollection', req] as const, - createToken: (req: CreateTokenArgs) => ['Collections', 'createToken', req] as const, - getToken: (req: GetTokenArgs) => ['Collections', 'getToken', req] as const, - listTokens: (req: ListTokensArgs) => ['Collections', 'listTokens', req] as const, - updateToken: (req: UpdateTokenArgs) => ['Collections', 'updateToken', req] as const, - deleteToken: (req: DeleteTokenArgs) => ['Collections', 'deleteToken', req] as const, - createAsset: (req: CreateAssetArgs) => ['Collections', 'createAsset', req] as const, - getAsset: (req: GetAssetArgs) => ['Collections', 'getAsset', req] as const, - updateAsset: (req: UpdateAssetArgs) => ['Collections', 'updateAsset', req] as const, - deleteAsset: (req: DeleteAssetArgs) => ['Collections', 'deleteAsset', req] as const, - } - createCollection = ( - req: CreateCollectionArgs, + args: CreateCollectionArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('CreateCollection'), - createHttpRequest(JsonEncode(req, 'CreateCollectionArgs'), headers, signal), - ).then( + return this.fetch(this.url('CreateCollection'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'CreateCollectionReturn') + return { + collection: _data.collection, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } - getCollection = (req: GetCollectionArgs, headers?: object, signal?: AbortSignal): Promise => { - return this.fetch( - this.url('GetCollection'), - createHttpRequest(JsonEncode(req, 'GetCollectionArgs'), headers, signal), - ).then( + getCollection = (args: GetCollectionArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('GetCollection'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'GetCollectionReturn') + return { + collection: _data.collection, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } listCollections = ( - req: ListCollectionsArgs, + args: ListCollectionsArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('ListCollections'), - createHttpRequest(JsonEncode(req, 'ListCollectionsArgs'), headers, signal), - ).then( + return this.fetch(this.url('ListCollections'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'ListCollectionsReturn') + return { + page: _data.page, + collections: >_data.collections, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } updateCollection = ( - req: UpdateCollectionArgs, + args: UpdateCollectionArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('UpdateCollection'), - createHttpRequest(JsonEncode(req, 'UpdateCollectionArgs'), headers, signal), - ).then( + return this.fetch(this.url('UpdateCollection'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'UpdateCollectionReturn') + return { + collection: _data.collection, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } deleteCollection = ( - req: DeleteCollectionArgs, + args: DeleteCollectionArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('DeleteCollection'), - createHttpRequest(JsonEncode(req, 'DeleteCollectionArgs'), headers, signal), - ).then( + return this.fetch(this.url('DeleteCollection'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'DeleteCollectionReturn') + return { + status: _data.status, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } publishCollection = ( - req: PublishCollectionArgs, + args: PublishCollectionArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('PublishCollection'), - createHttpRequest(JsonEncode(req, 'PublishCollectionArgs'), headers, signal), - ).then( + return this.fetch(this.url('PublishCollection'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'PublishCollectionReturn') + return { + collection: _data.collection, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } unpublishCollection = ( - req: UnpublishCollectionArgs, + args: UnpublishCollectionArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('UnpublishCollection'), - createHttpRequest(JsonEncode(req, 'UnpublishCollectionArgs'), headers, signal), - ).then( + return this.fetch(this.url('UnpublishCollection'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'UnpublishCollectionReturn') + return { + collection: _data.collection, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } createContractCollection = ( - req: CreateContractCollectionArgs, + args: CreateContractCollectionArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('CreateContractCollection'), - createHttpRequest(JsonEncode(req, 'CreateContractCollectionArgs'), headers, signal), - ).then( + return this.fetch(this.url('CreateContractCollection'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'CreateContractCollectionReturn') + return { + contractCollection: _data.contractCollection, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } getContractCollection = ( - req: GetContractCollectionArgs, + args: GetContractCollectionArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('GetContractCollection'), - createHttpRequest(JsonEncode(req, 'GetContractCollectionArgs'), headers, signal), - ).then( + return this.fetch(this.url('GetContractCollection'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'GetContractCollectionReturn') + return { + contractCollection: _data.contractCollection, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } listContractCollections = ( - req: ListContractCollectionsArgs, + args: ListContractCollectionsArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('ListContractCollections'), - createHttpRequest(JsonEncode(req, 'ListContractCollectionsArgs'), headers, signal), - ).then( + return this.fetch(this.url('ListContractCollections'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'ListContractCollectionsReturn') + return { + contractCollections: >_data.contractCollections, + collections: >_data.collections, + page: _data.page, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } updateContractCollection = ( - req: UpdateContractCollectionArgs, + args: UpdateContractCollectionArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('UpdateContractCollection'), - createHttpRequest(JsonEncode(req, 'UpdateContractCollectionArgs'), headers, signal), - ).then( + return this.fetch(this.url('UpdateContractCollection'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'UpdateContractCollectionReturn') + return { + ok: _data.ok, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } deleteContractCollection = ( - req: DeleteContractCollectionArgs, + args: DeleteContractCollectionArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('DeleteContractCollection'), - createHttpRequest(JsonEncode(req, 'DeleteContractCollectionArgs'), headers, signal), - ).then( + return this.fetch(this.url('DeleteContractCollection'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'DeleteContractCollectionReturn') + return { + ok: _data.ok, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } - createToken = (req: CreateTokenArgs, headers?: object, signal?: AbortSignal): Promise => { - return this.fetch( - this.url('CreateToken'), - createHttpRequest(JsonEncode(req, 'CreateTokenArgs'), headers, signal), - ).then( + createToken = (args: CreateTokenArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('CreateToken'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'CreateTokenReturn') + return { + token: _data.token, + assets: >_data.assets, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } - getToken = (req: GetTokenArgs, headers?: object, signal?: AbortSignal): Promise => { - return this.fetch(this.url('GetToken'), createHttpRequest(JsonEncode(req, 'GetTokenArgs'), headers, signal)).then( + getToken = (args: GetTokenArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('GetToken'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'GetTokenReturn') + return { + token: _data.token, + assets: >_data.assets, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } - listTokens = (req: ListTokensArgs, headers?: object, signal?: AbortSignal): Promise => { - return this.fetch( - this.url('ListTokens'), - createHttpRequest(JsonEncode(req, 'ListTokensArgs'), headers, signal), - ).then( + listTokens = (args: ListTokensArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('ListTokens'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'ListTokensReturn') + return { + page: _data.page, + tokens: >_data.tokens, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } - updateToken = (req: UpdateTokenArgs, headers?: object, signal?: AbortSignal): Promise => { - return this.fetch( - this.url('UpdateToken'), - createHttpRequest(JsonEncode(req, 'UpdateTokenArgs'), headers, signal), - ).then( + updateToken = (args: UpdateTokenArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('UpdateToken'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'UpdateTokenReturn') + return { + token: _data.token, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } - deleteToken = (req: DeleteTokenArgs, headers?: object, signal?: AbortSignal): Promise => { - return this.fetch( - this.url('DeleteToken'), - createHttpRequest(JsonEncode(req, 'DeleteTokenArgs'), headers, signal), - ).then( + deleteToken = (args: DeleteTokenArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('DeleteToken'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'DeleteTokenReturn') + return { + status: _data.status, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } - createAsset = (req: CreateAssetArgs, headers?: object, signal?: AbortSignal): Promise => { - return this.fetch( - this.url('CreateAsset'), - createHttpRequest(JsonEncode(req, 'CreateAssetArgs'), headers, signal), - ).then( + createAsset = (args: CreateAssetArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('CreateAsset'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'CreateAssetReturn') + return { + asset: _data.asset, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } - getAsset = (req: GetAssetArgs, headers?: object, signal?: AbortSignal): Promise => { - return this.fetch(this.url('GetAsset'), createHttpRequest(JsonEncode(req, 'GetAssetArgs'), headers, signal)).then( + getAsset = (args: GetAssetArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('GetAsset'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'GetAssetReturn') + return { + asset: _data.asset, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } - updateAsset = (req: UpdateAssetArgs, headers?: object, signal?: AbortSignal): Promise => { - return this.fetch( - this.url('UpdateAsset'), - createHttpRequest(JsonEncode(req, 'UpdateAssetArgs'), headers, signal), - ).then( + updateAsset = (args: UpdateAssetArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('UpdateAsset'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'UpdateAssetReturn') + return { + asset: _data.asset, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } - deleteAsset = (req: DeleteAssetArgs, headers?: object, signal?: AbortSignal): Promise => { - return this.fetch( - this.url('DeleteAsset'), - createHttpRequest(JsonEncode(req, 'DeleteAssetArgs'), headers, signal), - ).then( + deleteAsset = (args: DeleteAssetArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('DeleteAsset'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'DeleteAssetReturn') + return { + status: _data.status, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } } -export class Admin implements AdminClient { +export class Admin implements Admin { protected hostname: string protected fetch: Fetch protected path = '/rpc/Admin/' @@ -2260,294 +2030,243 @@ export class Admin implements AdminClient { return this.hostname + this.path + name } - queryKey = { - refreshContractInfoUpdatedBefore: (req: RefreshContractInfoUpdatedBeforeArgs) => - ['Admin', 'refreshContractInfoUpdatedBefore', req] as const, - refreshTokenMetadataUpdatedBefore: (req: RefreshTokenMetadataUpdatedBeforeArgs) => - ['Admin', 'refreshTokenMetadataUpdatedBefore', req] as const, - getContractInfoOverride: (req: GetContractInfoOverrideArgs) => ['Admin', 'getContractInfoOverride', req] as const, - getContractInfoOverrides: (req: GetContractInfoOverridesArgs) => - ['Admin', 'getContractInfoOverrides', req] as const, - addContractInfoOverride: (req: AddContractInfoOverrideArgs) => ['Admin', 'addContractInfoOverride', req] as const, - updateContractInfoOverride: (req: UpdateContractInfoOverrideArgs) => - ['Admin', 'updateContractInfoOverride', req] as const, - removeContractInfoOverride: (req: RemoveContractInfoOverrideArgs) => - ['Admin', 'removeContractInfoOverride', req] as const, - isInTokenDirectory: (req: IsInTokenDirectoryArgs) => ['Admin', 'isInTokenDirectory', req] as const, - setTokenDirectoryFeatureIndex: (req: SetTokenDirectoryFeatureIndexArgs) => - ['Admin', 'setTokenDirectoryFeatureIndex', req] as const, - addContractToTokenDirectory: (req: AddContractToTokenDirectoryArgs) => - ['Admin', 'addContractToTokenDirectory', req] as const, - removeContractFromTokenDirectory: (req: RemoveContractFromTokenDirectoryArgs) => - ['Admin', 'removeContractFromTokenDirectory', req] as const, - refreshTokenDirectory: () => ['Admin', 'refreshTokenDirectory'] as const, - } - refreshContractInfoUpdatedBefore = ( - req: RefreshContractInfoUpdatedBeforeArgs, + args: RefreshContractInfoUpdatedBeforeArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('RefreshContractInfoUpdatedBefore'), - createHttpRequest(JsonEncode(req, 'RefreshContractInfoUpdatedBeforeArgs'), headers, signal), - ).then( + return this.fetch(this.url('RefreshContractInfoUpdatedBefore'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'RefreshContractInfoUpdatedBeforeReturn') + return { + taskIDs: >_data.taskIDs, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } refreshTokenMetadataUpdatedBefore = ( - req: RefreshTokenMetadataUpdatedBeforeArgs, + args: RefreshTokenMetadataUpdatedBeforeArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('RefreshTokenMetadataUpdatedBefore'), - createHttpRequest(JsonEncode(req, 'RefreshTokenMetadataUpdatedBeforeArgs'), headers, signal), - ).then( + return this.fetch(this.url('RefreshTokenMetadataUpdatedBefore'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'RefreshTokenMetadataUpdatedBeforeReturn') + return { + taskIDs: >_data.taskIDs, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } getContractInfoOverride = ( - req: GetContractInfoOverrideArgs, + args: GetContractInfoOverrideArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('GetContractInfoOverride'), - createHttpRequest(JsonEncode(req, 'GetContractInfoOverrideArgs'), headers, signal), - ).then( + return this.fetch(this.url('GetContractInfoOverride'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'GetContractInfoOverrideReturn') + return { + contractInfoOverride: _data.contractInfoOverride, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } getContractInfoOverrides = ( - req: GetContractInfoOverridesArgs, + args: GetContractInfoOverridesArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('GetContractInfoOverrides'), - createHttpRequest(JsonEncode(req, 'GetContractInfoOverridesArgs'), headers, signal), - ).then( + return this.fetch(this.url('GetContractInfoOverrides'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'GetContractInfoOverridesReturn') + return { + contractInfoOverrides: >_data.contractInfoOverrides, + page: _data.page, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } addContractInfoOverride = ( - req: AddContractInfoOverrideArgs, + args: AddContractInfoOverrideArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('AddContractInfoOverride'), - createHttpRequest(JsonEncode(req, 'AddContractInfoOverrideArgs'), headers, signal), - ).then( + return this.fetch(this.url('AddContractInfoOverride'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'AddContractInfoOverrideReturn') + return { + ok: _data.ok, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } updateContractInfoOverride = ( - req: UpdateContractInfoOverrideArgs, + args: UpdateContractInfoOverrideArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('UpdateContractInfoOverride'), - createHttpRequest(JsonEncode(req, 'UpdateContractInfoOverrideArgs'), headers, signal), - ).then( + return this.fetch(this.url('UpdateContractInfoOverride'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'UpdateContractInfoOverrideReturn') + return { + ok: _data.ok, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } removeContractInfoOverride = ( - req: RemoveContractInfoOverrideArgs, + args: RemoveContractInfoOverrideArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('RemoveContractInfoOverride'), - createHttpRequest(JsonEncode(req, 'RemoveContractInfoOverrideArgs'), headers, signal), - ).then( + return this.fetch(this.url('RemoveContractInfoOverride'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'RemoveContractInfoOverrideReturn') + return { + ok: _data.ok, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } isInTokenDirectory = ( - req: IsInTokenDirectoryArgs, + args: IsInTokenDirectoryArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('IsInTokenDirectory'), - createHttpRequest(JsonEncode(req, 'IsInTokenDirectoryArgs'), headers, signal), - ).then( + return this.fetch(this.url('IsInTokenDirectory'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'IsInTokenDirectoryReturn') + return { + ok: _data.ok, + featureIndex: _data.featureIndex, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } setTokenDirectoryFeatureIndex = ( - req: SetTokenDirectoryFeatureIndexArgs, + args: SetTokenDirectoryFeatureIndexArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('SetTokenDirectoryFeatureIndex'), - createHttpRequest(JsonEncode(req, 'SetTokenDirectoryFeatureIndexArgs'), headers, signal), - ).then( + return this.fetch(this.url('SetTokenDirectoryFeatureIndex'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'SetTokenDirectoryFeatureIndexReturn') + return { + ok: _data.ok, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } addContractToTokenDirectory = ( - req: AddContractToTokenDirectoryArgs, + args: AddContractToTokenDirectoryArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('AddContractToTokenDirectory'), - createHttpRequest(JsonEncode(req, 'AddContractToTokenDirectoryArgs'), headers, signal), - ).then( + return this.fetch(this.url('AddContractToTokenDirectory'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'AddContractToTokenDirectoryReturn') + return { + ok: _data.ok, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } removeContractFromTokenDirectory = ( - req: RemoveContractFromTokenDirectoryArgs, + args: RemoveContractFromTokenDirectoryArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('RemoveContractFromTokenDirectory'), - createHttpRequest(JsonEncode(req, 'RemoveContractFromTokenDirectoryArgs'), headers, signal), - ).then( + return this.fetch(this.url('RemoveContractFromTokenDirectory'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'RemoveContractFromTokenDirectoryReturn') + return { + ok: _data.ok, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } refreshTokenDirectory = (headers?: object, signal?: AbortSignal): Promise => { - return this.fetch(this.url('RefreshTokenDirectory'), createHttpRequest('{}', headers, signal)).then( + return this.fetch(this.url('RefreshTokenDirectory'), createHTTPRequest({}, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'RefreshTokenDirectoryReturn') + return { + taskID: _data.taskID, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } } -const createHttpRequest = (body: string = '{}', headers: object = {}, signal: AbortSignal | null = null): object => { - const reqHeaders: { [key: string]: string } = { - ...headers, - 'Content-Type': 'application/json', - [WebrpcHeader]: WebrpcHeaderValue, +const createHTTPRequest = (body: object = {}, headers: object = {}, signal: AbortSignal | null = null): object => { + const reqHeaders: { [key: string]: string } = { ...headers, 'Content-Type': 'application/json' } + reqHeaders[WebrpcHeader] = WebrpcHeaderValue + + return { + method: 'POST', + headers: reqHeaders, + body: JSON.stringify(body || {}), + signal, } - return { method: 'POST', headers: reqHeaders, body, signal } } const buildResponse = (res: Response): Promise => { @@ -2556,9 +2275,13 @@ const buildResponse = (res: Response): Promise => { 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(): ${error instanceof Error ? error.message : String(error)}: response text: ${text}`, + cause: `JSON.parse(): ${message}: response text: ${text}`, }) } if (!res.ok) { @@ -2569,409 +2292,426 @@ const buildResponse = (res: Response): Promise => { }) } -export type Fetch = (input: RequestInfo, init?: RequestInit) => Promise - -export const JsonEncode = (obj: T, _typ: string = ''): string => { - return JSON.stringify(obj) -} - -export const JsonDecode = (data: string | any, _typ: string = ''): T => { - let parsed: any = data - if (typeof data === 'string') { - try { - parsed = JSON.parse(data) - } catch (err) { - throw WebrpcBadResponseError.new({ cause: `JsonDecode: JSON.parse failed: ${(err as Error).message}` }) - } - } - return parsed as T -} - // // Errors // -type WebrpcErrorParams = { name?: string; code?: number; message?: string; status?: number; cause?: string } - export class WebrpcError extends Error { + name: string code: number + message: string status: number - - constructor(error: WebrpcErrorParams = {}) { - super(error.message) - this.name = error.name || 'WebrpcEndpointError' - this.code = typeof error.code === 'number' ? error.code : 0 - this.message = error.message || `endpoint error` - this.status = typeof error.status === 'number' ? error.status : 400 - if (error.cause !== undefined) this.cause = error.cause + 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({ message: payload.message, code: payload.code, status: payload.status, cause: payload.cause }) + return new this(payload.error, payload.code, payload.message || payload.msg, payload.status, payload.cause) } } +// Webrpc errors + export class WebrpcEndpointError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'WebrpcEndpoint' - this.code = typeof error.code === 'number' ? error.code : 0 - this.message = error.message || `endpoint error` - this.status = typeof error.status === 'number' ? error.status : 400 - if (error.cause !== undefined) this.cause = error.cause + 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(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'WebrpcRequestFailed' - this.code = typeof error.code === 'number' ? error.code : -1 - this.message = error.message || `request failed` - this.status = typeof error.status === 'number' ? error.status : 400 - if (error.cause !== undefined) this.cause = error.cause + 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(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'WebrpcBadRoute' - this.code = typeof error.code === 'number' ? error.code : -2 - this.message = error.message || `bad route` - this.status = typeof error.status === 'number' ? error.status : 404 - if (error.cause !== undefined) this.cause = error.cause + 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(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'WebrpcBadMethod' - this.code = typeof error.code === 'number' ? error.code : -3 - this.message = error.message || `bad method` - this.status = typeof error.status === 'number' ? error.status : 405 - if (error.cause !== undefined) this.cause = error.cause + 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(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'WebrpcBadRequest' - this.code = typeof error.code === 'number' ? error.code : -4 - this.message = error.message || `bad request` - this.status = typeof error.status === 'number' ? error.status : 400 - if (error.cause !== undefined) this.cause = error.cause + 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(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'WebrpcBadResponse' - this.code = typeof error.code === 'number' ? error.code : -5 - this.message = error.message || `bad response` - this.status = typeof error.status === 'number' ? error.status : 500 - if (error.cause !== undefined) this.cause = error.cause + 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(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'WebrpcServerPanic' - this.code = typeof error.code === 'number' ? error.code : -6 - this.message = error.message || `server panic` - this.status = typeof error.status === 'number' ? error.status : 500 - if (error.cause !== undefined) this.cause = error.cause + 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(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'WebrpcInternalError' - this.code = typeof error.code === 'number' ? error.code : -7 - this.message = error.message || `internal error` - this.status = typeof error.status === 'number' ? error.status : 500 - if (error.cause !== undefined) this.cause = error.cause + 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 WebrpcClientAbortedError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'WebrpcClientAborted' - this.code = typeof error.code === 'number' ? error.code : -8 - this.message = error.message || `request aborted by client` - this.status = typeof error.status === 'number' ? error.status : 400 - if (error.cause !== undefined) this.cause = error.cause - Object.setPrototypeOf(this, WebrpcClientAbortedError.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(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'WebrpcStreamLost' - this.code = typeof error.code === 'number' ? error.code : -9 - this.message = error.message || `stream lost` - this.status = typeof error.status === 'number' ? error.status : 400 - if (error.cause !== undefined) this.cause = error.cause + 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(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'WebrpcStreamFinished' - this.code = typeof error.code === 'number' ? error.code : -10 - this.message = error.message || `stream finished` - this.status = typeof error.status === 'number' ? error.status : 200 - if (error.cause !== undefined) this.cause = error.cause + 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(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'Unauthorized' - this.code = typeof error.code === 'number' ? error.code : 1000 - this.message = error.message || `Unauthorized access` - this.status = typeof error.status === 'number' ? error.status : 401 - if (error.cause !== undefined) this.cause = error.cause + 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(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'PermissionDenied' - this.code = typeof error.code === 'number' ? error.code : 1001 - this.message = error.message || `Permission denied` - this.status = typeof error.status === 'number' ? error.status : 403 - if (error.cause !== undefined) this.cause = error.cause + 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(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'SessionExpired' - this.code = typeof error.code === 'number' ? error.code : 1002 - this.message = error.message || `Session expired` - this.status = typeof error.status === 'number' ? error.status : 403 - if (error.cause !== undefined) this.cause = error.cause + 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 MethodNotFoundError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'MethodNotFound' - this.code = typeof error.code === 'number' ? error.code : 1003 - this.message = error.message || `Method not found` - this.status = typeof error.status === 'number' ? error.status : 404 - if (error.cause !== undefined) this.cause = error.cause + constructor( + name: string = 'MethodNotFound', + code: number = 1003, + message: string = `Method not found`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) Object.setPrototypeOf(this, MethodNotFoundError.prototype) } } export class RequestConflictError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'RequestConflict' - this.code = typeof error.code === 'number' ? error.code : 1004 - this.message = error.message || `Conflict with target resource` - this.status = typeof error.status === 'number' ? error.status : 409 - if (error.cause !== undefined) this.cause = error.cause + constructor( + name: string = 'RequestConflict', + code: number = 1004, + message: string = `Conflict with target resource`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) Object.setPrototypeOf(this, RequestConflictError.prototype) } } export class FailError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'Fail' - this.code = typeof error.code === 'number' ? error.code : 1005 - this.message = error.message || `Request Failed` - this.status = typeof error.status === 'number' ? error.status : 400 - if (error.cause !== undefined) this.cause = error.cause + constructor( + name: string = 'Fail', + code: number = 1005, + message: string = `Request Failed`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) Object.setPrototypeOf(this, FailError.prototype) } } export class GeoblockedError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'Geoblocked' - this.code = typeof error.code === 'number' ? error.code : 1006 - this.message = error.message || `Geoblocked region` - this.status = typeof error.status === 'number' ? error.status : 451 - if (error.cause !== undefined) this.cause = error.cause + constructor( + name: string = 'Geoblocked', + code: number = 1006, + message: string = `Geoblocked region`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) Object.setPrototypeOf(this, GeoblockedError.prototype) } } export class TaskFailedError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'TaskFailed' - this.code = typeof error.code === 'number' ? error.code : 1007 - this.message = error.message || `Task failed` - this.status = typeof error.status === 'number' ? error.status : 400 - if (error.cause !== undefined) this.cause = error.cause + constructor( + name: string = 'TaskFailed', + code: number = 1007, + message: string = `Task failed`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) Object.setPrototypeOf(this, TaskFailedError.prototype) } } export class DeprecatedError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'Deprecated' - this.code = typeof error.code === 'number' ? error.code : 1008 - this.message = error.message || `RPC method is deprecated` - this.status = typeof error.status === 'number' ? error.status : 400 - if (error.cause !== undefined) this.cause = error.cause + constructor( + name: string = 'Deprecated', + code: number = 1008, + message: string = `RPC method is deprecated`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) Object.setPrototypeOf(this, DeprecatedError.prototype) } } export class TimeoutError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'Timeout' - this.code = typeof error.code === 'number' ? error.code : 2000 - this.message = error.message || `Request timed out` - this.status = typeof error.status === 'number' ? error.status : 408 - if (error.cause !== undefined) this.cause = error.cause + constructor( + name: string = 'Timeout', + code: number = 2000, + message: string = `Request timed out`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) Object.setPrototypeOf(this, TimeoutError.prototype) } } export class InvalidArgumentError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'InvalidArgument' - this.code = typeof error.code === 'number' ? error.code : 2001 - this.message = error.message || `Invalid argument` - this.status = typeof error.status === 'number' ? error.status : 400 - if (error.cause !== undefined) this.cause = error.cause + constructor( + name: string = 'InvalidArgument', + code: number = 2001, + message: string = `Invalid argument`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) Object.setPrototypeOf(this, InvalidArgumentError.prototype) } } export class RequiredArgumentError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'RequiredArgument' - this.code = typeof error.code === 'number' ? error.code : 2002 - this.message = error.message || `Required argument missing` - this.status = typeof error.status === 'number' ? error.status : 400 - if (error.cause !== undefined) this.cause = error.cause + constructor( + name: string = 'RequiredArgument', + code: number = 2002, + message: string = `Required argument missing`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) Object.setPrototypeOf(this, RequiredArgumentError.prototype) } } export class QueryFailedError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'QueryFailed' - this.code = typeof error.code === 'number' ? error.code : 2003 - this.message = error.message || `Query failed` - this.status = typeof error.status === 'number' ? error.status : 400 - if (error.cause !== undefined) this.cause = error.cause + 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 ValidationFailedError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'ValidationFailed' - this.code = typeof error.code === 'number' ? error.code : 2004 - this.message = error.message || `Validation failed` - this.status = typeof error.status === 'number' ? error.status : 400 - if (error.cause !== undefined) this.cause = error.cause + constructor( + name: string = 'ValidationFailed', + code: number = 2004, + message: string = `Validation failed`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) Object.setPrototypeOf(this, ValidationFailedError.prototype) } } export class RateLimitedError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'RateLimited' - this.code = typeof error.code === 'number' ? error.code : 2005 - this.message = error.message || `Rate limited` - this.status = typeof error.status === 'number' ? error.status : 429 - if (error.cause !== undefined) this.cause = error.cause + constructor( + name: string = 'RateLimited', + code: number = 2005, + message: string = `Rate limited`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) Object.setPrototypeOf(this, RateLimitedError.prototype) } } export class NotFoundError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'NotFound' - this.code = typeof error.code === 'number' ? error.code : 3000 - this.message = error.message || `Resource not found` - this.status = typeof error.status === 'number' ? error.status : 400 - if (error.cause !== undefined) this.cause = error.cause + 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 class ProjectNotFoundError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'ProjectNotFound' - this.code = typeof error.code === 'number' ? error.code : 3002 - this.message = error.message || `Project not found` - this.status = typeof error.status === 'number' ? error.status : 400 - if (error.cause !== undefined) this.cause = error.cause + constructor( + name: string = 'ProjectNotFound', + code: number = 3002, + message: string = `Project not found`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) Object.setPrototypeOf(this, ProjectNotFoundError.prototype) } } export class ChainNotFoundError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'ChainNotFound' - this.code = typeof error.code === 'number' ? error.code : 3003 - this.message = error.message || `Chain not found` - this.status = typeof error.status === 'number' ? error.status : 400 - if (error.cause !== undefined) this.cause = error.cause + constructor( + name: string = 'ChainNotFound', + code: number = 3003, + message: string = `Chain not found`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) Object.setPrototypeOf(this, ChainNotFoundError.prototype) } } export class TokenDirectoryDisabledError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'TokenDirectoryDisabled' - this.code = typeof error.code === 'number' ? error.code : 4001 - this.message = error.message || `Token Directory is disabled` - this.status = typeof error.status === 'number' ? error.status : 400 - if (error.cause !== undefined) this.cause = error.cause + constructor( + name: string = 'TokenDirectoryDisabled', + code: number = 4001, + message: string = `Token Directory is disabled`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) Object.setPrototypeOf(this, TokenDirectoryDisabledError.prototype) } } @@ -2985,7 +2725,7 @@ export enum errors { WebrpcBadResponse = 'WebrpcBadResponse', WebrpcServerPanic = 'WebrpcServerPanic', WebrpcInternalError = 'WebrpcInternalError', - WebrpcClientAborted = 'WebrpcClientAborted', + WebrpcClientDisconnected = 'WebrpcClientDisconnected', WebrpcStreamLost = 'WebrpcStreamLost', WebrpcStreamFinished = 'WebrpcStreamFinished', Unauthorized = 'Unauthorized', @@ -3018,7 +2758,7 @@ export enum WebrpcErrorCodes { WebrpcBadResponse = -5, WebrpcServerPanic = -6, WebrpcInternalError = -7, - WebrpcClientAborted = -8, + WebrpcClientDisconnected = -8, WebrpcStreamLost = -9, WebrpcStreamFinished = -10, Unauthorized = 1000, @@ -3051,7 +2791,7 @@ export const webrpcErrorByCode: { [code: number]: any } = { [-5]: WebrpcBadResponseError, [-6]: WebrpcServerPanicError, [-7]: WebrpcInternalErrorError, - [-8]: WebrpcClientAbortedError, + [-8]: WebrpcClientDisconnectedError, [-9]: WebrpcStreamLostError, [-10]: WebrpcStreamFinishedError, [1000]: UnauthorizedError, @@ -3075,58 +2815,4 @@ export const webrpcErrorByCode: { [code: number]: any } = { [4001]: TokenDirectoryDisabledError, } -// -// Webrpc -// - -export const WebrpcHeader = 'Webrpc' - -export const WebrpcHeaderValue = 'webrpc@v0.31.0;gen-typescript@v0.22.5;sequence-metadata@v0.4.0' - -type WebrpcGenVersions = { - WebrpcGenVersion: string - codeGenName: string - codeGenVersion: string - schemaName: string - schemaVersion: string -} - -export function VersionFromHeader(headers: Headers): WebrpcGenVersions { - const headerValue = headers.get(WebrpcHeader) - if (!headerValue) { - return { - WebrpcGenVersion: '', - codeGenName: '', - codeGenVersion: '', - schemaName: '', - schemaVersion: '', - } - } - - return parseWebrpcGenVersions(headerValue) -} - -function parseWebrpcGenVersions(header: string): WebrpcGenVersions { - const versions = header.split(';') - if (versions.length < 3) { - return { - WebrpcGenVersion: '', - codeGenName: '', - codeGenVersion: '', - schemaName: '', - schemaVersion: '', - } - } - - const [_, WebrpcGenVersion] = versions[0]!.split('@') - const [codeGenName, codeGenVersion] = versions[1]!.split('@') - const [schemaName, schemaVersion] = versions[2]!.split('@') - - return { - WebrpcGenVersion: WebrpcGenVersion ?? '', - codeGenName: codeGenName ?? '', - codeGenVersion: codeGenVersion ?? '', - schemaName: schemaName ?? '', - schemaVersion: schemaVersion ?? '', - } -} +export type Fetch = (input: RequestInfo, init?: RequestInit) => Promise diff --git a/packages/services/relayer/hardhat.config.js b/packages/services/relayer/hardhat.config.js new file mode 100644 index 0000000000..fd760378b1 --- /dev/null +++ b/packages/services/relayer/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/services/relayer/src/index.ts b/packages/services/relayer/src/index.ts index dc28bfc771..4859839b55 100644 --- a/packages/services/relayer/src/index.ts +++ b/packages/services/relayer/src/index.ts @@ -1,3 +1 @@ -export * as Relayer from './relayer/index.js' -export * as RpcRelayerGen from './relayer/rpc-relayer/relayer.gen.js' -export * as Preconditions from './preconditions/index.js' +export * from './rpc-relayer/index.js' diff --git a/packages/services/relayer/src/local-relayer.ts b/packages/services/relayer/src/local-relayer.ts new file mode 100644 index 0000000000..29850be344 --- /dev/null +++ b/packages/services/relayer/src/local-relayer.ts @@ -0,0 +1,125 @@ +// import { ethers } from 'ethers' +// import { logger } from '@0xsequence/utils' +// import { FeeOption, FeeQuote, proto, Relayer } from '.' +// import { ProviderRelayer, ProviderRelayerOptions } from './provider-relayer' +// import { commons } from '@0xsequence/core' + +// export type LocalRelayerOptions = Omit & { +// signer: ethers.Signer +// } + +// export function isLocalRelayerOptions(obj: any): obj is LocalRelayerOptions { +// return typeof obj === 'object' && isAbstractSigner(obj.signer) +// } + +// export class LocalRelayer extends ProviderRelayer implements Relayer { +// private signer: ethers.Signer +// private txnOptions: ethers.TransactionRequest + +// constructor(options: LocalRelayerOptions | ethers.AbstractSigner) { +// super(isAbstractSigner(options) ? { provider: options.provider! } : { ...options, provider: options.signer.provider! }) +// this.signer = isAbstractSigner(options) ? options : options.signer +// if (!this.signer.provider) throw new Error('Signer must have a provider') +// } + +// async getFeeOptions(_address: string, ..._transactions: commons.transaction.Transaction[]): Promise<{ options: FeeOption[] }> { +// return { options: [] } +// } + +// async getFeeOptionsRaw( +// _entrypoint: string, +// _data: ethers.BytesLike, +// _options?: { +// simulate?: boolean +// } +// ): Promise<{ options: FeeOption[] }> { +// return { options: [] } +// } + +// async gasRefundOptions(address: string, ...transactions: commons.transaction.Transaction[]): Promise { +// const { options } = await this.getFeeOptions(address, ...transactions) +// return options +// } + +// setTransactionOptions(transactionRequest: ethers.TransactionRequest) { +// this.txnOptions = transactionRequest +// } + +// async relay( +// signedTxs: commons.transaction.IntendedTransactionBundle, +// quote?: FeeQuote, +// waitForReceipt: boolean = true +// ): Promise> { +// if (quote !== undefined) { +// logger.warn(`LocalRelayer doesn't accept fee quotes`) +// } + +// const data = commons.transaction.encodeBundleExecData(signedTxs) + +// // TODO: think about computing gas limit individually, summing together and passing across +// // NOTE: we expect that all txns have set their gasLimit ahead of time through proper estimation +// // const gasLimit = signedTxs.transactions.reduce((sum, tx) => sum + tx.gasLimit, 0n) +// // txRequest.gasLimit = gasLimit + +// const responsePromise = this.signer.sendTransaction({ +// to: signedTxs.entrypoint, +// data, +// ...this.txnOptions, +// gasLimit: 9000000 +// }) + +// if (waitForReceipt) { +// const response: commons.transaction.TransactionResponse = await responsePromise +// response.receipt = await response.wait() +// return response +// } else { +// return responsePromise +// } +// } + +// async getMetaTransactions( +// projectId: number, +// page?: proto.Page +// ): Promise<{ +// page: proto.Page +// transactions: proto.MetaTxnLog[] +// }> { +// return { page: { page: 0, pageSize: 100 }, transactions: [] } +// } + +// async getTransactionCost( +// projectId: number, +// from: string, +// to: string +// ): Promise<{ +// cost: number +// }> { +// return { cost: 0 } +// } + +// async listGasSponsors(args: proto.ListGasSponsorsArgs): Promise { +// return { page: { page: 0, pageSize: 100 }, gasSponsors: [] } +// } + +// async addGasSponsor(args: proto.AddGasSponsorArgs): Promise { +// return { status: true, gasSponsor: {} as proto.GasSponsor } +// } + +// async updateGasSponsor(args: proto.UpdateGasSponsorArgs): Promise { +// return { status: true, gasSponsor: {} as proto.GasSponsor } +// } + +// async removeGasSponsor(args: proto.RemoveGasSponsorArgs): Promise { +// return { status: true } +// } +// } + +// function isAbstractSigner(signer: any): signer is ethers.AbstractSigner { +// return ( +// signer && +// typeof signer === 'object' && +// typeof signer.provider === 'object' && +// typeof signer.getAddress === 'function' && +// typeof signer.connect === 'function' +// ) +// } diff --git a/packages/services/relayer/src/provider-relayer.ts b/packages/services/relayer/src/provider-relayer.ts new file mode 100644 index 0000000000..85e9257f24 --- /dev/null +++ b/packages/services/relayer/src/provider-relayer.ts @@ -0,0 +1,284 @@ +// import { ethers } from 'ethers' +// import { walletContracts } from '@0xsequence/abi' +// import { FeeOption, FeeQuote, proto, Relayer, SimulateResult } from '.' +// import { logger, Optionals } from '@0xsequence/utils' +// import { commons } from '@0xsequence/core' + +// const DEFAULT_GAS_LIMIT = 800000n + +// export interface ProviderRelayerOptions { +// provider: ethers.Provider +// waitPollRate?: number +// deltaBlocksLog?: number +// fromBlockLog?: number +// } + +// export const ProviderRelayerDefaults: Required> = { +// waitPollRate: 1000, +// deltaBlocksLog: 12, +// fromBlockLog: -1024 +// } + +// export function isProviderRelayerOptions(obj: any): obj is ProviderRelayerOptions { +// return typeof obj === 'object' && isAbstractProvider(obj.provider) +// } + +// export abstract class ProviderRelayer implements Relayer { +// public provider: ethers.Provider +// public waitPollRate: number +// public deltaBlocksLog: number +// public fromBlockLog: number + +// constructor(options: ProviderRelayerOptions) { +// const opts = { ...ProviderRelayerDefaults, ...options } + +// this.provider = opts.provider +// this.waitPollRate = opts.waitPollRate +// this.deltaBlocksLog = opts.deltaBlocksLog +// this.fromBlockLog = opts.fromBlockLog +// } + +// abstract getFeeOptions( +// address: string, +// ...transactions: commons.transaction.Transaction[] +// ): Promise<{ options: FeeOption[]; quote?: FeeQuote }> + +// abstract getFeeOptionsRaw( +// entrypoint: string, +// data: ethers.BytesLike, +// options?: { +// simulate?: boolean +// } +// ): Promise<{ options: FeeOption[]; quote?: FeeQuote }> + +// abstract gasRefundOptions(address: string, ...transactions: commons.transaction.Transaction[]): Promise + +// abstract relay( +// signedTxs: commons.transaction.IntendedTransactionBundle, +// quote?: FeeQuote, +// waitForReceipt?: boolean +// ): Promise + +// abstract getTransactionCost( +// projectId: number, +// from: string, +// to: string +// ): Promise<{ +// cost: number +// }> + +// abstract getMetaTransactions( +// projectId: number, +// page?: proto.Page +// ): Promise<{ +// page: proto.Page +// transactions: proto.MetaTxnLog[] +// }> + +// abstract listGasSponsors(args: proto.ListGasSponsorsArgs): Promise + +// abstract addGasSponsor(args: proto.AddGasSponsorArgs): Promise + +// abstract updateGasSponsor(args: proto.UpdateGasSponsorArgs): Promise + +// abstract removeGasSponsor(args: proto.RemoveGasSponsorArgs): Promise + +// async simulate(wallet: string, ...transactions: commons.transaction.Transaction[]): Promise { +// return ( +// await Promise.all( +// transactions.map(async tx => { +// // Respect gasLimit request of the transaction (as long as its not 0) +// if (tx.gasLimit && BigInt(tx.gasLimit || 0) !== 0n) { +// return tx.gasLimit +// } + +// // Fee can't be estimated locally for delegateCalls +// if (tx.delegateCall) { +// return DEFAULT_GAS_LIMIT +// } + +// // Fee can't be estimated for self-called if wallet hasn't been deployed +// if (tx.to === wallet && (await this.provider.getCode(wallet).then(code => ethers.getBytes(code).length === 0))) { +// return DEFAULT_GAS_LIMIT +// } + +// if (!this.provider) { +// throw new Error('signer.provider is not set, but is required') +// } + +// // TODO: If the wallet address has been deployed, gas limits can be +// // estimated with more accurately by using self-calls with the batch transactions one by one +// return this.provider.estimateGas({ +// from: wallet, +// to: tx.to, +// data: tx.data, +// value: tx.value +// }) +// }) +// ) +// ).map(gasLimit => ({ +// executed: true, +// succeeded: true, +// gasUsed: Number(gasLimit), +// gasLimit: Number(gasLimit) +// })) +// } + +// async getNonce(address: string, space?: ethers.BigNumberish, blockTag?: ethers.BlockTag): Promise { +// if (!this.provider) { +// throw new Error('provider is not set') +// } + +// if ((await this.provider.getCode(address)) === '0x') { +// return 0 +// } + +// if (space === undefined) { +// space = 0 +// } + +// const module = new ethers.Contract(address, walletContracts.mainModule.abi, this.provider) +// const nonce = await module.readNonce(space, { blockTag: blockTag }) +// return commons.transaction.encodeNonce(space, nonce) +// } + +// async wait( +// metaTxnId: string | commons.transaction.SignedTransactionBundle, +// timeoutDuration?: number, +// delay: number = this.waitPollRate, +// maxFails: number = 5 +// ): Promise { +// if (typeof metaTxnId !== 'string') { +// metaTxnId = commons.transaction.intendedTransactionID(metaTxnId) +// } + +// let timedOut = false + +// const retry = async (f: () => Promise, errorMessage: string): Promise => { +// let fails = 0 + +// while (!timedOut) { +// try { +// return await f() +// } catch (error) { +// fails++ + +// if (maxFails !== undefined && fails >= maxFails) { +// logger.error(`giving up after ${fails} failed attempts${errorMessage ? `: ${errorMessage}` : ''}`, error) +// throw error +// } else { +// logger.warn(`attempt #${fails} failed${errorMessage ? `: ${errorMessage}` : ''}`, error) +// } +// } + +// if (delay > 0) { +// await new Promise(resolve => setTimeout(resolve, delay)) +// } +// } + +// throw new Error(`timed out after ${fails} failed attempts${errorMessage ? `: ${errorMessage}` : ''}`) +// } + +// const waitReceipt = async (): Promise => { +// // Transactions can only get executed on nonce change +// // get all nonce changes and look for metaTxnIds in between logs +// let lastBlock: number = this.fromBlockLog + +// if (lastBlock < 0) { +// const block = await retry(() => this.provider.getBlockNumber(), 'unable to get latest block number') +// lastBlock = block + lastBlock +// } + +// if (typeof metaTxnId !== 'string') { +// throw new Error('impossible') +// } + +// const normalMetaTxnId = metaTxnId.replace('0x', '') + +// while (!timedOut) { +// const block = await retry(() => this.provider.getBlockNumber(), 'unable to get latest block number') + +// const logs = await retry( +// () => +// this.provider.getLogs({ +// fromBlock: Math.max(0, lastBlock - this.deltaBlocksLog), +// toBlock: block, +// // Nonce change event topic +// topics: ['0x1f180c27086c7a39ea2a7b25239d1ab92348f07ca7bb59d1438fcf527568f881'] +// }), +// `unable to get NonceChange logs for blocks ${Math.max(0, lastBlock - this.deltaBlocksLog)} to ${block}` +// ) + +// lastBlock = block + +// // Get receipts of all transactions +// const txs = await Promise.all( +// logs.map(l => +// retry( +// () => this.provider.getTransactionReceipt(l.transactionHash), +// `unable to get receipt for transaction ${l.transactionHash}` +// ) +// ) +// ) + +// // Find a transaction with a TxExecuted log +// const found = txs.find(tx => +// tx?.logs.find( +// l => +// (l.topics.length === 0 && l.data.replace('0x', '') === normalMetaTxnId) || +// (l.topics.length === 1 && +// // TxFailed event topic +// l.topics[0] === '0x3dbd1590ea96dd3253a91f24e64e3a502e1225d602a5731357bc12643070ccd7' && +// l.data.length >= 64 && +// l.data.replace('0x', '').startsWith(normalMetaTxnId)) +// ) +// ) + +// // If found return that +// if (found) { +// const response = await retry(() => this.provider.getTransaction(found.hash), `unable to get transaction ${found.hash}`) +// if (!response) { +// throw new Error(`Transaction response not found for ${metaTxnId}`) +// } + +// // NOTE: we have to do this, because ethers-v6 uses private fields +// // and we can't just extend the class and override the method, so +// // we just modify the response object directly by adding the receipt to it. +// const out: any = response +// out.receipt = found +// return out +// } + +// // Otherwise wait and try again +// if (!timedOut) { +// await new Promise(r => setTimeout(r, delay)) +// } +// } + +// throw new Error(`Timeout waiting for transaction receipt ${metaTxnId}`) +// } + +// if (timeoutDuration !== undefined) { +// return Promise.race([ +// waitReceipt(), +// new Promise((_, reject) => +// setTimeout(() => { +// timedOut = true +// reject(`Timeout waiting for transaction receipt ${metaTxnId}`) +// }, timeoutDuration) +// ) +// ]) +// } else { +// return waitReceipt() +// } +// } +// } + +// function isAbstractProvider(provider: any): provider is ethers.AbstractProvider { +// return ( +// provider && +// typeof provider === 'object' && +// typeof provider.getNetwork === 'function' && +// typeof provider.getBlockNumber === 'function' +// ) +// } diff --git a/packages/services/relayer/src/relayer/relayer.ts b/packages/services/relayer/src/relayer/relayer.ts deleted file mode 100644 index f685368200..0000000000 --- a/packages/services/relayer/src/relayer/relayer.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { Address, Hex } from 'ox' -import { FeeToken } from './rpc-relayer/relayer.gen.js' -import { FeeOption, FeeQuote, OperationStatus } from './index.js' -import { Payload, Precondition } from '@0xsequence/wallet-primitives' - -export interface Relayer { - kind: 'relayer' - - type: string - id: string - - isAvailable(wallet: Address.Address, chainId: number): Promise - - feeTokens(): Promise<{ isFeeRequired: boolean; tokens?: FeeToken[]; paymentAddress?: Address.Address }> - - feeOptions( - wallet: Address.Address, - chainId: number, - to: Address.Address, - calls: Payload.Call[], - ): Promise<{ options: FeeOption[]; quote?: FeeQuote }> - - relay(to: Address.Address, data: Hex.Hex, chainId: number, quote?: FeeQuote): Promise<{ opHash: Hex.Hex }> - - status(opHash: Hex.Hex, chainId: number): Promise - - checkPrecondition(precondition: Precondition.Precondition): Promise -} - -export function isRelayer(relayer: unknown): relayer is Relayer { - return ( - typeof relayer === 'object' && - relayer !== null && - 'isAvailable' in relayer && - 'feeOptions' in relayer && - 'relay' in relayer && - 'status' in relayer && - 'checkPrecondition' in relayer - ) -} diff --git a/packages/services/relayer/src/relayer/rpc-relayer/relayer.gen.ts b/packages/services/relayer/src/relayer/rpc-relayer/relayer.gen.ts deleted file mode 100644 index 8a9ff4a7b4..0000000000 --- a/packages/services/relayer/src/relayer/rpc-relayer/relayer.gen.ts +++ /dev/null @@ -1,2500 +0,0 @@ -/* eslint-disable */ -// sequence-relayer v0.4.1 0a2503bc893179ba968b0015d7580aabf6a88dd4 -// -- -// Code generated by Webrpc-gen@v0.32.2 with typescript generator. DO NOT EDIT. -// -// webrpc-gen -schema=relayer.ridl -target=typescript -client -out=./clients/relayer.gen.ts -compat - -// Webrpc description and code-gen version -export const WebrpcVersion = 'v1' - -// Schema version of your RIDL schema -export const WebrpcSchemaVersion = 'v0.4.1' - -// Schema hash generated from your RIDL schema -export const WebrpcSchemaHash = '0a2503bc893179ba968b0015d7580aabf6a88dd4' - -// -// Client interface -// - -export interface RelayerClient { - ping(headers?: object, signal?: AbortSignal): Promise - - version(headers?: object, signal?: AbortSignal): Promise - - runtimeStatus(headers?: object, signal?: AbortSignal): Promise - - getSequenceContext(headers?: object, signal?: AbortSignal): Promise - - getChainID(headers?: object, signal?: AbortSignal): Promise - - /** - * - * Transactions - * - * TODO (future): rename this to just, 'SendTransaction(txn: MetaTransaction)' or 'SendTransaction(txn: SignedTransaction)', or something.. - * Project ID is only used by service and admin calls. Other clients must have projectID passed via the context - * TODO: rename return txnHash: string to metaTxnID: string - */ - sendMetaTxn(req: SendMetaTxnArgs, headers?: object, signal?: AbortSignal): Promise - - getMetaTxnNonce(req: GetMetaTxnNonceArgs, headers?: object, signal?: AbortSignal): Promise - - /** - * TODO: one day, make GetMetaTxnReceipt respond immediately with receipt or not - * and add WaitTransactionReceipt method, which will block and wait, similar to how GetMetaTxnReceipt - * is implemented now. - * For backwards compat, we can leave the current GetMetaTxnReceipt how it is, an deprecate it, and introduce - * new, GetTransactionReceipt and WaitTransactionReceipt methods - * we can also accept metaTxnId and txnHash .. so can take either or.. I wonder if ERC-4337 has any convention on this? - */ - getMetaTxnReceipt( - req: GetMetaTxnReceiptArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - - simulate(req: SimulateArgs, headers?: object, signal?: AbortSignal): Promise - - simulateV3(req: SimulateV3Args, headers?: object, signal?: AbortSignal): Promise - - /** - * TODO: deprecated, to be removed by https://github.com/0xsequence/stack/pull/356 at a later date - */ - updateMetaTxnGasLimits( - req: UpdateMetaTxnGasLimitsArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - - feeTokens(headers?: object, signal?: AbortSignal): Promise - - feeOptions(req: FeeOptionsArgs, headers?: object, signal?: AbortSignal): Promise - - /** - * Bridge gas endpoints for S2S calls - * Used for bridge fees (e.g., LayerZero messaging fees) that require msg.value to be fronted at runtime. - * bridgeGas will be included in fee calculation so the relayer gets reimbursed. - */ - sendMetaTxnWithBridgeGas( - req: SendMetaTxnWithBridgeGasArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - - feeOptionsWithBridgeGas( - req: FeeOptionsWithBridgeGasArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - - /** - * TODO: deprecated, to be removed by https://github.com/0xsequence/stack/pull/356 at a later date - */ - getMetaTxnNetworkFeeOptions( - req: GetMetaTxnNetworkFeeOptionsArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - - /** - * - * Sender administration - * - */ - startSender(req: StartSenderArgs, headers?: object, signal?: AbortSignal): Promise - - stopSender(req: StopSenderArgs, headers?: object, signal?: AbortSignal): Promise - - repairSender(req: RepairSenderArgs, headers?: object, signal?: AbortSignal): Promise - - getMetaTransactions( - req: GetMetaTransactionsArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - - getTransactionCost( - req: GetTransactionCostArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - - /** - * Legacy Gas Tank - */ - getGasTank(req: GetGasTankArgs, headers?: object, signal?: AbortSignal): Promise - - addGasTank(req: AddGasTankArgs, headers?: object, signal?: AbortSignal): Promise - - updateGasTank(req: UpdateGasTankArgs, headers?: object, signal?: AbortSignal): Promise - - /** - * Legacy Gas Adjustment - */ - nextGasTankBalanceAdjustmentNonce( - req: NextGasTankBalanceAdjustmentNonceArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - - adjustGasTankBalance( - req: AdjustGasTankBalanceArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - - getGasTankBalanceAdjustment( - req: GetGasTankBalanceAdjustmentArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - - listGasTankBalanceAdjustments( - req: ListGasTankBalanceAdjustmentsArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - - /** - * Project-Level Gas Sponsorship - */ - listGasSponsors(req: ListGasSponsorsArgs, headers?: object, signal?: AbortSignal): Promise - - getGasSponsor(req: GetGasSponsorArgs, headers?: object, signal?: AbortSignal): Promise - - addGasSponsor(req: AddGasSponsorArgs, headers?: object, signal?: AbortSignal): Promise - - updateGasSponsor(req: UpdateGasSponsorArgs, headers?: object, signal?: AbortSignal): Promise - - removeGasSponsor(req: RemoveGasSponsorArgs, headers?: object, signal?: AbortSignal): Promise - - /** - * Ecosystem-level Gas Sponsorship - */ - listEcosystemGasSponsors( - req: ListEcosystemGasSponsorsArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - - getEcosystemGasSponsor( - req: GetEcosystemGasSponsorArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - - addEcosystemGasSponsor( - req: AddEcosystemGasSponsorArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - - updateEcosystemGasSponsor( - req: UpdateEcosystemGasSponsorArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - - removeEcosystemGasSponsor( - req: RemoveEcosystemGasSponsorArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - - /** - * Gas Sponsor Lookup - */ - addressGasSponsors( - req: AddressGasSponsorsArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - - /** - * Project Balance - */ - getProjectBalance( - req: GetProjectBalanceArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - - adjustProjectBalance( - req: AdjustProjectBalanceArgs, - headers?: object, - signal?: AbortSignal, - ): Promise -} - -// -// Schema types -// - -export enum RepairOperation { - SKIP = 'SKIP', - REQUEUE = 'REQUEUE', - DROP = 'DROP', -} - -export enum ETHTxnStatus { - UNKNOWN = 'UNKNOWN', - DROPPED = 'DROPPED', - QUEUED = 'QUEUED', - SENT = 'SENT', - SUCCEEDED = 'SUCCEEDED', - PARTIALLY_FAILED = 'PARTIALLY_FAILED', - FAILED = 'FAILED', - PENDING_PRECONDITION = 'PENDING_PRECONDITION', - MINED = 'MINED', -} - -export enum TransferType { - SEND = 'SEND', - RECEIVE = 'RECEIVE', - BRIDGE_DEPOSIT = 'BRIDGE_DEPOSIT', - BRIDGE_WITHDRAW = 'BRIDGE_WITHDRAW', - BURN = 'BURN', - UNKNOWN = 'UNKNOWN', -} - -export enum SimulateStatus { - SKIPPED = 'SKIPPED', - SUCCEEDED = 'SUCCEEDED', - FAILED = 'FAILED', - ABORTED = 'ABORTED', - REVERTED = 'REVERTED', - NOT_ENOUGH_GAS = 'NOT_ENOUGH_GAS', -} - -export enum FeeTokenType { - UNKNOWN = 'UNKNOWN', - ERC20_TOKEN = 'ERC20_TOKEN', - ERC1155_TOKEN = 'ERC1155_TOKEN', -} - -export enum Order { - 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 - chainID: number - useEIP1559: boolean - senders: Array - checks: RuntimeChecks -} - -export interface SenderStatus { - index: number - address: string - etherBalance: number - enabled: boolean - active: boolean - nonce?: NonceStatus - current?: CurrentStatus -} - -export interface NonceStatus { - chain: number - mempool: number -} - -export interface CurrentStatus { - transaction: string - first: TransactionStatus - latest?: TransactionStatus -} - -export interface TransactionStatus { - transaction: string - gas: number - gasPrice: string - priorityFee: string - time: string - age: string - error?: string -} - -export interface RuntimeChecks {} - -export interface SequenceContext { - factory: string - mainModule: string - mainModuleUpgradable: string - guestModule: string - utils: string -} - -export interface GasTank { - id: number - chainId: number - name: string - currentBalance: number - unlimited: boolean - feeMarkupFactor: number - updatedAt: string - createdAt: string -} - -export interface GasTankBalanceAdjustment { - gasTankId: number - nonce: number - amount: number - totalBalance: number - balanceTimestamp: string - createdAt: string -} - -export interface GasSponsor { - id: number - gasTankId: number - projectId: number - ecosystemId: number - chainId: number - address: string - name: string - active: boolean - updatedAt: string - createdAt: string - deletedAt: string -} - -export interface GasSponsorUsage { - name: string - id: number - totalGasUsed: number - totalTxnFees: number - totalTxnFeesUsd: number - avgGasPrice: number - totalTxns: number - startTime: string - endTime: string -} - -export interface MetaTxn { - walletAddress: string - contract: string - input: string -} - -export interface MetaTxnLog { - id: number - chainId: number - projectId: number - txnHash: string - txnNonce: string - metaTxnID?: string - txnStatus: ETHTxnStatus - txnRevertReason: string - requeues: number - queuedAt: string - sentAt: string - minedAt: string - target: string - input: string - bridgeGas?: string - txnArgs: { [key: string]: any } - txnReceipt?: { [key: string]: any } - walletAddress: string - metaTxnNonce: string - gasLimit: number - gasPrice: string - gasUsed: number - gasEstimated: number - gasFeeMarkup?: number - usdRate: string - creditsUsed: number - cost: string - isWhitelisted: boolean - gasSponsor?: number - gasTank?: number - updatedAt: string - createdAt: string -} - -export interface MetaTxnReceipt { - id: string - status: string - revertReason?: string - index: number - logs: Array - receipts: Array - blockNumber: string - txnHash: string - txnReceipt: string -} - -export interface MetaTxnReceiptLog { - address: string - topics: Array - data: string -} - -export interface Transactions { - chainID: string - transactions: Array - preconditions?: Array -} - -export interface Transaction { - delegateCall: boolean - revertOnError: boolean - gasLimit: string - target: string - value: string - data: string -} - -export interface TransactionPrecondition { - type: string - chainId: number - ownerAddress: string - tokenAddress: string - minAmount: bigint -} - -export interface TxnLogUser { - username: string -} - -export interface TxnLogTransfer { - transferType: TransferType - contractAddress: string - from: string - to: string - ids: Array - amounts: Array -} - -export interface SimulateResult { - executed: boolean - succeeded: boolean - result?: string - reason?: string - gasUsed: number - gasLimit: number -} - -export interface SimulateV3Result { - status: SimulateStatus - result?: string - error?: string - gasUsed: number - gasLimit: number -} - -export interface FeeOption { - token: FeeToken - to: string - value: string - gasLimit: number -} - -export interface FeeToken { - chainId: number - name: string - symbol: string - type: FeeTokenType - decimals?: number - logoURL: string - contractAddress?: string - tokenID?: string -} - -export interface Page { - pageSize: number - page: number - more: boolean - column: string - sort: Array -} - -export interface Sort { - column: string - order: Order -} - -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 GetSequenceContextArgs {} - -export interface GetSequenceContextReturn { - data: SequenceContext -} - -export interface GetChainIDArgs {} - -export interface GetChainIDReturn { - chainID: number -} - -export interface SendMetaTxnArgs { - call: MetaTxn - quote?: string - projectID?: number - preconditions?: Array -} - -export interface SendMetaTxnReturn { - status: boolean - txnHash: string -} - -export interface GetMetaTxnNonceArgs { - walletContractAddress: string - space?: string -} - -export interface GetMetaTxnNonceReturn { - nonce: string -} - -export interface GetMetaTxnReceiptArgs { - metaTxID: string -} - -export interface GetMetaTxnReceiptReturn { - receipt: MetaTxnReceipt -} - -export interface SimulateArgs { - wallet: string - transactions: string -} - -export interface SimulateReturn { - results: Array -} - -export interface SimulateV3Args { - wallet: string - calls: string -} - -export interface SimulateV3Return { - results: Array -} - -export interface UpdateMetaTxnGasLimitsArgs { - walletAddress: string - walletConfig: any - payload: string -} - -export interface UpdateMetaTxnGasLimitsReturn { - payload: string -} - -export interface FeeTokensArgs {} - -export interface FeeTokensReturn { - isFeeRequired: boolean - tokens: Array - paymentAddress: string -} - -export interface FeeOptionsArgs { - wallet: string - to: string - data: string - simulate?: boolean -} - -export interface FeeOptionsReturn { - options: Array - sponsored: boolean - quote?: string -} - -export interface SendMetaTxnWithBridgeGasArgs { - call: MetaTxn - quote?: string - projectID?: number - bridgeGas: string - preconditions?: Array -} - -export interface SendMetaTxnWithBridgeGasReturn { - status: boolean - txnHash: string -} - -export interface FeeOptionsWithBridgeGasArgs { - wallet: string - to: string - data: string - simulate?: boolean - bridgeGas: string -} - -export interface FeeOptionsWithBridgeGasReturn { - options: Array - sponsored: boolean - quote?: string -} - -export interface GetMetaTxnNetworkFeeOptionsArgs { - walletConfig: any - payload: string -} - -export interface GetMetaTxnNetworkFeeOptionsReturn { - options: Array -} - -export interface StartSenderArgs { - sender: number -} - -export interface StartSenderReturn {} - -export interface StopSenderArgs { - sender: number -} - -export interface StopSenderReturn {} - -export interface RepairSenderArgs { - sender: number - nonce: number - operation: RepairOperation -} - -export interface RepairSenderReturn {} - -export interface GetMetaTransactionsArgs { - projectId: number - page?: Page -} - -export interface GetMetaTransactionsReturn { - page: Page - transactions: Array -} - -export interface GetTransactionCostArgs { - projectId: number - from: string - to: string -} - -export interface GetTransactionCostReturn { - cost: number -} - -export interface GetGasTankArgs { - id: number -} - -export interface GetGasTankReturn { - gasTank: GasTank -} - -export interface AddGasTankArgs { - name: string - feeMarkupFactor: number - unlimited?: boolean -} - -export interface AddGasTankReturn { - status: boolean - gasTank: GasTank -} - -export interface UpdateGasTankArgs { - id: number - name?: string - feeMarkupFactor?: number - unlimited?: boolean -} - -export interface UpdateGasTankReturn { - status: boolean - gasTank: GasTank -} - -export interface NextGasTankBalanceAdjustmentNonceArgs { - id: number -} - -export interface NextGasTankBalanceAdjustmentNonceReturn { - nonce: number -} - -export interface AdjustGasTankBalanceArgs { - id: number - nonce: number - amount: number -} - -export interface AdjustGasTankBalanceReturn { - status: boolean - adjustment: GasTankBalanceAdjustment -} - -export interface GetGasTankBalanceAdjustmentArgs { - id: number - nonce: number -} - -export interface GetGasTankBalanceAdjustmentReturn { - adjustment: GasTankBalanceAdjustment -} - -export interface ListGasTankBalanceAdjustmentsArgs { - id: number - page?: Page -} - -export interface ListGasTankBalanceAdjustmentsReturn { - page: Page - adjustments: Array -} - -export interface ListGasSponsorsArgs { - projectId: number - page?: Page -} - -export interface ListGasSponsorsReturn { - page: Page - gasSponsors: Array -} - -export interface GetGasSponsorArgs { - projectId: number - id: number -} - -export interface GetGasSponsorReturn { - gasSponsor: GasSponsor -} - -export interface AddGasSponsorArgs { - projectId: number - address: string - name?: string - active?: boolean -} - -export interface AddGasSponsorReturn { - status: boolean - gasSponsor: GasSponsor -} - -export interface UpdateGasSponsorArgs { - projectId: number - id: number - name?: string - active?: boolean -} - -export interface UpdateGasSponsorReturn { - status: boolean - gasSponsor: GasSponsor -} - -export interface RemoveGasSponsorArgs { - projectId: number - id: number -} - -export interface RemoveGasSponsorReturn { - status: boolean -} - -export interface ListEcosystemGasSponsorsArgs { - ecosystemId: number - page?: Page -} - -export interface ListEcosystemGasSponsorsReturn { - page: Page - gasSponsors: Array -} - -export interface GetEcosystemGasSponsorArgs { - ecosystemId: number - id: number -} - -export interface GetEcosystemGasSponsorReturn { - gasSponsor: GasSponsor -} - -export interface AddEcosystemGasSponsorArgs { - ecosystemId: number - address: string - name?: string - active?: boolean -} - -export interface AddEcosystemGasSponsorReturn { - status: boolean - gasSponsor: GasSponsor -} - -export interface UpdateEcosystemGasSponsorArgs { - ecosystemId: number - id: number - name?: string - active?: boolean -} - -export interface UpdateEcosystemGasSponsorReturn { - status: boolean - gasSponsor: GasSponsor -} - -export interface RemoveEcosystemGasSponsorArgs { - ecosystemId: number - id: number -} - -export interface RemoveEcosystemGasSponsorReturn { - status: boolean -} - -export interface AddressGasSponsorsArgs { - address: string - page?: Page -} - -export interface AddressGasSponsorsReturn { - page: Page - gasSponsors: Array -} - -export interface GetProjectBalanceArgs { - projectId: number -} - -export interface GetProjectBalanceReturn { - balance: number -} - -export interface AdjustProjectBalanceArgs { - projectId: number - amount: number - identifier: string -} - -export interface AdjustProjectBalanceReturn { - balance: number -} - -// -// Client -// - -export class Relayer implements RelayerClient { - protected hostname: string - protected fetch: Fetch - protected path = '/rpc/Relayer/' - - constructor(hostname: string, fetch: Fetch) { - this.hostname = hostname.replace(/\/*$/, '') - this.fetch = (input: RequestInfo, init?: RequestInit) => fetch(input, init) - } - - private url(name: string): string { - return this.hostname + this.path + name - } - - queryKey = { - ping: () => ['Relayer', 'ping'] as const, - version: () => ['Relayer', 'version'] as const, - runtimeStatus: () => ['Relayer', 'runtimeStatus'] as const, - getSequenceContext: () => ['Relayer', 'getSequenceContext'] as const, - getChainID: () => ['Relayer', 'getChainID'] as const, - sendMetaTxn: (req: SendMetaTxnArgs) => ['Relayer', 'sendMetaTxn', req] as const, - getMetaTxnNonce: (req: GetMetaTxnNonceArgs) => ['Relayer', 'getMetaTxnNonce', req] as const, - getMetaTxnReceipt: (req: GetMetaTxnReceiptArgs) => ['Relayer', 'getMetaTxnReceipt', req] as const, - simulate: (req: SimulateArgs) => ['Relayer', 'simulate', req] as const, - simulateV3: (req: SimulateV3Args) => ['Relayer', 'simulateV3', req] as const, - updateMetaTxnGasLimits: (req: UpdateMetaTxnGasLimitsArgs) => ['Relayer', 'updateMetaTxnGasLimits', req] as const, - feeTokens: () => ['Relayer', 'feeTokens'] as const, - feeOptions: (req: FeeOptionsArgs) => ['Relayer', 'feeOptions', req] as const, - sendMetaTxnWithBridgeGas: (req: SendMetaTxnWithBridgeGasArgs) => - ['Relayer', 'sendMetaTxnWithBridgeGas', req] as const, - feeOptionsWithBridgeGas: (req: FeeOptionsWithBridgeGasArgs) => ['Relayer', 'feeOptionsWithBridgeGas', req] as const, - getMetaTxnNetworkFeeOptions: (req: GetMetaTxnNetworkFeeOptionsArgs) => - ['Relayer', 'getMetaTxnNetworkFeeOptions', req] as const, - startSender: (req: StartSenderArgs) => ['Relayer', 'startSender', req] as const, - stopSender: (req: StopSenderArgs) => ['Relayer', 'stopSender', req] as const, - repairSender: (req: RepairSenderArgs) => ['Relayer', 'repairSender', req] as const, - getMetaTransactions: (req: GetMetaTransactionsArgs) => ['Relayer', 'getMetaTransactions', req] as const, - getTransactionCost: (req: GetTransactionCostArgs) => ['Relayer', 'getTransactionCost', req] as const, - getGasTank: (req: GetGasTankArgs) => ['Relayer', 'getGasTank', req] as const, - addGasTank: (req: AddGasTankArgs) => ['Relayer', 'addGasTank', req] as const, - updateGasTank: (req: UpdateGasTankArgs) => ['Relayer', 'updateGasTank', req] as const, - nextGasTankBalanceAdjustmentNonce: (req: NextGasTankBalanceAdjustmentNonceArgs) => - ['Relayer', 'nextGasTankBalanceAdjustmentNonce', req] as const, - adjustGasTankBalance: (req: AdjustGasTankBalanceArgs) => ['Relayer', 'adjustGasTankBalance', req] as const, - getGasTankBalanceAdjustment: (req: GetGasTankBalanceAdjustmentArgs) => - ['Relayer', 'getGasTankBalanceAdjustment', req] as const, - listGasTankBalanceAdjustments: (req: ListGasTankBalanceAdjustmentsArgs) => - ['Relayer', 'listGasTankBalanceAdjustments', req] as const, - listGasSponsors: (req: ListGasSponsorsArgs) => ['Relayer', 'listGasSponsors', req] as const, - getGasSponsor: (req: GetGasSponsorArgs) => ['Relayer', 'getGasSponsor', req] as const, - addGasSponsor: (req: AddGasSponsorArgs) => ['Relayer', 'addGasSponsor', req] as const, - updateGasSponsor: (req: UpdateGasSponsorArgs) => ['Relayer', 'updateGasSponsor', req] as const, - removeGasSponsor: (req: RemoveGasSponsorArgs) => ['Relayer', 'removeGasSponsor', req] as const, - listEcosystemGasSponsors: (req: ListEcosystemGasSponsorsArgs) => - ['Relayer', 'listEcosystemGasSponsors', req] as const, - getEcosystemGasSponsor: (req: GetEcosystemGasSponsorArgs) => ['Relayer', 'getEcosystemGasSponsor', req] as const, - addEcosystemGasSponsor: (req: AddEcosystemGasSponsorArgs) => ['Relayer', 'addEcosystemGasSponsor', req] as const, - updateEcosystemGasSponsor: (req: UpdateEcosystemGasSponsorArgs) => - ['Relayer', 'updateEcosystemGasSponsor', req] as const, - removeEcosystemGasSponsor: (req: RemoveEcosystemGasSponsorArgs) => - ['Relayer', 'removeEcosystemGasSponsor', req] as const, - addressGasSponsors: (req: AddressGasSponsorsArgs) => ['Relayer', 'addressGasSponsors', req] as const, - getProjectBalance: (req: GetProjectBalanceArgs) => ['Relayer', 'getProjectBalance', req] as const, - adjustProjectBalance: (req: AdjustProjectBalanceArgs) => ['Relayer', 'adjustProjectBalance', req] as const, - } - - ping = (headers?: object, signal?: AbortSignal): Promise => { - return this.fetch(this.url('Ping'), createHttpRequest('{}', headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'PingReturn') - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - version = (headers?: object, signal?: AbortSignal): Promise => { - return this.fetch(this.url('Version'), createHttpRequest('{}', headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'VersionReturn') - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - runtimeStatus = (headers?: object, signal?: AbortSignal): Promise => { - return this.fetch(this.url('RuntimeStatus'), createHttpRequest('{}', headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'RuntimeStatusReturn') - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - getSequenceContext = (headers?: object, signal?: AbortSignal): Promise => { - return this.fetch(this.url('GetSequenceContext'), createHttpRequest('{}', headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'GetSequenceContextReturn') - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - getChainID = (headers?: object, signal?: AbortSignal): Promise => { - return this.fetch(this.url('GetChainID'), createHttpRequest('{}', headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'GetChainIDReturn') - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - sendMetaTxn = (req: SendMetaTxnArgs, headers?: object, signal?: AbortSignal): Promise => { - return this.fetch(this.url('SendMetaTxn'), createHttpRequest(JsonEncode(req), headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'SendMetaTxnReturn') - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - getMetaTxnNonce = ( - req: GetMetaTxnNonceArgs, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch(this.url('GetMetaTxnNonce'), createHttpRequest(JsonEncode(req), headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'GetMetaTxnNonceReturn') - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - getMetaTxnReceipt = ( - req: GetMetaTxnReceiptArgs, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch(this.url('GetMetaTxnReceipt'), createHttpRequest(JsonEncode(req), headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'GetMetaTxnReceiptReturn') - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - simulate = (req: SimulateArgs, headers?: object, signal?: AbortSignal): Promise => { - return this.fetch(this.url('Simulate'), createHttpRequest(JsonEncode(req), headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'SimulateReturn') - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - simulateV3 = (req: SimulateV3Args, headers?: object, signal?: AbortSignal): Promise => { - return this.fetch(this.url('SimulateV3'), createHttpRequest(JsonEncode(req), headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'SimulateV3Return') - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - updateMetaTxnGasLimits = ( - req: UpdateMetaTxnGasLimitsArgs, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch(this.url('UpdateMetaTxnGasLimits'), createHttpRequest(JsonEncode(req), headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'UpdateMetaTxnGasLimitsReturn') - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - feeTokens = (headers?: object, signal?: AbortSignal): Promise => { - return this.fetch(this.url('FeeTokens'), createHttpRequest('{}', headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'FeeTokensReturn') - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - feeOptions = (req: FeeOptionsArgs, headers?: object, signal?: AbortSignal): Promise => { - return this.fetch(this.url('FeeOptions'), createHttpRequest(JsonEncode(req), headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'FeeOptionsReturn') - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - sendMetaTxnWithBridgeGas = ( - req: SendMetaTxnWithBridgeGasArgs, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch(this.url('SendMetaTxnWithBridgeGas'), createHttpRequest(JsonEncode(req), headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'SendMetaTxnWithBridgeGasReturn') - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - feeOptionsWithBridgeGas = ( - req: FeeOptionsWithBridgeGasArgs, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch(this.url('FeeOptionsWithBridgeGas'), createHttpRequest(JsonEncode(req), headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'FeeOptionsWithBridgeGasReturn') - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - getMetaTxnNetworkFeeOptions = ( - req: GetMetaTxnNetworkFeeOptionsArgs, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch( - this.url('GetMetaTxnNetworkFeeOptions'), - createHttpRequest(JsonEncode(req), headers, signal), - ).then( - (res) => { - return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'GetMetaTxnNetworkFeeOptionsReturn') - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - startSender = (req: StartSenderArgs, headers?: object, signal?: AbortSignal): Promise => { - return this.fetch(this.url('StartSender'), createHttpRequest(JsonEncode(req), headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'StartSenderReturn') - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - stopSender = (req: StopSenderArgs, headers?: object, signal?: AbortSignal): Promise => { - return this.fetch(this.url('StopSender'), createHttpRequest(JsonEncode(req), headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'StopSenderReturn') - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - repairSender = (req: RepairSenderArgs, headers?: object, signal?: AbortSignal): Promise => { - return this.fetch(this.url('RepairSender'), createHttpRequest(JsonEncode(req), headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'RepairSenderReturn') - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - getMetaTransactions = ( - req: GetMetaTransactionsArgs, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch(this.url('GetMetaTransactions'), createHttpRequest(JsonEncode(req), headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'GetMetaTransactionsReturn') - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - getTransactionCost = ( - req: GetTransactionCostArgs, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch(this.url('GetTransactionCost'), createHttpRequest(JsonEncode(req), headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'GetTransactionCostReturn') - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - getGasTank = (req: GetGasTankArgs, headers?: object, signal?: AbortSignal): Promise => { - return this.fetch(this.url('GetGasTank'), createHttpRequest(JsonEncode(req), headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'GetGasTankReturn') - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - addGasTank = (req: AddGasTankArgs, headers?: object, signal?: AbortSignal): Promise => { - return this.fetch(this.url('AddGasTank'), createHttpRequest(JsonEncode(req), headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'AddGasTankReturn') - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - updateGasTank = (req: UpdateGasTankArgs, headers?: object, signal?: AbortSignal): Promise => { - return this.fetch(this.url('UpdateGasTank'), createHttpRequest(JsonEncode(req), headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'UpdateGasTankReturn') - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - nextGasTankBalanceAdjustmentNonce = ( - req: NextGasTankBalanceAdjustmentNonceArgs, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch( - this.url('NextGasTankBalanceAdjustmentNonce'), - createHttpRequest(JsonEncode(req), headers, signal), - ).then( - (res) => { - return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'NextGasTankBalanceAdjustmentNonceReturn') - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - adjustGasTankBalance = ( - req: AdjustGasTankBalanceArgs, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch(this.url('AdjustGasTankBalance'), createHttpRequest(JsonEncode(req), headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'AdjustGasTankBalanceReturn') - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - getGasTankBalanceAdjustment = ( - req: GetGasTankBalanceAdjustmentArgs, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch( - this.url('GetGasTankBalanceAdjustment'), - createHttpRequest(JsonEncode(req), headers, signal), - ).then( - (res) => { - return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'GetGasTankBalanceAdjustmentReturn') - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - listGasTankBalanceAdjustments = ( - req: ListGasTankBalanceAdjustmentsArgs, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch( - this.url('ListGasTankBalanceAdjustments'), - createHttpRequest(JsonEncode(req), headers, signal), - ).then( - (res) => { - return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'ListGasTankBalanceAdjustmentsReturn') - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - listGasSponsors = ( - req: ListGasSponsorsArgs, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch(this.url('ListGasSponsors'), createHttpRequest(JsonEncode(req), headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'ListGasSponsorsReturn') - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - getGasSponsor = (req: GetGasSponsorArgs, headers?: object, signal?: AbortSignal): Promise => { - return this.fetch(this.url('GetGasSponsor'), createHttpRequest(JsonEncode(req), headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'GetGasSponsorReturn') - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - addGasSponsor = (req: AddGasSponsorArgs, headers?: object, signal?: AbortSignal): Promise => { - return this.fetch(this.url('AddGasSponsor'), createHttpRequest(JsonEncode(req), headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'AddGasSponsorReturn') - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - updateGasSponsor = ( - req: UpdateGasSponsorArgs, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch(this.url('UpdateGasSponsor'), createHttpRequest(JsonEncode(req), headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'UpdateGasSponsorReturn') - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - removeGasSponsor = ( - req: RemoveGasSponsorArgs, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch(this.url('RemoveGasSponsor'), createHttpRequest(JsonEncode(req), headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'RemoveGasSponsorReturn') - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - listEcosystemGasSponsors = ( - req: ListEcosystemGasSponsorsArgs, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch(this.url('ListEcosystemGasSponsors'), createHttpRequest(JsonEncode(req), headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'ListEcosystemGasSponsorsReturn') - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - getEcosystemGasSponsor = ( - req: GetEcosystemGasSponsorArgs, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch(this.url('GetEcosystemGasSponsor'), createHttpRequest(JsonEncode(req), headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'GetEcosystemGasSponsorReturn') - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - addEcosystemGasSponsor = ( - req: AddEcosystemGasSponsorArgs, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch(this.url('AddEcosystemGasSponsor'), createHttpRequest(JsonEncode(req), headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'AddEcosystemGasSponsorReturn') - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - updateEcosystemGasSponsor = ( - req: UpdateEcosystemGasSponsorArgs, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch(this.url('UpdateEcosystemGasSponsor'), createHttpRequest(JsonEncode(req), headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'UpdateEcosystemGasSponsorReturn') - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - removeEcosystemGasSponsor = ( - req: RemoveEcosystemGasSponsorArgs, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch(this.url('RemoveEcosystemGasSponsor'), createHttpRequest(JsonEncode(req), headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'RemoveEcosystemGasSponsorReturn') - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - addressGasSponsors = ( - req: AddressGasSponsorsArgs, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch(this.url('AddressGasSponsors'), createHttpRequest(JsonEncode(req), headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'AddressGasSponsorsReturn') - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - getProjectBalance = ( - req: GetProjectBalanceArgs, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch(this.url('GetProjectBalance'), createHttpRequest(JsonEncode(req), headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'GetProjectBalanceReturn') - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - adjustProjectBalance = ( - req: AdjustProjectBalanceArgs, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch(this.url('AdjustProjectBalance'), createHttpRequest(JsonEncode(req), headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'AdjustProjectBalanceReturn') - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } -} - -const createHttpRequest = (body: string = '{}', headers: object = {}, signal: AbortSignal | null = null): object => { - const reqHeaders: { [key: string]: string } = { - ...headers, - 'Content-Type': 'application/json', - [WebrpcHeader]: WebrpcHeaderValue, - } - return { method: 'POST', headers: reqHeaders, body, signal } -} - -const buildResponse = (res: Response): Promise => { - return res.text().then((text) => { - let data - try { - data = JSON.parse(text) - } catch (error) { - throw WebrpcBadResponseError.new({ - status: res.status, - cause: `JSON.parse(): ${error instanceof Error ? error.message : String(error)}: response text: ${text}`, - }) - } - if (!res.ok) { - const code: number = typeof data.code === 'number' ? data.code : 0 - throw (webrpcErrorByCode[code] || WebrpcError).new(data) - } - return data - }) -} - -export type Fetch = (input: RequestInfo, init?: RequestInit) => Promise - -// -// BigInt helpers -// - -const BIG_INT_FIELDS: { [typ: string]: (string | [string, string])[] } = { - SendMetaTxnArgs: [['preconditions', 'TransactionPrecondition[]']], - SendMetaTxnWithBridgeGasArgs: [['preconditions', 'TransactionPrecondition[]']], - TransactionPrecondition: ['minAmount'], - Transactions: [['preconditions', 'TransactionPrecondition[]']], -} - -// Decode in-place: mutate object graph; throw if expected numeric string is invalid. -function decodeType(typ: string, obj: any): any { - if (obj == null || typeof obj !== 'object') return obj - const descs = BIG_INT_FIELDS[typ] || [] - if (!descs.length) return obj - for (const d of descs) { - if (Array.isArray(d)) { - const [fieldName, nestedType] = d - if (fieldName.endsWith('[]')) { - const base = fieldName.slice(0, -2) - const arr = obj[base] - if (Array.isArray(arr)) { - for (let i = 0; i < arr.length; i++) arr[i] = decodeType(nestedType, arr[i]) - } - } else if (obj[fieldName]) { - // Handle nestedType that might be an array type like 'Message[]' - if (nestedType.endsWith('[]')) { - const baseType = nestedType.slice(0, -2) - const arr = obj[fieldName] - if (Array.isArray(arr)) { - for (let i = 0; i < arr.length; i++) arr[i] = decodeType(baseType, arr[i]) - } - } else { - obj[fieldName] = decodeType(nestedType, obj[fieldName]) - } - } - continue - } - if (d.endsWith('[]')) { - const base = d.slice(0, -2) - const arr = obj[base] - if (Array.isArray(arr)) { - for (let i = 0; i < arr.length; i++) { - const v = arr[i] - if (typeof v === 'string') { - try { - arr[i] = BigInt(v) - } catch (e) { - throw WebrpcBadResponseError.new({ cause: `Invalid bigint value for ${base}[${i}]: ${v}` }) - } - } - } - } - continue - } - const v = obj[d] - if (typeof v === 'string') { - try { - obj[d] = BigInt(v) - } catch (e) { - throw WebrpcBadResponseError.new({ cause: `Invalid bigint value for ${d}: ${v}` }) - } - } - } - return obj -} - -// Encode object to JSON with BigInts converted to decimal strings. -export const JsonEncode = (obj: T): string => { - return JSON.stringify(obj, (key, value) => (typeof value === 'bigint' ? value.toString() : value)) -} - -// Decode data (JSON string or already-parsed object) and convert declared BigInt string fields back to BigInt. -export const JsonDecode = (data: string | any, typ: string = ''): T => { - let parsed: any = data - if (typeof data === 'string') { - try { - parsed = JSON.parse(data) - } catch (err) { - throw WebrpcBadResponseError.new({ cause: `JsonDecode: JSON.parse failed: ${(err as Error).message}` }) - } - } - return decodeType(typ, parsed) as T -} - -// -// Errors -// - -type WebrpcErrorParams = { name?: string; code?: number; message?: string; status?: number; cause?: string } - -export class WebrpcError extends Error { - code: number - status: number - - constructor(error: WebrpcErrorParams = {}) { - super(error.message) - this.name = error.name || 'WebrpcEndpointError' - this.code = typeof error.code === 'number' ? error.code : 0 - this.message = error.message || `endpoint error` - this.status = typeof error.status === 'number' ? error.status : 400 - if (error.cause !== undefined) this.cause = error.cause - Object.setPrototypeOf(this, WebrpcError.prototype) - } - - static new(payload: any): WebrpcError { - return new this({ message: payload.message, code: payload.code, status: payload.status, cause: payload.cause }) - } -} - -export class WebrpcEndpointError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'WebrpcEndpoint' - this.code = typeof error.code === 'number' ? error.code : 0 - this.message = error.message || `endpoint error` - this.status = typeof error.status === 'number' ? error.status : 400 - if (error.cause !== undefined) this.cause = error.cause - Object.setPrototypeOf(this, WebrpcEndpointError.prototype) - } -} - -export class WebrpcRequestFailedError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'WebrpcRequestFailed' - this.code = typeof error.code === 'number' ? error.code : -1 - this.message = error.message || `request failed` - this.status = typeof error.status === 'number' ? error.status : 400 - if (error.cause !== undefined) this.cause = error.cause - Object.setPrototypeOf(this, WebrpcRequestFailedError.prototype) - } -} - -export class WebrpcBadRouteError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'WebrpcBadRoute' - this.code = typeof error.code === 'number' ? error.code : -2 - this.message = error.message || `bad route` - this.status = typeof error.status === 'number' ? error.status : 404 - if (error.cause !== undefined) this.cause = error.cause - Object.setPrototypeOf(this, WebrpcBadRouteError.prototype) - } -} - -export class WebrpcBadMethodError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'WebrpcBadMethod' - this.code = typeof error.code === 'number' ? error.code : -3 - this.message = error.message || `bad method` - this.status = typeof error.status === 'number' ? error.status : 405 - if (error.cause !== undefined) this.cause = error.cause - Object.setPrototypeOf(this, WebrpcBadMethodError.prototype) - } -} - -export class WebrpcBadRequestError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'WebrpcBadRequest' - this.code = typeof error.code === 'number' ? error.code : -4 - this.message = error.message || `bad request` - this.status = typeof error.status === 'number' ? error.status : 400 - if (error.cause !== undefined) this.cause = error.cause - Object.setPrototypeOf(this, WebrpcBadRequestError.prototype) - } -} - -export class WebrpcBadResponseError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'WebrpcBadResponse' - this.code = typeof error.code === 'number' ? error.code : -5 - this.message = error.message || `bad response` - this.status = typeof error.status === 'number' ? error.status : 500 - if (error.cause !== undefined) this.cause = error.cause - Object.setPrototypeOf(this, WebrpcBadResponseError.prototype) - } -} - -export class WebrpcServerPanicError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'WebrpcServerPanic' - this.code = typeof error.code === 'number' ? error.code : -6 - this.message = error.message || `server panic` - this.status = typeof error.status === 'number' ? error.status : 500 - if (error.cause !== undefined) this.cause = error.cause - Object.setPrototypeOf(this, WebrpcServerPanicError.prototype) - } -} - -export class WebrpcInternalErrorError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'WebrpcInternalError' - this.code = typeof error.code === 'number' ? error.code : -7 - this.message = error.message || `internal error` - this.status = typeof error.status === 'number' ? error.status : 500 - if (error.cause !== undefined) this.cause = error.cause - Object.setPrototypeOf(this, WebrpcInternalErrorError.prototype) - } -} - -export class WebrpcClientAbortedError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'WebrpcClientAborted' - this.code = typeof error.code === 'number' ? error.code : -8 - this.message = error.message || `request aborted by client` - this.status = typeof error.status === 'number' ? error.status : 400 - if (error.cause !== undefined) this.cause = error.cause - Object.setPrototypeOf(this, WebrpcClientAbortedError.prototype) - } -} - -export class WebrpcStreamLostError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'WebrpcStreamLost' - this.code = typeof error.code === 'number' ? error.code : -9 - this.message = error.message || `stream lost` - this.status = typeof error.status === 'number' ? error.status : 400 - if (error.cause !== undefined) this.cause = error.cause - Object.setPrototypeOf(this, WebrpcStreamLostError.prototype) - } -} - -export class WebrpcStreamFinishedError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'WebrpcStreamFinished' - this.code = typeof error.code === 'number' ? error.code : -10 - this.message = error.message || `stream finished` - this.status = typeof error.status === 'number' ? error.status : 200 - if (error.cause !== undefined) this.cause = error.cause - Object.setPrototypeOf(this, WebrpcStreamFinishedError.prototype) - } -} - -// -// Schema errors -// - -export class UnauthorizedError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'Unauthorized' - this.code = typeof error.code === 'number' ? error.code : 1000 - this.message = error.message || `Unauthorized access` - this.status = typeof error.status === 'number' ? error.status : 401 - if (error.cause !== undefined) this.cause = error.cause - Object.setPrototypeOf(this, UnauthorizedError.prototype) - } -} - -export class PermissionDeniedError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'PermissionDenied' - this.code = typeof error.code === 'number' ? error.code : 1001 - this.message = error.message || `Permission denied` - this.status = typeof error.status === 'number' ? error.status : 403 - if (error.cause !== undefined) this.cause = error.cause - Object.setPrototypeOf(this, PermissionDeniedError.prototype) - } -} - -export class SessionExpiredError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'SessionExpired' - this.code = typeof error.code === 'number' ? error.code : 1002 - this.message = error.message || `Session expired` - this.status = typeof error.status === 'number' ? error.status : 403 - if (error.cause !== undefined) this.cause = error.cause - Object.setPrototypeOf(this, SessionExpiredError.prototype) - } -} - -export class MethodNotFoundError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'MethodNotFound' - this.code = typeof error.code === 'number' ? error.code : 1003 - this.message = error.message || `Method not found` - this.status = typeof error.status === 'number' ? error.status : 404 - if (error.cause !== undefined) this.cause = error.cause - Object.setPrototypeOf(this, MethodNotFoundError.prototype) - } -} - -export class RequestConflictError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'RequestConflict' - this.code = typeof error.code === 'number' ? error.code : 1004 - this.message = error.message || `Conflict with target resource` - this.status = typeof error.status === 'number' ? error.status : 409 - if (error.cause !== undefined) this.cause = error.cause - Object.setPrototypeOf(this, RequestConflictError.prototype) - } -} - -export class AbortedError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'Aborted' - this.code = typeof error.code === 'number' ? error.code : 1005 - this.message = error.message || `Request aborted` - this.status = typeof error.status === 'number' ? error.status : 400 - if (error.cause !== undefined) this.cause = error.cause - Object.setPrototypeOf(this, AbortedError.prototype) - } -} - -export class GeoblockedError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'Geoblocked' - this.code = typeof error.code === 'number' ? error.code : 1006 - this.message = error.message || `Geoblocked region` - this.status = typeof error.status === 'number' ? error.status : 451 - if (error.cause !== undefined) this.cause = error.cause - Object.setPrototypeOf(this, GeoblockedError.prototype) - } -} - -export class RateLimitedError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'RateLimited' - this.code = typeof error.code === 'number' ? error.code : 1007 - this.message = error.message || `Rate-limited. Please slow down.` - this.status = typeof error.status === 'number' ? error.status : 429 - if (error.cause !== undefined) this.cause = error.cause - Object.setPrototypeOf(this, RateLimitedError.prototype) - } -} - -export class ProjectNotFoundError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'ProjectNotFound' - this.code = typeof error.code === 'number' ? error.code : 1008 - this.message = error.message || `Project not found` - this.status = typeof error.status === 'number' ? error.status : 401 - if (error.cause !== undefined) this.cause = error.cause - Object.setPrototypeOf(this, ProjectNotFoundError.prototype) - } -} - -export class AccessKeyNotFoundError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'AccessKeyNotFound' - this.code = typeof error.code === 'number' ? error.code : 1101 - this.message = error.message || `Access key not found` - this.status = typeof error.status === 'number' ? error.status : 401 - if (error.cause !== undefined) this.cause = error.cause - Object.setPrototypeOf(this, AccessKeyNotFoundError.prototype) - } -} - -export class AccessKeyMismatchError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'AccessKeyMismatch' - this.code = typeof error.code === 'number' ? error.code : 1102 - this.message = error.message || `Access key mismatch` - this.status = typeof error.status === 'number' ? error.status : 403 - if (error.cause !== undefined) this.cause = error.cause - Object.setPrototypeOf(this, AccessKeyMismatchError.prototype) - } -} - -export class InvalidOriginError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'InvalidOrigin' - this.code = typeof error.code === 'number' ? error.code : 1103 - this.message = error.message || `Invalid origin for Access Key` - this.status = typeof error.status === 'number' ? error.status : 403 - if (error.cause !== undefined) this.cause = error.cause - Object.setPrototypeOf(this, InvalidOriginError.prototype) - } -} - -export class InvalidServiceError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'InvalidService' - this.code = typeof error.code === 'number' ? error.code : 1104 - this.message = error.message || `Service not enabled for Access key` - this.status = typeof error.status === 'number' ? error.status : 403 - if (error.cause !== undefined) this.cause = error.cause - Object.setPrototypeOf(this, InvalidServiceError.prototype) - } -} - -export class UnauthorizedUserError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'UnauthorizedUser' - this.code = typeof error.code === 'number' ? error.code : 1105 - this.message = error.message || `Unauthorized user` - this.status = typeof error.status === 'number' ? error.status : 403 - if (error.cause !== undefined) this.cause = error.cause - Object.setPrototypeOf(this, UnauthorizedUserError.prototype) - } -} - -export class InvalidChainError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'InvalidChain' - this.code = typeof error.code === 'number' ? error.code : 1106 - this.message = error.message || `Network not enabled for Access key` - this.status = typeof error.status === 'number' ? error.status : 403 - if (error.cause !== undefined) this.cause = error.cause - Object.setPrototypeOf(this, InvalidChainError.prototype) - } -} - -export class QuotaExceededError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'QuotaExceeded' - this.code = typeof error.code === 'number' ? error.code : 1200 - this.message = error.message || `Quota request exceeded` - this.status = typeof error.status === 'number' ? error.status : 429 - if (error.cause !== undefined) this.cause = error.cause - Object.setPrototypeOf(this, QuotaExceededError.prototype) - } -} - -export class QuotaRateLimitError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'QuotaRateLimit' - this.code = typeof error.code === 'number' ? error.code : 1201 - this.message = error.message || `Quota rate limit exceeded` - this.status = typeof error.status === 'number' ? error.status : 429 - if (error.cause !== undefined) this.cause = error.cause - Object.setPrototypeOf(this, QuotaRateLimitError.prototype) - } -} - -export class NoDefaultKeyError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'NoDefaultKey' - this.code = typeof error.code === 'number' ? error.code : 1300 - this.message = error.message || `No default access key found` - this.status = typeof error.status === 'number' ? error.status : 403 - if (error.cause !== undefined) this.cause = error.cause - Object.setPrototypeOf(this, NoDefaultKeyError.prototype) - } -} - -export class MaxAccessKeysError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'MaxAccessKeys' - this.code = typeof error.code === 'number' ? error.code : 1301 - this.message = error.message || `Access keys limit reached` - this.status = typeof error.status === 'number' ? error.status : 403 - if (error.cause !== undefined) this.cause = error.cause - Object.setPrototypeOf(this, MaxAccessKeysError.prototype) - } -} - -export class AtLeastOneKeyError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'AtLeastOneKey' - this.code = typeof error.code === 'number' ? error.code : 1302 - this.message = error.message || `You need at least one Access Key` - this.status = typeof error.status === 'number' ? error.status : 403 - if (error.cause !== undefined) this.cause = error.cause - Object.setPrototypeOf(this, AtLeastOneKeyError.prototype) - } -} - -export class TimeoutError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'Timeout' - this.code = typeof error.code === 'number' ? error.code : 1900 - this.message = error.message || `Request timed out` - this.status = typeof error.status === 'number' ? error.status : 408 - if (error.cause !== undefined) this.cause = error.cause - Object.setPrototypeOf(this, TimeoutError.prototype) - } -} - -export class InvalidArgumentError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'InvalidArgument' - this.code = typeof error.code === 'number' ? error.code : 2001 - this.message = error.message || `Invalid argument` - this.status = typeof error.status === 'number' ? error.status : 400 - if (error.cause !== undefined) this.cause = error.cause - Object.setPrototypeOf(this, InvalidArgumentError.prototype) - } -} - -export class UnavailableError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'Unavailable' - this.code = typeof error.code === 'number' ? error.code : 2002 - this.message = error.message || `Unavailable resource` - this.status = typeof error.status === 'number' ? error.status : 400 - if (error.cause !== undefined) this.cause = error.cause - Object.setPrototypeOf(this, UnavailableError.prototype) - } -} - -export class QueryFailedError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'QueryFailed' - this.code = typeof error.code === 'number' ? error.code : 2003 - this.message = error.message || `Query failed` - this.status = typeof error.status === 'number' ? error.status : 400 - if (error.cause !== undefined) this.cause = error.cause - Object.setPrototypeOf(this, QueryFailedError.prototype) - } -} - -export class NotFoundError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'NotFound' - this.code = typeof error.code === 'number' ? error.code : 3000 - this.message = error.message || `Resource not found` - this.status = typeof error.status === 'number' ? error.status : 400 - if (error.cause !== undefined) this.cause = error.cause - Object.setPrototypeOf(this, NotFoundError.prototype) - } -} - -export class InsufficientFeeError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'InsufficientFee' - this.code = typeof error.code === 'number' ? error.code : 3004 - this.message = error.message || `Insufficient fee` - this.status = typeof error.status === 'number' ? error.status : 402 - if (error.cause !== undefined) this.cause = error.cause - Object.setPrototypeOf(this, InsufficientFeeError.prototype) - } -} - -export class NotEnoughBalanceError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'NotEnoughBalance' - this.code = typeof error.code === 'number' ? error.code : 3005 - this.message = error.message || `Not enough balance` - this.status = typeof error.status === 'number' ? error.status : 402 - if (error.cause !== undefined) this.cause = error.cause - Object.setPrototypeOf(this, NotEnoughBalanceError.prototype) - } -} - -export class SimulationFailedError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'SimulationFailed' - this.code = typeof error.code === 'number' ? error.code : 3006 - this.message = error.message || `Simulation failed` - this.status = typeof error.status === 'number' ? error.status : 400 - if (error.cause !== undefined) this.cause = error.cause - Object.setPrototypeOf(this, SimulationFailedError.prototype) - } -} - -export enum errors { - WebrpcEndpoint = 'WebrpcEndpoint', - WebrpcRequestFailed = 'WebrpcRequestFailed', - WebrpcBadRoute = 'WebrpcBadRoute', - WebrpcBadMethod = 'WebrpcBadMethod', - WebrpcBadRequest = 'WebrpcBadRequest', - WebrpcBadResponse = 'WebrpcBadResponse', - WebrpcServerPanic = 'WebrpcServerPanic', - WebrpcInternalError = 'WebrpcInternalError', - WebrpcClientAborted = 'WebrpcClientAborted', - WebrpcStreamLost = 'WebrpcStreamLost', - WebrpcStreamFinished = 'WebrpcStreamFinished', - Unauthorized = 'Unauthorized', - PermissionDenied = 'PermissionDenied', - SessionExpired = 'SessionExpired', - MethodNotFound = 'MethodNotFound', - RequestConflict = 'RequestConflict', - Aborted = 'Aborted', - Geoblocked = 'Geoblocked', - RateLimited = 'RateLimited', - ProjectNotFound = 'ProjectNotFound', - AccessKeyNotFound = 'AccessKeyNotFound', - AccessKeyMismatch = 'AccessKeyMismatch', - InvalidOrigin = 'InvalidOrigin', - InvalidService = 'InvalidService', - UnauthorizedUser = 'UnauthorizedUser', - InvalidChain = 'InvalidChain', - QuotaExceeded = 'QuotaExceeded', - QuotaRateLimit = 'QuotaRateLimit', - NoDefaultKey = 'NoDefaultKey', - MaxAccessKeys = 'MaxAccessKeys', - AtLeastOneKey = 'AtLeastOneKey', - Timeout = 'Timeout', - InvalidArgument = 'InvalidArgument', - Unavailable = 'Unavailable', - QueryFailed = 'QueryFailed', - NotFound = 'NotFound', - InsufficientFee = 'InsufficientFee', - NotEnoughBalance = 'NotEnoughBalance', - SimulationFailed = 'SimulationFailed', -} - -export enum WebrpcErrorCodes { - WebrpcEndpoint = 0, - WebrpcRequestFailed = -1, - WebrpcBadRoute = -2, - WebrpcBadMethod = -3, - WebrpcBadRequest = -4, - WebrpcBadResponse = -5, - WebrpcServerPanic = -6, - WebrpcInternalError = -7, - WebrpcClientAborted = -8, - WebrpcStreamLost = -9, - WebrpcStreamFinished = -10, - Unauthorized = 1000, - PermissionDenied = 1001, - SessionExpired = 1002, - MethodNotFound = 1003, - RequestConflict = 1004, - Aborted = 1005, - Geoblocked = 1006, - RateLimited = 1007, - ProjectNotFound = 1008, - AccessKeyNotFound = 1101, - AccessKeyMismatch = 1102, - InvalidOrigin = 1103, - InvalidService = 1104, - UnauthorizedUser = 1105, - InvalidChain = 1106, - QuotaExceeded = 1200, - QuotaRateLimit = 1201, - NoDefaultKey = 1300, - MaxAccessKeys = 1301, - AtLeastOneKey = 1302, - Timeout = 1900, - InvalidArgument = 2001, - Unavailable = 2002, - QueryFailed = 2003, - NotFound = 3000, - InsufficientFee = 3004, - NotEnoughBalance = 3005, - SimulationFailed = 3006, -} - -export const webrpcErrorByCode: { [code: number]: any } = { - [0]: WebrpcEndpointError, - [-1]: WebrpcRequestFailedError, - [-2]: WebrpcBadRouteError, - [-3]: WebrpcBadMethodError, - [-4]: WebrpcBadRequestError, - [-5]: WebrpcBadResponseError, - [-6]: WebrpcServerPanicError, - [-7]: WebrpcInternalErrorError, - [-8]: WebrpcClientAbortedError, - [-9]: WebrpcStreamLostError, - [-10]: WebrpcStreamFinishedError, - [1000]: UnauthorizedError, - [1001]: PermissionDeniedError, - [1002]: SessionExpiredError, - [1003]: MethodNotFoundError, - [1004]: RequestConflictError, - [1005]: AbortedError, - [1006]: GeoblockedError, - [1007]: RateLimitedError, - [1008]: ProjectNotFoundError, - [1101]: AccessKeyNotFoundError, - [1102]: AccessKeyMismatchError, - [1103]: InvalidOriginError, - [1104]: InvalidServiceError, - [1105]: UnauthorizedUserError, - [1106]: InvalidChainError, - [1200]: QuotaExceededError, - [1201]: QuotaRateLimitError, - [1300]: NoDefaultKeyError, - [1301]: MaxAccessKeysError, - [1302]: AtLeastOneKeyError, - [1900]: TimeoutError, - [2001]: InvalidArgumentError, - [2002]: UnavailableError, - [2003]: QueryFailedError, - [3000]: NotFoundError, - [3004]: InsufficientFeeError, - [3005]: NotEnoughBalanceError, - [3006]: SimulationFailedError, -} - -// -// Webrpc -// - -export const WebrpcHeader = 'Webrpc' - -export const WebrpcHeaderValue = 'webrpc@v0.32.2;gen-typescript@v0.23.1;sequence-relayer@v0.4.1' - -type WebrpcGenVersions = { - WebrpcGenVersion: string - codeGenName: string - codeGenVersion: string - schemaName: string - schemaVersion: string -} - -export function VersionFromHeader(headers: Headers): WebrpcGenVersions { - const headerValue = headers.get(WebrpcHeader) - if (!headerValue) { - return { - WebrpcGenVersion: '', - codeGenName: '', - codeGenVersion: '', - schemaName: '', - schemaVersion: '', - } - } - - return parseWebrpcGenVersions(headerValue) -} - -function parseWebrpcGenVersions(header: string): WebrpcGenVersions { - const versions = header.split(';') - if (versions.length < 3) { - return { - WebrpcGenVersion: '', - codeGenName: '', - codeGenVersion: '', - schemaName: '', - schemaVersion: '', - } - } - - const [_, WebrpcGenVersion] = versions[0]!.split('@') - const [codeGenName, codeGenVersion] = versions[1]!.split('@') - const [schemaName, schemaVersion] = versions[2]!.split('@') - - return { - WebrpcGenVersion: WebrpcGenVersion ?? '', - codeGenName: codeGenName ?? '', - codeGenVersion: codeGenVersion ?? '', - schemaName: schemaName ?? '', - schemaVersion: schemaVersion ?? '', - } -} diff --git a/packages/services/relayer/src/rpc-relayer/index.ts b/packages/services/relayer/src/rpc-relayer/index.ts new file mode 100644 index 0000000000..6e10f600bd --- /dev/null +++ b/packages/services/relayer/src/rpc-relayer/index.ts @@ -0,0 +1 @@ +export * from './relayer.gen.js' diff --git a/packages/services/relayer/src/rpc-relayer/relayer.gen.ts b/packages/services/relayer/src/rpc-relayer/relayer.gen.ts new file mode 100644 index 0000000000..79ca492968 --- /dev/null +++ b/packages/services/relayer/src/rpc-relayer/relayer.gen.ts @@ -0,0 +1,1900 @@ +/* eslint-disable */ +// sequence-relayer v0.4.1 62fe2b49d57c4a0d3960ac1176d48ecfffc7af5a +// -- +// Code generated by webrpc-gen@v0.26.0 with typescript generator. DO NOT EDIT. +// +// webrpc-gen -schema=relayer.ridl -target=typescript -client -out=./clients/relayer.gen.ts + +export const WebrpcHeader = "Webrpc" + +export const WebrpcHeaderValue = "webrpc@v0.26.0;gen-typescript@v0.17.0;sequence-relayer@v0.4.1" + +// WebRPC description and code-gen version +export const WebRPCVersion = "v1" + +// Schema version of your RIDL schema +export const WebRPCSchemaVersion = "v0.4.1" + +// Schema hash generated from your RIDL schema +export const WebRPCSchemaHash = "62fe2b49d57c4a0d3960ac1176d48ecfffc7af5a" + +type WebrpcGenVersions = { + webrpcGenVersion: string; + codeGenName: string; + codeGenVersion: string; + schemaName: string; + schemaVersion: string; +}; + +export function VersionFromHeader(headers: Headers): WebrpcGenVersions { + const headerValue = headers.get(WebrpcHeader); + if (!headerValue) { + return { + webrpcGenVersion: "", + codeGenName: "", + codeGenVersion: "", + schemaName: "", + schemaVersion: "", + }; + } + + return parseWebrpcGenVersions(headerValue); +} + +function parseWebrpcGenVersions(header: string): WebrpcGenVersions { + const versions = header.split(";"); + if (versions.length < 3) { + return { + webrpcGenVersion: "", + codeGenName: "", + codeGenVersion: "", + schemaName: "", + schemaVersion: "", + }; + } + + const [_, webrpcGenVersion] = versions[0]!.split("@"); + const [codeGenName, codeGenVersion] = versions[1]!.split("@"); + const [schemaName, schemaVersion] = versions[2]!.split("@"); + + return { + webrpcGenVersion: webrpcGenVersion ?? "", + codeGenName: codeGenName ?? "", + codeGenVersion: codeGenVersion ?? "", + schemaName: schemaName ?? "", + schemaVersion: schemaVersion ?? "", + }; +} + +// +// Types +// + + +export enum ETHTxnStatus { + UNKNOWN = 'UNKNOWN', + DROPPED = 'DROPPED', + QUEUED = 'QUEUED', + SENT = 'SENT', + SUCCEEDED = 'SUCCEEDED', + PARTIALLY_FAILED = 'PARTIALLY_FAILED', + FAILED = 'FAILED', + PENDING_PRECONDITION = 'PENDING_PRECONDITION' +} + +export enum TransferType { + SEND = 'SEND', + RECEIVE = 'RECEIVE', + BRIDGE_DEPOSIT = 'BRIDGE_DEPOSIT', + BRIDGE_WITHDRAW = 'BRIDGE_WITHDRAW', + BURN = 'BURN', + UNKNOWN = 'UNKNOWN' +} + +export enum SimulateStatus { + SKIPPED = 'SKIPPED', + SUCCEEDED = 'SUCCEEDED', + FAILED = 'FAILED', + ABORTED = 'ABORTED', + REVERTED = 'REVERTED', + NOT_ENOUGH_GAS = 'NOT_ENOUGH_GAS' +} + +export enum FeeTokenType { + UNKNOWN = 'UNKNOWN', + ERC20_TOKEN = 'ERC20_TOKEN', + ERC1155_TOKEN = 'ERC1155_TOKEN' +} + +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 + chainID: number + useEIP1559: boolean + senders: Array + checks: RuntimeChecks +} + +export interface SenderStatus { + index: number + address: string + etherBalance: number + active: boolean +} + +export interface RuntimeChecks { +} + +export interface SequenceContext { + factory: string + mainModule: string + mainModuleUpgradable: string + guestModule: string + utils: string +} + +export interface GasTank { + id: number + chainId: number + name: string + currentBalance: number + unlimited: boolean + feeMarkupFactor: number + updatedAt: string + createdAt: string +} + +export interface GasTankBalanceAdjustment { + gasTankId: number + nonce: number + amount: number + totalBalance: number + balanceTimestamp: string + createdAt: string +} + +export interface GasSponsor { + id: number + gasTankId: number + projectId: number + chainId: number + address: string + name: string + active: boolean + updatedAt: string + createdAt: string + deletedAt: string +} + +export interface GasSponsorUsage { + name: string + id: number + totalGasUsed: number + totalTxnFees: number + totalTxnFeesUsd: number + avgGasPrice: number + totalTxns: number + startTime: string + endTime: string +} + +export interface MetaTxn { + walletAddress: string + contract: string + input: string +} + +export interface MetaTxnLog { + id: number + chainId: number + projectId: number + txnHash: string + txnNonce: string + metaTxnID?: string + txnStatus: ETHTxnStatus + txnRevertReason: string + requeues: number + queuedAt: string + sentAt: string + minedAt: string + target: string + input: string + txnArgs: {[key: string]: any} + txnReceipt?: {[key: string]: any} + walletAddress: string + metaTxnNonce: string + gasLimit: number + gasPrice: string + gasUsed: number + gasEstimated: number + gasFeeMarkup?: number + usdRate: string + creditsUsed: number + cost: string + isWhitelisted: boolean + gasSponsor?: number + gasTank?: number + updatedAt: string + createdAt: string +} + +export interface MetaTxnReceipt { + id: string + status: string + revertReason?: string + index: number + logs: Array + receipts: Array + blockNumber: string + txnHash: string + txnReceipt: string +} + +export interface MetaTxnReceiptLog { + address: string + topics: Array + data: string +} + +export interface IntentPrecondition { + type: string + chainId: string + data: any +} + +export interface IntentSolution { + transactions: Array +} + +export interface Transactions { + chainID: string + transactions: Array + preconditions?: Array +} + +export interface Transaction { + delegateCall: boolean + revertOnError: boolean + gasLimit: string + target: string + value: string + data: string +} + +export interface TxnLogUser { + username: string +} + +export interface TxnLogTransfer { + transferType: TransferType + contractAddress: string + from: string + to: string + ids: Array + amounts: Array +} + +export interface SentTransactionsFilter { + pending?: boolean + failed?: boolean +} + +export interface SimulateResult { + executed: boolean + succeeded: boolean + result?: string + reason?: string + gasUsed: number + gasLimit: number +} + +export interface SimulateV3Result { + status: SimulateStatus + result?: string + error?: string + gasUsed: number + gasLimit: number +} + +export interface FeeOption { + token: FeeToken + to: string + value: string + gasLimit: number +} + +export interface FeeToken { + chainId: number + name: string + symbol: string + type: FeeTokenType + decimals?: number + logoURL: string + contractAddress?: string + tokenID?: string +} + +export interface Page { + pageSize?: number + page?: number + more?: boolean + totalRecords?: number + column?: string + before?: any + after?: any + sort?: Array +} + +export interface SortBy { + column: string + order: SortOrder +} + +export interface Relayer { + ping(headers?: object, signal?: AbortSignal): Promise + version(headers?: object, signal?: AbortSignal): Promise + runtimeStatus(headers?: object, signal?: AbortSignal): Promise + getSequenceContext(headers?: object, signal?: AbortSignal): Promise + getChainID(headers?: object, signal?: AbortSignal): Promise + /** + * + * Transactions + * + * TODO (future): rename this to just, 'SendTransaction(txn: MetaTransaction)' or 'SendTransaction(txn: SignedTransaction)', or something.. + * Project ID is only used by service and admin calls. Other clients must have projectID passed via the context + * TODO: rename return txnHash: string to metaTxnID: string + */ + sendMetaTxn(args: SendMetaTxnArgs, headers?: object, signal?: AbortSignal): Promise + getMetaTxnNonce(args: GetMetaTxnNonceArgs, headers?: object, signal?: AbortSignal): Promise + /** + * TODO: one day, make GetMetaTxnReceipt respond immediately with receipt or not + * and add WaitTransactionReceipt method, which will block and wait, similar to how GetMetaTxnReceipt + * is implemented now. + * For backwards compat, we can leave the current GetMetaTxnReceipt how it is, an deprecate it, and introduce + * new, GetTransactionReceipt and WaitTransactionReceipt methods + * we can also accept metaTxnId and txnHash .. so can take either or.. I wonder if ERC-4337 has any convention on this? + */ + getMetaTxnReceipt(args: GetMetaTxnReceiptArgs, headers?: object, signal?: AbortSignal): Promise + simulate(args: SimulateArgs, headers?: object, signal?: AbortSignal): Promise + simulateV3(args: SimulateV3Args, headers?: object, signal?: AbortSignal): Promise + /** + * TODO: deprecated, to be removed by https://github.com/0xsequence/stack/pull/356 at a later date + */ + updateMetaTxnGasLimits(args: UpdateMetaTxnGasLimitsArgs, headers?: object, signal?: AbortSignal): Promise + feeTokens(headers?: object, signal?: AbortSignal): Promise + feeOptions(args: FeeOptionsArgs, headers?: object, signal?: AbortSignal): Promise + /** + * TODO: deprecated, to be removed by https://github.com/0xsequence/stack/pull/356 at a later date + */ + getMetaTxnNetworkFeeOptions(args: GetMetaTxnNetworkFeeOptionsArgs, headers?: object, signal?: AbortSignal): Promise + getMetaTransactions(args: GetMetaTransactionsArgs, headers?: object, signal?: AbortSignal): Promise + getTransactionCost(args: GetTransactionCostArgs, headers?: object, signal?: AbortSignal): Promise + /** + * Sent transactions from an account. If filter is omitted then it will return all transactions. + */ + sentTransactions(args: SentTransactionsArgs, headers?: object, signal?: AbortSignal): Promise + /** + * Pending transactions waiting to be mined for an account. This endpoint is just a sugar of `SentTransactions` + * with the filter set to pending: true. + */ + pendingTransactions(args: PendingTransactionsArgs, headers?: object, signal?: AbortSignal): Promise + /** + * Legacy Gas Tank + */ + getGasTank(args: GetGasTankArgs, headers?: object, signal?: AbortSignal): Promise + addGasTank(args: AddGasTankArgs, headers?: object, signal?: AbortSignal): Promise + updateGasTank(args: UpdateGasTankArgs, headers?: object, signal?: AbortSignal): Promise + /** + * Legacy Gas Adjustment + */ + nextGasTankBalanceAdjustmentNonce(args: NextGasTankBalanceAdjustmentNonceArgs, headers?: object, signal?: AbortSignal): Promise + adjustGasTankBalance(args: AdjustGasTankBalanceArgs, headers?: object, signal?: AbortSignal): Promise + getGasTankBalanceAdjustment(args: GetGasTankBalanceAdjustmentArgs, headers?: object, signal?: AbortSignal): Promise + listGasTankBalanceAdjustments(args: ListGasTankBalanceAdjustmentsArgs, headers?: object, signal?: AbortSignal): Promise + /** + * Gas Sponsorship + */ + listGasSponsors(args: ListGasSponsorsArgs, headers?: object, signal?: AbortSignal): Promise + getGasSponsor(args: GetGasSponsorArgs, headers?: object, signal?: AbortSignal): Promise + addGasSponsor(args: AddGasSponsorArgs, headers?: object, signal?: AbortSignal): Promise + updateGasSponsor(args: UpdateGasSponsorArgs, headers?: object, signal?: AbortSignal): Promise + removeGasSponsor(args: RemoveGasSponsorArgs, headers?: object, signal?: AbortSignal): Promise + /** + * Gas Sponsor Lookup + */ + addressGasSponsors(args: AddressGasSponsorsArgs, headers?: object, signal?: AbortSignal): Promise + /** + * Project Balance + */ + getProjectBalance(args: GetProjectBalanceArgs, headers?: object, signal?: AbortSignal): Promise + adjustProjectBalance(args: AdjustProjectBalanceArgs, 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 GetSequenceContextArgs { +} + +export interface GetSequenceContextReturn { + data: SequenceContext +} +export interface GetChainIDArgs { +} + +export interface GetChainIDReturn { + chainID: number +} +export interface SendMetaTxnArgs { + call: MetaTxn + quote?: string + projectID?: number + preconditions?: Array +} + +export interface SendMetaTxnReturn { + status: boolean + txnHash: string +} +export interface GetMetaTxnNonceArgs { + walletContractAddress: string + space?: string +} + +export interface GetMetaTxnNonceReturn { + nonce: string +} +export interface GetMetaTxnReceiptArgs { + metaTxID: string +} + +export interface GetMetaTxnReceiptReturn { + receipt: MetaTxnReceipt +} +export interface SimulateArgs { + wallet: string + transactions: string +} + +export interface SimulateReturn { + results: Array +} +export interface SimulateV3Args { + wallet: string + calls: string +} + +export interface SimulateV3Return { + results: Array +} +export interface UpdateMetaTxnGasLimitsArgs { + walletAddress: string + walletConfig: any + payload: string +} + +export interface UpdateMetaTxnGasLimitsReturn { + payload: string +} +export interface FeeTokensArgs { +} + +export interface FeeTokensReturn { + isFeeRequired: boolean + tokens: Array +} +export interface FeeOptionsArgs { + wallet: string + to: string + data: string + simulate?: boolean +} + +export interface FeeOptionsReturn { + options: Array + sponsored: boolean + quote?: string +} +export interface GetMetaTxnNetworkFeeOptionsArgs { + walletConfig: any + payload: string +} + +export interface GetMetaTxnNetworkFeeOptionsReturn { + options: Array +} +export interface GetMetaTransactionsArgs { + projectId: number + page?: Page +} + +export interface GetMetaTransactionsReturn { + page: Page + transactions: Array +} +export interface GetTransactionCostArgs { + projectId: number + from: string + to: string +} + +export interface GetTransactionCostReturn { + cost: number +} +export interface SentTransactionsArgs { + filter?: SentTransactionsFilter + page?: Page +} + +export interface SentTransactionsReturn { + page: Page + transactions: Array +} +export interface PendingTransactionsArgs { + page?: Page +} + +export interface PendingTransactionsReturn { + page: Page + transactions: Array +} +export interface GetGasTankArgs { + id: number +} + +export interface GetGasTankReturn { + gasTank: GasTank +} +export interface AddGasTankArgs { + name: string + feeMarkupFactor: number + unlimited?: boolean +} + +export interface AddGasTankReturn { + status: boolean + gasTank: GasTank +} +export interface UpdateGasTankArgs { + id: number + name?: string + feeMarkupFactor?: number + unlimited?: boolean +} + +export interface UpdateGasTankReturn { + status: boolean + gasTank: GasTank +} +export interface NextGasTankBalanceAdjustmentNonceArgs { + id: number +} + +export interface NextGasTankBalanceAdjustmentNonceReturn { + nonce: number +} +export interface AdjustGasTankBalanceArgs { + id: number + nonce: number + amount: number +} + +export interface AdjustGasTankBalanceReturn { + status: boolean + adjustment: GasTankBalanceAdjustment +} +export interface GetGasTankBalanceAdjustmentArgs { + id: number + nonce: number +} + +export interface GetGasTankBalanceAdjustmentReturn { + adjustment: GasTankBalanceAdjustment +} +export interface ListGasTankBalanceAdjustmentsArgs { + id: number + page?: Page +} + +export interface ListGasTankBalanceAdjustmentsReturn { + page: Page + adjustments: Array +} +export interface ListGasSponsorsArgs { + projectId: number + page?: Page +} + +export interface ListGasSponsorsReturn { + page: Page + gasSponsors: Array +} +export interface GetGasSponsorArgs { + projectId: number + id: number +} + +export interface GetGasSponsorReturn { + gasSponsor: GasSponsor +} +export interface AddGasSponsorArgs { + projectId: number + address: string + name?: string + active?: boolean +} + +export interface AddGasSponsorReturn { + status: boolean + gasSponsor: GasSponsor +} +export interface UpdateGasSponsorArgs { + projectId: number + id: number + name?: string + active?: boolean +} + +export interface UpdateGasSponsorReturn { + status: boolean + gasSponsor: GasSponsor +} +export interface RemoveGasSponsorArgs { + projectId: number + id: number +} + +export interface RemoveGasSponsorReturn { + status: boolean +} +export interface AddressGasSponsorsArgs { + address: string + page?: Page +} + +export interface AddressGasSponsorsReturn { + page: Page + gasSponsors: Array +} +export interface GetProjectBalanceArgs { + projectId: number +} + +export interface GetProjectBalanceReturn { + balance: number +} +export interface AdjustProjectBalanceArgs { + projectId: number + amount: number + identifier: string +} + +export interface AdjustProjectBalanceReturn { + balance: number +} + + + +// +// Client +// +export class Relayer implements Relayer { + protected hostname: string + protected fetch: Fetch + protected path = '/rpc/Relayer/' + + constructor(hostname: string, fetch: Fetch) { + this.hostname = hostname.replace(/\/*$/, '') + 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 || ''}` }) + }) + } + + 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 || ''}` }) + }) + } + + getChainID = (headers?: object, signal?: AbortSignal): Promise => { + return this.fetch( + this.url('GetChainID'), + createHTTPRequest({}, headers, signal) + ).then((res) => { + return buildResponse(res).then(_data => { + return { + chainID: (_data.chainID), + } + }) + }, (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }) + } + + sendMetaTxn = (args: SendMetaTxnArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch( + this.url('SendMetaTxn'), + createHTTPRequest(args, headers, signal)).then((res) => { + return buildResponse(res).then(_data => { + return { + status: (_data.status), + txnHash: (_data.txnHash), + } + }) + }, (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }) + } + + getMetaTxnNonce = (args: GetMetaTxnNonceArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch( + this.url('GetMetaTxnNonce'), + createHTTPRequest(args, headers, signal)).then((res) => { + return buildResponse(res).then(_data => { + return { + nonce: (_data.nonce), + } + }) + }, (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }) + } + + getMetaTxnReceipt = (args: GetMetaTxnReceiptArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch( + this.url('GetMetaTxnReceipt'), + createHTTPRequest(args, headers, signal)).then((res) => { + return buildResponse(res).then(_data => { + return { + receipt: (_data.receipt), + } + }) + }, (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }) + } + + simulate = (args: SimulateArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch( + this.url('Simulate'), + createHTTPRequest(args, headers, signal)).then((res) => { + return buildResponse(res).then(_data => { + return { + results: >(_data.results), + } + }) + }, (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }) + } + + simulateV3 = (args: SimulateV3Args, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch( + this.url('SimulateV3'), + createHTTPRequest(args, headers, signal)).then((res) => { + return buildResponse(res).then(_data => { + return { + results: >(_data.results), + } + }) + }, (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }) + } + + updateMetaTxnGasLimits = (args: UpdateMetaTxnGasLimitsArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch( + this.url('UpdateMetaTxnGasLimits'), + createHTTPRequest(args, headers, signal)).then((res) => { + return buildResponse(res).then(_data => { + return { + payload: (_data.payload), + } + }) + }, (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }) + } + + feeTokens = (headers?: object, signal?: AbortSignal): Promise => { + return this.fetch( + this.url('FeeTokens'), + createHTTPRequest({}, headers, signal) + ).then((res) => { + return buildResponse(res).then(_data => { + return { + isFeeRequired: (_data.isFeeRequired), + tokens: >(_data.tokens), + } + }) + }, (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }) + } + + feeOptions = (args: FeeOptionsArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch( + this.url('FeeOptions'), + createHTTPRequest(args, headers, signal)).then((res) => { + return buildResponse(res).then(_data => { + return { + options: >(_data.options), + sponsored: (_data.sponsored), + quote: (_data.quote), + } + }) + }, (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }) + } + + getMetaTxnNetworkFeeOptions = (args: GetMetaTxnNetworkFeeOptionsArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch( + this.url('GetMetaTxnNetworkFeeOptions'), + createHTTPRequest(args, headers, signal)).then((res) => { + return buildResponse(res).then(_data => { + return { + options: >(_data.options), + } + }) + }, (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }) + } + + getMetaTransactions = (args: GetMetaTransactionsArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch( + this.url('GetMetaTransactions'), + createHTTPRequest(args, headers, signal)).then((res) => { + return buildResponse(res).then(_data => { + return { + page: (_data.page), + transactions: >(_data.transactions), + } + }) + }, (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }) + } + + getTransactionCost = (args: GetTransactionCostArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch( + this.url('GetTransactionCost'), + createHTTPRequest(args, headers, signal)).then((res) => { + return buildResponse(res).then(_data => { + return { + cost: (_data.cost), + } + }) + }, (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }) + } + + sentTransactions = (args: SentTransactionsArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch( + this.url('SentTransactions'), + createHTTPRequest(args, headers, signal)).then((res) => { + return buildResponse(res).then(_data => { + return { + page: (_data.page), + transactions: >(_data.transactions), + } + }) + }, (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }) + } + + pendingTransactions = (args: PendingTransactionsArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch( + this.url('PendingTransactions'), + createHTTPRequest(args, headers, signal)).then((res) => { + return buildResponse(res).then(_data => { + return { + page: (_data.page), + transactions: >(_data.transactions), + } + }) + }, (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }) + } + + getGasTank = (args: GetGasTankArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch( + this.url('GetGasTank'), + createHTTPRequest(args, headers, signal)).then((res) => { + return buildResponse(res).then(_data => { + return { + gasTank: (_data.gasTank), + } + }) + }, (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }) + } + + addGasTank = (args: AddGasTankArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch( + this.url('AddGasTank'), + createHTTPRequest(args, headers, signal)).then((res) => { + return buildResponse(res).then(_data => { + return { + status: (_data.status), + gasTank: (_data.gasTank), + } + }) + }, (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }) + } + + updateGasTank = (args: UpdateGasTankArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch( + this.url('UpdateGasTank'), + createHTTPRequest(args, headers, signal)).then((res) => { + return buildResponse(res).then(_data => { + return { + status: (_data.status), + gasTank: (_data.gasTank), + } + }) + }, (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }) + } + + nextGasTankBalanceAdjustmentNonce = (args: NextGasTankBalanceAdjustmentNonceArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch( + this.url('NextGasTankBalanceAdjustmentNonce'), + createHTTPRequest(args, headers, signal)).then((res) => { + return buildResponse(res).then(_data => { + return { + nonce: (_data.nonce), + } + }) + }, (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }) + } + + adjustGasTankBalance = (args: AdjustGasTankBalanceArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch( + this.url('AdjustGasTankBalance'), + createHTTPRequest(args, headers, signal)).then((res) => { + return buildResponse(res).then(_data => { + return { + status: (_data.status), + adjustment: (_data.adjustment), + } + }) + }, (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }) + } + + getGasTankBalanceAdjustment = (args: GetGasTankBalanceAdjustmentArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch( + this.url('GetGasTankBalanceAdjustment'), + createHTTPRequest(args, headers, signal)).then((res) => { + return buildResponse(res).then(_data => { + return { + adjustment: (_data.adjustment), + } + }) + }, (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }) + } + + listGasTankBalanceAdjustments = (args: ListGasTankBalanceAdjustmentsArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch( + this.url('ListGasTankBalanceAdjustments'), + createHTTPRequest(args, headers, signal)).then((res) => { + return buildResponse(res).then(_data => { + return { + page: (_data.page), + adjustments: >(_data.adjustments), + } + }) + }, (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }) + } + + listGasSponsors = (args: ListGasSponsorsArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch( + this.url('ListGasSponsors'), + createHTTPRequest(args, headers, signal)).then((res) => { + return buildResponse(res).then(_data => { + return { + page: (_data.page), + gasSponsors: >(_data.gasSponsors), + } + }) + }, (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }) + } + + getGasSponsor = (args: GetGasSponsorArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch( + this.url('GetGasSponsor'), + createHTTPRequest(args, headers, signal)).then((res) => { + return buildResponse(res).then(_data => { + return { + gasSponsor: (_data.gasSponsor), + } + }) + }, (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }) + } + + addGasSponsor = (args: AddGasSponsorArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch( + this.url('AddGasSponsor'), + createHTTPRequest(args, headers, signal)).then((res) => { + return buildResponse(res).then(_data => { + return { + status: (_data.status), + gasSponsor: (_data.gasSponsor), + } + }) + }, (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }) + } + + updateGasSponsor = (args: UpdateGasSponsorArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch( + this.url('UpdateGasSponsor'), + createHTTPRequest(args, headers, signal)).then((res) => { + return buildResponse(res).then(_data => { + return { + status: (_data.status), + gasSponsor: (_data.gasSponsor), + } + }) + }, (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }) + } + + removeGasSponsor = (args: RemoveGasSponsorArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch( + this.url('RemoveGasSponsor'), + createHTTPRequest(args, headers, signal)).then((res) => { + return buildResponse(res).then(_data => { + return { + status: (_data.status), + } + }) + }, (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }) + } + + addressGasSponsors = (args: AddressGasSponsorsArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch( + this.url('AddressGasSponsors'), + createHTTPRequest(args, headers, signal)).then((res) => { + return buildResponse(res).then(_data => { + return { + page: (_data.page), + gasSponsors: >(_data.gasSponsors), + } + }) + }, (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }) + } + + getProjectBalance = (args: GetProjectBalanceArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch( + this.url('GetProjectBalance'), + createHTTPRequest(args, headers, signal)).then((res) => { + return buildResponse(res).then(_data => { + return { + balance: (_data.balance), + } + }) + }, (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }) + } + + adjustProjectBalance = (args: AdjustProjectBalanceArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch( + this.url('AdjustProjectBalance'), + createHTTPRequest(args, headers, signal)).then((res) => { + return buildResponse(res).then(_data => { + return { + balance: (_data.balance), + } + }) + }, (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }) + } + +} + + const createHTTPRequest = (body: object = {}, headers: object = {}, signal: AbortSignal | null = null): object => { + const reqHeaders: {[key: string]: string} = { ...headers, 'Content-Type': 'application/json' } + reqHeaders[WebrpcHeader] = WebrpcHeaderValue + + return { + method: 'POST', + headers: reqHeaders, + 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 MethodNotFoundError extends WebrpcError { + constructor( + name: string = 'MethodNotFound', + code: number = 1003, + message: string = `Method not found`, + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, MethodNotFoundError.prototype) + } +} + +export class RequestConflictError extends WebrpcError { + constructor( + name: string = 'RequestConflict', + code: number = 1004, + message: string = `Conflict with target resource`, + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, RequestConflictError.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 GeoblockedError extends WebrpcError { + constructor( + name: string = 'Geoblocked', + code: number = 1006, + message: string = `Geoblocked region`, + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, GeoblockedError.prototype) + } +} + +export class RateLimitedError extends WebrpcError { + constructor( + name: string = 'RateLimited', + code: number = 1007, + message: string = `Rate-limited. Please slow down.`, + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, RateLimitedError.prototype) + } +} + +export class ProjectNotFoundError extends WebrpcError { + constructor( + name: string = 'ProjectNotFound', + code: number = 1008, + message: string = `Project not found`, + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, ProjectNotFoundError.prototype) + } +} + +export class AccessKeyNotFoundError extends WebrpcError { + constructor( + name: string = 'AccessKeyNotFound', + code: number = 1101, + message: string = `Access key not found`, + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, AccessKeyNotFoundError.prototype) + } +} + +export class AccessKeyMismatchError extends WebrpcError { + constructor( + name: string = 'AccessKeyMismatch', + code: number = 1102, + message: string = `Access key mismatch`, + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, AccessKeyMismatchError.prototype) + } +} + +export class InvalidOriginError extends WebrpcError { + constructor( + name: string = 'InvalidOrigin', + code: number = 1103, + message: string = `Invalid origin for Access Key`, + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, InvalidOriginError.prototype) + } +} + +export class InvalidServiceError extends WebrpcError { + constructor( + name: string = 'InvalidService', + code: number = 1104, + message: string = `Service not enabled for Access key`, + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, InvalidServiceError.prototype) + } +} + +export class UnauthorizedUserError extends WebrpcError { + constructor( + name: string = 'UnauthorizedUser', + code: number = 1105, + message: string = `Unauthorized user`, + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, UnauthorizedUserError.prototype) + } +} + +export class QuotaExceededError extends WebrpcError { + constructor( + name: string = 'QuotaExceeded', + code: number = 1200, + message: string = `Quota request exceeded`, + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, QuotaExceededError.prototype) + } +} + +export class QuotaRateLimitError extends WebrpcError { + constructor( + name: string = 'QuotaRateLimit', + code: number = 1201, + message: string = `Quota rate limit exceeded`, + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, QuotaRateLimitError.prototype) + } +} + +export class NoDefaultKeyError extends WebrpcError { + constructor( + name: string = 'NoDefaultKey', + code: number = 1300, + message: string = `No default access key found`, + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, NoDefaultKeyError.prototype) + } +} + +export class MaxAccessKeysError extends WebrpcError { + constructor( + name: string = 'MaxAccessKeys', + code: number = 1301, + message: string = `Access keys limit reached`, + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, MaxAccessKeysError.prototype) + } +} + +export class AtLeastOneKeyError extends WebrpcError { + constructor( + name: string = 'AtLeastOneKey', + code: number = 1302, + message: string = `You need at least one Access Key`, + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, AtLeastOneKeyError.prototype) + } +} + +export class TimeoutError extends WebrpcError { + constructor( + name: string = 'Timeout', + code: number = 1900, + message: string = `Request timed out`, + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, TimeoutError.prototype) + } +} + +export class InvalidArgumentError extends WebrpcError { + constructor( + name: string = 'InvalidArgument', + code: number = 2001, + 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 class InsufficientFeeError extends WebrpcError { + constructor( + name: string = 'InsufficientFee', + code: number = 3004, + message: string = `Insufficient fee`, + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, InsufficientFeeError.prototype) + } +} + +export class NotEnoughBalanceError extends WebrpcError { + constructor( + name: string = 'NotEnoughBalance', + code: number = 3005, + message: string = `Not enough balance`, + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, NotEnoughBalanceError.prototype) + } +} + +export class SimulationFailedError extends WebrpcError { + constructor( + name: string = 'SimulationFailed', + code: number = 3006, + message: string = `Simulation failed`, + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, SimulationFailedError.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', + MethodNotFound = 'MethodNotFound', + RequestConflict = 'RequestConflict', + Aborted = 'Aborted', + Geoblocked = 'Geoblocked', + RateLimited = 'RateLimited', + ProjectNotFound = 'ProjectNotFound', + AccessKeyNotFound = 'AccessKeyNotFound', + AccessKeyMismatch = 'AccessKeyMismatch', + InvalidOrigin = 'InvalidOrigin', + InvalidService = 'InvalidService', + UnauthorizedUser = 'UnauthorizedUser', + QuotaExceeded = 'QuotaExceeded', + QuotaRateLimit = 'QuotaRateLimit', + NoDefaultKey = 'NoDefaultKey', + MaxAccessKeys = 'MaxAccessKeys', + AtLeastOneKey = 'AtLeastOneKey', + Timeout = 'Timeout', + InvalidArgument = 'InvalidArgument', + Unavailable = 'Unavailable', + QueryFailed = 'QueryFailed', + NotFound = 'NotFound', + InsufficientFee = 'InsufficientFee', + NotEnoughBalance = 'NotEnoughBalance', + SimulationFailed = 'SimulationFailed', +} + +export enum WebrpcErrorCodes { + WebrpcEndpoint = 0, + WebrpcRequestFailed = -1, + WebrpcBadRoute = -2, + WebrpcBadMethod = -3, + WebrpcBadRequest = -4, + WebrpcBadResponse = -5, + WebrpcServerPanic = -6, + WebrpcInternalError = -7, + WebrpcClientDisconnected = -8, + WebrpcStreamLost = -9, + WebrpcStreamFinished = -10, + Unauthorized = 1000, + PermissionDenied = 1001, + SessionExpired = 1002, + MethodNotFound = 1003, + RequestConflict = 1004, + Aborted = 1005, + Geoblocked = 1006, + RateLimited = 1007, + ProjectNotFound = 1008, + AccessKeyNotFound = 1101, + AccessKeyMismatch = 1102, + InvalidOrigin = 1103, + InvalidService = 1104, + UnauthorizedUser = 1105, + QuotaExceeded = 1200, + QuotaRateLimit = 1201, + NoDefaultKey = 1300, + MaxAccessKeys = 1301, + AtLeastOneKey = 1302, + Timeout = 1900, + InvalidArgument = 2001, + Unavailable = 2002, + QueryFailed = 2003, + NotFound = 3000, + InsufficientFee = 3004, + NotEnoughBalance = 3005, + SimulationFailed = 3006, +} + +export 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, + [1003]: MethodNotFoundError, + [1004]: RequestConflictError, + [1005]: AbortedError, + [1006]: GeoblockedError, + [1007]: RateLimitedError, + [1008]: ProjectNotFoundError, + [1101]: AccessKeyNotFoundError, + [1102]: AccessKeyMismatchError, + [1103]: InvalidOriginError, + [1104]: InvalidServiceError, + [1105]: UnauthorizedUserError, + [1200]: QuotaExceededError, + [1201]: QuotaRateLimitError, + [1300]: NoDefaultKeyError, + [1301]: MaxAccessKeysError, + [1302]: AtLeastOneKeyError, + [1900]: TimeoutError, + [2001]: InvalidArgumentError, + [2002]: UnavailableError, + [2003]: QueryFailedError, + [3000]: NotFoundError, + [3004]: InsufficientFeeError, + [3005]: NotEnoughBalanceError, + [3006]: SimulationFailedError, +} + +export type Fetch = (input: RequestInfo, init?: RequestInit) => Promise + diff --git a/packages/services/userdata/CHANGELOG.md b/packages/services/userdata/CHANGELOG.md deleted file mode 100644 index 51ebad4131..0000000000 --- a/packages/services/userdata/CHANGELOG.md +++ /dev/null @@ -1,142 +0,0 @@ -# @0xsequence/userdata - -## 3.0.5 - -### Patch Changes - -- Account federation support - -## 3.0.4 - -### Patch Changes - -- id-token login support - -## 3.0.3 - -### Patch Changes - -- 3.0.3 - -## 3.0.2 - -### Patch Changes - -- allow native self transfer - -## 3.0.1 - -### Patch Changes - -- Network and session fixes - -## 3.0.0 - -### Patch Changes - -- f68be62: ethauth support -- 49d8a2f: New chains, minor fixes -- 3411232: Beta release with dapp connector fixes -- 23cb9e9: New chains, relayer rpc fix -- f5f6a7a: dapp-client updates -- e7de3b1: Fix signer 404 error, minor fixes -- 493836f: multicall3 optimization -- 30e1f1a: 3.0.0 beta -- d5017e8: Beta release for v3 -- 24a5fab: Final RC before 3.0.0 -- e5e1a03: Apple auth fixes -- 0b63113: Apple auth fix -- a89134a: Userdata service updates -- 3.0.0 release -- 747e6b5: Relayer fee options fix -- 40c19ff: dapp client updates for EOA login - -## 3.0.0-beta.19 - -### Patch Changes - -- Final RC before 3.0.0 - -## 3.0.0-beta.18 - -### Patch Changes - -- multicall3 optimization - -## 3.0.0-beta.17 - -### Patch Changes - -- New chains, relayer rpc fix - -## 3.0.0-beta.16 - -### Patch Changes - -- ethauth support - -## 3.0.0-beta.15 - -### Patch Changes - -- New chains, minor fixes - -## 3.0.0-beta.14 - -### Patch Changes - -- Relayer fee options fix - -## 3.0.0-beta.13 - -### Patch Changes - -- Userdata service updates - -## 3.0.0-beta.12 - -### Patch Changes - -- Beta release with dapp connector fixes - -## 3.0.0-beta.11 - -### Patch Changes - -- 3.0.0 beta - -## 3.0.0-beta.10 - -### Patch Changes - -- dapp-client updates - -## 3.0.0-beta.9 - -### Patch Changes - -- dapp client updates for EOA login - -## 3.0.0-beta.8 - -### Patch Changes - -- Apple auth fixes - -## 3.0.0-beta.7 - -### Patch Changes - -- Apple auth fix - -## 3.0.0-beta.6 - -### Patch Changes - -- Fix signer 404 error, minor fixes - -## 3.0.0-beta.5 - -### Patch Changes - -- Beta release for v3 diff --git a/packages/services/userdata/README.md b/packages/services/userdata/README.md deleted file mode 100644 index 2387b56e2e..0000000000 --- a/packages/services/userdata/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# @0xsequence/userdata - -See [0xsequence project page](https://github.com/0xsequence/sequence.js). diff --git a/packages/services/userdata/package.json b/packages/services/userdata/package.json deleted file mode 100644 index 38f3c9d5a8..0000000000 --- a/packages/services/userdata/package.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "name": "@0xsequence/userdata", - "version": "3.0.5", - "description": "userdata sub-package for Sequence", - "repository": "https://github.com/0xsequence/sequence.js/tree/master/packages/services/userdata", - "author": "Sequence Platforms ULC", - "license": "Apache-2.0", - "publishConfig": { - "access": "public" - }, - "type": "module", - "scripts": { - "build": "tsc", - "dev": "tsc --watch", - "test": "echo", - "typecheck": "tsc --noEmit", - "lint": "eslint . --max-warnings 0" - }, - "exports": { - ".": { - "types": "./dist/index.d.ts", - "default": "./dist/index.js" - } - }, - "devDependencies": { - "@repo/eslint-config": "workspace:^", - "@repo/typescript-config": "workspace:^", - "@types/node": "^25.3.0", - "typescript": "^5.9.3" - } -} diff --git a/packages/services/userdata/src/index.ts b/packages/services/userdata/src/index.ts deleted file mode 100644 index 63b8559678..0000000000 --- a/packages/services/userdata/src/index.ts +++ /dev/null @@ -1,36 +0,0 @@ -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/services/userdata/src/userdata.gen.ts b/packages/services/userdata/src/userdata.gen.ts deleted file mode 100644 index d671010bed..0000000000 --- a/packages/services/userdata/src/userdata.gen.ts +++ /dev/null @@ -1,1729 +0,0 @@ -/* eslint-disable */ -// userdata v0.1.0 88764bb5f99353e11d849a1aa8f8a998501ffedb -// -- -// Code generated by Webrpc-gen@v0.30.2 with typescript generator. DO NOT EDIT. -// -// webrpc-gen -schema=userdata.ridl -target=typescript -client -out=./clients/userdata.gen.ts - -// Webrpc description and code-gen version -export const WebrpcVersion = 'v1' - -// Schema version of your RIDL schema -export const WebrpcSchemaVersion = 'v0.1.0' - -// Schema hash generated from your RIDL schema -export const WebrpcSchemaHash = '88764bb5f99353e11d849a1aa8f8a998501ffedb' - -// -// Client interface -// - -export interface UserDataClient { - getCapabilities(headers?: object, signal?: AbortSignal): Promise - - getAccessToken(req: GetAccessTokenRequest, headers?: object, signal?: AbortSignal): Promise - - getIdentityToken( - req: GetIdentityTokenRequest, - headers?: object, - signal?: AbortSignal, - ): Promise - - getWalletPreferences( - req: GetWalletPreferencesRequest, - headers?: object, - signal?: AbortSignal, - ): Promise - - putWalletPreferences( - req: PutWalletPreferencesRequest, - headers?: object, - signal?: AbortSignal, - ): Promise - - listWalletSigners( - req: ListWalletSignersRequest, - headers?: object, - signal?: AbortSignal, - ): Promise - - putWalletSigner(req: PutWalletSignerRequest, headers?: object, signal?: AbortSignal): Promise - - deleteWalletSigner( - req: DeleteWalletSignerRequest, - headers?: object, - signal?: AbortSignal, - ): Promise - - listSessions(req: ListSessionsRequest, headers?: object, signal?: AbortSignal): Promise - - putSession(req: PutSessionRequest, headers?: object, signal?: AbortSignal): Promise - - deleteSession(req: DeleteSessionRequest, headers?: object, signal?: AbortSignal): Promise - - listContacts(req: ListContactsRequest, headers?: object, signal?: AbortSignal): Promise - - putContact(req: PutContactRequest, headers?: object, signal?: AbortSignal): Promise - - deleteContact(req: DeleteContactRequest, headers?: object, signal?: AbortSignal): Promise - - listWatchedWallets( - req: ListWatchedWalletsRequest, - headers?: object, - signal?: AbortSignal, - ): Promise - - putWatchedWallet( - req: PutWatchedWalletRequest, - headers?: object, - signal?: AbortSignal, - ): Promise - - deleteWatchedWallet( - req: DeleteWatchedWalletRequest, - headers?: object, - signal?: AbortSignal, - ): Promise - - listDiscoverFavorites( - req: ListDiscoverFavoritesRequest, - headers?: object, - signal?: AbortSignal, - ): Promise - - putDiscoverFavorite( - req: PutDiscoverFavoriteRequest, - headers?: object, - signal?: AbortSignal, - ): Promise - - deleteDiscoverFavorite( - req: DeleteDiscoverFavoriteRequest, - headers?: object, - signal?: AbortSignal, - ): Promise - - listDiscoverHistory( - req: ListDiscoverHistoryRequest, - headers?: object, - signal?: AbortSignal, - ): Promise - - putDiscoverHistory( - req: PutDiscoverHistoryRequest, - headers?: object, - signal?: AbortSignal, - ): Promise - - deleteDiscoverHistory( - req: DeleteDiscoverHistoryRequest, - headers?: object, - signal?: AbortSignal, - ): Promise - - listTokenFavorites( - req: ListTokenFavoritesRequest, - headers?: object, - signal?: AbortSignal, - ): Promise - - putTokenFavorite( - req: PutTokenFavoriteRequest, - headers?: object, - signal?: AbortSignal, - ): Promise - - deleteTokenFavorite( - req: DeleteTokenFavoriteRequest, - headers?: object, - signal?: AbortSignal, - ): Promise - - listHiddenTokens( - req: ListHiddenTokensRequest, - headers?: object, - signal?: AbortSignal, - ): Promise - - putHiddenToken(req: PutHiddenTokenRequest, headers?: object, signal?: AbortSignal): Promise - - deleteHiddenToken( - req: DeleteHiddenTokenRequest, - headers?: object, - signal?: AbortSignal, - ): Promise -} - -// -// Schema types -// - -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 -} - -export interface Wallet { - address: string - ecosystem?: number - preferences: WalletPreferences - updatedAt: string - createdAt: string -} - -export interface WalletPreferences { - manualSigning?: boolean - hideUnlistedTokens?: boolean - hideCollectibles?: boolean - includeTestnets?: boolean - currency?: string -} - -export interface WalletSigner { - walletAddress: string - signerAddress: string - kind: string - email?: string - updatedAt: string - createdAt: string -} - -export interface Session { - walletAddress: string - sessionAddress: string - ipAddress: string - userAgent: string - originUrl: string - appUrl: string - createdAt: string -} - -export interface Contact { - walletAddress: string - contactAddress: string - nickname: string - updatedAt: string - createdAt: string -} - -export interface WatchedWallet { - walletAddress: string - watchedAddress: string - nickname: string - updatedAt: string - createdAt: string -} - -export interface DiscoverFavorite { - walletAddress: string - id: number - dappId: string - createdAt: string -} - -export interface DiscoverHistory { - walletAddress: string - id: number - dappId: string - accessedAt: string -} - -export interface TokenFavorite { - walletAddress: string - id: number - chainId: string - contractAddress: string - tokenId: string - createdAt: string -} - -export interface HiddenToken { - walletAddress: string - id: number - chainId: string - contractAddress: string - tokenId?: string - createdAt: string -} - -export interface SessionProps { - address: string - appUrl: string -} - -export interface WalletSignerProps { - address: string - kind: string - email?: string -} - -export interface ContactProps { - address: string - nickname?: string -} - -export interface DiscoverProps { - dappId: string -} - -export interface TokenFavoriteProps { - chainId: string - contractAddress: string - tokenId: string -} - -export interface HiddenTokenProps { - chainId: string - contractAddress: string - tokenId?: string -} - -export interface WatchedWalletProps { - watchedAddress: string - nickname?: string -} - -export interface GetCapabilitiesRequest {} - -export interface GetCapabilitiesResponse { - supportedMethods: Array -} - -export interface GetAccessTokenRequest { - ethauthProof: string - chainId: string -} - -export interface GetAccessTokenResponse { - accessToken: string - refreshToken: string - expiresIn: number -} - -export interface GetIdentityTokenRequest { - claims: { [key: string]: any } -} - -export interface GetIdentityTokenResponse { - idToken: string -} - -export interface GetWalletPreferencesRequest { - wallet: string -} - -export interface GetWalletPreferencesResponse { - preferences: WalletPreferences -} - -export interface PutWalletPreferencesRequest { - wallet: string - preferences: WalletPreferences -} - -export interface PutWalletPreferencesResponse {} - -export interface ListWalletSignersRequest { - wallet: string - pageSize: number - cursor: string -} - -export interface ListWalletSignersResponse { - signers: Array - nextCursor: string -} - -export interface PutWalletSignerRequest { - wallet: string - signer: WalletSignerProps -} - -export interface PutWalletSignerResponse { - signer: WalletSigner -} - -export interface DeleteWalletSignerRequest { - wallet: string - signer: string -} - -export interface DeleteWalletSignerResponse {} - -export interface ListSessionsRequest { - wallet: string - pageSize: number - cursor: string -} - -export interface ListSessionsResponse { - sessions: Array - nextCursor: string -} - -export interface PutSessionRequest { - wallet: string - session: SessionProps -} - -export interface PutSessionResponse { - session: Session -} - -export interface DeleteSessionRequest { - wallet: string - session: string -} - -export interface DeleteSessionResponse {} - -export interface ListContactsRequest { - wallet: string - pageSize: number - cursor: string -} - -export interface ListContactsResponse { - contacts: Array - nextCursor: string -} - -export interface PutContactRequest { - wallet: string - contact: ContactProps -} - -export interface PutContactResponse { - contact: Contact -} - -export interface DeleteContactRequest { - wallet: string - contact: string -} - -export interface DeleteContactResponse {} - -export interface ListWatchedWalletsRequest { - wallet: string - pageSize: number - cursor: string -} - -export interface ListWatchedWalletsResponse { - watchedWallets: Array - nextCursor: string -} - -export interface PutWatchedWalletRequest { - wallet: string - watchedWallet: WatchedWalletProps -} - -export interface PutWatchedWalletResponse { - watchedWallet: WatchedWallet -} - -export interface DeleteWatchedWalletRequest { - wallet: string - watchedWallet: string -} - -export interface DeleteWatchedWalletResponse {} - -export interface ListDiscoverFavoritesRequest { - wallet: string - pageSize: number - cursor: string -} - -export interface ListDiscoverFavoritesResponse { - favorites: Array - nextCursor: string -} - -export interface PutDiscoverFavoriteRequest { - wallet: string - favorite: DiscoverProps -} - -export interface PutDiscoverFavoriteResponse { - favorite: DiscoverFavorite -} - -export interface DeleteDiscoverFavoriteRequest { - wallet: string - id: number -} - -export interface DeleteDiscoverFavoriteResponse {} - -export interface ListDiscoverHistoryRequest { - wallet: string - pageSize: number - cursor: string -} - -export interface ListDiscoverHistoryResponse { - history: Array - nextCursor: string -} - -export interface PutDiscoverHistoryRequest { - wallet: string - history: DiscoverProps -} - -export interface PutDiscoverHistoryResponse { - history: DiscoverHistory -} - -export interface DeleteDiscoverHistoryRequest { - wallet: string - id: number -} - -export interface DeleteDiscoverHistoryResponse {} - -export interface ListTokenFavoritesRequest { - wallet: string - pageSize: number - cursor: string -} - -export interface ListTokenFavoritesResponse { - favorites: Array - nextCursor: string -} - -export interface PutTokenFavoriteRequest { - wallet: string - favorite: TokenFavoriteProps -} - -export interface PutTokenFavoriteResponse { - favorite: TokenFavorite -} - -export interface DeleteTokenFavoriteRequest { - wallet: string - id: number -} - -export interface DeleteTokenFavoriteResponse {} - -export interface ListHiddenTokensRequest { - wallet: string - pageSize: number - cursor: string -} - -export interface ListHiddenTokensResponse { - hiddenTokens: Array - nextCursor: string -} - -export interface PutHiddenTokenRequest { - wallet: string - token: HiddenTokenProps -} - -export interface PutHiddenTokenResponse { - hiddenToken: HiddenToken -} - -export interface DeleteHiddenTokenRequest { - wallet: string - id: number -} - -export interface DeleteHiddenTokenResponse {} - -// -// Client -// - -export class UserData implements UserDataClient { - protected hostname: string - protected fetch: Fetch - protected path = '/rpc/UserData/' - - constructor(hostname: string, fetch: Fetch) { - this.hostname = hostname.replace(/\/*$/, '') - this.fetch = (input: RequestInfo, init?: RequestInit) => fetch(input, init) - } - - private url(name: string): string { - return this.hostname + this.path + name - } - - queryKey = { - getCapabilities: () => ['UserData', 'getCapabilities'] as const, - getAccessToken: (req: GetAccessTokenRequest) => ['UserData', 'getAccessToken', req] as const, - getIdentityToken: (req: GetIdentityTokenRequest) => ['UserData', 'getIdentityToken', req] as const, - getWalletPreferences: (req: GetWalletPreferencesRequest) => ['UserData', 'getWalletPreferences', req] as const, - putWalletPreferences: (req: PutWalletPreferencesRequest) => ['UserData', 'putWalletPreferences', req] as const, - listWalletSigners: (req: ListWalletSignersRequest) => ['UserData', 'listWalletSigners', req] as const, - putWalletSigner: (req: PutWalletSignerRequest) => ['UserData', 'putWalletSigner', req] as const, - deleteWalletSigner: (req: DeleteWalletSignerRequest) => ['UserData', 'deleteWalletSigner', req] as const, - listSessions: (req: ListSessionsRequest) => ['UserData', 'listSessions', req] as const, - putSession: (req: PutSessionRequest) => ['UserData', 'putSession', req] as const, - deleteSession: (req: DeleteSessionRequest) => ['UserData', 'deleteSession', req] as const, - listContacts: (req: ListContactsRequest) => ['UserData', 'listContacts', req] as const, - putContact: (req: PutContactRequest) => ['UserData', 'putContact', req] as const, - deleteContact: (req: DeleteContactRequest) => ['UserData', 'deleteContact', req] as const, - listWatchedWallets: (req: ListWatchedWalletsRequest) => ['UserData', 'listWatchedWallets', req] as const, - putWatchedWallet: (req: PutWatchedWalletRequest) => ['UserData', 'putWatchedWallet', req] as const, - deleteWatchedWallet: (req: DeleteWatchedWalletRequest) => ['UserData', 'deleteWatchedWallet', req] as const, - listDiscoverFavorites: (req: ListDiscoverFavoritesRequest) => ['UserData', 'listDiscoverFavorites', req] as const, - putDiscoverFavorite: (req: PutDiscoverFavoriteRequest) => ['UserData', 'putDiscoverFavorite', req] as const, - deleteDiscoverFavorite: (req: DeleteDiscoverFavoriteRequest) => - ['UserData', 'deleteDiscoverFavorite', req] as const, - listDiscoverHistory: (req: ListDiscoverHistoryRequest) => ['UserData', 'listDiscoverHistory', req] as const, - putDiscoverHistory: (req: PutDiscoverHistoryRequest) => ['UserData', 'putDiscoverHistory', req] as const, - deleteDiscoverHistory: (req: DeleteDiscoverHistoryRequest) => ['UserData', 'deleteDiscoverHistory', req] as const, - listTokenFavorites: (req: ListTokenFavoritesRequest) => ['UserData', 'listTokenFavorites', req] as const, - putTokenFavorite: (req: PutTokenFavoriteRequest) => ['UserData', 'putTokenFavorite', req] as const, - deleteTokenFavorite: (req: DeleteTokenFavoriteRequest) => ['UserData', 'deleteTokenFavorite', req] as const, - listHiddenTokens: (req: ListHiddenTokensRequest) => ['UserData', 'listHiddenTokens', req] as const, - putHiddenToken: (req: PutHiddenTokenRequest) => ['UserData', 'putHiddenToken', req] as const, - deleteHiddenToken: (req: DeleteHiddenTokenRequest) => ['UserData', 'deleteHiddenToken', req] as const, - } - - getCapabilities = (headers?: object, signal?: AbortSignal): Promise => { - return this.fetch(this.url('GetCapabilities'), createHttpRequest('{}', headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'GetCapabilitiesResponse') - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - getAccessToken = ( - req: GetAccessTokenRequest, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch( - this.url('GetAccessToken'), - createHttpRequest(JsonEncode(req, 'GetAccessTokenRequest'), headers, signal), - ).then( - (res) => { - return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'GetAccessTokenResponse') - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - getIdentityToken = ( - req: GetIdentityTokenRequest, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch( - this.url('GetIdentityToken'), - createHttpRequest(JsonEncode(req, 'GetIdentityTokenRequest'), headers, signal), - ).then( - (res) => { - return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'GetIdentityTokenResponse') - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - getWalletPreferences = ( - req: GetWalletPreferencesRequest, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch( - this.url('GetWalletPreferences'), - createHttpRequest(JsonEncode(req, 'GetWalletPreferencesRequest'), headers, signal), - ).then( - (res) => { - return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'GetWalletPreferencesResponse') - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - putWalletPreferences = ( - req: PutWalletPreferencesRequest, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch( - this.url('PutWalletPreferences'), - createHttpRequest(JsonEncode(req, 'PutWalletPreferencesRequest'), headers, signal), - ).then( - (res) => { - return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'PutWalletPreferencesResponse') - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - listWalletSigners = ( - req: ListWalletSignersRequest, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch( - this.url('ListWalletSigners'), - createHttpRequest(JsonEncode(req, 'ListWalletSignersRequest'), headers, signal), - ).then( - (res) => { - return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'ListWalletSignersResponse') - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - putWalletSigner = ( - req: PutWalletSignerRequest, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch( - this.url('PutWalletSigner'), - createHttpRequest(JsonEncode(req, 'PutWalletSignerRequest'), headers, signal), - ).then( - (res) => { - return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'PutWalletSignerResponse') - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - deleteWalletSigner = ( - req: DeleteWalletSignerRequest, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch( - this.url('DeleteWalletSigner'), - createHttpRequest(JsonEncode(req, 'DeleteWalletSignerRequest'), headers, signal), - ).then( - (res) => { - return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'DeleteWalletSignerResponse') - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - listSessions = (req: ListSessionsRequest, headers?: object, signal?: AbortSignal): Promise => { - return this.fetch( - this.url('ListSessions'), - createHttpRequest(JsonEncode(req, 'ListSessionsRequest'), headers, signal), - ).then( - (res) => { - return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'ListSessionsResponse') - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - putSession = (req: PutSessionRequest, headers?: object, signal?: AbortSignal): Promise => { - return this.fetch( - this.url('PutSession'), - createHttpRequest(JsonEncode(req, 'PutSessionRequest'), headers, signal), - ).then( - (res) => { - return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'PutSessionResponse') - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - deleteSession = ( - req: DeleteSessionRequest, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch( - this.url('DeleteSession'), - createHttpRequest(JsonEncode(req, 'DeleteSessionRequest'), headers, signal), - ).then( - (res) => { - return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'DeleteSessionResponse') - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - listContacts = (req: ListContactsRequest, headers?: object, signal?: AbortSignal): Promise => { - return this.fetch( - this.url('ListContacts'), - createHttpRequest(JsonEncode(req, 'ListContactsRequest'), headers, signal), - ).then( - (res) => { - return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'ListContactsResponse') - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - putContact = (req: PutContactRequest, headers?: object, signal?: AbortSignal): Promise => { - return this.fetch( - this.url('PutContact'), - createHttpRequest(JsonEncode(req, 'PutContactRequest'), headers, signal), - ).then( - (res) => { - return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'PutContactResponse') - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - deleteContact = ( - req: DeleteContactRequest, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch( - this.url('DeleteContact'), - createHttpRequest(JsonEncode(req, 'DeleteContactRequest'), headers, signal), - ).then( - (res) => { - return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'DeleteContactResponse') - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - listWatchedWallets = ( - req: ListWatchedWalletsRequest, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch( - this.url('ListWatchedWallets'), - createHttpRequest(JsonEncode(req, 'ListWatchedWalletsRequest'), headers, signal), - ).then( - (res) => { - return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'ListWatchedWalletsResponse') - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - putWatchedWallet = ( - req: PutWatchedWalletRequest, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch( - this.url('PutWatchedWallet'), - createHttpRequest(JsonEncode(req, 'PutWatchedWalletRequest'), headers, signal), - ).then( - (res) => { - return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'PutWatchedWalletResponse') - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - deleteWatchedWallet = ( - req: DeleteWatchedWalletRequest, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch( - this.url('DeleteWatchedWallet'), - createHttpRequest(JsonEncode(req, 'DeleteWatchedWalletRequest'), headers, signal), - ).then( - (res) => { - return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'DeleteWatchedWalletResponse') - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - listDiscoverFavorites = ( - req: ListDiscoverFavoritesRequest, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch( - this.url('ListDiscoverFavorites'), - createHttpRequest(JsonEncode(req, 'ListDiscoverFavoritesRequest'), headers, signal), - ).then( - (res) => { - return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'ListDiscoverFavoritesResponse') - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - putDiscoverFavorite = ( - req: PutDiscoverFavoriteRequest, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch( - this.url('PutDiscoverFavorite'), - createHttpRequest(JsonEncode(req, 'PutDiscoverFavoriteRequest'), headers, signal), - ).then( - (res) => { - return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'PutDiscoverFavoriteResponse') - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - deleteDiscoverFavorite = ( - req: DeleteDiscoverFavoriteRequest, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch( - this.url('DeleteDiscoverFavorite'), - createHttpRequest(JsonEncode(req, 'DeleteDiscoverFavoriteRequest'), headers, signal), - ).then( - (res) => { - return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'DeleteDiscoverFavoriteResponse') - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - listDiscoverHistory = ( - req: ListDiscoverHistoryRequest, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch( - this.url('ListDiscoverHistory'), - createHttpRequest(JsonEncode(req, 'ListDiscoverHistoryRequest'), headers, signal), - ).then( - (res) => { - return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'ListDiscoverHistoryResponse') - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - putDiscoverHistory = ( - req: PutDiscoverHistoryRequest, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch( - this.url('PutDiscoverHistory'), - createHttpRequest(JsonEncode(req, 'PutDiscoverHistoryRequest'), headers, signal), - ).then( - (res) => { - return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'PutDiscoverHistoryResponse') - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - deleteDiscoverHistory = ( - req: DeleteDiscoverHistoryRequest, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch( - this.url('DeleteDiscoverHistory'), - createHttpRequest(JsonEncode(req, 'DeleteDiscoverHistoryRequest'), headers, signal), - ).then( - (res) => { - return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'DeleteDiscoverHistoryResponse') - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - listTokenFavorites = ( - req: ListTokenFavoritesRequest, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch( - this.url('ListTokenFavorites'), - createHttpRequest(JsonEncode(req, 'ListTokenFavoritesRequest'), headers, signal), - ).then( - (res) => { - return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'ListTokenFavoritesResponse') - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - putTokenFavorite = ( - req: PutTokenFavoriteRequest, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch( - this.url('PutTokenFavorite'), - createHttpRequest(JsonEncode(req, 'PutTokenFavoriteRequest'), headers, signal), - ).then( - (res) => { - return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'PutTokenFavoriteResponse') - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - deleteTokenFavorite = ( - req: DeleteTokenFavoriteRequest, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch( - this.url('DeleteTokenFavorite'), - createHttpRequest(JsonEncode(req, 'DeleteTokenFavoriteRequest'), headers, signal), - ).then( - (res) => { - return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'DeleteTokenFavoriteResponse') - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - listHiddenTokens = ( - req: ListHiddenTokensRequest, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch( - this.url('ListHiddenTokens'), - createHttpRequest(JsonEncode(req, 'ListHiddenTokensRequest'), headers, signal), - ).then( - (res) => { - return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'ListHiddenTokensResponse') - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - putHiddenToken = ( - req: PutHiddenTokenRequest, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch( - this.url('PutHiddenToken'), - createHttpRequest(JsonEncode(req, 'PutHiddenTokenRequest'), headers, signal), - ).then( - (res) => { - return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'PutHiddenTokenResponse') - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - deleteHiddenToken = ( - req: DeleteHiddenTokenRequest, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch( - this.url('DeleteHiddenToken'), - createHttpRequest(JsonEncode(req, 'DeleteHiddenTokenRequest'), headers, signal), - ).then( - (res) => { - return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'DeleteHiddenTokenResponse') - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } -} - -const createHttpRequest = (body: string = '{}', headers: object = {}, signal: AbortSignal | null = null): object => { - const reqHeaders: { [key: string]: string } = { ...headers, 'Content-Type': 'application/json' } - return { method: 'POST', headers: reqHeaders, body, signal } -} - -const buildResponse = (res: Response): Promise => { - return res.text().then((text) => { - let data - try { - data = JSON.parse(text) - } catch (error) { - throw WebrpcBadResponseError.new({ - status: res.status, - cause: `JSON.parse(): ${error instanceof Error ? error.message : String(error)}: response text: ${text}`, - }) - } - if (!res.ok) { - const code: number = typeof data.code === 'number' ? data.code : 0 - throw (webrpcErrorByCode[code] || WebrpcError).new(data) - } - return data - }) -} - -export type Fetch = (input: RequestInfo, init?: RequestInit) => Promise - -export const JsonEncode = (obj: T, _typ: string = ''): string => { - return JSON.stringify(obj) -} - -export const JsonDecode = (data: string | any, _typ: string = ''): T => { - let parsed: any = data - if (typeof data === 'string') { - try { - parsed = JSON.parse(data) - } catch (err) { - throw WebrpcBadResponseError.new({ cause: `JsonDecode: JSON.parse failed: ${(err as Error).message}` }) - } - } - return parsed as T -} - -// -// Errors -// - -type WebrpcErrorParams = { name?: string; code?: number; message?: string; status?: number; cause?: string } - -export class WebrpcError extends Error { - code: number - status: number - - constructor(error: WebrpcErrorParams = {}) { - super(error.message) - this.name = error.name || 'WebrpcEndpointError' - this.code = typeof error.code === 'number' ? error.code : 0 - this.message = error.message || `endpoint error` - this.status = typeof error.status === 'number' ? error.status : 400 - if (error.cause !== undefined) this.cause = error.cause - Object.setPrototypeOf(this, WebrpcError.prototype) - } - - static new(payload: any): WebrpcError { - return new this({ message: payload.message, code: payload.code, status: payload.status, cause: payload.cause }) - } -} - -export class WebrpcEndpointError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'WebrpcEndpoint' - this.code = typeof error.code === 'number' ? error.code : 0 - this.message = error.message || `endpoint error` - this.status = typeof error.status === 'number' ? error.status : 400 - if (error.cause !== undefined) this.cause = error.cause - Object.setPrototypeOf(this, WebrpcEndpointError.prototype) - } -} - -export class WebrpcRequestFailedError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'WebrpcRequestFailed' - this.code = typeof error.code === 'number' ? error.code : -1 - this.message = error.message || `request failed` - this.status = typeof error.status === 'number' ? error.status : 400 - if (error.cause !== undefined) this.cause = error.cause - Object.setPrototypeOf(this, WebrpcRequestFailedError.prototype) - } -} - -export class WebrpcBadRouteError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'WebrpcBadRoute' - this.code = typeof error.code === 'number' ? error.code : -2 - this.message = error.message || `bad route` - this.status = typeof error.status === 'number' ? error.status : 404 - if (error.cause !== undefined) this.cause = error.cause - Object.setPrototypeOf(this, WebrpcBadRouteError.prototype) - } -} - -export class WebrpcBadMethodError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'WebrpcBadMethod' - this.code = typeof error.code === 'number' ? error.code : -3 - this.message = error.message || `bad method` - this.status = typeof error.status === 'number' ? error.status : 405 - if (error.cause !== undefined) this.cause = error.cause - Object.setPrototypeOf(this, WebrpcBadMethodError.prototype) - } -} - -export class WebrpcBadRequestError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'WebrpcBadRequest' - this.code = typeof error.code === 'number' ? error.code : -4 - this.message = error.message || `bad request` - this.status = typeof error.status === 'number' ? error.status : 400 - if (error.cause !== undefined) this.cause = error.cause - Object.setPrototypeOf(this, WebrpcBadRequestError.prototype) - } -} - -export class WebrpcBadResponseError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'WebrpcBadResponse' - this.code = typeof error.code === 'number' ? error.code : -5 - this.message = error.message || `bad response` - this.status = typeof error.status === 'number' ? error.status : 500 - if (error.cause !== undefined) this.cause = error.cause - Object.setPrototypeOf(this, WebrpcBadResponseError.prototype) - } -} - -export class WebrpcServerPanicError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'WebrpcServerPanic' - this.code = typeof error.code === 'number' ? error.code : -6 - this.message = error.message || `server panic` - this.status = typeof error.status === 'number' ? error.status : 500 - if (error.cause !== undefined) this.cause = error.cause - Object.setPrototypeOf(this, WebrpcServerPanicError.prototype) - } -} - -export class WebrpcInternalErrorError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'WebrpcInternalError' - this.code = typeof error.code === 'number' ? error.code : -7 - this.message = error.message || `internal error` - this.status = typeof error.status === 'number' ? error.status : 500 - if (error.cause !== undefined) this.cause = error.cause - Object.setPrototypeOf(this, WebrpcInternalErrorError.prototype) - } -} - -export class WebrpcClientAbortedError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'WebrpcClientAborted' - this.code = typeof error.code === 'number' ? error.code : -8 - this.message = error.message || `request aborted by client` - this.status = typeof error.status === 'number' ? error.status : 400 - if (error.cause !== undefined) this.cause = error.cause - Object.setPrototypeOf(this, WebrpcClientAbortedError.prototype) - } -} - -export class WebrpcStreamLostError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'WebrpcStreamLost' - this.code = typeof error.code === 'number' ? error.code : -9 - this.message = error.message || `stream lost` - this.status = typeof error.status === 'number' ? error.status : 400 - if (error.cause !== undefined) this.cause = error.cause - Object.setPrototypeOf(this, WebrpcStreamLostError.prototype) - } -} - -export class WebrpcStreamFinishedError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'WebrpcStreamFinished' - this.code = typeof error.code === 'number' ? error.code : -10 - this.message = error.message || `stream finished` - this.status = typeof error.status === 'number' ? error.status : 200 - if (error.cause !== undefined) this.cause = error.cause - Object.setPrototypeOf(this, WebrpcStreamFinishedError.prototype) - } -} - -// -// Schema errors -// - -export class UnauthorizedError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'Unauthorized' - this.code = typeof error.code === 'number' ? error.code : 1000 - this.message = error.message || `Unauthorized access` - this.status = typeof error.status === 'number' ? error.status : 401 - if (error.cause !== undefined) this.cause = error.cause - Object.setPrototypeOf(this, UnauthorizedError.prototype) - } -} - -export class PermissionDeniedError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'PermissionDenied' - this.code = typeof error.code === 'number' ? error.code : 1001 - this.message = error.message || `Permission denied` - this.status = typeof error.status === 'number' ? error.status : 403 - if (error.cause !== undefined) this.cause = error.cause - Object.setPrototypeOf(this, PermissionDeniedError.prototype) - } -} - -export class SessionExpiredError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'SessionExpired' - this.code = typeof error.code === 'number' ? error.code : 1002 - this.message = error.message || `Session expired` - this.status = typeof error.status === 'number' ? error.status : 403 - if (error.cause !== undefined) this.cause = error.cause - Object.setPrototypeOf(this, SessionExpiredError.prototype) - } -} - -export class MethodNotFoundError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'MethodNotFound' - this.code = typeof error.code === 'number' ? error.code : 1003 - this.message = error.message || `Method not found` - this.status = typeof error.status === 'number' ? error.status : 404 - if (error.cause !== undefined) this.cause = error.cause - Object.setPrototypeOf(this, MethodNotFoundError.prototype) - } -} - -export class RequestConflictError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'RequestConflict' - this.code = typeof error.code === 'number' ? error.code : 1004 - this.message = error.message || `Conflict with target resource` - this.status = typeof error.status === 'number' ? error.status : 409 - if (error.cause !== undefined) this.cause = error.cause - Object.setPrototypeOf(this, RequestConflictError.prototype) - } -} - -export class AbortedError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'Aborted' - this.code = typeof error.code === 'number' ? error.code : 1005 - this.message = error.message || `Request aborted` - this.status = typeof error.status === 'number' ? error.status : 400 - if (error.cause !== undefined) this.cause = error.cause - Object.setPrototypeOf(this, AbortedError.prototype) - } -} - -export class GeoblockedError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'Geoblocked' - this.code = typeof error.code === 'number' ? error.code : 1006 - this.message = error.message || `Geoblocked region` - this.status = typeof error.status === 'number' ? error.status : 451 - if (error.cause !== undefined) this.cause = error.cause - Object.setPrototypeOf(this, GeoblockedError.prototype) - } -} - -export class RateLimitedError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'RateLimited' - this.code = typeof error.code === 'number' ? error.code : 1007 - this.message = error.message || `Rate-limited. Please slow down.` - this.status = typeof error.status === 'number' ? error.status : 429 - if (error.cause !== undefined) this.cause = error.cause - Object.setPrototypeOf(this, RateLimitedError.prototype) - } -} - -export class ProjectNotFoundError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'ProjectNotFound' - this.code = typeof error.code === 'number' ? error.code : 1008 - this.message = error.message || `Project not found` - this.status = typeof error.status === 'number' ? error.status : 401 - if (error.cause !== undefined) this.cause = error.cause - Object.setPrototypeOf(this, ProjectNotFoundError.prototype) - } -} - -export class InvalidArgumentError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'InvalidArgument' - this.code = typeof error.code === 'number' ? error.code : 2000 - this.message = error.message || `Invalid argument` - this.status = typeof error.status === 'number' ? error.status : 400 - if (error.cause !== undefined) this.cause = error.cause - Object.setPrototypeOf(this, InvalidArgumentError.prototype) - } -} - -export class UnavailableError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'Unavailable' - this.code = typeof error.code === 'number' ? error.code : 2002 - this.message = error.message || `Unavailable resource` - this.status = typeof error.status === 'number' ? error.status : 400 - if (error.cause !== undefined) this.cause = error.cause - Object.setPrototypeOf(this, UnavailableError.prototype) - } -} - -export class QueryFailedError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'QueryFailed' - this.code = typeof error.code === 'number' ? error.code : 2003 - this.message = error.message || `Query failed` - this.status = typeof error.status === 'number' ? error.status : 400 - if (error.cause !== undefined) this.cause = error.cause - Object.setPrototypeOf(this, QueryFailedError.prototype) - } -} - -export class NotFoundError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'NotFound' - this.code = typeof error.code === 'number' ? error.code : 3000 - this.message = error.message || `Resource not found` - this.status = typeof error.status === 'number' ? error.status : 400 - if (error.cause !== undefined) this.cause = error.cause - Object.setPrototypeOf(this, NotFoundError.prototype) - } -} - -export class UnsupportedNetworkError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'UnsupportedNetwork' - this.code = typeof error.code === 'number' ? error.code : 3008 - this.message = error.message || `Unsupported network` - this.status = typeof error.status === 'number' ? error.status : 422 - if (error.cause !== undefined) this.cause = error.cause - Object.setPrototypeOf(this, UnsupportedNetworkError.prototype) - } -} - -export enum errors { - WebrpcEndpoint = 'WebrpcEndpoint', - WebrpcRequestFailed = 'WebrpcRequestFailed', - WebrpcBadRoute = 'WebrpcBadRoute', - WebrpcBadMethod = 'WebrpcBadMethod', - WebrpcBadRequest = 'WebrpcBadRequest', - WebrpcBadResponse = 'WebrpcBadResponse', - WebrpcServerPanic = 'WebrpcServerPanic', - WebrpcInternalError = 'WebrpcInternalError', - WebrpcClientAborted = 'WebrpcClientAborted', - WebrpcStreamLost = 'WebrpcStreamLost', - WebrpcStreamFinished = 'WebrpcStreamFinished', - Unauthorized = 'Unauthorized', - PermissionDenied = 'PermissionDenied', - SessionExpired = 'SessionExpired', - MethodNotFound = 'MethodNotFound', - RequestConflict = 'RequestConflict', - Aborted = 'Aborted', - Geoblocked = 'Geoblocked', - RateLimited = 'RateLimited', - ProjectNotFound = 'ProjectNotFound', - InvalidArgument = 'InvalidArgument', - Unavailable = 'Unavailable', - QueryFailed = 'QueryFailed', - NotFound = 'NotFound', - UnsupportedNetwork = 'UnsupportedNetwork', -} - -export enum WebrpcErrorCodes { - WebrpcEndpoint = 0, - WebrpcRequestFailed = -1, - WebrpcBadRoute = -2, - WebrpcBadMethod = -3, - WebrpcBadRequest = -4, - WebrpcBadResponse = -5, - WebrpcServerPanic = -6, - WebrpcInternalError = -7, - WebrpcClientAborted = -8, - WebrpcStreamLost = -9, - WebrpcStreamFinished = -10, - Unauthorized = 1000, - PermissionDenied = 1001, - SessionExpired = 1002, - MethodNotFound = 1003, - RequestConflict = 1004, - Aborted = 1005, - Geoblocked = 1006, - RateLimited = 1007, - ProjectNotFound = 1008, - InvalidArgument = 2000, - Unavailable = 2002, - QueryFailed = 2003, - NotFound = 3000, - UnsupportedNetwork = 3008, -} - -export const webrpcErrorByCode: { [code: number]: any } = { - [0]: WebrpcEndpointError, - [-1]: WebrpcRequestFailedError, - [-2]: WebrpcBadRouteError, - [-3]: WebrpcBadMethodError, - [-4]: WebrpcBadRequestError, - [-5]: WebrpcBadResponseError, - [-6]: WebrpcServerPanicError, - [-7]: WebrpcInternalErrorError, - [-8]: WebrpcClientAbortedError, - [-9]: WebrpcStreamLostError, - [-10]: WebrpcStreamFinishedError, - [1000]: UnauthorizedError, - [1001]: PermissionDeniedError, - [1002]: SessionExpiredError, - [1003]: MethodNotFoundError, - [1004]: RequestConflictError, - [1005]: AbortedError, - [1006]: GeoblockedError, - [1007]: RateLimitedError, - [1008]: ProjectNotFoundError, - [2000]: InvalidArgumentError, - [2002]: UnavailableError, - [2003]: QueryFailedError, - [3000]: NotFoundError, - [3008]: UnsupportedNetworkError, -} - -// -// Webrpc -// - -export const WebrpcHeader = 'Webrpc' - -export const WebrpcHeaderValue = 'webrpc@v0.30.2;gen-typescript@v0.22.2;userdata@v0.1.0' - -type WebrpcGenVersions = { - WebrpcGenVersion: string - codeGenName: string - codeGenVersion: string - schemaName: string - schemaVersion: string -} - -export function VersionFromHeader(headers: Headers): WebrpcGenVersions { - const headerValue = headers.get(WebrpcHeader) - if (!headerValue) { - return { - WebrpcGenVersion: '', - codeGenName: '', - codeGenVersion: '', - schemaName: '', - schemaVersion: '', - } - } - - return parseWebrpcGenVersions(headerValue) -} - -function parseWebrpcGenVersions(header: string): WebrpcGenVersions { - const versions = header.split(';') - if (versions.length < 3) { - return { - WebrpcGenVersion: '', - codeGenName: '', - codeGenVersion: '', - schemaName: '', - schemaVersion: '', - } - } - - const [_, WebrpcGenVersion] = versions[0]!.split('@') - const [codeGenName, codeGenVersion] = versions[1]!.split('@') - const [schemaName, schemaVersion] = versions[2]!.split('@') - - return { - WebrpcGenVersion: WebrpcGenVersion ?? '', - codeGenName: codeGenName ?? '', - codeGenVersion: codeGenVersion ?? '', - schemaName: schemaName ?? '', - schemaVersion: schemaVersion ?? '', - } -} diff --git a/packages/services/userdata/tsconfig.json b/packages/services/userdata/tsconfig.json deleted file mode 100644 index fed9c77b49..0000000000 --- a/packages/services/userdata/tsconfig.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "@repo/typescript-config/base.json", - "compilerOptions": { - "rootDir": "src", - "outDir": "dist", - "types": ["node"] - }, - "include": ["src"], - "exclude": ["node_modules", "dist"] -} diff --git a/packages/wallet/core/CHANGELOG.md b/packages/wallet/core/CHANGELOG.md deleted file mode 100644 index 23fc45fe44..0000000000 --- a/packages/wallet/core/CHANGELOG.md +++ /dev/null @@ -1,289 +0,0 @@ -# @0xsequence/wallet-core - -## 3.0.5 - -### Patch Changes - -- Account federation support -- Updated dependencies - - @0xsequence/guard@3.0.5 - - @0xsequence/relayer@3.0.5 - - @0xsequence/wallet-primitives@3.0.5 - -## 3.0.4 - -### Patch Changes - -- id-token login support -- Updated dependencies - - @0xsequence/guard@3.0.4 - - @0xsequence/relayer@3.0.4 - - @0xsequence/wallet-primitives@3.0.4 - -## 3.0.3 - -### Patch Changes - -- 3.0.3 -- Updated dependencies - - @0xsequence/guard@3.0.3 - - @0xsequence/relayer@3.0.3 - - @0xsequence/wallet-primitives@3.0.3 - -## 3.0.2 - -### Patch Changes - -- allow native self transfer -- Updated dependencies - - @0xsequence/guard@3.0.2 - - @0xsequence/relayer@3.0.2 - - @0xsequence/wallet-primitives@3.0.2 - -## 3.0.1 - -### Patch Changes - -- Network and session fixes -- Updated dependencies - - @0xsequence/guard@3.0.1 - - @0xsequence/relayer@3.0.1 - - @0xsequence/wallet-primitives@3.0.1 - -## 3.0.0 - -### Patch Changes - -- f68be62: ethauth support -- 49d8a2f: New chains, minor fixes -- 3411232: Beta release with dapp connector fixes -- 23cb9e9: New chains, relayer rpc fix -- f5f6a7a: dapp-client updates -- e7de3b1: Fix signer 404 error, minor fixes -- 493836f: multicall3 optimization -- 30e1f1a: 3.0.0 beta -- d5017e8: Beta release for v3 -- 24a5fab: Final RC before 3.0.0 -- e5e1a03: Apple auth fixes -- 0b63113: Apple auth fix -- a89134a: Userdata service updates -- 7c6c811: 3.0.0-beta.3 with fixes -- 3.0.0 release -- 98ce38b: 3.0.0-beta.2 with identity instrument updates -- 747e6b5: Relayer fee options fix -- 40c19ff: dapp client updates for EOA login -- 6d5de25: 3.0.0-beta.1 -- 934acd1: RC5 upgrade -- Updated dependencies [f68be62] -- Updated dependencies [49d8a2f] -- Updated dependencies [3411232] -- Updated dependencies [23cb9e9] -- Updated dependencies [f5f6a7a] -- Updated dependencies [e7de3b1] -- Updated dependencies [493836f] -- Updated dependencies [30e1f1a] -- Updated dependencies [d5017e8] -- Updated dependencies [24a5fab] -- Updated dependencies [e5e1a03] -- Updated dependencies [0b63113] -- Updated dependencies [a89134a] -- Updated dependencies [7c6c811] -- Updated dependencies -- Updated dependencies [98ce38b] -- Updated dependencies [747e6b5] -- Updated dependencies [40c19ff] -- Updated dependencies [6d5de25] -- Updated dependencies [934acd1] - - @0xsequence/guard@3.0.0 - - @0xsequence/relayer@3.0.0 - - @0xsequence/wallet-primitives@3.0.0 - -## 3.0.0-beta.19 - -### Patch Changes - -- Final RC before 3.0.0 -- Updated dependencies - - @0xsequence/guard@3.0.0-beta.19 - - @0xsequence/relayer@3.0.0-beta.19 - - @0xsequence/wallet-primitives@3.0.0-beta.19 - -## 3.0.0-beta.18 - -### Patch Changes - -- multicall3 optimization -- Updated dependencies - - @0xsequence/guard@3.0.0-beta.18 - - @0xsequence/relayer@3.0.0-beta.18 - - @0xsequence/wallet-primitives@3.0.0-beta.18 - -## 3.0.0-beta.17 - -### Patch Changes - -- New chains, relayer rpc fix -- Updated dependencies - - @0xsequence/guard@3.0.0-beta.17 - - @0xsequence/relayer@3.0.0-beta.17 - - @0xsequence/wallet-primitives@3.0.0-beta.17 - -## 3.0.0-beta.16 - -### Patch Changes - -- ethauth support -- Updated dependencies - - @0xsequence/guard@3.0.0-beta.16 - - @0xsequence/relayer@3.0.0-beta.16 - - @0xsequence/wallet-primitives@3.0.0-beta.16 - -## 3.0.0-beta.15 - -### Patch Changes - -- New chains, minor fixes -- Updated dependencies - - @0xsequence/guard@3.0.0-beta.15 - - @0xsequence/relayer@3.0.0-beta.15 - - @0xsequence/wallet-primitives@3.0.0-beta.15 - -## 3.0.0-beta.14 - -### Patch Changes - -- Relayer fee options fix -- Updated dependencies - - @0xsequence/guard@3.0.0-beta.14 - - @0xsequence/relayer@3.0.0-beta.14 - - @0xsequence/wallet-primitives@3.0.0-beta.14 - -## 3.0.0-beta.13 - -### Patch Changes - -- Userdata service updates -- Updated dependencies - - @0xsequence/guard@3.0.0-beta.13 - - @0xsequence/relayer@3.0.0-beta.13 - - @0xsequence/wallet-primitives@3.0.0-beta.13 - -## 3.0.0-beta.12 - -### Patch Changes - -- Beta release with dapp connector fixes -- Updated dependencies - - @0xsequence/guard@3.0.0-beta.12 - - @0xsequence/relayer@3.0.0-beta.12 - - @0xsequence/wallet-primitives@3.0.0-beta.12 - -## 3.0.0-beta.11 - -### Patch Changes - -- 3.0.0 beta -- Updated dependencies - - @0xsequence/guard@3.0.0-beta.11 - - @0xsequence/relayer@3.0.0-beta.11 - - @0xsequence/wallet-primitives@3.0.0-beta.11 - -## 3.0.0-beta.10 - -### Patch Changes - -- dapp-client updates -- Updated dependencies - - @0xsequence/guard@3.0.0-beta.10 - - @0xsequence/relayer@3.0.0-beta.10 - - @0xsequence/wallet-primitives@3.0.0-beta.10 - -## 3.0.0-beta.9 - -### Patch Changes - -- dapp client updates for EOA login -- Updated dependencies - - @0xsequence/guard@3.0.0-beta.9 - - @0xsequence/relayer@3.0.0-beta.9 - - @0xsequence/wallet-primitives@3.0.0-beta.9 - -## 3.0.0-beta.8 - -### Patch Changes - -- Apple auth fixes -- Updated dependencies - - @0xsequence/guard@3.0.0-beta.8 - - @0xsequence/relayer@3.0.0-beta.8 - - @0xsequence/wallet-primitives@3.0.0-beta.8 - -## 3.0.0-beta.7 - -### Patch Changes - -- Apple auth fix -- Updated dependencies - - @0xsequence/guard@3.0.0-beta.7 - - @0xsequence/relayer@3.0.0-beta.7 - - @0xsequence/wallet-primitives@3.0.0-beta.7 - -## 3.0.0-beta.6 - -### Patch Changes - -- Fix signer 404 error, minor fixes -- Updated dependencies - - @0xsequence/guard@3.0.0-beta.6 - - @0xsequence/relayer@3.0.0-beta.6 - - @0xsequence/wallet-primitives@3.0.0-beta.6 - -## 3.0.0-beta.5 - -### Patch Changes - -- Beta release for v3 -- Updated dependencies - - @0xsequence/guard@3.0.0-beta.5 - - @0xsequence/relayer@3.0.0-beta.5 - - @0xsequence/wallet-primitives@3.0.0-beta.5 - -## 3.0.0-beta.4 - -### Patch Changes - -- RC5 upgrade -- Updated dependencies - - @0xsequence/guard@3.0.0-beta.4 - - @0xsequence/relayer@3.0.0-beta.4 - - @0xsequence/wallet-primitives@3.0.0-beta.4 - -## 3.0.0-beta.3 - -### Patch Changes - -- 3.0.0-beta.3 with fixes -- Updated dependencies - - @0xsequence/guard@3.0.0-beta.3 - - @0xsequence/relayer@3.0.0-beta.3 - - @0xsequence/wallet-primitives@3.0.0-beta.3 - -## 3.0.0-beta.2 - -### Patch Changes - -- 3.0.0-beta.2 with identity instrument updates -- Updated dependencies - - @0xsequence/guard@3.0.0-beta.2 - - @0xsequence/relayer@3.0.0-beta.2 - - @0xsequence/wallet-primitives@3.0.0-beta.2 - -## 3.0.0-beta.1 - -### Patch Changes - -- 3.0.0-beta.1 -- Updated dependencies - - @0xsequence/guard@3.0.0-beta.1 - - @0xsequence/relayer@3.0.0-beta.1 - - @0xsequence/wallet-primitives@3.0.0-beta.1 diff --git a/packages/services/relayer/src/preconditions/codec.ts b/packages/wallet/core/src/preconditions/codec.ts similarity index 75% rename from packages/services/relayer/src/preconditions/codec.ts rename to packages/wallet/core/src/preconditions/codec.ts index b59fae6d67..a50c1984f2 100644 --- a/packages/services/relayer/src/preconditions/codec.ts +++ b/packages/wallet/core/src/preconditions/codec.ts @@ -10,15 +10,12 @@ import { Erc1155ApprovalPrecondition, } from './types.js' -export interface TransactionPrecondition { +export interface IntentPrecondition { type: string - chainId: number - ownerAddress: string - tokenAddress: string - minAmount: bigint + data: string } -export function decodePreconditions(preconditions: TransactionPrecondition[]): Precondition[] { +export function decodePreconditions(preconditions: IntentPrecondition[]): Precondition[] { const decodedPreconditions: Precondition[] = [] for (const p of preconditions) { @@ -31,7 +28,7 @@ export function decodePreconditions(preconditions: TransactionPrecondition[]): P return decodedPreconditions } -export function decodePrecondition(p: TransactionPrecondition): Precondition | undefined { +export function decodePrecondition(p: IntentPrecondition): Precondition | undefined { if (!p) { return undefined } @@ -44,64 +41,70 @@ export function decodePrecondition(p: TransactionPrecondition): Precondition | u let precondition: Precondition | undefined try { + const data = JSON.parse(p.data) + switch (p.type) { case 'native-balance': - precondition = new NativeBalancePrecondition(Address.from(p.ownerAddress), p.minAmount, undefined) + precondition = new NativeBalancePrecondition( + Address.from(data.address), + data.min ? BigInt(data.min) : undefined, + data.max ? BigInt(data.max) : undefined, + ) break case 'erc20-balance': precondition = new Erc20BalancePrecondition( - Address.from(p.ownerAddress), - Address.from(p.tokenAddress), - p.minAmount, - undefined, + Address.from(data.address), + Address.from(data.token), + data.min ? BigInt(data.min) : undefined, + data.max ? BigInt(data.max) : undefined, ) break case 'erc20-approval': precondition = new Erc20ApprovalPrecondition( - Address.from(p.ownerAddress), - Address.from(p.tokenAddress), - Address.from(p.ownerAddress), - p.minAmount, + Address.from(data.address), + Address.from(data.token), + Address.from(data.operator), + BigInt(data.min), ) break case 'erc721-ownership': precondition = new Erc721OwnershipPrecondition( - Address.from(p.ownerAddress), - Address.from(p.tokenAddress), - BigInt(0), - true, + Address.from(data.address), + Address.from(data.token), + BigInt(data.tokenId), + data.owned, ) break case 'erc721-approval': precondition = new Erc721ApprovalPrecondition( - Address.from(p.ownerAddress), - Address.from(p.tokenAddress), - BigInt(0), - Address.from(p.ownerAddress), + Address.from(data.address), + Address.from(data.token), + BigInt(data.tokenId), + Address.from(data.operator), ) break case 'erc1155-balance': precondition = new Erc1155BalancePrecondition( - Address.from(p.ownerAddress), - Address.from(p.tokenAddress), - BigInt(0), - p.minAmount, - undefined, + Address.from(data.address), + Address.from(data.token), + BigInt(data.tokenId), + data.min ? BigInt(data.min) : undefined, + data.max ? BigInt(data.max) : undefined, ) break case 'erc1155-approval': precondition = new Erc1155ApprovalPrecondition( - Address.from(p.ownerAddress), - Address.from(p.tokenAddress), - BigInt(0), - Address.from(p.ownerAddress), - p.minAmount, + Address.from(data.address), + Address.from(data.token), + BigInt(data.tokenId), + Address.from(data.operator), + BigInt(data.min), ) break diff --git a/packages/services/relayer/src/preconditions/index.ts b/packages/wallet/core/src/preconditions/index.ts similarity index 100% rename from packages/services/relayer/src/preconditions/index.ts rename to packages/wallet/core/src/preconditions/index.ts diff --git a/packages/services/relayer/src/preconditions/selectors.ts b/packages/wallet/core/src/preconditions/selectors.ts similarity index 57% rename from packages/services/relayer/src/preconditions/selectors.ts rename to packages/wallet/core/src/preconditions/selectors.ts index d5985a8622..42b8cbb3b8 100644 --- a/packages/services/relayer/src/preconditions/selectors.ts +++ b/packages/wallet/core/src/preconditions/selectors.ts @@ -1,15 +1,20 @@ import { Precondition, NativeBalancePrecondition, Erc20BalancePrecondition } from './types.js' -import { TransactionPrecondition, decodePreconditions } from './codec.js' +import { IntentPrecondition, decodePreconditions } from './codec.js' -export function extractChainID(precondition: TransactionPrecondition): number | undefined { +export function extractChainID(precondition: IntentPrecondition): number | undefined { if (!precondition) { return undefined } - return precondition.chainId + try { + const data = JSON.parse(precondition.data) + return data.chainID ? Number(data.chainID) : undefined + } catch (e) { + return undefined + } } -export function extractSupportedPreconditions(preconditions: TransactionPrecondition[]): Precondition[] { +export function extractSupportedPreconditions(preconditions: IntentPrecondition[]): Precondition[] { if (!preconditions || preconditions.length === 0) { return [] } @@ -17,9 +22,7 @@ export function extractSupportedPreconditions(preconditions: TransactionPrecondi return decodePreconditions(preconditions) } -export function extractNativeBalancePreconditions( - preconditions: TransactionPrecondition[], -): NativeBalancePrecondition[] { +export function extractNativeBalancePreconditions(preconditions: IntentPrecondition[]): NativeBalancePrecondition[] { if (!preconditions || preconditions.length === 0) { return [] } @@ -28,7 +31,7 @@ export function extractNativeBalancePreconditions( return decoded.filter((p): p is NativeBalancePrecondition => p.type() === 'native-balance') } -export function extractERC20BalancePreconditions(preconditions: TransactionPrecondition[]): Erc20BalancePrecondition[] { +export function extractERC20BalancePreconditions(preconditions: IntentPrecondition[]): Erc20BalancePrecondition[] { if (!preconditions || preconditions.length === 0) { return [] } diff --git a/packages/services/relayer/src/preconditions/types.ts b/packages/wallet/core/src/preconditions/types.ts similarity index 100% rename from packages/services/relayer/src/preconditions/types.ts rename to packages/wallet/core/src/preconditions/types.ts diff --git a/packages/wallet/core/src/bundler/bundler.ts b/packages/wallet/core/src/relayer/bundler.ts similarity index 85% rename from packages/wallet/core/src/bundler/bundler.ts rename to packages/wallet/core/src/relayer/bundler.ts index baa473b817..4468f086de 100644 --- a/packages/wallet/core/src/bundler/bundler.ts +++ b/packages/wallet/core/src/relayer/bundler.ts @@ -1,7 +1,7 @@ import { Payload } from '@0xsequence/wallet-primitives' import { Address, Hex } from 'ox' import { UserOperation } from 'ox/erc4337' -import { Relayer } from '@0xsequence/relayer' +import { OperationStatus } from './relayer.js' export interface Bundler { kind: 'bundler' @@ -13,7 +13,7 @@ export interface Bundler { payload: Payload.Calls4337_07, ): Promise<{ speed?: 'slow' | 'standard' | 'fast'; payload: Payload.Calls4337_07 }[]> relay(entrypoint: Address.Address, userOperation: UserOperation.RpcV07): Promise<{ opHash: Hex.Hex }> - status(opHash: Hex.Hex, chainId: number): Promise + status(opHash: Hex.Hex, chainId: number): Promise isAvailable(entrypoint: Address.Address, chainId: number): Promise } diff --git a/packages/wallet/core/src/bundler/bundlers/index.ts b/packages/wallet/core/src/relayer/bundlers/index.ts similarity index 100% rename from packages/wallet/core/src/bundler/bundlers/index.ts rename to packages/wallet/core/src/relayer/bundlers/index.ts diff --git a/packages/wallet/core/src/bundler/bundlers/pimlico.ts b/packages/wallet/core/src/relayer/bundlers/pimlico.ts similarity index 97% rename from packages/wallet/core/src/bundler/bundlers/pimlico.ts rename to packages/wallet/core/src/relayer/bundlers/pimlico.ts index 4837babee0..7452844e27 100644 --- a/packages/wallet/core/src/bundler/bundlers/pimlico.ts +++ b/packages/wallet/core/src/relayer/bundlers/pimlico.ts @@ -2,7 +2,7 @@ import { Payload } from '@0xsequence/wallet-primitives' import { Bundler } from '../bundler.js' import { Provider, Hex, Address, RpcTransport } from 'ox' import { UserOperation } from 'ox/erc4337' -import { Relayer } from '@0xsequence/relayer' +import { OperationStatus } from '../relayer.js' type FeePerGasPair = { maxFeePerGas: Hex.Hex | bigint @@ -109,7 +109,7 @@ export class PimlicoBundler implements Bundler { } } - async status(opHash: Hex.Hex, _chainId: number): Promise { + async status(opHash: Hex.Hex, _chainId: number): Promise { try { type PimlicoStatusResp = { status: 'not_found' | 'not_submitted' | 'submitted' | 'rejected' | 'included' | 'failed' | 'reverted' diff --git a/packages/wallet/core/src/bundler/index.ts b/packages/wallet/core/src/relayer/index.ts similarity index 67% rename from packages/wallet/core/src/bundler/index.ts rename to packages/wallet/core/src/relayer/index.ts index 53c531a9be..5fb0b67240 100644 --- a/packages/wallet/core/src/bundler/index.ts +++ b/packages/wallet/core/src/relayer/index.ts @@ -1,5 +1,7 @@ // Export the core interfaces and type guards +export * from './relayer.js' export * from './bundler.js' // Group and export implementations +export * as Standard from './standard/index.js' export * as Bundlers from './bundlers/index.js' diff --git a/packages/services/relayer/src/relayer/index.ts b/packages/wallet/core/src/relayer/relayer.ts similarity index 50% rename from packages/services/relayer/src/relayer/index.ts rename to packages/wallet/core/src/relayer/relayer.ts index 52362d5c95..db28608fca 100644 --- a/packages/services/relayer/src/relayer/index.ts +++ b/packages/wallet/core/src/relayer/relayer.ts @@ -1,10 +1,6 @@ -import { Hex } from 'ox' -import type { FeeToken, GetMetaTxnReceiptReturn } from './rpc-relayer/relayer.gen.js' - -export * from './rpc-relayer/index.js' -export * from './standard/index.js' -export * from './relayer.js' -export type { FeeToken } from './rpc-relayer/relayer.gen.js' +import { Payload, Precondition } from '@0xsequence/wallet-primitives' +import { Address, Hex } from 'ox' +import { FeeToken, GetMetaTxnReceiptReturn } from './standard/rpc/index.js' export interface FeeOption { token: FeeToken @@ -58,3 +54,34 @@ export type OperationStatus = | OperationPendingPreconditionStatus | OperationConfirmedStatus | OperationFailedStatus + +export interface Relayer { + kind: 'relayer' + + type: string + id: string + + isAvailable(wallet: Address.Address, chainId: number): Promise + + feeOptions( + wallet: Address.Address, + chainId: number, + calls: Payload.Call[], + ): Promise<{ options: FeeOption[]; quote?: FeeQuote }> + + relay(to: Address.Address, data: Hex.Hex, chainId: number, quote?: FeeQuote): Promise<{ opHash: Hex.Hex }> + + status(opHash: Hex.Hex, chainId: number): Promise + + checkPrecondition(precondition: Precondition.Precondition): Promise +} + +export function isRelayer(relayer: any): relayer is Relayer { + return ( + 'isAvailable' in relayer && + 'feeOptions' in relayer && + 'relay' in relayer && + 'status' in relayer && + 'checkPrecondition' in relayer + ) +} diff --git a/packages/services/relayer/src/relayer/standard/abi.ts b/packages/wallet/core/src/relayer/standard/abi.ts similarity index 100% rename from packages/services/relayer/src/relayer/standard/abi.ts rename to packages/wallet/core/src/relayer/standard/abi.ts diff --git a/packages/services/relayer/src/relayer/standard/eip6963.ts b/packages/wallet/core/src/relayer/standard/eip6963.ts similarity index 86% rename from packages/services/relayer/src/relayer/standard/eip6963.ts rename to packages/wallet/core/src/relayer/standard/eip6963.ts index a290b2c6f9..a9cb1d8deb 100644 --- a/packages/services/relayer/src/relayer/standard/eip6963.ts +++ b/packages/wallet/core/src/relayer/standard/eip6963.ts @@ -1,9 +1,9 @@ import { createStore, EIP6963ProviderInfo, EIP6963ProviderDetail } from 'mipd' import { EIP1193ProviderAdapter, LocalRelayer } from './local.js' -import { FeeOption, FeeQuote, OperationStatus, Relayer } from '../index.js' +import { FeeOption, FeeQuote, OperationStatus, Relayer } from '../relayer.js' import { Address, Hex } from 'ox' import { Payload } from '@0xsequence/wallet-primitives' -import { FeeToken, TransactionPrecondition } from '../rpc-relayer/relayer.gen.js' +import { IntentPrecondition } from './rpc/relayer.gen.js' export class EIP6963Relayer implements Relayer { public readonly kind = 'relayer' @@ -23,10 +23,6 @@ export class EIP6963Relayer implements Relayer { return this.relayer.isAvailable(wallet, chainId) } - feeTokens(): Promise<{ isFeeRequired: boolean; tokens?: FeeToken[]; paymentAddress?: Address.Address }> { - return this.relayer.feeTokens() - } - feeOptions( wallet: Address.Address, chainId: number, @@ -44,7 +40,7 @@ export class EIP6963Relayer implements Relayer { return this.relayer.status(opHash, chainId) } - async checkPrecondition(precondition: TransactionPrecondition): Promise { + async checkPrecondition(precondition: IntentPrecondition): Promise { return this.relayer.checkPrecondition(precondition) } } diff --git a/packages/services/relayer/src/relayer/standard/index.ts b/packages/wallet/core/src/relayer/standard/index.ts similarity index 77% rename from packages/services/relayer/src/relayer/standard/index.ts rename to packages/wallet/core/src/relayer/standard/index.ts index d04527fa03..12260aef4a 100644 --- a/packages/services/relayer/src/relayer/standard/index.ts +++ b/packages/wallet/core/src/relayer/standard/index.ts @@ -1,4 +1,5 @@ export * from './local.js' export * from './pk-relayer.js' export * from './sequence.js' +export * as Rpc from './rpc/index.js' export * as EIP6963 from './eip6963.js' diff --git a/packages/services/relayer/src/relayer/standard/local.ts b/packages/wallet/core/src/relayer/standard/local.ts similarity index 100% rename from packages/services/relayer/src/relayer/standard/local.ts rename to packages/wallet/core/src/relayer/standard/local.ts diff --git a/packages/services/relayer/src/relayer/standard/pk-relayer.ts b/packages/wallet/core/src/relayer/standard/pk-relayer.ts similarity index 96% rename from packages/services/relayer/src/relayer/standard/pk-relayer.ts rename to packages/wallet/core/src/relayer/standard/pk-relayer.ts index b1d420a586..ac591b47ed 100644 --- a/packages/services/relayer/src/relayer/standard/pk-relayer.ts +++ b/packages/wallet/core/src/relayer/standard/pk-relayer.ts @@ -1,8 +1,7 @@ import { Payload, Precondition } from '@0xsequence/wallet-primitives' import { Address, Hex, Provider, Secp256k1, TransactionEnvelopeEip1559, TransactionReceipt } from 'ox' import { LocalRelayer } from './local.js' -import { FeeOption, FeeQuote, OperationStatus, Relayer } from '../index.js' -import { FeeToken } from '../rpc-relayer/relayer.gen.js' +import { FeeOption, FeeQuote, OperationStatus, Relayer } from '../relayer.js' export class PkRelayer implements Relayer { public readonly kind = 'relayer' @@ -107,10 +106,6 @@ export class PkRelayer implements Relayer { return providerChainId === chainId } - feeTokens(): Promise<{ isFeeRequired: boolean; tokens?: FeeToken[]; paymentAddress?: Address.Address }> { - return this.relayer.feeTokens() - } - feeOptions( wallet: Address.Address, chainId: number, diff --git a/packages/services/relayer/src/relayer/rpc-relayer/index.ts b/packages/wallet/core/src/relayer/standard/rpc/index.ts similarity index 100% rename from packages/services/relayer/src/relayer/rpc-relayer/index.ts rename to packages/wallet/core/src/relayer/standard/rpc/index.ts diff --git a/packages/wallet/core/src/relayer/standard/rpc/relayer.gen.ts b/packages/wallet/core/src/relayer/standard/rpc/relayer.gen.ts new file mode 100644 index 0000000000..a9e6b44405 --- /dev/null +++ b/packages/wallet/core/src/relayer/standard/rpc/relayer.gen.ts @@ -0,0 +1,2037 @@ +/* eslint-disable */ +// sequence-relayer v0.4.1 62fe2b49d57c4a0d3960ac1176d48ecfffc7af5a +// -- +// Code generated by webrpc-gen@v0.26.0 with typescript generator. DO NOT EDIT. +// +// webrpc-gen -schema=relayer.ridl -target=typescript -client -out=./clients/relayer.gen.ts + +export const WebrpcHeader = 'Webrpc' + +export const WebrpcHeaderValue = 'webrpc@v0.26.0;gen-typescript@v0.17.0;sequence-relayer@v0.4.1' + +// WebRPC description and code-gen version +export const WebRPCVersion = 'v1' + +// Schema version of your RIDL schema +export const WebRPCSchemaVersion = 'v0.4.1' + +// Schema hash generated from your RIDL schema +export const WebRPCSchemaHash = '62fe2b49d57c4a0d3960ac1176d48ecfffc7af5a' + +type WebrpcGenVersions = { + webrpcGenVersion: string + codeGenName: string + codeGenVersion: string + schemaName: string + schemaVersion: string +} + +export function VersionFromHeader(headers: Headers): WebrpcGenVersions { + const headerValue = headers.get(WebrpcHeader) + if (!headerValue) { + return { + webrpcGenVersion: '', + codeGenName: '', + codeGenVersion: '', + schemaName: '', + schemaVersion: '', + } + } + + return parseWebrpcGenVersions(headerValue) +} + +function parseWebrpcGenVersions(header: string): WebrpcGenVersions { + const versions = header.split(';') + if (versions.length < 3) { + return { + webrpcGenVersion: '', + codeGenName: '', + codeGenVersion: '', + schemaName: '', + schemaVersion: '', + } + } + + const [_, webrpcGenVersion] = versions[0]!.split('@') + const [codeGenName, codeGenVersion] = versions[1]!.split('@') + const [schemaName, schemaVersion] = versions[2]!.split('@') + + return { + webrpcGenVersion: webrpcGenVersion ?? '', + codeGenName: codeGenName ?? '', + codeGenVersion: codeGenVersion ?? '', + schemaName: schemaName ?? '', + schemaVersion: schemaVersion ?? '', + } +} + +// +// Types +// + +export enum ETHTxnStatus { + UNKNOWN = 'UNKNOWN', + DROPPED = 'DROPPED', + QUEUED = 'QUEUED', + SENT = 'SENT', + SUCCEEDED = 'SUCCEEDED', + PARTIALLY_FAILED = 'PARTIALLY_FAILED', + FAILED = 'FAILED', + PENDING_PRECONDITION = 'PENDING_PRECONDITION', +} + +export enum TransferType { + SEND = 'SEND', + RECEIVE = 'RECEIVE', + BRIDGE_DEPOSIT = 'BRIDGE_DEPOSIT', + BRIDGE_WITHDRAW = 'BRIDGE_WITHDRAW', + BURN = 'BURN', + UNKNOWN = 'UNKNOWN', +} + +export enum SimulateStatus { + SKIPPED = 'SKIPPED', + SUCCEEDED = 'SUCCEEDED', + FAILED = 'FAILED', + ABORTED = 'ABORTED', + REVERTED = 'REVERTED', + NOT_ENOUGH_GAS = 'NOT_ENOUGH_GAS', +} + +export enum FeeTokenType { + UNKNOWN = 'UNKNOWN', + ERC20_TOKEN = 'ERC20_TOKEN', + ERC1155_TOKEN = 'ERC1155_TOKEN', +} + +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 + chainID: number + useEIP1559: boolean + senders: Array + checks: RuntimeChecks +} + +export interface SenderStatus { + index: number + address: string + etherBalance: number + active: boolean +} + +export interface RuntimeChecks {} + +export interface SequenceContext { + factory: string + mainModule: string + mainModuleUpgradable: string + guestModule: string + utils: string +} + +export interface GasTank { + id: number + chainId: number + name: string + currentBalance: number + unlimited: boolean + feeMarkupFactor: number + updatedAt: string + createdAt: string +} + +export interface GasTankBalanceAdjustment { + gasTankId: number + nonce: number + amount: number + totalBalance: number + balanceTimestamp: string + createdAt: string +} + +export interface GasSponsor { + id: number + gasTankId: number + projectId: number + chainId: number + address: string + name: string + active: boolean + updatedAt: string + createdAt: string + deletedAt: string +} + +export interface GasSponsorUsage { + name: string + id: number + totalGasUsed: number + totalTxnFees: number + totalTxnFeesUsd: number + avgGasPrice: number + totalTxns: number + startTime: string + endTime: string +} + +export interface MetaTxn { + walletAddress: string + contract: string + input: string +} + +export interface MetaTxnLog { + id: number + chainId: number + projectId: number + txnHash: string + txnNonce: string + metaTxnID?: string + txnStatus: ETHTxnStatus + txnRevertReason: string + requeues: number + queuedAt: string + sentAt: string + minedAt: string + target: string + input: string + txnArgs: { [key: string]: any } + txnReceipt?: { [key: string]: any } + walletAddress: string + metaTxnNonce: string + gasLimit: number + gasPrice: string + gasUsed: number + gasEstimated: number + gasFeeMarkup?: number + usdRate: string + creditsUsed: number + cost: string + isWhitelisted: boolean + gasSponsor?: number + gasTank?: number + updatedAt: string + createdAt: string +} + +export interface MetaTxnReceipt { + id: string + status: string + revertReason?: string + index: number + logs: Array + receipts: Array + blockNumber: string + txnHash: string + txnReceipt: string +} + +export interface MetaTxnReceiptLog { + address: string + topics: Array + data: string +} + +export interface IntentPrecondition { + type: string + chainId: string + data: any +} + +export interface IntentSolution { + transactions: Array +} + +export interface Transactions { + chainID: string + transactions: Array + preconditions?: Array +} + +export interface Transaction { + delegateCall: boolean + revertOnError: boolean + gasLimit: string + target: string + value: string + data: string +} + +export interface TxnLogUser { + username: string +} + +export interface TxnLogTransfer { + transferType: TransferType + contractAddress: string + from: string + to: string + ids: Array + amounts: Array +} + +export interface SentTransactionsFilter { + pending?: boolean + failed?: boolean +} + +export interface SimulateResult { + executed: boolean + succeeded: boolean + result?: string + reason?: string + gasUsed: number + gasLimit: number +} + +export interface SimulateV3Result { + status: SimulateStatus + result?: string + error?: string + gasUsed: number + gasLimit: number +} + +export interface FeeOption { + token: FeeToken + to: string + value: string + gasLimit: number +} + +export interface FeeToken { + chainId: number + name: string + symbol: string + type: FeeTokenType + decimals?: number + logoURL: string + contractAddress?: string + tokenID?: string +} + +export interface Page { + pageSize?: number + page?: number + more?: boolean + totalRecords?: number + column?: string + before?: any + after?: any + sort?: Array +} + +export interface SortBy { + column: string + order: SortOrder +} + +export interface Relayer { + ping(headers?: object, signal?: AbortSignal): Promise + version(headers?: object, signal?: AbortSignal): Promise + runtimeStatus(headers?: object, signal?: AbortSignal): Promise + getSequenceContext(headers?: object, signal?: AbortSignal): Promise + getChainID(headers?: object, signal?: AbortSignal): Promise + /** + * + * Transactions + * + * TODO (future): rename this to just, 'SendTransaction(txn: MetaTransaction)' or 'SendTransaction(txn: SignedTransaction)', or something.. + * Project ID is only used by service and admin calls. Other clients must have projectID passed via the context + * TODO: rename return txnHash: string to metaTxnID: string + */ + sendMetaTxn(args: SendMetaTxnArgs, headers?: object, signal?: AbortSignal): Promise + getMetaTxnNonce(args: GetMetaTxnNonceArgs, headers?: object, signal?: AbortSignal): Promise + /** + * TODO: one day, make GetMetaTxnReceipt respond immediately with receipt or not + * and add WaitTransactionReceipt method, which will block and wait, similar to how GetMetaTxnReceipt + * is implemented now. + * For backwards compat, we can leave the current GetMetaTxnReceipt how it is, an deprecate it, and introduce + * new, GetTransactionReceipt and WaitTransactionReceipt methods + * we can also accept metaTxnId and txnHash .. so can take either or.. I wonder if ERC-4337 has any convention on this? + */ + getMetaTxnReceipt( + args: GetMetaTxnReceiptArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + simulate(args: SimulateArgs, headers?: object, signal?: AbortSignal): Promise + simulateV3(args: SimulateV3Args, headers?: object, signal?: AbortSignal): Promise + /** + * TODO: deprecated, to be removed by https://github.com/0xsequence/stack/pull/356 at a later date + */ + updateMetaTxnGasLimits( + args: UpdateMetaTxnGasLimitsArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + feeTokens(headers?: object, signal?: AbortSignal): Promise + feeOptions(args: FeeOptionsArgs, headers?: object, signal?: AbortSignal): Promise + /** + * TODO: deprecated, to be removed by https://github.com/0xsequence/stack/pull/356 at a later date + */ + getMetaTxnNetworkFeeOptions( + args: GetMetaTxnNetworkFeeOptionsArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + getMetaTransactions( + args: GetMetaTransactionsArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + getTransactionCost( + args: GetTransactionCostArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + /** + * Sent transactions from an account. If filter is omitted then it will return all transactions. + */ + sentTransactions(args: SentTransactionsArgs, headers?: object, signal?: AbortSignal): Promise + /** + * Pending transactions waiting to be mined for an account. This endpoint is just a sugar of `SentTransactions` + * with the filter set to pending: true. + */ + pendingTransactions( + args: PendingTransactionsArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + /** + * Legacy Gas Tank + */ + getGasTank(args: GetGasTankArgs, headers?: object, signal?: AbortSignal): Promise + addGasTank(args: AddGasTankArgs, headers?: object, signal?: AbortSignal): Promise + updateGasTank(args: UpdateGasTankArgs, headers?: object, signal?: AbortSignal): Promise + /** + * Legacy Gas Adjustment + */ + nextGasTankBalanceAdjustmentNonce( + args: NextGasTankBalanceAdjustmentNonceArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + adjustGasTankBalance( + args: AdjustGasTankBalanceArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + getGasTankBalanceAdjustment( + args: GetGasTankBalanceAdjustmentArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + listGasTankBalanceAdjustments( + args: ListGasTankBalanceAdjustmentsArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + /** + * Gas Sponsorship + */ + listGasSponsors(args: ListGasSponsorsArgs, headers?: object, signal?: AbortSignal): Promise + getGasSponsor(args: GetGasSponsorArgs, headers?: object, signal?: AbortSignal): Promise + addGasSponsor(args: AddGasSponsorArgs, headers?: object, signal?: AbortSignal): Promise + updateGasSponsor(args: UpdateGasSponsorArgs, headers?: object, signal?: AbortSignal): Promise + removeGasSponsor(args: RemoveGasSponsorArgs, headers?: object, signal?: AbortSignal): Promise + /** + * Gas Sponsor Lookup + */ + addressGasSponsors( + args: AddressGasSponsorsArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + /** + * Project Balance + */ + getProjectBalance( + args: GetProjectBalanceArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + adjustProjectBalance( + args: AdjustProjectBalanceArgs, + 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 GetSequenceContextArgs {} + +export interface GetSequenceContextReturn { + data: SequenceContext +} +export interface GetChainIDArgs {} + +export interface GetChainIDReturn { + chainID: number +} +export interface SendMetaTxnArgs { + call: MetaTxn + quote?: string + projectID?: number + preconditions?: Array +} + +export interface SendMetaTxnReturn { + status: boolean + txnHash: string +} +export interface GetMetaTxnNonceArgs { + walletContractAddress: string + space?: string +} + +export interface GetMetaTxnNonceReturn { + nonce: string +} +export interface GetMetaTxnReceiptArgs { + metaTxID: string +} + +export interface GetMetaTxnReceiptReturn { + receipt: MetaTxnReceipt +} +export interface SimulateArgs { + wallet: string + transactions: string +} + +export interface SimulateReturn { + results: Array +} +export interface SimulateV3Args { + wallet: string + calls: string +} + +export interface SimulateV3Return { + results: Array +} +export interface UpdateMetaTxnGasLimitsArgs { + walletAddress: string + walletConfig: any + payload: string +} + +export interface UpdateMetaTxnGasLimitsReturn { + payload: string +} +export interface FeeTokensArgs {} + +export interface FeeTokensReturn { + isFeeRequired: boolean + tokens: Array +} +export interface FeeOptionsArgs { + wallet: string + to: string + data: string + simulate?: boolean +} + +export interface FeeOptionsReturn { + options: Array + sponsored: boolean + quote?: string +} +export interface GetMetaTxnNetworkFeeOptionsArgs { + walletConfig: any + payload: string +} + +export interface GetMetaTxnNetworkFeeOptionsReturn { + options: Array +} +export interface GetMetaTransactionsArgs { + projectId: number + page?: Page +} + +export interface GetMetaTransactionsReturn { + page: Page + transactions: Array +} +export interface GetTransactionCostArgs { + projectId: number + from: string + to: string +} + +export interface GetTransactionCostReturn { + cost: number +} +export interface SentTransactionsArgs { + filter?: SentTransactionsFilter + page?: Page +} + +export interface SentTransactionsReturn { + page: Page + transactions: Array +} +export interface PendingTransactionsArgs { + page?: Page +} + +export interface PendingTransactionsReturn { + page: Page + transactions: Array +} +export interface GetGasTankArgs { + id: number +} + +export interface GetGasTankReturn { + gasTank: GasTank +} +export interface AddGasTankArgs { + name: string + feeMarkupFactor: number + unlimited?: boolean +} + +export interface AddGasTankReturn { + status: boolean + gasTank: GasTank +} +export interface UpdateGasTankArgs { + id: number + name?: string + feeMarkupFactor?: number + unlimited?: boolean +} + +export interface UpdateGasTankReturn { + status: boolean + gasTank: GasTank +} +export interface NextGasTankBalanceAdjustmentNonceArgs { + id: number +} + +export interface NextGasTankBalanceAdjustmentNonceReturn { + nonce: number +} +export interface AdjustGasTankBalanceArgs { + id: number + nonce: number + amount: number +} + +export interface AdjustGasTankBalanceReturn { + status: boolean + adjustment: GasTankBalanceAdjustment +} +export interface GetGasTankBalanceAdjustmentArgs { + id: number + nonce: number +} + +export interface GetGasTankBalanceAdjustmentReturn { + adjustment: GasTankBalanceAdjustment +} +export interface ListGasTankBalanceAdjustmentsArgs { + id: number + page?: Page +} + +export interface ListGasTankBalanceAdjustmentsReturn { + page: Page + adjustments: Array +} +export interface ListGasSponsorsArgs { + projectId: number + page?: Page +} + +export interface ListGasSponsorsReturn { + page: Page + gasSponsors: Array +} +export interface GetGasSponsorArgs { + projectId: number + id: number +} + +export interface GetGasSponsorReturn { + gasSponsor: GasSponsor +} +export interface AddGasSponsorArgs { + projectId: number + address: string + name?: string + active?: boolean +} + +export interface AddGasSponsorReturn { + status: boolean + gasSponsor: GasSponsor +} +export interface UpdateGasSponsorArgs { + projectId: number + id: number + name?: string + active?: boolean +} + +export interface UpdateGasSponsorReturn { + status: boolean + gasSponsor: GasSponsor +} +export interface RemoveGasSponsorArgs { + projectId: number + id: number +} + +export interface RemoveGasSponsorReturn { + status: boolean +} +export interface AddressGasSponsorsArgs { + address: string + page?: Page +} + +export interface AddressGasSponsorsReturn { + page: Page + gasSponsors: Array +} +export interface GetProjectBalanceArgs { + projectId: number +} + +export interface GetProjectBalanceReturn { + balance: number +} +export interface AdjustProjectBalanceArgs { + projectId: number + amount: number + identifier: string +} + +export interface AdjustProjectBalanceReturn { + balance: number +} + +// +// Client +// +export class Relayer implements Relayer { + protected hostname: string + protected fetch: Fetch + protected path = '/rpc/Relayer/' + + constructor(hostname: string, fetch: Fetch) { + this.hostname = hostname.replace(/\/*$/, '') + 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 || ''}` }) + }, + ) + } + + 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 || ''}` }) + }, + ) + } + + getChainID = (headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('GetChainID'), createHTTPRequest({}, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + chainID: _data.chainID, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + sendMetaTxn = (args: SendMetaTxnArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('SendMetaTxn'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + status: _data.status, + txnHash: _data.txnHash, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + getMetaTxnNonce = ( + args: GetMetaTxnNonceArgs, + headers?: object, + signal?: AbortSignal, + ): Promise => { + return this.fetch(this.url('GetMetaTxnNonce'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + nonce: _data.nonce, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + getMetaTxnReceipt = ( + args: GetMetaTxnReceiptArgs, + headers?: object, + signal?: AbortSignal, + ): Promise => { + return this.fetch(this.url('GetMetaTxnReceipt'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + receipt: _data.receipt, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + simulate = (args: SimulateArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('Simulate'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + results: >_data.results, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + simulateV3 = (args: SimulateV3Args, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('SimulateV3'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + results: >_data.results, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + updateMetaTxnGasLimits = ( + args: UpdateMetaTxnGasLimitsArgs, + headers?: object, + signal?: AbortSignal, + ): Promise => { + return this.fetch(this.url('UpdateMetaTxnGasLimits'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + payload: _data.payload, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + feeTokens = (headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('FeeTokens'), createHTTPRequest({}, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + isFeeRequired: _data.isFeeRequired, + tokens: >_data.tokens, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + feeOptions = (args: FeeOptionsArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('FeeOptions'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + options: >_data.options, + sponsored: _data.sponsored, + quote: _data.quote, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + getMetaTxnNetworkFeeOptions = ( + args: GetMetaTxnNetworkFeeOptionsArgs, + headers?: object, + signal?: AbortSignal, + ): Promise => { + return this.fetch(this.url('GetMetaTxnNetworkFeeOptions'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + options: >_data.options, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + getMetaTransactions = ( + args: GetMetaTransactionsArgs, + headers?: object, + signal?: AbortSignal, + ): Promise => { + return this.fetch(this.url('GetMetaTransactions'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + page: _data.page, + transactions: >_data.transactions, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + getTransactionCost = ( + args: GetTransactionCostArgs, + headers?: object, + signal?: AbortSignal, + ): Promise => { + return this.fetch(this.url('GetTransactionCost'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + cost: _data.cost, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + sentTransactions = ( + args: SentTransactionsArgs, + headers?: object, + signal?: AbortSignal, + ): Promise => { + return this.fetch(this.url('SentTransactions'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + page: _data.page, + transactions: >_data.transactions, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + pendingTransactions = ( + args: PendingTransactionsArgs, + headers?: object, + signal?: AbortSignal, + ): Promise => { + return this.fetch(this.url('PendingTransactions'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + page: _data.page, + transactions: >_data.transactions, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + getGasTank = (args: GetGasTankArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('GetGasTank'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + gasTank: _data.gasTank, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + addGasTank = (args: AddGasTankArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('AddGasTank'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + status: _data.status, + gasTank: _data.gasTank, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + updateGasTank = (args: UpdateGasTankArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('UpdateGasTank'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + status: _data.status, + gasTank: _data.gasTank, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + nextGasTankBalanceAdjustmentNonce = ( + args: NextGasTankBalanceAdjustmentNonceArgs, + headers?: object, + signal?: AbortSignal, + ): Promise => { + return this.fetch(this.url('NextGasTankBalanceAdjustmentNonce'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + nonce: _data.nonce, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + adjustGasTankBalance = ( + args: AdjustGasTankBalanceArgs, + headers?: object, + signal?: AbortSignal, + ): Promise => { + return this.fetch(this.url('AdjustGasTankBalance'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + status: _data.status, + adjustment: _data.adjustment, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + getGasTankBalanceAdjustment = ( + args: GetGasTankBalanceAdjustmentArgs, + headers?: object, + signal?: AbortSignal, + ): Promise => { + return this.fetch(this.url('GetGasTankBalanceAdjustment'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + adjustment: _data.adjustment, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + listGasTankBalanceAdjustments = ( + args: ListGasTankBalanceAdjustmentsArgs, + headers?: object, + signal?: AbortSignal, + ): Promise => { + return this.fetch(this.url('ListGasTankBalanceAdjustments'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + page: _data.page, + adjustments: >_data.adjustments, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + listGasSponsors = ( + args: ListGasSponsorsArgs, + headers?: object, + signal?: AbortSignal, + ): Promise => { + return this.fetch(this.url('ListGasSponsors'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + page: _data.page, + gasSponsors: >_data.gasSponsors, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + getGasSponsor = (args: GetGasSponsorArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('GetGasSponsor'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + gasSponsor: _data.gasSponsor, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + addGasSponsor = (args: AddGasSponsorArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('AddGasSponsor'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + status: _data.status, + gasSponsor: _data.gasSponsor, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + updateGasSponsor = ( + args: UpdateGasSponsorArgs, + headers?: object, + signal?: AbortSignal, + ): Promise => { + return this.fetch(this.url('UpdateGasSponsor'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + status: _data.status, + gasSponsor: _data.gasSponsor, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + removeGasSponsor = ( + args: RemoveGasSponsorArgs, + headers?: object, + signal?: AbortSignal, + ): Promise => { + return this.fetch(this.url('RemoveGasSponsor'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + status: _data.status, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + addressGasSponsors = ( + args: AddressGasSponsorsArgs, + headers?: object, + signal?: AbortSignal, + ): Promise => { + return this.fetch(this.url('AddressGasSponsors'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + page: _data.page, + gasSponsors: >_data.gasSponsors, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + getProjectBalance = ( + args: GetProjectBalanceArgs, + headers?: object, + signal?: AbortSignal, + ): Promise => { + return this.fetch(this.url('GetProjectBalance'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + balance: _data.balance, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + adjustProjectBalance = ( + args: AdjustProjectBalanceArgs, + headers?: object, + signal?: AbortSignal, + ): Promise => { + return this.fetch(this.url('AdjustProjectBalance'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + balance: _data.balance, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } +} + +const createHTTPRequest = (body: object = {}, headers: object = {}, signal: AbortSignal | null = null): object => { + const reqHeaders: { [key: string]: string } = { ...headers, 'Content-Type': 'application/json' } + reqHeaders[WebrpcHeader] = WebrpcHeaderValue + + return { + method: 'POST', + headers: reqHeaders, + 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 MethodNotFoundError extends WebrpcError { + constructor( + name: string = 'MethodNotFound', + code: number = 1003, + message: string = `Method not found`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, MethodNotFoundError.prototype) + } +} + +export class RequestConflictError extends WebrpcError { + constructor( + name: string = 'RequestConflict', + code: number = 1004, + message: string = `Conflict with target resource`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, RequestConflictError.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 GeoblockedError extends WebrpcError { + constructor( + name: string = 'Geoblocked', + code: number = 1006, + message: string = `Geoblocked region`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, GeoblockedError.prototype) + } +} + +export class RateLimitedError extends WebrpcError { + constructor( + name: string = 'RateLimited', + code: number = 1007, + message: string = `Rate-limited. Please slow down.`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, RateLimitedError.prototype) + } +} + +export class ProjectNotFoundError extends WebrpcError { + constructor( + name: string = 'ProjectNotFound', + code: number = 1008, + message: string = `Project not found`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, ProjectNotFoundError.prototype) + } +} + +export class AccessKeyNotFoundError extends WebrpcError { + constructor( + name: string = 'AccessKeyNotFound', + code: number = 1101, + message: string = `Access key not found`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, AccessKeyNotFoundError.prototype) + } +} + +export class AccessKeyMismatchError extends WebrpcError { + constructor( + name: string = 'AccessKeyMismatch', + code: number = 1102, + message: string = `Access key mismatch`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, AccessKeyMismatchError.prototype) + } +} + +export class InvalidOriginError extends WebrpcError { + constructor( + name: string = 'InvalidOrigin', + code: number = 1103, + message: string = `Invalid origin for Access Key`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, InvalidOriginError.prototype) + } +} + +export class InvalidServiceError extends WebrpcError { + constructor( + name: string = 'InvalidService', + code: number = 1104, + message: string = `Service not enabled for Access key`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, InvalidServiceError.prototype) + } +} + +export class UnauthorizedUserError extends WebrpcError { + constructor( + name: string = 'UnauthorizedUser', + code: number = 1105, + message: string = `Unauthorized user`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, UnauthorizedUserError.prototype) + } +} + +export class QuotaExceededError extends WebrpcError { + constructor( + name: string = 'QuotaExceeded', + code: number = 1200, + message: string = `Quota request exceeded`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, QuotaExceededError.prototype) + } +} + +export class QuotaRateLimitError extends WebrpcError { + constructor( + name: string = 'QuotaRateLimit', + code: number = 1201, + message: string = `Quota rate limit exceeded`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, QuotaRateLimitError.prototype) + } +} + +export class NoDefaultKeyError extends WebrpcError { + constructor( + name: string = 'NoDefaultKey', + code: number = 1300, + message: string = `No default access key found`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, NoDefaultKeyError.prototype) + } +} + +export class MaxAccessKeysError extends WebrpcError { + constructor( + name: string = 'MaxAccessKeys', + code: number = 1301, + message: string = `Access keys limit reached`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, MaxAccessKeysError.prototype) + } +} + +export class AtLeastOneKeyError extends WebrpcError { + constructor( + name: string = 'AtLeastOneKey', + code: number = 1302, + message: string = `You need at least one Access Key`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, AtLeastOneKeyError.prototype) + } +} + +export class TimeoutError extends WebrpcError { + constructor( + name: string = 'Timeout', + code: number = 1900, + message: string = `Request timed out`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, TimeoutError.prototype) + } +} + +export class InvalidArgumentError extends WebrpcError { + constructor( + name: string = 'InvalidArgument', + code: number = 2001, + 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 class InsufficientFeeError extends WebrpcError { + constructor( + name: string = 'InsufficientFee', + code: number = 3004, + message: string = `Insufficient fee`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, InsufficientFeeError.prototype) + } +} + +export class NotEnoughBalanceError extends WebrpcError { + constructor( + name: string = 'NotEnoughBalance', + code: number = 3005, + message: string = `Not enough balance`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, NotEnoughBalanceError.prototype) + } +} + +export class SimulationFailedError extends WebrpcError { + constructor( + name: string = 'SimulationFailed', + code: number = 3006, + message: string = `Simulation failed`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, SimulationFailedError.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', + MethodNotFound = 'MethodNotFound', + RequestConflict = 'RequestConflict', + Aborted = 'Aborted', + Geoblocked = 'Geoblocked', + RateLimited = 'RateLimited', + ProjectNotFound = 'ProjectNotFound', + AccessKeyNotFound = 'AccessKeyNotFound', + AccessKeyMismatch = 'AccessKeyMismatch', + InvalidOrigin = 'InvalidOrigin', + InvalidService = 'InvalidService', + UnauthorizedUser = 'UnauthorizedUser', + QuotaExceeded = 'QuotaExceeded', + QuotaRateLimit = 'QuotaRateLimit', + NoDefaultKey = 'NoDefaultKey', + MaxAccessKeys = 'MaxAccessKeys', + AtLeastOneKey = 'AtLeastOneKey', + Timeout = 'Timeout', + InvalidArgument = 'InvalidArgument', + Unavailable = 'Unavailable', + QueryFailed = 'QueryFailed', + NotFound = 'NotFound', + InsufficientFee = 'InsufficientFee', + NotEnoughBalance = 'NotEnoughBalance', + SimulationFailed = 'SimulationFailed', +} + +export enum WebrpcErrorCodes { + WebrpcEndpoint = 0, + WebrpcRequestFailed = -1, + WebrpcBadRoute = -2, + WebrpcBadMethod = -3, + WebrpcBadRequest = -4, + WebrpcBadResponse = -5, + WebrpcServerPanic = -6, + WebrpcInternalError = -7, + WebrpcClientDisconnected = -8, + WebrpcStreamLost = -9, + WebrpcStreamFinished = -10, + Unauthorized = 1000, + PermissionDenied = 1001, + SessionExpired = 1002, + MethodNotFound = 1003, + RequestConflict = 1004, + Aborted = 1005, + Geoblocked = 1006, + RateLimited = 1007, + ProjectNotFound = 1008, + AccessKeyNotFound = 1101, + AccessKeyMismatch = 1102, + InvalidOrigin = 1103, + InvalidService = 1104, + UnauthorizedUser = 1105, + QuotaExceeded = 1200, + QuotaRateLimit = 1201, + NoDefaultKey = 1300, + MaxAccessKeys = 1301, + AtLeastOneKey = 1302, + Timeout = 1900, + InvalidArgument = 2001, + Unavailable = 2002, + QueryFailed = 2003, + NotFound = 3000, + InsufficientFee = 3004, + NotEnoughBalance = 3005, + SimulationFailed = 3006, +} + +export 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, + [1003]: MethodNotFoundError, + [1004]: RequestConflictError, + [1005]: AbortedError, + [1006]: GeoblockedError, + [1007]: RateLimitedError, + [1008]: ProjectNotFoundError, + [1101]: AccessKeyNotFoundError, + [1102]: AccessKeyMismatchError, + [1103]: InvalidOriginError, + [1104]: InvalidServiceError, + [1105]: UnauthorizedUserError, + [1200]: QuotaExceededError, + [1201]: QuotaRateLimitError, + [1300]: NoDefaultKeyError, + [1301]: MaxAccessKeysError, + [1302]: AtLeastOneKeyError, + [1900]: TimeoutError, + [2001]: InvalidArgumentError, + [2002]: UnavailableError, + [2003]: QueryFailedError, + [3000]: NotFoundError, + [3004]: InsufficientFeeError, + [3005]: NotEnoughBalanceError, + [3006]: SimulationFailedError, +} + +export type Fetch = (input: RequestInfo, init?: RequestInit) => Promise diff --git a/packages/services/relayer/src/relayer/standard/sequence.ts b/packages/wallet/core/src/relayer/standard/sequence.ts similarity index 100% rename from packages/services/relayer/src/relayer/standard/sequence.ts rename to packages/wallet/core/src/relayer/standard/sequence.ts diff --git a/packages/wallet/core/src/signers/guard.ts b/packages/wallet/core/src/signers/guard.ts index 6ee2f21302..3a654edb46 100644 --- a/packages/wallet/core/src/signers/guard.ts +++ b/packages/wallet/core/src/signers/guard.ts @@ -3,10 +3,9 @@ import { Attestation, Payload } from '@0xsequence/wallet-primitives' import * as GuardService from '@0xsequence/guard' import * as Envelope from '../envelope.js' -export type GuardToken = { - id: 'TOTP' | 'PIN' | 'recovery' +type GuardToken = { + id: 'TOTP' | 'PIN' code: string - resetAuth?: boolean } export class Guard { @@ -37,7 +36,7 @@ export class Guard { digest, message, previousSignatures, - token ? { id: token.id, token: token.code, resetAuth: token.resetAuth } : undefined, + token ? { id: token.id, token: token.code } : undefined, ) return { address: this.guard.address, diff --git a/packages/wallet/core/src/signers/pk/encrypted.ts b/packages/wallet/core/src/signers/pk/encrypted.ts index dce0eb3cc7..40d26d16a5 100644 --- a/packages/wallet/core/src/signers/pk/encrypted.ts +++ b/packages/wallet/core/src/signers/pk/encrypted.ts @@ -3,8 +3,8 @@ import { resolveCoreEnv, type CoreEnv, type CryptoLike, type StorageLike, type T import { PkStore } from './index.js' export interface EncryptedData { - iv: BufferSource - data: BufferSource + iv: Uint8Array + data: ArrayBuffer keyPointer: string address: Address.Address publicKey: PublicKey.PublicKey diff --git a/packages/wallet/core/src/signers/session/explicit.ts b/packages/wallet/core/src/signers/session/explicit.ts index ef78c554a6..278027bf20 100644 --- a/packages/wallet/core/src/signers/session/explicit.ts +++ b/packages/wallet/core/src/signers/session/explicit.ts @@ -248,7 +248,10 @@ export class Explicit implements ExplicitSessionSigner { } // Sign it - const callHash = SessionSignature.hashPayloadWithCallIdx(wallet, payload, callIdx, chainId, sessionManagerAddress) + const useDeprecatedHash = + Address.isEqual(sessionManagerAddress, Extensions.Dev1.sessions) || + Address.isEqual(sessionManagerAddress, Extensions.Dev2.sessions) + const callHash = SessionSignature.hashCallWithReplayProtection(payload, callIdx, chainId, useDeprecatedHash) const sessionSignature = await this._privateKey.signDigest(Bytes.fromHex(callHash)) return { permissionIndex: BigInt(permissionIndex), diff --git a/packages/wallet/core/src/signers/session/implicit.ts b/packages/wallet/core/src/signers/session/implicit.ts index 8eb765808a..5e10439356 100644 --- a/packages/wallet/core/src/signers/session/implicit.ts +++ b/packages/wallet/core/src/signers/session/implicit.ts @@ -7,11 +7,11 @@ import { } from '@0xsequence/wallet-primitives' import { AbiFunction, Address, Bytes, Hex, Provider, Secp256k1, Signature } from 'ox' import { MemoryPkStore, PkStore } from '../pk/index.js' -import { ImplicitSessionSigner, SessionSignerValidity } from './session.js' +import { SessionSigner, SessionSignerValidity } from './session.js' export type AttestationParams = Omit -export class Implicit implements ImplicitSessionSigner { +export class Implicit implements SessionSigner { private readonly _privateKey: PkStore private readonly _identitySignature: SequenceSignature.RSY public readonly address: Address.Address @@ -42,11 +42,13 @@ export class Implicit implements ImplicitSessionSigner { } isValid(sessionTopology: SessionConfig.SessionsTopology, _chainId: number): SessionSignerValidity { - const implicitSigners = SessionConfig.getIdentitySigners(sessionTopology) - const thisIdentitySigner = this.identitySigner - if (!implicitSigners.some((s) => Address.isEqual(s, thisIdentitySigner))) { + const implicitSigner = SessionConfig.getIdentitySigner(sessionTopology) + if (!implicitSigner) { return { isValid: false, invalidReason: 'Identity signer not found' } } + if (!Address.isEqual(implicitSigner, this.identitySigner)) { + return { isValid: false, invalidReason: 'Identity signer mismatch' } + } const blacklist = SessionConfig.getImplicitBlacklist(sessionTopology) if (blacklist?.some((b) => Address.isEqual(b, this.address))) { return { isValid: false, invalidReason: 'Blacklisted' } @@ -114,7 +116,10 @@ export class Implicit implements ImplicitSessionSigner { if (!isSupported) { throw new Error('Unsupported call') } - const callHash = SessionSignature.hashPayloadWithCallIdx(wallet, payload, callIdx, chainId, sessionManagerAddress) + const useDeprecatedHash = + Address.isEqual(sessionManagerAddress, Extensions.Dev1.sessions) || + Address.isEqual(sessionManagerAddress, Extensions.Dev2.sessions) + const callHash = SessionSignature.hashCallWithReplayProtection(payload, callIdx, chainId, useDeprecatedHash) const sessionSignature = await this._privateKey.signDigest(Bytes.fromHex(callHash)) return { attestation: this._attestation, diff --git a/packages/wallet/core/src/state/local/index.ts b/packages/wallet/core/src/state/local/index.ts index 282de20e0a..d34568b878 100644 --- a/packages/wallet/core/src/state/local/index.ts +++ b/packages/wallet/core/src/state/local/index.ts @@ -66,7 +66,7 @@ export interface Store { export class Provider implements ProviderInterface { constructor( private readonly store: Store = new MemoryStore(), - public readonly extensions: Extensions.Extensions = Extensions.Rc5, + public readonly extensions: Extensions.Extensions = Extensions.Rc3, ) {} getConfiguration(imageHash: Hex.Hex): Promise { diff --git a/packages/wallet/core/src/utils/session/permission-builder.ts b/packages/wallet/core/src/utils/session/permission-builder.ts index c77580a188..08b279509a 100644 --- a/packages/wallet/core/src/utils/session/permission-builder.ts +++ b/packages/wallet/core/src/utils/session/permission-builder.ts @@ -59,8 +59,8 @@ export class PermissionBuilder { throw new Error(`cannot call exactCalldata() after calling allowAll() or adding rules`) } for (let offset = 0; offset < calldata.length; offset += 32) { - let value: Bytes.Bytes = calldata.slice(offset, offset + 32) - let mask: Bytes.Bytes = Permission.MASK.BYTES32 + let value = calldata.slice(offset, offset + 32) + let mask = Permission.MASK.BYTES32 if (value.length < 32) { mask = Bytes.fromHex(`0x${'ff'.repeat(value.length)}${'00'.repeat(32 - value.length)}`) value = Bytes.padRight(value, 32) diff --git a/packages/wallet/core/src/utils/session/types.ts b/packages/wallet/core/src/utils/session/types.ts deleted file mode 100644 index 6bf1086d4d..0000000000 --- a/packages/wallet/core/src/utils/session/types.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { Permission } from '@0xsequence/wallet-primitives' -import { Address } from 'ox' - -export type ExplicitSessionConfig = { - valueLimit: bigint - deadline: bigint - permissions: Permission.Permission[] - chainId: number -} - -// Complete session types - what the SDK returns after session creation -export type ImplicitSession = { - sessionAddress: Address.Address - type: 'implicit' -} - -export type ExplicitSession = { - sessionAddress: Address.Address - valueLimit: bigint - deadline: bigint - permissions: Permission.Permission[] - chainId: number - type: 'explicit' -} - -export type Session = { - type: 'explicit' | 'implicit' - sessionAddress: Address.Address - valueLimit?: bigint - deadline?: bigint - permissions?: Permission.Permission[] - chainId?: number -} diff --git a/packages/wallet/core/src/wallet.ts b/packages/wallet/core/src/wallet.ts index d89d5b2b98..7c05fa837a 100644 --- a/packages/wallet/core/src/wallet.ts +++ b/packages/wallet/core/src/wallet.ts @@ -402,7 +402,7 @@ export class Wallet { factory, factoryData, }, - ...(await this.prepareBlankEnvelope(Number(chainId), provider)), + ...(await this.prepareBlankEnvelope(Number(chainId))), } } @@ -490,7 +490,7 @@ export class Wallet { nonce, calls, }, - ...(await this.prepareBlankEnvelope(Number(chainId), provider)), + ...(await this.prepareBlankEnvelope(Number(chainId))), } } @@ -597,8 +597,8 @@ export class Wallet { return encoded } - private async prepareBlankEnvelope(chainId: number, provider?: Provider.Provider) { - const status = await this.getStatus(provider) + private async prepareBlankEnvelope(chainId: number) { + const status = await this.getStatus() return { wallet: this.address, diff --git a/packages/services/relayer/test/preconditions/preconditions.test.ts b/packages/wallet/core/test/preconditions.test.ts similarity index 100% rename from packages/services/relayer/test/preconditions/preconditions.test.ts rename to packages/wallet/core/test/preconditions.test.ts diff --git a/packages/services/relayer/test/preconditions/codec.test.ts b/packages/wallet/core/test/preconditions/codec.test.ts similarity index 100% rename from packages/services/relayer/test/preconditions/codec.test.ts rename to packages/wallet/core/test/preconditions/codec.test.ts diff --git a/packages/services/relayer/test/preconditions/selectors.test.ts b/packages/wallet/core/test/preconditions/selectors.test.ts similarity index 100% rename from packages/services/relayer/test/preconditions/selectors.test.ts rename to packages/wallet/core/test/preconditions/selectors.test.ts diff --git a/packages/services/relayer/test/preconditions/types.test.ts b/packages/wallet/core/test/preconditions/types.test.ts similarity index 100% rename from packages/services/relayer/test/preconditions/types.test.ts rename to packages/wallet/core/test/preconditions/types.test.ts diff --git a/packages/wallet/core/test/relayer/bundler.test.ts b/packages/wallet/core/test/relayer/bundler.test.ts index bc565e1cc3..cf5b3df469 100644 --- a/packages/wallet/core/test/relayer/bundler.test.ts +++ b/packages/wallet/core/test/relayer/bundler.test.ts @@ -2,8 +2,8 @@ import { describe, expect, it, vi, beforeEach } from 'vitest' import { Address, Hex } from 'ox' import { UserOperation } from 'ox/erc4337' import { Network, Payload } from '@0xsequence/wallet-primitives' -import { Bundler, isBundler } from '../../src/bundler/index.js' -import { Relayer } from '@0xsequence/relayer' +import { Bundler, isBundler } from '../../src/relayer/bundler.js' +import { OperationStatus } from '../../src/relayer/relayer.js' // Test addresses and data const TEST_WALLET_ADDRESS = Address.from('0x1234567890123456789012345678901234567890') @@ -220,7 +220,7 @@ describe('Bundler', () => { }) it('should handle various operation statuses', async () => { - const statuses: Relayer.OperationStatus[] = [ + const statuses: OperationStatus[] = [ { status: 'unknown' }, { status: 'pending' }, { status: 'confirmed', transactionHash: TEST_OP_HASH }, diff --git a/packages/services/relayer/test/relayer/relayer.test.ts b/packages/wallet/core/test/relayer/relayer.test.ts similarity index 100% rename from packages/services/relayer/test/relayer/relayer.test.ts rename to packages/wallet/core/test/relayer/relayer.test.ts diff --git a/packages/wallet/core/test/signers-session-implicit.test.ts b/packages/wallet/core/test/signers-session-implicit.test.ts index 5b0a370823..9edc6f47ff 100644 --- a/packages/wallet/core/test/signers-session-implicit.test.ts +++ b/packages/wallet/core/test/signers-session-implicit.test.ts @@ -103,7 +103,7 @@ describe('Implicit Session', () => { const result = implicitSigner.isValid(topology, 1) expect(result.isValid).toBe(false) - expect(result.invalidReason).toBe('Identity signer not found') + expect(result.invalidReason).toBe('Identity signer mismatch') }) it('should return true regardless of chainId', () => { @@ -223,7 +223,7 @@ describe('Implicit Session', () => { const result = implicitSigner.isValid(topology, 1) expect(result.isValid).toBe(false) - expect(result.invalidReason).toBe('Identity signer not found') + expect(result.invalidReason).toBe('Identity signer mismatch') }) it('should return false when attestation is issued in the future', () => { diff --git a/packages/wallet/core/vitest.config.ts b/packages/wallet/core/vitest.config.ts new file mode 100644 index 0000000000..0b2f7c6c76 --- /dev/null +++ b/packages/wallet/core/vitest.config.ts @@ -0,0 +1,9 @@ +import { defineConfig } from 'vitest/config' + +export default defineConfig({ + test: { + poolOptions: { + singleThread: true, + }, + }, +}) diff --git a/packages/wallet/dapp-client/CHANGELOG.md b/packages/wallet/dapp-client/CHANGELOG.md deleted file mode 100644 index 2039d0c2d2..0000000000 --- a/packages/wallet/dapp-client/CHANGELOG.md +++ /dev/null @@ -1,314 +0,0 @@ -# @0xsequence/dapp-client - -## 3.0.5 - -### Patch Changes - -- Account federation support -- Updated dependencies - - @0xsequence/guard@3.0.5 - - @0xsequence/relayer@3.0.5 - - @0xsequence/wallet-core@3.0.5 - - @0xsequence/wallet-primitives@3.0.5 - -## 3.0.4 - -### Patch Changes - -- id-token login support -- Updated dependencies - - @0xsequence/guard@3.0.4 - - @0xsequence/relayer@3.0.4 - - @0xsequence/wallet-core@3.0.4 - - @0xsequence/wallet-primitives@3.0.4 - -## 3.0.3 - -### Patch Changes - -- 3.0.3 -- Updated dependencies - - @0xsequence/guard@3.0.3 - - @0xsequence/relayer@3.0.3 - - @0xsequence/wallet-core@3.0.3 - - @0xsequence/wallet-primitives@3.0.3 - -## 3.0.2 - -### Patch Changes - -- allow native self transfer -- Updated dependencies - - @0xsequence/guard@3.0.2 - - @0xsequence/relayer@3.0.2 - - @0xsequence/wallet-core@3.0.2 - - @0xsequence/wallet-primitives@3.0.2 - -## 3.0.1 - -### Patch Changes - -- Network and session fixes -- Updated dependencies - - @0xsequence/guard@3.0.1 - - @0xsequence/relayer@3.0.1 - - @0xsequence/wallet-core@3.0.1 - - @0xsequence/wallet-primitives@3.0.1 - -## 3.0.0 - -### Patch Changes - -- f68be62: ethauth support -- 49d8a2f: New chains, minor fixes -- 3411232: Beta release with dapp connector fixes -- 23cb9e9: New chains, relayer rpc fix -- f5f6a7a: dapp-client updates -- e7de3b1: Fix signer 404 error, minor fixes -- 493836f: multicall3 optimization -- 30e1f1a: 3.0.0 beta -- d5017e8: Beta release for v3 -- 24a5fab: Final RC before 3.0.0 -- e5e1a03: Apple auth fixes -- 0b63113: Apple auth fix -- a89134a: Userdata service updates -- 7c6c811: 3.0.0-beta.3 with fixes -- 3.0.0 release -- 98ce38b: 3.0.0-beta.2 with identity instrument updates -- 747e6b5: Relayer fee options fix -- 40c19ff: dapp client updates for EOA login -- 6d5de25: 3.0.0-beta.1 -- 934acd1: RC5 upgrade -- Updated dependencies [f68be62] -- Updated dependencies [49d8a2f] -- Updated dependencies [3411232] -- Updated dependencies [23cb9e9] -- Updated dependencies [f5f6a7a] -- Updated dependencies [e7de3b1] -- Updated dependencies [493836f] -- Updated dependencies [30e1f1a] -- Updated dependencies [d5017e8] -- Updated dependencies [24a5fab] -- Updated dependencies [e5e1a03] -- Updated dependencies [0b63113] -- Updated dependencies [a89134a] -- Updated dependencies [7c6c811] -- Updated dependencies -- Updated dependencies [98ce38b] -- Updated dependencies [747e6b5] -- Updated dependencies [40c19ff] -- Updated dependencies [6d5de25] -- Updated dependencies [934acd1] - - @0xsequence/guard@3.0.0 - - @0xsequence/relayer@3.0.0 - - @0xsequence/wallet-core@3.0.0 - - @0xsequence/wallet-primitives@3.0.0 - -## 3.0.0-beta.19 - -### Patch Changes - -- Final RC before 3.0.0 -- Updated dependencies - - @0xsequence/guard@3.0.0-beta.19 - - @0xsequence/relayer@3.0.0-beta.19 - - @0xsequence/wallet-core@3.0.0-beta.19 - - @0xsequence/wallet-primitives@3.0.0-beta.19 - -## 3.0.0-beta.18 - -### Patch Changes - -- multicall3 optimization -- Updated dependencies - - @0xsequence/guard@3.0.0-beta.18 - - @0xsequence/relayer@3.0.0-beta.18 - - @0xsequence/wallet-core@3.0.0-beta.18 - - @0xsequence/wallet-primitives@3.0.0-beta.18 - -## 3.0.0-beta.17 - -### Patch Changes - -- New chains, relayer rpc fix -- Updated dependencies - - @0xsequence/guard@3.0.0-beta.17 - - @0xsequence/relayer@3.0.0-beta.17 - - @0xsequence/wallet-core@3.0.0-beta.17 - - @0xsequence/wallet-primitives@3.0.0-beta.17 - -## 3.0.0-beta.16 - -### Patch Changes - -- ethauth support -- Updated dependencies - - @0xsequence/guard@3.0.0-beta.16 - - @0xsequence/relayer@3.0.0-beta.16 - - @0xsequence/wallet-core@3.0.0-beta.16 - - @0xsequence/wallet-primitives@3.0.0-beta.16 - -## 3.0.0-beta.15 - -### Patch Changes - -- New chains, minor fixes -- Updated dependencies - - @0xsequence/guard@3.0.0-beta.15 - - @0xsequence/relayer@3.0.0-beta.15 - - @0xsequence/wallet-core@3.0.0-beta.15 - - @0xsequence/wallet-primitives@3.0.0-beta.15 - -## 3.0.0-beta.14 - -### Patch Changes - -- Relayer fee options fix -- Updated dependencies - - @0xsequence/guard@3.0.0-beta.14 - - @0xsequence/relayer@3.0.0-beta.14 - - @0xsequence/wallet-core@3.0.0-beta.14 - - @0xsequence/wallet-primitives@3.0.0-beta.14 - -## 3.0.0-beta.13 - -### Patch Changes - -- Userdata service updates -- Updated dependencies - - @0xsequence/guard@3.0.0-beta.13 - - @0xsequence/relayer@3.0.0-beta.13 - - @0xsequence/wallet-core@3.0.0-beta.13 - - @0xsequence/wallet-primitives@3.0.0-beta.13 - -## 3.0.0-beta.12 - -### Patch Changes - -- Beta release with dapp connector fixes -- Updated dependencies - - @0xsequence/guard@3.0.0-beta.12 - - @0xsequence/relayer@3.0.0-beta.12 - - @0xsequence/wallet-core@3.0.0-beta.12 - - @0xsequence/wallet-primitives@3.0.0-beta.12 - -## 3.0.0-beta.11 - -### Patch Changes - -- 3.0.0 beta -- Updated dependencies - - @0xsequence/guard@3.0.0-beta.11 - - @0xsequence/relayer@3.0.0-beta.11 - - @0xsequence/wallet-core@3.0.0-beta.11 - - @0xsequence/wallet-primitives@3.0.0-beta.11 - -## 3.0.0-beta.10 - -### Patch Changes - -- dapp-client updates -- Updated dependencies - - @0xsequence/guard@3.0.0-beta.10 - - @0xsequence/relayer@3.0.0-beta.10 - - @0xsequence/wallet-core@3.0.0-beta.10 - - @0xsequence/wallet-primitives@3.0.0-beta.10 - -## 3.0.0-beta.9 - -### Patch Changes - -- dapp client updates for EOA login -- Updated dependencies - - @0xsequence/guard@3.0.0-beta.9 - - @0xsequence/relayer@3.0.0-beta.9 - - @0xsequence/wallet-core@3.0.0-beta.9 - - @0xsequence/wallet-primitives@3.0.0-beta.9 - -## 3.0.0-beta.8 - -### Patch Changes - -- Apple auth fixes -- Updated dependencies - - @0xsequence/guard@3.0.0-beta.8 - - @0xsequence/relayer@3.0.0-beta.8 - - @0xsequence/wallet-core@3.0.0-beta.8 - - @0xsequence/wallet-primitives@3.0.0-beta.8 - -## 3.0.0-beta.7 - -### Patch Changes - -- Apple auth fix -- Updated dependencies - - @0xsequence/guard@3.0.0-beta.7 - - @0xsequence/relayer@3.0.0-beta.7 - - @0xsequence/wallet-core@3.0.0-beta.7 - - @0xsequence/wallet-primitives@3.0.0-beta.7 - -## 3.0.0-beta.6 - -### Patch Changes - -- Fix signer 404 error, minor fixes -- Updated dependencies - - @0xsequence/guard@3.0.0-beta.6 - - @0xsequence/relayer@3.0.0-beta.6 - - @0xsequence/wallet-core@3.0.0-beta.6 - - @0xsequence/wallet-primitives@3.0.0-beta.6 - -## 3.0.0-beta.5 - -### Patch Changes - -- Beta release for v3 -- Updated dependencies - - @0xsequence/guard@3.0.0-beta.5 - - @0xsequence/relayer@3.0.0-beta.5 - - @0xsequence/wallet-core@3.0.0-beta.5 - - @0xsequence/wallet-primitives@3.0.0-beta.5 - -## 3.0.0-beta.4 - -### Patch Changes - -- RC5 upgrade -- Updated dependencies - - @0xsequence/guard@3.0.0-beta.4 - - @0xsequence/relayer@3.0.0-beta.4 - - @0xsequence/wallet-core@3.0.0-beta.4 - - @0xsequence/wallet-primitives@3.0.0-beta.4 - -## 3.0.0-beta.3 - -### Patch Changes - -- 3.0.0-beta.3 with fixes -- Updated dependencies - - @0xsequence/guard@3.0.0-beta.3 - - @0xsequence/relayer@3.0.0-beta.3 - - @0xsequence/wallet-core@3.0.0-beta.3 - - @0xsequence/wallet-primitives@3.0.0-beta.3 - -## 3.0.0-beta.2 - -### Patch Changes - -- 3.0.0-beta.2 with identity instrument updates -- Updated dependencies - - @0xsequence/guard@3.0.0-beta.2 - - @0xsequence/relayer@3.0.0-beta.2 - - @0xsequence/wallet-core@3.0.0-beta.2 - - @0xsequence/wallet-primitives@3.0.0-beta.2 - -## 3.0.0-beta.1 - -### Patch Changes - -- 3.0.0-beta.1 -- Updated dependencies - - @0xsequence/guard@3.0.0-beta.1 - - @0xsequence/relayer@3.0.0-beta.1 - - @0xsequence/wallet-core@3.0.0-beta.1 - - @0xsequence/wallet-primitives@3.0.0-beta.1 diff --git a/packages/wallet/dapp-client/src/DappTransport.ts b/packages/wallet/dapp-client/src/DappTransport.ts index 090b1070b8..d9061ed0a5 100644 --- a/packages/wallet/dapp-client/src/DappTransport.ts +++ b/packages/wallet/dapp-client/src/DappTransport.ts @@ -12,28 +12,6 @@ import { WalletSize, } from './types/index.js' -const isBrowserEnvironment = typeof window !== 'undefined' && typeof document !== 'undefined' - -const base64Encode = (value: string) => { - if (typeof btoa !== 'undefined') { - return btoa(value) - } - if (typeof Buffer !== 'undefined') { - return Buffer.from(value, 'utf-8').toString('base64') - } - throw new Error('Base64 encoding is not supported in this environment.') -} - -const base64Decode = (value: string) => { - if (typeof atob !== 'undefined') { - return atob(value) - } - if (typeof Buffer !== 'undefined') { - return Buffer.from(value, 'base64').toString('utf-8') - } - throw new Error('Base64 decoding is not supported in this environment.') -} - enum ConnectionState { DISCONNECTED = 'DISCONNECTED', CONNECTING = 'CONNECTING', @@ -58,7 +36,6 @@ export class DappTransport { private readonly handshakeTimeoutMs: number private readonly sequenceSessionStorage: SequenceSessionStorage private readonly redirectActionHandler?: (url: string) => void - private readonly isBrowser: boolean public readonly walletOrigin: string @@ -69,7 +46,6 @@ export class DappTransport { sequenceSessionStorage?: SequenceSessionStorage, redirectActionHandler?: (url: string) => void, ) { - this.isBrowser = isBrowserEnvironment try { this.walletOrigin = new URL(walletUrl).origin } catch (e) { @@ -81,26 +57,18 @@ export class DappTransport { throw new Error('Invalid wallet origin derived from walletUrl.') } - this.sequenceSessionStorage = - sequenceSessionStorage || - ({ - getItem: (key: string) => (this.isBrowser && window.sessionStorage ? window.sessionStorage.getItem(key) : null), - setItem: (key: string, value: string) => { - if (this.isBrowser && window.sessionStorage) { - window.sessionStorage.setItem(key, value) - } - }, - removeItem: (key: string) => { - if (this.isBrowser && window.sessionStorage) { - window.sessionStorage.removeItem(key) - } - }, - } satisfies SequenceSessionStorage) + if (sequenceSessionStorage) { + this.sequenceSessionStorage = sequenceSessionStorage + } else if (typeof window !== 'undefined' && window.sessionStorage) { + this.sequenceSessionStorage = window.sessionStorage + } else { + throw new Error('A storage implementation must be provided for non-browser environments.') + } this.requestTimeoutMs = popupModeOptions.requestTimeoutMs ?? 300000 this.handshakeTimeoutMs = popupModeOptions.handshakeTimeoutMs ?? 15000 - if (this.mode === TransportMode.POPUP && this.isBrowser) { + if (this.mode === TransportMode.POPUP) { window.addEventListener('message', this.handleMessage) } @@ -123,23 +91,13 @@ export class DappTransport { payload?: TRequest, options: SendRequestOptions = {}, ): Promise { - if (!this.isBrowser && this.mode === TransportMode.POPUP) { - throw new Error( - 'Popup transport requires a browser environment. Use redirect mode or provide a redirect handler.', - ) - } - if (this.mode === TransportMode.REDIRECT) { const url = await this.getRequestRedirectUrl(action, payload, redirectUrl, options.path) if (this.redirectActionHandler) { this.redirectActionHandler(url) - } else if (this.isBrowser) { + } else { console.info('[DappTransport] No redirectActionHandler provided. Using window.location.href to navigate.') window.location.href = url - } else { - throw new Error( - 'Redirect navigation is not possible outside the browser without a redirectActionHandler. Provide a handler to perform navigation.', - ) } return new Promise(() => {}) } @@ -190,7 +148,7 @@ export class DappTransport { throw new Error('Could not save redirect state to storage. Redirect flow is unavailable.') } - const serializedPayload = base64Encode(JSON.stringify(payload || {}, jsonReplacers)) + const serializedPayload = btoa(JSON.stringify(payload || {}, jsonReplacers)) const fullWalletUrl = path ? `${this.walletUrl}${path}` : this.walletUrl const url = new URL(fullWalletUrl) url.searchParams.set('action', action) @@ -206,12 +164,7 @@ export class DappTransport { cleanState: boolean = true, url?: string, ): Promise<{ payload: TResponse; action: string } | { error: any; action: string } | null> { - if (!url && !this.isBrowser) { - throw new Error('A URL must be provided when handling redirect responses outside of a browser environment.') - } - - const search = url ? new URL(url).search : this.isBrowser ? window.location.search : '' - const params = new URLSearchParams(search) + const params = new URLSearchParams(url ? new URL(url).search : window.location.search) const responseId = params.get('id') if (!responseId) return null @@ -238,9 +191,11 @@ export class DappTransport { const responsePayloadB64 = params.get('payload') const responseErrorB64 = params.get('error') + const isBrowser = typeof window !== 'undefined' && window.history + if (cleanState) { await this.sequenceSessionStorage.removeItem(REDIRECT_REQUEST_KEY) - if (this.isBrowser && !url && window.history) { + if (isBrowser && !url) { const cleanUrl = new URL(window.location.href) ;['id', 'payload', 'error', 'mode'].forEach((p) => cleanUrl.searchParams.delete(p)) history.replaceState({}, document.title, cleanUrl.toString()) @@ -250,7 +205,7 @@ export class DappTransport { if (responseErrorB64) { try { return { - error: JSON.parse(base64Decode(responseErrorB64), jsonRevivers), + error: JSON.parse(atob(responseErrorB64), jsonRevivers), action: originalRequest.action, } } catch (e) { @@ -264,7 +219,7 @@ export class DappTransport { if (responsePayloadB64) { try { return { - payload: JSON.parse(base64Decode(responsePayloadB64), jsonRevivers), + payload: JSON.parse(atob(responsePayloadB64), jsonRevivers), action: originalRequest.action, } } catch (e) { @@ -285,9 +240,6 @@ export class DappTransport { if (this.mode === TransportMode.REDIRECT) { throw new Error("`openWallet` is not available in 'redirect' mode.") } - if (!this.isBrowser) { - throw new Error('Popup transport requires a browser environment.') - } if (this.connectionState !== ConnectionState.DISCONNECTED) { if (this.isWalletOpen) this.walletWindow?.focus() return this.readyPromise || Promise.resolve() @@ -362,14 +314,12 @@ export class DappTransport { } destroy(): void { - if (this.mode === TransportMode.POPUP && this.isBrowser) { + if (this.mode === TransportMode.POPUP) { window.removeEventListener('message', this.handleMessage) if (this.isWalletOpen) { this.walletWindow?.close() } this._resetConnection(new Error('Transport destroyed.'), 'Destroying transport...') - } else { - this._resetConnection(new Error('Transport destroyed.'), 'Destroying transport...') } } @@ -541,7 +491,7 @@ export class DappTransport { const requestsToClear = new Map(this.pendingRequests) this.pendingRequests.clear() requestsToClear.forEach((pending) => { - clearTimeout(pending.timer) + window.clearTimeout(pending.timer) const errorToSend = reason instanceof Error ? reason : new Error(`Operation failed: ${reason}`) pending.reject(errorToSend) }) @@ -550,11 +500,11 @@ export class DappTransport { private clearTimeouts(): void { if (this.handshakeTimeoutId !== undefined) { - clearTimeout(this.handshakeTimeoutId) + window.clearTimeout(this.handshakeTimeoutId) this.handshakeTimeoutId = undefined } if (this.closeCheckIntervalId !== undefined) { - clearInterval(this.closeCheckIntervalId) + window.clearInterval(this.closeCheckIntervalId) this.closeCheckIntervalId = undefined } } diff --git a/packages/wallet/dapp-client/src/types/index.ts b/packages/wallet/dapp-client/src/types/index.ts index 0f023c2bb8..3b5e284cdf 100644 --- a/packages/wallet/dapp-client/src/types/index.ts +++ b/packages/wallet/dapp-client/src/types/index.ts @@ -1,17 +1,11 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ -import { Relayer } from '@0xsequence/relayer' -import { ExplicitSession } from '@0xsequence/wallet-core' import { Attestation, Payload } from '@0xsequence/wallet-primitives' +import { Signers } from '@0xsequence/wallet-core' import { Address, Hex } from 'ox' import type { TypedData } from 'ox/TypedData' // --- Public Interfaces and Constants --- -export type FeeToken = Relayer.FeeToken -export type FeeOption = Relayer.FeeOption -export type OperationFailedStatus = Relayer.OperationFailedStatus -export type OperationStatus = Relayer.OperationStatus - export const RequestActionType = { CREATE_NEW_SESSION: 'createNewSession', ADD_EXPLICIT_SESSION: 'addExplicitSession', @@ -50,8 +44,9 @@ export interface ETHAuthProof { // --- Payloads for Transport --- export interface CreateNewSessionPayload { - origin?: string - session?: ExplicitSession + sessionAddress: Address.Address + origin: string + permissions?: Signers.Session.ExplicitParams includeImplicitSession?: boolean ethAuth?: EthAuthSettings preferredLoginMethod?: LoginMethod @@ -59,14 +54,16 @@ export interface CreateNewSessionPayload { } export interface AddExplicitSessionPayload { - session: ExplicitSession + sessionAddress: Address.Address + permissions: Signers.Session.ExplicitParams preferredLoginMethod?: LoginMethod email?: string } -export interface ModifyExplicitSessionPayload { +export interface ModifySessionPayload { walletAddress: Address.Address - session: ExplicitSession + sessionAddress: Address.Address + permissions: Signers.Session.ExplicitParams } export interface SignMessagePayload { @@ -81,12 +78,6 @@ export interface SignTypedDataPayload { chainId: number } -export interface SendWalletTransactionPayload { - address: Address.Address - transactionRequest: TransactionRequest - chainId: number -} - export type TransactionRequest = { to: Address.Address value?: bigint @@ -94,7 +85,13 @@ export type TransactionRequest = { gasLimit?: bigint } -export interface CreateNewSessionResponse { +export interface SendWalletTransactionPayload { + address: Address.Address + transactionRequest: TransactionRequest + chainId: number +} + +export interface ConnectSuccessResponsePayload { walletAddress: string attestation?: Attestation.Attestation signature?: Hex.Hex @@ -104,23 +101,28 @@ export interface CreateNewSessionResponse { ethAuthProof?: ETHAuthProof } -export interface SignatureResponse { - signature: Hex.Hex +export interface AddExplicitSessionSuccessResponsePayload { walletAddress: string + sessionAddress: string } -export interface SendWalletTransactionResponse { - transactionHash: Hex.Hex +export interface ModifySessionSuccessResponsePayload { walletAddress: string + sessionAddress: string } -export type WalletActionResponse = SignatureResponse | SendWalletTransactionResponse +export interface SignatureSuccessResponse { + signature: Hex.Hex + walletAddress: string +} -export interface SessionResponse { +export interface SendWalletTransactionSuccessResponse { + transactionHash: Hex.Hex walletAddress: string - sessionAddress: string } +export type WalletActionResponse = SignatureSuccessResponse | SendWalletTransactionSuccessResponse + // --- Dapp-facing Types --- export type RandomPrivateKeyFn = () => Hex.Hex | Promise @@ -133,11 +135,20 @@ export type Transaction = // All other properties from Payload.Call, but optional Partial> +export type Session = { + address: Address.Address + isImplicit: boolean + permissions?: Signers.Session.ExplicitParams + chainId?: number +} + // --- Event Types --- +export type ChainSessionManagerEvent = 'sessionsUpdated' | 'explicitSessionResponse' + export type ExplicitSessionEventListener = (data: { action: (typeof RequestActionType)['ADD_EXPLICIT_SESSION' | 'MODIFY_EXPLICIT_SESSION'] - response?: SessionResponse + response?: AddExplicitSessionSuccessResponsePayload | ModifySessionSuccessResponsePayload error?: any }) => void @@ -153,7 +164,7 @@ export type DappClientWalletActionEventListener = (data: { export type DappClientExplicitSessionEventListener = (data: { action: (typeof RequestActionType)['ADD_EXPLICIT_SESSION' | 'MODIFY_EXPLICIT_SESSION'] - response?: SessionResponse + response?: AddExplicitSessionSuccessResponsePayload | ModifySessionSuccessResponsePayload error?: any chainId: number }) => void @@ -192,6 +203,24 @@ export interface TransportMessage { error?: any } +export interface BaseRequest { + type: string +} + +export interface MessageSignatureRequest extends BaseRequest { + type: 'message_signature' + message: string + address: Address.Address + chainId: number +} + +export interface TypedDataSignatureRequest extends BaseRequest { + type: 'typed_data_signature' + typedData: unknown + address: Address.Address + chainId: number +} + export const WalletSize = { width: 380, height: 600, @@ -203,13 +232,8 @@ export interface PendingRequest { timer: number action: string } + export interface SendRequestOptions { timeout?: number path?: string } - -export type GetFeeTokensResponse = { - isFeeRequired: boolean - tokens?: FeeToken[] - paymentAddress?: Address.Address -} diff --git a/packages/wallet/dapp-client/src/utils/constants.ts b/packages/wallet/dapp-client/src/utils/constants.ts index 7d382d41c3..c1eec3ceff 100644 --- a/packages/wallet/dapp-client/src/utils/constants.ts +++ b/packages/wallet/dapp-client/src/utils/constants.ts @@ -1,5 +1,5 @@ export const CACHE_DB_NAME = 'sequence-cache' export const NODES_URL = 'https://nodes.sequence.app/{network}' -export const RELAYER_URL = 'https://{network}-relayer.sequence.app' -export const KEYMACHINE_URL = 'https://keymachine.sequence.app' +export const RELAYER_URL = 'https://dev-{network}-relayer.sequence.app' +export const KEYMACHINE_URL = 'https://v3-keymachine.sequence-dev.app' export const VALUE_FORWARDER_ADDRESS = '0xABAAd93EeE2a569cF0632f39B10A9f5D734777ca' diff --git a/packages/wallet/primitives-cli/src/subcommands/address.ts b/packages/wallet/primitives-cli/src/subcommands/address.ts index 062349efca..b418f14066 100644 --- a/packages/wallet/primitives-cli/src/subcommands/address.ts +++ b/packages/wallet/primitives-cli/src/subcommands/address.ts @@ -45,7 +45,7 @@ const addressCommand: CommandModule = { .option('creationCode', { type: 'string', description: 'Creation code (optional)', - default: Context.Rc5.creationCode, + default: Context.Rc3.creationCode, }) }, async (argv) => { diff --git a/packages/wallet/primitives-cli/src/subcommands/server.ts b/packages/wallet/primitives-cli/src/subcommands/server.ts index 29c5e1118b..6f932fcd7b 100644 --- a/packages/wallet/primitives-cli/src/subcommands/server.ts +++ b/packages/wallet/primitives-cli/src/subcommands/server.ts @@ -137,11 +137,10 @@ const rpcMethods: Record Promise> = { return result }, async session_encodeCallSignatures(params) { - const { sessionTopology, callSignatures, explicitSigners, implicitSigners, identitySigner } = params + const { sessionTopology, callSignatures, explicitSigners, implicitSigners } = params const result = await session.doEncodeSessionCallSignatures( JSON.stringify(sessionTopology), callSignatures.map(JSON.stringify), - identitySigner, explicitSigners, implicitSigners, ) @@ -327,7 +326,7 @@ async function handleHttpRequest(req: IncomingMessage, res: ServerResponse, debu } catch (error) { if (!silent) console.log(`[${new Date().toISOString()}] JSON parse error:`, error) res.statusCode = 400 - res.end(JSON.stringify(errorResponse(undefined, -32700, 'Parse error', String(error)))) + res.end(JSON.stringify(errorResponse(undefined, -32700, 'Parse error'))) return } diff --git a/packages/wallet/primitives-cli/src/subcommands/session.ts b/packages/wallet/primitives-cli/src/subcommands/session.ts index 2672721c61..3d343d1abe 100644 --- a/packages/wallet/primitives-cli/src/subcommands/session.ts +++ b/packages/wallet/primitives-cli/src/subcommands/session.ts @@ -19,24 +19,14 @@ export async function doEncodeTopology(sessionTopologyInput: string): Promise { const sessionTopology = SessionConfig.sessionsTopologyFromJson(sessionTopologyInput) const callSignatures = callSignaturesInput.map((s) => SessionSignature.sessionCallSignatureFromJson(s)) - // Use first identity signer if not provided - if (!identitySigner) { - const identitySigners = SessionConfig.getIdentitySigners(sessionTopology) - if (identitySigners.length === 0) { - throw new Error('No identity signers found') - } - identitySigner = identitySigners[0]! - } - const encoded = SessionSignature.encodeSessionSignature( + const encoded = SessionSignature.encodeSessionCallSignatures( callSignatures, sessionTopology, - identitySigner as `0x${string}`, explicitSigners as `0x${string}`[], implicitSigners as `0x${string}`[], ) @@ -100,13 +90,6 @@ const sessionCommand: CommandModule = { description: 'The call signatures', demandOption: true, }) - .option('identity-signer', { - type: 'string', - description: 'The identity signer', - demandOption: false, - default: undefined, - alias: 'id', - }) .option('explicit-signers', { type: 'string', array: true, @@ -129,7 +112,6 @@ const sessionCommand: CommandModule = { await doEncodeSessionCallSignatures( args.sessionTopology, args.callSignatures, - args.identitySigner, args.explicitSigners, args.implicitSigners, ), diff --git a/packages/wallet/primitives/CHANGELOG.md b/packages/wallet/primitives/CHANGELOG.md deleted file mode 100644 index 7e5a4cdbf7..0000000000 --- a/packages/wallet/primitives/CHANGELOG.md +++ /dev/null @@ -1,170 +0,0 @@ -# @0xsequence/wallet-primitives - -## 3.0.5 - -### Patch Changes - -- Account federation support - -## 3.0.4 - -### Patch Changes - -- id-token login support - -## 3.0.3 - -### Patch Changes - -- 3.0.3 - -## 3.0.2 - -### Patch Changes - -- allow native self transfer - -## 3.0.1 - -### Patch Changes - -- Network and session fixes - -## 3.0.0 - -### Patch Changes - -- f68be62: ethauth support -- 49d8a2f: New chains, minor fixes -- 3411232: Beta release with dapp connector fixes -- 23cb9e9: New chains, relayer rpc fix -- f5f6a7a: dapp-client updates -- e7de3b1: Fix signer 404 error, minor fixes -- 493836f: multicall3 optimization -- 30e1f1a: 3.0.0 beta -- d5017e8: Beta release for v3 -- 24a5fab: Final RC before 3.0.0 -- e5e1a03: Apple auth fixes -- 0b63113: Apple auth fix -- a89134a: Userdata service updates -- 7c6c811: 3.0.0-beta.3 with fixes -- 3.0.0 release -- 98ce38b: 3.0.0-beta.2 with identity instrument updates -- 747e6b5: Relayer fee options fix -- 40c19ff: dapp client updates for EOA login -- 6d5de25: 3.0.0-beta.1 -- 934acd1: RC5 upgrade - -## 3.0.0-beta.19 - -### Patch Changes - -- Final RC before 3.0.0 - -## 3.0.0-beta.18 - -### Patch Changes - -- multicall3 optimization - -## 3.0.0-beta.17 - -### Patch Changes - -- New chains, relayer rpc fix - -## 3.0.0-beta.16 - -### Patch Changes - -- ethauth support - -## 3.0.0-beta.15 - -### Patch Changes - -- New chains, minor fixes - -## 3.0.0-beta.14 - -### Patch Changes - -- Relayer fee options fix - -## 3.0.0-beta.13 - -### Patch Changes - -- Userdata service updates - -## 3.0.0-beta.12 - -### Patch Changes - -- Beta release with dapp connector fixes - -## 3.0.0-beta.11 - -### Patch Changes - -- 3.0.0 beta - -## 3.0.0-beta.10 - -### Patch Changes - -- dapp-client updates - -## 3.0.0-beta.9 - -### Patch Changes - -- dapp client updates for EOA login - -## 3.0.0-beta.8 - -### Patch Changes - -- Apple auth fixes - -## 3.0.0-beta.7 - -### Patch Changes - -- Apple auth fix - -## 3.0.0-beta.6 - -### Patch Changes - -- Fix signer 404 error, minor fixes - -## 3.0.0-beta.5 - -### Patch Changes - -- Beta release for v3 - -## 3.0.0-beta.4 - -### Patch Changes - -- RC5 upgrade - -## 3.0.0-beta.3 - -### Patch Changes - -- 3.0.0-beta.3 with fixes - -## 3.0.0-beta.2 - -### Patch Changes - -- 3.0.0-beta.2 with identity instrument updates - -## 3.0.0-beta.1 - -### Patch Changes - -- 3.0.0-beta.1 diff --git a/packages/wallet/primitives/src/config.ts b/packages/wallet/primitives/src/config.ts index 20c54dc494..d77a759e94 100644 --- a/packages/wallet/primitives/src/config.ts +++ b/packages/wallet/primitives/src/config.ts @@ -323,16 +323,6 @@ export function flatLeavesToTopology(leaves: Leaf[]): Topology { ] } -export function topologyToFlatLeaves(topology: Topology): Leaf[] { - if (isNode(topology)) { - return [...topologyToFlatLeaves(topology[0]), ...topologyToFlatLeaves(topology[1])] - } - if (isNestedLeaf(topology)) { - return [...topologyToFlatLeaves(topology.tree)] - } - return [topology] -} - export function configToJson(config: Config): string { return JSON.stringify({ threshold: config.threshold.toString(), @@ -669,39 +659,3 @@ function mergeLeaf(a: Leaf, b: Leaf): Leaf { throw new Error('Topology mismatch: incompatible leaf types') } - -export function replaceAddress( - topology: Topology, - targetAddress: Address.Address, - replacementAddress: Address.Address, -): Topology { - // 1. Handle Branches/Nodes (Recursion) - if (isNode(topology)) { - return [ - replaceAddress(topology[0], targetAddress, replacementAddress), - replaceAddress(topology[1], targetAddress, replacementAddress), - ] - } - - // 2. Handle Nested Leaves (Recursion) - if (isNestedLeaf(topology)) { - return { - ...topology, - tree: replaceAddress(topology.tree, targetAddress, replacementAddress), - } - } - - // 3. Handle Leaves (Replacement) - if (isSignerLeaf(topology) || isSapientSignerLeaf(topology)) { - // If this leaf holds the placeholder address, swap it - if (Address.isEqual(topology.address, targetAddress)) { - return { - ...topology, - address: replacementAddress, - } - } - } - - // 4. Return other leaf types unchanged (Subdigest, NodeLeaf, etc.) - return topology -} diff --git a/packages/wallet/primitives/src/constants.ts b/packages/wallet/primitives/src/constants.ts index 763f94389e..46185a49dd 100644 --- a/packages/wallet/primitives/src/constants.ts +++ b/packages/wallet/primitives/src/constants.ts @@ -1,9 +1,8 @@ import { Abi } from 'ox' export const ZeroAddress = '0x0000000000000000000000000000000000000000' as const -export const PlaceholderAddress = '0xffff0000ffff0000ffff0000ffff0000ffff0000' as const -export const DefaultGuestAddress = '0x0000000000006Ac72ed1d192fa28f0058D3F8806' as const +export const DefaultGuestAddress = '0x0000000000601fcA38f0cCA649453F6739436d6C' as const // ERC1271 export const IS_VALID_SIGNATURE = Abi.from([ diff --git a/packages/wallet/primitives/src/context.ts b/packages/wallet/primitives/src/context.ts index fa70f8e3ac..001b9a5f19 100644 --- a/packages/wallet/primitives/src/context.ts +++ b/packages/wallet/primitives/src/context.ts @@ -59,44 +59,6 @@ export const Rc3_4337: Context = { }, } -export const Rc4: Context = { - factory: '0x00000000000018A77519fcCCa060c2537c9D6d3F', - stage1: '0x0000000000003DF093bc4257E6dCE45D937EF161', - stage2: '0x10bE1Abf3cD0918bb1079ECc6b8220c177F34088', - creationCode: '0x6041600e3d396021805130553df33d3d36153402601f57363d3d373d363d30545af43d82803e903d91601f57fd5bf3', -} - -export const Rc4_4337: Context = { - factory: '0x00000000000018A77519fcCCa060c2537c9D6d3F', - stage1: '0x0000000000003add039FF84b064B7347Fc23C444', - stage2: '0x4B3E5735665057A0A15eE448A7293bC01e3b4De9', - creationCode: '0x6041600e3d396021805130553df33d3d36153402601f57363d3d373d363d30545af43d82803e903d91601f57fd5bf3', - capabilities: { - erc4337: { - entrypoint: '0x0000000071727De22E5E9d8BAf0edAc6f37da032', - }, - }, -} - -export const Rc5: Context = { - factory: '0x00000000000018A77519fcCCa060c2537c9D6d3F', - stage1: '0x0000000000001f3C39d61698ab21131a12134454', - stage2: '0xD0ae8eF93b7DA4eabb32Ec4d81b7a501DCa04D4C', - creationCode: '0x6041600e3d396021805130553df33d3d36153402601f57363d3d373d363d30545af43d82803e903d91601f57fd5bf3', -} - -export const Rc5_4337: Context = { - factory: '0x00000000000018A77519fcCCa060c2537c9D6d3F', - stage1: '0x0000000000009caFdeDb6f64Bf5F31a22124B2a8', - stage2: '0xcBca3328a731deffE6Ce4c2fb51b585c3c37FB92', - creationCode: '0x6041600e3d396021805130553df33d3d36153402601f57363d3d373d363d30545af43d82803e903d91601f57fd5bf3', - capabilities: { - erc4337: { - entrypoint: '0x0000000071727De22E5E9d8BAf0edAc6f37da032', - }, - }, -} - export type KnownContext = Context & { name: string development: boolean @@ -108,10 +70,6 @@ export const KnownContexts: KnownContext[] = [ { name: 'Dev2_4337', development: true, ...Dev2_4337 }, { name: 'Rc3', development: true, ...Rc3 }, { name: 'Rc3_4337', development: true, ...Rc3_4337 }, - { name: 'Rc4', development: false, ...Rc4 }, - { name: 'Rc4_4337', development: false, ...Rc4_4337 }, - { name: 'Rc5', development: false, ...Rc5 }, - { name: 'Rc5_4337', development: false, ...Rc5_4337 }, ] export function isKnownContext(context: Context): context is KnownContext { diff --git a/packages/wallet/primitives/src/erc-6492.ts b/packages/wallet/primitives/src/erc-6492.ts index 868350edff..a07de019cf 100644 --- a/packages/wallet/primitives/src/erc-6492.ts +++ b/packages/wallet/primitives/src/erc-6492.ts @@ -1,5 +1,5 @@ import { AbiFunction, AbiParameters, Address, Bytes, Hex, Provider } from 'ox' -import { SignatureErc6492 } from 'ox/erc6492' +import { WrappedSignature } from 'ox/erc6492' import { DEPLOY } from './constants.js' import { Context } from './context.js' @@ -29,7 +29,7 @@ export function wrap( [{ type: 'address' }, { type: 'bytes' }, { type: 'bytes' }], [to, Hex.from(data), Hex.from(signature)], ), - SignatureErc6492.magicBytes, + WrappedSignature.magicBytes, ) switch (typeof signature) { @@ -46,12 +46,12 @@ export function decode( switch (typeof signature) { case 'object': if ( - Bytes.toHex(signature.subarray(-SignatureErc6492.magicBytes.slice(2).length / 2)) === - SignatureErc6492.magicBytes + Bytes.toHex(signature.subarray(-WrappedSignature.magicBytes.slice(2).length / 2)) === + WrappedSignature.magicBytes ) { const [to, data, decoded] = AbiParameters.decode( [{ type: 'address' }, { type: 'bytes' }, { type: 'bytes' }], - signature.subarray(0, -SignatureErc6492.magicBytes.slice(2).length / 2), + signature.subarray(0, -WrappedSignature.magicBytes.slice(2).length / 2), ) return { signature: Hex.toBytes(decoded) as T, erc6492: { to, data: Hex.toBytes(data) as T } } } else { @@ -59,11 +59,11 @@ export function decode( } case 'string': - if (signature.endsWith(SignatureErc6492.magicBytes.slice(2))) { + if (signature.endsWith(WrappedSignature.magicBytes.slice(2))) { try { const [to, data, decoded] = AbiParameters.decode( [{ type: 'address' }, { type: 'bytes' }, { type: 'bytes' }], - signature.slice(0, -SignatureErc6492.magicBytes.slice(2).length) as Hex.Hex, + signature.slice(0, -WrappedSignature.magicBytes.slice(2).length) as Hex.Hex, ) return { signature: decoded as T, erc6492: { to, data: data as T } } } catch { diff --git a/packages/wallet/primitives/src/extensions/index.ts b/packages/wallet/primitives/src/extensions/index.ts index 2ff8ac16b2..3d7582cbc2 100644 --- a/packages/wallet/primitives/src/extensions/index.ts +++ b/packages/wallet/primitives/src/extensions/index.ts @@ -24,17 +24,5 @@ export const Rc3: Extensions = { sessions: '0x0000000000CC58810c33F3a0D78aA1Ed80FaDcD8', } -export const Rc4: Extensions = { - passkeys: '0x0000000000005204F3711851EAD52CC9c241499a', - recovery: '0x000000000001FC499c3E177DD56Febb0A4bc15b7', - sessions: '0x00000000000030Bcc832F7d657f50D6Be35C92b3', -} - -export const Rc5: Extensions = { - passkeys: '0x0000000000005204F3711851EAD52CC9c241499a', - recovery: '0x000000000000AB36D17eB1150116371520565205', - sessions: '0x00000000000030Bcc832F7d657f50D6Be35C92b3', -} - export * as Passkeys from './passkeys.js' export * as Recovery from './recovery.js' diff --git a/packages/wallet/primitives/src/payload.ts b/packages/wallet/primitives/src/payload.ts index c933a6118e..cc6cceafec 100644 --- a/packages/wallet/primitives/src/payload.ts +++ b/packages/wallet/primitives/src/payload.ts @@ -184,10 +184,6 @@ export function isCalls4337_07(payload: Payload): payload is Calls4337_07 { return payload.type === 'call_4337_07' } -export function isParented(payload: Payload): payload is Parented { - return 'parentWallets' in payload -} - export function toRecovery(payload: T): Recovery { if (isRecovery(payload)) { return payload diff --git a/packages/wallet/primitives/src/permission.ts b/packages/wallet/primitives/src/permission.ts index c2909696d8..773a176e59 100644 --- a/packages/wallet/primitives/src/permission.ts +++ b/packages/wallet/primitives/src/permission.ts @@ -25,7 +25,7 @@ export type SessionPermissions = { chainId: number valueLimit: bigint deadline: bigint // uint64 - permissions: Permission[] + permissions: [Permission, ...Permission[]] } export const MAX_PERMISSIONS_COUNT = 2 ** 7 - 1 @@ -127,7 +127,7 @@ export function decodeSessionPermissions(bytes: Bytes.Bytes): SessionPermissions chainId, valueLimit, deadline, - permissions: permissions, + permissions: permissions as [Permission, ...Permission[]], } } diff --git a/packages/wallet/primitives/src/session-config.ts b/packages/wallet/primitives/src/session-config.ts index 38ba2056ca..d65563c048 100644 --- a/packages/wallet/primitives/src/session-config.ts +++ b/packages/wallet/primitives/src/session-config.ts @@ -35,10 +35,8 @@ export type SessionLeaf = SessionPermissionsLeaf | ImplicitBlacklistLeaf | Ident export type SessionBranch = [SessionsTopology, SessionsTopology, ...SessionsTopology[]] export type SessionsTopology = SessionBranch | SessionLeaf | SessionNode -const SESSIONS_NODE_SIZE_BYTES = 32 - function isSessionsNode(topology: any): topology is SessionNode { - return Hex.validate(topology) && Hex.size(topology) === SESSIONS_NODE_SIZE_BYTES + return Hex.validate(topology) && Hex.size(topology) === 32 } function isImplicitBlacklist(topology: any): topology is ImplicitBlacklistLeaf { @@ -67,8 +65,7 @@ export function isSessionsTopology(topology: any): topology is SessionsTopology /** * Checks if the topology is complete. - * A complete topology has at least one identity signer and one blacklist. - * When performing encoding, exactly one identity signer is required. Others must be hashed into nodes. + * A complete topology has exactly one identity signer and one blacklist. * @param topology The topology to check * @returns True if the topology is complete */ @@ -77,9 +74,9 @@ export function isCompleteSessionsTopology(topology: any): topology is SessionsT if (!isSessionsTopology(topology)) { return false } - // Check the topology contains at least one identity signer and exactly one blacklist + // Check the topology contains exactly one identity signer and one blacklist const { identitySignerCount, blacklistCount } = checkIsCompleteSessionsBranch(topology) - return identitySignerCount >= 1 && blacklistCount === 1 + return identitySignerCount === 1 && blacklistCount === 1 } function checkIsCompleteSessionsBranch(topology: SessionsTopology): { @@ -105,22 +102,28 @@ function checkIsCompleteSessionsBranch(topology: SessionsTopology): { } /** - * Gets the identity signers from the topology. + * Gets the identity signer from the topology. * @param topology The topology to get the identity signer from - * @returns The identity signers + * @returns The identity signer or null if it's not present */ -export function getIdentitySigners(topology: SessionsTopology): Address.Address[] { +export function getIdentitySigner(topology: SessionsTopology): Address.Address | null { if (isIdentitySignerLeaf(topology)) { - // Got one - return [topology.identitySigner] + // Got it + return topology.identitySigner } if (isSessionsBranch(topology)) { // Check branches - return topology.map(getIdentitySigners).flat() + const results = topology.map(getIdentitySigner).filter((t) => t !== null) + if (results.length > 1) { + throw new Error('Multiple identity signers') + } + if (results.length === 1) { + return results[0]! + } } - return [] + return null } /** @@ -161,10 +164,7 @@ export function getImplicitBlacklistLeaf(topology: SessionsTopology): ImplicitBl return null } -export function getSessionPermissions( - topology: SessionsTopology, - address: Address.Address, -): SessionPermissionsLeaf | null { +export function getSessionPermissions(topology: SessionsTopology, address: Address.Address): SessionPermissions | null { if (isSessionPermissions(topology)) { if (Address.isEqual(topology.signer, address)) { return topology @@ -344,90 +344,6 @@ export function encodeSessionsTopology(topology: SessionsTopology): Bytes.Bytes throw new Error('Invalid topology') } -export function decodeSessionsTopology(bytes: Bytes.Bytes): SessionsTopology { - const { topology } = decodeSessionTopologyPointer(bytes) - return topology -} - -function decodeSessionTopologyPointer(bytes: Bytes.Bytes): { - topology: SessionsTopology - pointer: number -} { - if (bytes.length === 0) { - throw new Error('Empty topology bytes') - } - - const flagByte = bytes[0]! - const flag = (flagByte & 0xf0) >> 4 - const sizeSize = flagByte & 0x0f - - if (flag === SESSIONS_FLAG_BRANCH) { - // Branch - if (sizeSize === 0 || sizeSize > 15) { - throw new Error('Invalid branch size') - } - - let offset = 1 - const encodedLength = Bytes.toNumber(bytes.slice(offset, offset + sizeSize)) - offset += sizeSize - - const encodedBranches = bytes.slice(offset, offset + encodedLength) - const branches: SessionsTopology[] = [] - - let branchOffset = 0 - while (branchOffset < encodedBranches.length) { - const { topology: branchTopology, pointer: branchPointer } = decodeSessionTopologyPointer( - encodedBranches.slice(branchOffset), - ) - branches.push(branchTopology) - branchOffset += branchPointer - } - - return { topology: branches as SessionsTopology, pointer: offset + encodedLength } - } else if (flag === SESSIONS_FLAG_PERMISSIONS) { - // Permissions - const sessionPermissions = decodeSessionPermissions(bytes.slice(1)) - const nodeLength = 1 + encodeSessionPermissions(sessionPermissions).length - return { topology: { type: 'session-permissions', ...sessionPermissions }, pointer: nodeLength } - } else if (flag === SESSIONS_FLAG_NODE) { - // Node - const nodeLength = SESSIONS_NODE_SIZE_BYTES + 1 - if (bytes.length < nodeLength) { - throw new Error('Invalid node length') - } - return { topology: Hex.fromBytes(bytes.slice(1, nodeLength)), pointer: nodeLength } - } else if (flag === SESSIONS_FLAG_BLACKLIST) { - // Blacklist - let offset = 1 - let blacklistLength = sizeSize - if (sizeSize === 0x0f) { - // Size is encoded in the next 2 bytes - blacklistLength = Bytes.toNumber(bytes.slice(offset, offset + 2)) - offset += 2 - } - - const blacklist: Address.Address[] = [] - for (let i = 0; i < blacklistLength; i++) { - const addressBytes = bytes.slice(offset + i * 20, offset + (i + 1) * 20) - blacklist.push(Address.from(Hex.fromBytes(addressBytes))) - } - - return { topology: { type: 'implicit-blacklist', blacklist }, pointer: offset + blacklistLength * 20 } - } else if (flag === SESSIONS_FLAG_IDENTITY_SIGNER) { - // Identity signer - const nodeLength = 21 // Flag + address - if (bytes.length < nodeLength) { - throw new Error('Invalid identity signer length') - } - return { - topology: { type: 'identity-signer', identitySigner: Address.from(Hex.fromBytes(bytes.slice(1, nodeLength))) }, - pointer: nodeLength, - } - } else { - throw new Error(`Invalid topology flag: ${flag}`) - } -} - // JSON export function sessionsTopologyToJson(topology: SessionsTopology): string { @@ -500,39 +416,28 @@ function sessionsTopologyFromParsed(parsed: any): SessionsTopology { // Operations -function removeLeaf(topology: SessionsTopology, leaf: SessionLeaf | SessionNode): SessionsTopology | null { - if (isSessionsLeaf(topology) && isSessionsLeaf(leaf)) { - if (topology.type === leaf.type) { - if (isSessionPermissions(topology) && isSessionPermissions(leaf)) { - if (Address.isEqual(topology.signer, leaf.signer)) { - return null - } - } else if (isImplicitBlacklist(topology) && isImplicitBlacklist(leaf)) { - // Remove blacklist items in leaf from topology - const newBlacklist = topology.blacklist.filter((b) => !leaf.blacklist.includes(b)) - if (newBlacklist.length === 0) { - return null - } - return { type: 'implicit-blacklist', blacklist: newBlacklist } - } else if (isIdentitySignerLeaf(topology) && isIdentitySignerLeaf(leaf)) { - // Remove identity signer from topology - if (Address.isEqual(topology.identitySigner, leaf.identitySigner)) { - return null - } - } - } - } else if (isSessionsNode(topology) && isSessionsNode(leaf)) { - if (Hex.isEqual(topology, leaf)) { - // Match, remove the node +/** + * Removes all explicit sessions (permissions leaf nodes) that match the given signer from the topology. + * Returns the updated topology or null if it becomes empty (for nesting). + * If the signer is not found, the topology is returned unchanged. + */ +export function removeExplicitSession( + topology: SessionsTopology, + signerAddress: `0x${string}`, +): SessionsTopology | null { + if (isSessionPermissions(topology)) { + if (Address.isEqual(topology.signer, signerAddress)) { return null } + // Return the leaf unchanged + return topology } // If it's a branch, recurse on each child: if (isSessionsBranch(topology)) { const newChildren: SessionsTopology[] = [] for (const child of topology) { - const updatedChild = removeLeaf(child, leaf) + const updatedChild = removeExplicitSession(child, signerAddress) if (updatedChild != null) { newChildren.push(updatedChild) } @@ -556,29 +461,6 @@ function removeLeaf(topology: SessionsTopology, leaf: SessionLeaf | SessionNode) return topology } -/** - * Removes all explicit sessions (permissions leaf nodes) that match the given signer from the topology. - * Returns the updated topology or null if it becomes empty (for nesting). - * If the signer is not found, the topology is returned unchanged. - */ -export function removeExplicitSession( - topology: SessionsTopology, - signerAddress: `0x${string}`, -): SessionsTopology | null { - const explicitLeaf = getSessionPermissions(topology, signerAddress) - if (!explicitLeaf) { - // Not found, return unchanged - return topology - } - const removed = removeLeaf(topology, explicitLeaf) - if (!removed) { - // Empty, return null - return null - } - // Balance it - return balanceSessionsTopology(removed) -} - export function addExplicitSession( topology: SessionsTopology, sessionPermissions: SessionPermissions, @@ -592,33 +474,6 @@ export function addExplicitSession( return balanceSessionsTopology(merged) } -export function removeIdentitySigner( - topology: SessionsTopology, - identitySigner: Address.Address, -): SessionsTopology | null { - const identityLeaf: IdentitySignerLeaf = { - type: 'identity-signer', - identitySigner, - } - // Remove the old identity signer and balance - const removed = removeLeaf(topology, identityLeaf) - if (!removed) { - // Empty, return null - return null - } - return balanceSessionsTopology(removed) -} - -export function addIdentitySigner(topology: SessionsTopology, identitySigner: Address.Address): SessionsTopology { - // Find the session in the topology - if (getIdentitySigners(topology).some((s) => Address.isEqual(s, identitySigner))) { - throw new Error('Identity signer already exists') - } - // Merge and balance - const merged = mergeSessionsTopologies(topology, { type: 'identity-signer', identitySigner }) - return balanceSessionsTopology(merged) -} - /** * Merges two topologies into a new branch of [a, b]. */ @@ -666,9 +521,17 @@ function buildBalancedSessionsTopology(items: (SessionLeaf | SessionNode)[]): Se /** * Balances the topology by flattening and rebuilding as a balanced binary tree. + * This does not make a binary tree as the blacklist and identity signer are included at the top level. */ export function balanceSessionsTopology(topology: SessionsTopology): SessionsTopology { - return buildBalancedSessionsTopology(flattenSessionsTopology(topology)) + const flattened = flattenSessionsTopology(topology) + const blacklist = flattened.find((l) => isImplicitBlacklist(l)) + const identitySigner = flattened.find((l) => isIdentitySignerLeaf(l)) + const leaves = flattened.filter((l) => isSessionPermissions(l)) + if (!blacklist || !identitySigner) { + throw new Error('No blacklist or identity signer') + } + return buildBalancedSessionsTopology([blacklist, identitySigner, ...leaves]) } /** @@ -733,10 +596,9 @@ export function minimiseSessionsTopology( topology: SessionsTopology, explicitSigners: Address.Address[] = [], implicitSigners: Address.Address[] = [], - identitySigner?: Address.Address, ): SessionsTopology { if (isSessionsBranch(topology)) { - const branches = topology.map((b) => minimiseSessionsTopology(b, explicitSigners, implicitSigners, identitySigner)) + const branches = topology.map((b) => minimiseSessionsTopology(b, explicitSigners, implicitSigners)) // If all branches are nodes, the branch can be a node too if (branches.every((b) => isSessionsNode(b))) { return Hash.keccak256(Bytes.concat(...branches.map((b) => Hex.toBytes(b))), { as: 'Hex' }) @@ -759,11 +621,7 @@ export function minimiseSessionsTopology( return topology } if (isIdentitySignerLeaf(topology)) { - if (identitySigner && !Address.isEqual(topology.identitySigner, identitySigner)) { - // Not the identity signer we're looking for, so roll it up - return GenericTree.hash(encodeLeafToGeneric(topology)) - } - // Return this identity signer leaf + // Never roll up the identity signer return topology } if (isSessionsNode(topology)) { @@ -809,18 +667,15 @@ export function removeFromImplicitBlacklist(topology: SessionsTopology, address: /** * Generate an empty sessions topology with the given identity signer. No session permission and an empty blacklist */ -export function emptySessionsTopology( - identitySigner: Address.Address | [Address.Address, ...Address.Address[]], -): SessionsTopology { - if (!Array.isArray(identitySigner)) { - return emptySessionsTopology([identitySigner]) - } - const flattenedTopology: SessionLeaf[] = [ +export function emptySessionsTopology(identitySigner: Address.Address): SessionsTopology { + return [ { type: 'implicit-blacklist', blacklist: [], }, - ...identitySigner.map((signer): IdentitySignerLeaf => ({ type: 'identity-signer', identitySigner: signer })), + { + type: 'identity-signer', + identitySigner, + }, ] - return buildBalancedSessionsTopology(flattenedTopology) } diff --git a/packages/wallet/primitives/src/session-signature.ts b/packages/wallet/primitives/src/session-signature.ts index c3f67ca241..8b9306d7fc 100644 --- a/packages/wallet/primitives/src/session-signature.ts +++ b/packages/wallet/primitives/src/session-signature.ts @@ -1,19 +1,18 @@ import { Address, Bytes, Hash, Hex } from 'ox' -import { Attestation, Extensions, Payload } from './index.js' +import { Attestation, encode, encodeForJson, fromParsed, toJson } from './attestation.js' import { MAX_PERMISSIONS_COUNT } from './permission.js' import { - decodeSessionsTopology, encodeSessionsTopology, - getIdentitySigners, isCompleteSessionsTopology, minimiseSessionsTopology, SessionsTopology, } from './session-config.js' import { RSY } from './signature.js' -import { minBytesFor, packRSY, unpackRSY } from './utils.js' +import { minBytesFor, packRSY } from './utils.js' +import { Payload } from './index.js' export type ImplicitSessionCallSignature = { - attestation: Attestation.Attestation + attestation: Attestation identitySignature: RSY sessionSignature: RSY } @@ -46,7 +45,7 @@ export function sessionCallSignatureToJson(callSignature: SessionCallSignature): export function encodeSessionCallSignatureForJson(callSignature: SessionCallSignature): any { if (isImplicitSessionCallSignature(callSignature)) { return { - attestation: Attestation.encodeForJson(callSignature.attestation), + attestation: encodeForJson(callSignature.attestation), identitySignature: rsyToRsvStr(callSignature.identitySignature), sessionSignature: rsyToRsvStr(callSignature.sessionSignature), } @@ -68,7 +67,7 @@ export function sessionCallSignatureFromJson(json: string): SessionCallSignature export function sessionCallSignatureFromParsed(decoded: any): SessionCallSignature { if (decoded.attestation) { return { - attestation: Attestation.fromParsed(decoded.attestation), + attestation: fromParsed(decoded.attestation), identitySignature: rsyFromRsvStr(decoded.identitySignature), sessionSignature: rsyFromRsvStr(decoded.sessionSignature), } @@ -104,19 +103,9 @@ function rsyFromRsvStr(sigStr: string): RSY { // Usage -/** - * Encodes a list of session call signatures into a bytes array for contract validation. - * @param callSignatures The list of session call signatures to encode. - * @param topology The complete session topology. - * @param explicitSigners The list of explicit signers to encode. Others will be hashed into nodes. - * @param implicitSigners The list of implicit signers to encode. Others will be hashed into nodes. - * @param identitySigner The identity signer to encode. Others will be hashed into nodes. - * @returns The encoded session call signatures. - */ -export function encodeSessionSignature( +export function encodeSessionCallSignatures( callSignatures: SessionCallSignature[], topology: SessionsTopology, - identitySigner: Address.Address, explicitSigners: Address.Address[] = [], implicitSigners: Address.Address[] = [], ): Bytes.Bytes { @@ -128,14 +117,8 @@ export function encodeSessionSignature( throw new Error('Incomplete topology') } - // Check the topology contains the identity signer - const identitySigners = getIdentitySigners(topology) - if (!identitySigners.some((s) => Address.isEqual(s, identitySigner))) { - throw new Error('Identity signer not found') - } - // Optimise the configuration tree by rolling unused signers into nodes. - topology = minimiseSessionsTopology(topology, explicitSigners, implicitSigners, identitySigner) + topology = minimiseSessionsTopology(topology, explicitSigners, implicitSigners) // Session topology const encodedTopology = encodeSessionsTopology(topology) @@ -151,12 +134,10 @@ export function encodeSessionSignature( // Map each call signature to its attestation index callSignatures.filter(isImplicitSessionCallSignature).forEach((callSig) => { if (callSig.attestation) { - const attestationStr = Attestation.toJson(callSig.attestation) + const attestationStr = toJson(callSig.attestation) if (!attestationMap.has(attestationStr)) { attestationMap.set(attestationStr, encodedAttestations.length) - encodedAttestations.push( - Bytes.concat(Attestation.encode(callSig.attestation), packRSY(callSig.identitySignature)), - ) + encodedAttestations.push(Bytes.concat(encode(callSig.attestation), packRSY(callSig.identitySignature))) } } }) @@ -171,7 +152,7 @@ export function encodeSessionSignature( for (const callSignature of callSignatures) { if (isImplicitSessionCallSignature(callSignature)) { // Implicit - const attestationStr = Attestation.toJson(callSignature.attestation) + const attestationStr = toJson(callSignature.attestation) const attestationIndex = attestationMap.get(attestationStr) if (attestationIndex === undefined) { // Unreachable @@ -195,126 +176,24 @@ export function encodeSessionSignature( return Bytes.concat(...parts) } -export function decodeSessionSignature(encodedSignatures: Bytes.Bytes): { - topology: SessionsTopology - callSignatures: SessionCallSignature[] -} { - let offset = 0 - - // Parse session topology length (3 bytes) - const topologyLength = Bytes.toNumber(encodedSignatures.slice(offset, offset + 3)) - offset += 3 - - // Parse session topology - const topologyBytes = encodedSignatures.slice(offset, offset + topologyLength) - offset += topologyLength - const topology = decodeSessionsTopology(topologyBytes) - - // Parse attestations count (1 byte) - const attestationsCount = Bytes.toNumber(encodedSignatures.slice(offset, offset + 1)) - offset += 1 - - // Parse attestations and identity signatures - const attestations: Attestation.Attestation[] = [] - const identitySignatures: RSY[] = [] - - for (let i = 0; i < attestationsCount; i++) { - // Parse attestation - const attestation = Attestation.decode(encodedSignatures.slice(offset)) - offset += Attestation.encode(attestation).length - attestations.push(attestation) +// Helper - // Parse identity signature (64 bytes) - const identitySignature = unpackRSY(encodedSignatures.slice(offset, offset + 64)) - offset += 64 - identitySignatures.push(identitySignature) - } - - // Parse call signatures - const callSignatures: SessionCallSignature[] = [] - - while (offset < encodedSignatures.length) { - // Parse flag byte - const flagByte = encodedSignatures[offset]! - offset += 1 - - // Parse session signature (64 bytes) - const sessionSignature = unpackRSY(encodedSignatures.slice(offset, offset + 64)) - offset += 64 - - // Check if implicit (MSB set) or explicit - if ((flagByte & 0x80) !== 0) { - // Implicit call signature - const attestationIndex = flagByte & 0x7f - if (attestationIndex >= attestations.length) { - throw new Error('Invalid attestation index') - } - - callSignatures.push({ - attestation: attestations[attestationIndex]!, - identitySignature: identitySignatures[attestationIndex]!, - sessionSignature, - }) - } else { - // Explicit call signature - const permissionIndex = flagByte - callSignatures.push({ - permissionIndex: BigInt(permissionIndex), - sessionSignature, - }) - } - } - - return { - topology, - callSignatures, - } -} - -// Call encoding - -/** - * Hashes a call with replay protection parameters. - * @param payload The payload to hash. - * @param callIdx The index of the call to hash. - * @param chainId The chain ID. Use 0 when noChainId enabled. - * @param sessionManagerAddress The session manager address to compile the hash for. Only required to support deprecated hash encodings for Dev1, Dev2 and Rc3. - * @returns The hash of the call with replay protection parameters for sessions. - */ -export function hashPayloadWithCallIdx( - wallet: Address.Address, - payload: Payload.Calls & Payload.Parent, +export function hashCallWithReplayProtection( + payload: Payload.Calls, callIdx: number, chainId: number, - sessionManagerAddress?: Address.Address, + skipCallIdx: boolean = false, // Deprecated. Dev1 and Dev2 support ): Hex.Hex { - // Support deprecated hashes for Dev1, Dev2 and Rc3 - const deprecatedHashing = - sessionManagerAddress && - (Address.isEqual(sessionManagerAddress, Extensions.Dev1.sessions) || - Address.isEqual(sessionManagerAddress, Extensions.Dev2.sessions) || - Address.isEqual(sessionManagerAddress, Extensions.Rc3.sessions)) - if (deprecatedHashing) { - const call = payload.calls[callIdx]! - const ignoreCallIdx = !Address.isEqual(sessionManagerAddress, Extensions.Rc3.sessions) - return Hex.fromBytes( - Hash.keccak256( - Bytes.concat( - Bytes.fromNumber(chainId, { size: 32 }), - Bytes.fromNumber(payload.space, { size: 32 }), - Bytes.fromNumber(payload.nonce, { size: 32 }), - ignoreCallIdx ? Bytes.from([]) : Bytes.fromNumber(callIdx, { size: 32 }), - Bytes.fromHex(Payload.hashCall(call)), - ), + const call = payload.calls[callIdx]! + return Hex.fromBytes( + Hash.keccak256( + Bytes.concat( + Bytes.fromNumber(chainId, { size: 32 }), + Bytes.fromNumber(payload.space, { size: 32 }), + Bytes.fromNumber(payload.nonce, { size: 32 }), + skipCallIdx ? Bytes.from([]) : Bytes.fromNumber(callIdx, { size: 32 }), + Bytes.fromHex(Payload.hashCall(call)), ), - ) - } - // Current hashing scheme uses entire payload hash and call index (without last parent) - const parentWallets = payload.parentWallets - if (payload.parentWallets && payload.parentWallets.length > 0) { - payload.parentWallets.pop() - } - const payloadHash = Payload.hash(wallet, chainId, payload) - payload.parentWallets = parentWallets - return Hex.fromBytes(Hash.keccak256(Bytes.concat(payloadHash, Bytes.fromNumber(callIdx, { size: 32 })))) + ), + ) } diff --git a/packages/wallet/primitives/test/config.test.ts b/packages/wallet/primitives/test/config.test.ts index b4ff8e6d91..ffa7a653c4 100644 --- a/packages/wallet/primitives/test/config.test.ts +++ b/packages/wallet/primitives/test/config.test.ts @@ -33,13 +33,11 @@ import { maximumDepth, evaluateConfigurationSafety, normalizeSignerSignature, - replaceAddress, } from '../src/config.js' describe('Config', () => { const testAddress1 = '0x742d35cc6635c0532925a3b8d563a6b35b7f05f1' const testAddress2 = '0x8ba1f109551bd432803012645aac136c776056c0' - const replacementAddress = '0x1111111111111111111111111111111111111111' const testImageHash = '0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef' const testDigest = '0xabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef' @@ -318,67 +316,6 @@ describe('Config', () => { }) }) - describe('replaceAddress', () => { - it('should replace signer leaf addresses', () => { - const signerLeaf: SignerLeaf = { ...sampleSignerLeaf } - - const result = replaceAddress(signerLeaf, testAddress1, replacementAddress) - - expect(result).toEqual({ ...sampleSignerLeaf, address: replacementAddress }) - expect(result).not.toBe(signerLeaf) - expect(signerLeaf.address).toBe(testAddress1) - }) - - it('should replace sapient signer leaf addresses', () => { - const sapientLeaf: SapientSignerLeaf = { ...sampleSapientSignerLeaf } - - const result = replaceAddress(sapientLeaf, testAddress2, replacementAddress) - - expect(result).toEqual({ ...sampleSapientSignerLeaf, address: replacementAddress }) - expect(result).not.toBe(sapientLeaf) - expect(sapientLeaf.address).toBe(testAddress2) - }) - - it('should recurse through nodes and nested leaves', () => { - const nestedSapient: SapientSignerLeaf = { ...sampleSapientSignerLeaf, address: testAddress1 } - const nestedLeaf: NestedLeaf = { - type: 'nested', - tree: [nestedSapient, sampleSubdigestLeaf], - weight: 5n, - threshold: 1n, - } - const topology: Topology = [{ ...sampleSignerLeaf }, nestedLeaf] - - const result = replaceAddress(topology, testAddress1, replacementAddress) - - expect(result).toEqual([ - { ...sampleSignerLeaf, address: replacementAddress }, - { - ...nestedLeaf, - tree: [{ ...nestedSapient, address: replacementAddress }, sampleSubdigestLeaf], - }, - ]) - expect(nestedSapient.address).toBe(testAddress1) - expect((nestedLeaf.tree as Node)[1]).toBe(sampleSubdigestLeaf) - }) - - it('should return the original topology when no address matches', () => { - const sapientLeaf: SapientSignerLeaf = { ...sampleSapientSignerLeaf } - - const result = replaceAddress(sapientLeaf, replacementAddress, testAddress1) - - expect(result).toBe(sapientLeaf) - }) - - it('should leave non-signer leaves unchanged', () => { - expect(replaceAddress(sampleSubdigestLeaf, testAddress1, replacementAddress)).toBe(sampleSubdigestLeaf) - expect(replaceAddress(sampleAnyAddressSubdigestLeaf, testAddress1, replacementAddress)).toBe( - sampleAnyAddressSubdigestLeaf, - ) - expect(replaceAddress(sampleNodeLeaf, testAddress1, replacementAddress)).toBe(sampleNodeLeaf) - }) - }) - describe('getWeight', () => { it('should return correct weight for signer leaf with canSign true', () => { const result = getWeight(sampleSignerLeaf, () => true) diff --git a/packages/wallet/primitives/test/erc-6492.test.ts b/packages/wallet/primitives/test/erc-6492.test.ts index 7398f58db9..dcb7688ee0 100644 --- a/packages/wallet/primitives/test/erc-6492.test.ts +++ b/packages/wallet/primitives/test/erc-6492.test.ts @@ -1,6 +1,6 @@ import { describe, expect, it, vi } from 'vitest' import { Address, Bytes, Hex, Provider } from 'ox' -import { SignatureErc6492 } from 'ox/erc6492' +import { WrappedSignature } from 'ox/erc6492' import { deploy, wrap, decode, isValid } from '../src/erc-6492.js' import { Context } from '../src/context.js' @@ -82,7 +82,7 @@ describe('ERC-6492', () => { expect(result.startsWith('0x')).toBe(true) // Should end with the magic bytes - expect(result.endsWith(SignatureErc6492.magicBytes.slice(2))).toBe(true) + expect(result.endsWith(WrappedSignature.magicBytes.slice(2))).toBe(true) // Should contain the original signature data somewhere expect(result.length).toBeGreaterThan(testSignature.length) @@ -96,7 +96,7 @@ describe('ERC-6492', () => { // Convert to hex to check magic bytes const resultHex = Bytes.toHex(result) - expect(resultHex.endsWith(SignatureErc6492.magicBytes.slice(2))).toBe(true) + expect(resultHex.endsWith(WrappedSignature.magicBytes.slice(2))).toBe(true) }) it('should return same type as input signature', () => { @@ -133,7 +133,7 @@ describe('ERC-6492', () => { // The wrapped signature should contain encoded: address, bytes (data), bytes (signature) expect(result.length).toBeGreaterThan(testSignature.length + deployData.data.length) expect(result).toContain(testAddress.slice(2)) // Address without 0x - expect(result.endsWith(SignatureErc6492.magicBytes.slice(2))).toBe(true) + expect(result.endsWith(WrappedSignature.magicBytes.slice(2))).toBe(true) }) }) @@ -209,7 +209,7 @@ describe('ERC-6492', () => { it('should handle malformed wrapped signature gracefully', () => { // Create a signature that ends with magic bytes but has invalid encoding - const malformedSig = ('0x1234' + SignatureErc6492.magicBytes.slice(2)) as Hex.Hex + const malformedSig = ('0x1234' + WrappedSignature.magicBytes.slice(2)) as Hex.Hex const result = decode(malformedSig) // Should return original signature when decoding fails @@ -391,7 +391,7 @@ describe('ERC-6492', () => { // 2. Wrap signature with deploy data const wrappedSig = wrap(testSignature, deployCall) - expect(wrappedSig.endsWith(SignatureErc6492.magicBytes.slice(2))).toBe(true) + expect(wrappedSig.endsWith(WrappedSignature.magicBytes.slice(2))).toBe(true) // 3. Decode wrapped signature const decoded = decode(wrappedSig) @@ -457,7 +457,7 @@ describe('ERC-6492', () => { it('should handle signatures that accidentally contain magic bytes', () => { // Create a signature that contains the magic bytes but isn't wrapped - const magicInSignature = (testSignature + SignatureErc6492.magicBytes.slice(2) + '1234') as Hex.Hex + const magicInSignature = (testSignature + WrappedSignature.magicBytes.slice(2) + '1234') as Hex.Hex const result = decode(magicInSignature) // Should try to decode, but if it fails, should return original diff --git a/packages/wallet/primitives/test/session-config.test.ts b/packages/wallet/primitives/test/session-config.test.ts index 6e20d55974..7d092c15c0 100644 --- a/packages/wallet/primitives/test/session-config.test.ts +++ b/packages/wallet/primitives/test/session-config.test.ts @@ -1,60 +1,60 @@ -import { Address, Bytes } from 'ox' import { describe, expect, it } from 'vitest' +import { Address, Bytes, Hex } from 'ox' -import { ChainId } from '../src/network.js' -import { ParameterOperation, Permission, SessionPermissions } from '../src/permission.js' import { - IdentitySignerLeaf, - ImplicitBlacklistLeaf, - SESSIONS_FLAG_BLACKLIST, + SESSIONS_FLAG_PERMISSIONS, + SESSIONS_FLAG_NODE, SESSIONS_FLAG_BRANCH, + SESSIONS_FLAG_BLACKLIST, SESSIONS_FLAG_IDENTITY_SIGNER, - SESSIONS_FLAG_NODE, - SESSIONS_FLAG_PERMISSIONS, - SessionBranch, - SessionNode, + ImplicitBlacklistLeaf, + IdentitySignerLeaf, SessionPermissionsLeaf, + SessionNode, + SessionLeaf, + SessionBranch, SessionsTopology, - addExplicitSession, - addToImplicitBlacklist, - balanceSessionsTopology, - cleanSessionsTopology, - configurationTreeToSessionsTopology, - decodeLeafFromBytes, - decodeSessionsTopology, - emptySessionsTopology, - encodeLeafToGeneric, - encodeSessionsTopology, - getExplicitSigners, - getIdentitySigners, + isSessionsTopology, + isCompleteSessionsTopology, + getIdentitySigner, getImplicitBlacklist, getImplicitBlacklistLeaf, getSessionPermissions, - isCompleteSessionsTopology, - isSessionsTopology, + getExplicitSigners, + encodeLeafToGeneric, + decodeLeafFromBytes, + sessionsTopologyToConfigurationTree, + configurationTreeToSessionsTopology, + encodeSessionsTopology, + sessionsTopologyToJson, + sessionsTopologyFromJson, + removeExplicitSession, + addExplicitSession, mergeSessionsTopologies, + balanceSessionsTopology, + cleanSessionsTopology, minimiseSessionsTopology, - removeExplicitSession, + addToImplicitBlacklist, removeFromImplicitBlacklist, - sessionsTopologyFromJson, - sessionsTopologyToConfigurationTree, - sessionsTopologyToJson, + emptySessionsTopology, } from '../src/session-config.js' +import { SessionPermissions } from '../src/permission.js' +import { ChainId } from '../src/network.js' describe('Session Config', () => { // Test data - const testAddress1: Address.Address = '0x742d35cc6635c0532925a3b8d563a6b35b7f05f1' - const testAddress2: Address.Address = '0x8ba1f109551bd432803012645aac136c776056c0' - const testAddress3: Address.Address = '0xa0b86a33e6f8b5f56e64c9e1a1b8c6a9cc4b9a9e' - const testNode: SessionNode = '0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef' + const testAddress1 = '0x742d35cc6635c0532925a3b8d563a6b35b7f05f1' as Address.Address + const testAddress2 = '0x8ba1f109551bd432803012645aac136c776056c0' as Address.Address + const testAddress3 = '0xa0b86a33e6f8b5f56e64c9e1a1b8c6a9cc4b9a9e' as Address.Address + const testNode = '0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef' as SessionNode - const samplePermission: Permission = { + const samplePermission = { target: testAddress3, rules: [ { cumulative: false, - operation: ParameterOperation.EQUAL, - value: Bytes.fromHex('0x0000000000000000000000000000000000000000000000000000000000000000'), + operation: 0, // EQUAL + value: Bytes.fromHex('0x'), offset: 0n, mask: Bytes.fromHex('0xffffffff00000000000000000000000000000000000000000000000000000000'), }, @@ -152,9 +152,9 @@ describe('Session Config', () => { expect(isCompleteSessionsTopology(duplicateBlacklist)).toBe(false) }) - it('should return true for topology with multiple identity signers', () => { + it('should return false for topology with multiple identity signers', () => { const duplicateIdentity = [sampleBlacklistLeaf, sampleIdentitySignerLeaf, sampleIdentitySignerLeaf] - expect(isCompleteSessionsTopology(duplicateIdentity)).toBe(true) + expect(isCompleteSessionsTopology(duplicateIdentity)).toBe(false) }) it('should return false for invalid topology', () => { @@ -165,29 +165,29 @@ describe('Session Config', () => { }) describe('Topology Queries', () => { - describe('getIdentitySigners', () => { + describe('getIdentitySigner', () => { it('should return identity signer from identity signer leaf', () => { - const result = getIdentitySigners(sampleIdentitySignerLeaf) - expect(result).toEqual([testAddress1]) + const result = getIdentitySigner(sampleIdentitySignerLeaf) + expect(result).toBe(testAddress1) }) it('should return identity signer from branch', () => { - const result = getIdentitySigners(sampleCompleteTopology) - expect(result).toEqual([testAddress1]) + const result = getIdentitySigner(sampleCompleteTopology) + expect(result).toBe(testAddress1) }) - it('should return empty array when no identity signer present', () => { - const result = getIdentitySigners(sampleSessionPermissionsLeaf) - expect(result).toEqual([]) + it('should return null when no identity signer present', () => { + const result = getIdentitySigner(sampleSessionPermissionsLeaf) + expect(result).toBe(null) }) - it('should return multiple identity signers', () => { + it('should throw for multiple identity signers', () => { const multipleIdentity = [ sampleIdentitySignerLeaf, sampleIdentitySignerLeaf, sampleBlacklistLeaf, ] as SessionBranch - expect(getIdentitySigners(multipleIdentity)).toEqual([testAddress1, testAddress1]) + expect(() => getIdentitySigner(multipleIdentity)).toThrow('Multiple identity signers') }) }) @@ -400,14 +400,12 @@ describe('Session Config', () => { }) }) - describe('Sessions Topology Encoding and Decoding', () => { + describe('Sessions Topology Encoding', () => { describe('encodeSessionsTopology', () => { it('should encode session permissions leaf', () => { const result = encodeSessionsTopology(sampleSessionPermissionsLeaf) expect(result).toBeInstanceOf(Uint8Array) expect(result[0] >> 4).toBe(SESSIONS_FLAG_PERMISSIONS) - const decoded = decodeSessionsTopology(result) - expect(decoded).toEqual(sampleSessionPermissionsLeaf) }) it('should encode session node', () => { @@ -415,34 +413,12 @@ describe('Session Config', () => { expect(result).toBeInstanceOf(Uint8Array) expect(result[0] >> 4).toBe(SESSIONS_FLAG_NODE) expect(result.length).toBe(33) // 1 flag byte + 32 hash bytes - const decoded = decodeSessionsTopology(result) - expect(decoded).toEqual(testNode) }) it('should encode blacklist leaf', () => { const result = encodeSessionsTopology(sampleBlacklistLeaf) expect(result).toBeInstanceOf(Uint8Array) expect(result[0] >> 4).toBe(SESSIONS_FLAG_BLACKLIST) - const decoded = decodeSessionsTopology(result) - expect(decoded).toEqual(sampleBlacklistLeaf) - }) - - it('should encode large blacklist leaf', () => { - const blacklistCount = 1000 - const largeBlacklist: ImplicitBlacklistLeaf = { - type: 'implicit-blacklist', - blacklist: Array(blacklistCount).fill(testAddress1), - } - const result = encodeSessionsTopology(largeBlacklist) - expect(result).toBeInstanceOf(Uint8Array) - expect(result[0]).toBe((SESSIONS_FLAG_BLACKLIST << 4) | 0x0f) // Encoded large size flag - expect(Bytes.toNumber(result.slice(1, 3))).toBe(blacklistCount) - expect(result.slice(3)).toEqual( - Bytes.concat(...largeBlacklist.blacklist.map((b) => Bytes.padLeft(Bytes.fromHex(b), 20))), - ) - expect(result.length).toBe(3 + blacklistCount * 20) - const decoded = decodeSessionsTopology(result) - expect(decoded).toEqual(largeBlacklist) }) it('should encode identity signer leaf', () => { @@ -450,16 +426,12 @@ describe('Session Config', () => { expect(result).toBeInstanceOf(Uint8Array) expect(result[0] >> 4).toBe(SESSIONS_FLAG_IDENTITY_SIGNER) expect(result.length).toBe(21) // 1 flag byte + 20 address bytes - const decoded = decodeSessionsTopology(result) - expect(decoded).toEqual(sampleIdentitySignerLeaf) }) it('should encode session branch', () => { const result = encodeSessionsTopology(sampleBranch) expect(result).toBeInstanceOf(Uint8Array) expect(result[0] >> 4).toBe(SESSIONS_FLAG_BRANCH) - const decoded = decodeSessionsTopology(result) - expect(decoded).toEqual(sampleBranch) }) it('should handle large blacklist with extended encoding', () => { @@ -470,15 +442,6 @@ describe('Session Config', () => { const result = encodeSessionsTopology(largeBlacklist) expect(result).toBeInstanceOf(Uint8Array) expect(result[0] & 0x0f).toBe(0x0f) // Extended encoding flag - const decoded = decodeSessionsTopology(result) - expect(decoded).toEqual(largeBlacklist) - }) - - it('should handle complete topology', () => { - const result = encodeSessionsTopology(sampleCompleteTopology) - expect(result).toBeInstanceOf(Uint8Array) - const decoded = decodeSessionsTopology(result) - expect(decoded).toEqual(sampleCompleteTopology) }) it('should throw for blacklist too large', () => { @@ -656,9 +619,13 @@ describe('Session Config', () => { expect(isSessionsTopology(result)).toBe(true) const blacklist = getImplicitBlacklist(result) - const identitySigners = getIdentitySigners(result) + const identitySigner = getIdentitySigner(result) expect(blacklist).toBeTruthy() - expect(identitySigners).toBeTruthy() + expect(identitySigner).toBeTruthy() + }) + + it('should throw when missing blacklist or identity signer', () => { + expect(() => balanceSessionsTopology(sampleSessionPermissionsLeaf)).toThrow('No blacklist or identity signer') }) }) @@ -763,137 +730,6 @@ describe('Session Config', () => { it('should throw for invalid topology', () => { expect(() => minimiseSessionsTopology({} as any, [], [])).toThrow('Invalid topology') }) - - it('should minimize topology with multiple identity signers but keep only the specified one', () => { - // Create multiple identity signer leaves - const identitySigner1: IdentitySignerLeaf = { - type: 'identity-signer', - identitySigner: testAddress1, - } - const identitySigner2: IdentitySignerLeaf = { - type: 'identity-signer', - identitySigner: testAddress2, - } - const identitySigner3: IdentitySignerLeaf = { - type: 'identity-signer', - identitySigner: testAddress3, - } - - // Create topology with multiple identity signers - const topologyWithMultipleIdentitySigners: SessionBranch = [ - sampleBlacklistLeaf, - identitySigner1, - identitySigner2, - identitySigner3, - sampleSessionPermissionsLeaf, - ] - - // Minimize with only testAddress2 as the identity signer - const result = minimiseSessionsTopology( - topologyWithMultipleIdentitySigners, - [], // no explicit signers - [], // no implicit signers - testAddress2, // only keep this identity signer - ) - - expect(isSessionsTopology(result)).toBe(true) - - // Get all identity signers from the result - const identitySigners = getIdentitySigners(result) - - // Should only contain the specified identity signer - expect(identitySigners).toEqual([testAddress2]) - expect(identitySigners).not.toContain(testAddress1) - expect(identitySigners).not.toContain(testAddress3) - - // Verify the result is still a valid topology - expect(isSessionsTopology(result)).toBe(true) - }) - - it('should minimize deeply nested topology with multiple identity signers but keep only the specified one', () => { - // Create multiple identity signer leaves - const identitySigner1: IdentitySignerLeaf = { - type: 'identity-signer', - identitySigner: testAddress1, - } - const identitySigner2: IdentitySignerLeaf = { - type: 'identity-signer', - identitySigner: testAddress2, - } - const identitySigner3: IdentitySignerLeaf = { - type: 'identity-signer', - identitySigner: testAddress3, - } - - // Create additional session permissions for nesting - const sessionPermissions2: SessionPermissionsLeaf = { - type: 'session-permissions', - signer: testAddress2, - chainId: ChainId.MAINNET, - valueLimit: 500000000000000000n, - deadline: BigInt(Math.floor(Date.now() / 1000) + 1800), - permissions: [samplePermission], - } - - const sessionPermissions3: SessionPermissionsLeaf = { - type: 'session-permissions', - signer: testAddress3, - chainId: ChainId.MAINNET, - valueLimit: 750000000000000000n, - deadline: BigInt(Math.floor(Date.now() / 1000) + 2700), - permissions: [samplePermission], - } - - // Create a deeply nested topology structure - // Level 1: Main branch - // Level 2: Nested branches containing different combinations - const deeplyNestedTopology: SessionBranch = [ - // First nested branch: blacklist + identity signer 1 - [ - sampleBlacklistLeaf, - identitySigner1, - sampleSessionPermissionsLeaf, // testAddress1 session - ], - // Second nested branch: identity signer 2 + session permissions 2 - [ - identitySigner2, - sessionPermissions2, // testAddress2 session - ], - // Third nested branch: identity signer 3 + session permissions 3 - [ - identitySigner3, - sessionPermissions3, // testAddress3 session - ], - ] - - // Minimize with only testAddress2 as the identity signer - const result = minimiseSessionsTopology( - deeplyNestedTopology, - [], // no explicit signers - [], // no implicit signers - testAddress2, // only keep this identity signer - ) - - expect(isSessionsTopology(result)).toBe(true) - - // Get all identity signers from the result - const identitySigners = getIdentitySigners(result) - - // Should only contain the specified identity signer - expect(identitySigners).toEqual([testAddress2]) - expect(identitySigners).not.toContain(testAddress1) - expect(identitySigners).not.toContain(testAddress3) - - // Verify the result is still a valid topology - expect(isSessionsTopology(result)).toBe(true) - - // Verify that the nested structure is properly minimized - // The result should be a branch with hashed nodes and the preserved identity signer - if (Array.isArray(result)) { - // Should have some components (hashed nodes and the preserved identity signer) - expect(result.length).toBeGreaterThan(0) - } - }) }) describe('addToImplicitBlacklist', () => { @@ -960,23 +796,8 @@ describe('Session Config', () => { expect(isCompleteSessionsTopology(result)).toBe(true) - const identitySigners = getIdentitySigners(result) - expect(identitySigners).toEqual([testAddress1]) - - const blacklist = getImplicitBlacklist(result) - expect(blacklist).toEqual([]) - - const explicitSigners = getExplicitSigners(result) - expect(explicitSigners).toEqual([]) - }) - - it('should create empty topology with multiple identity signers', () => { - const result = emptySessionsTopology([testAddress1, testAddress2]) - - expect(isCompleteSessionsTopology(result)).toBe(true) - - const identitySigners = getIdentitySigners(result) - expect(identitySigners).toEqual([testAddress1, testAddress2]) + const identitySigner = getIdentitySigner(result) + expect(identitySigner).toBe(testAddress1) const blacklist = getImplicitBlacklist(result) expect(blacklist).toEqual([]) @@ -1016,8 +837,8 @@ describe('Session Config', () => { expect(isSessionsTopology(nestedTopology)).toBe(true) expect(isCompleteSessionsTopology(nestedTopology)).toBe(true) - const identitySigners = getIdentitySigners(nestedTopology) - expect(identitySigners).toEqual([testAddress1]) + const identitySigner = getIdentitySigner(nestedTopology) + expect(identitySigner).toBe(testAddress1) const blacklist = getImplicitBlacklist(nestedTopology) expect(blacklist).toContain(testAddress2) @@ -1081,7 +902,7 @@ describe('Session Config', () => { expect(isCompleteSessionsTopology(deserialized)).toBe(true) // Verify data integrity - expect(getIdentitySigners(deserialized)).toEqual([testAddress1]) + expect(getIdentitySigner(deserialized)).toBe(testAddress1) expect(getImplicitBlacklist(deserialized)).toContain(testAddress3) expect(getSessionPermissions(deserialized, testAddress2)).toBeTruthy() }) diff --git a/packages/wallet/primitives/test/session-signature.test.ts b/packages/wallet/primitives/test/session-signature.test.ts index a1fd0fe233..887ca6b047 100644 --- a/packages/wallet/primitives/test/session-signature.test.ts +++ b/packages/wallet/primitives/test/session-signature.test.ts @@ -1,32 +1,29 @@ -import { Address, Bytes, Hex } from 'ox' import { describe, expect, it } from 'vitest' +import { Address, Bytes, Hash, Hex } from 'ox' -import { Attestation } from '../src/attestation.js' -import { ChainId } from '../src/network.js' -import * as Payload from '../src/payload.js' -import { ParameterOperation } from '../src/permission.js' -import { minimiseSessionsTopology, SessionsTopology } from '../src/session-config.js' import { - decodeSessionSignature, - encodeSessionCallSignatureForJson, - encodeSessionSignature, - ExplicitSessionCallSignature, - hashPayloadWithCallIdx, ImplicitSessionCallSignature, - isExplicitSessionCallSignature, - isImplicitSessionCallSignature, + ExplicitSessionCallSignature, SessionCallSignature, + isImplicitSessionCallSignature, + isExplicitSessionCallSignature, + sessionCallSignatureToJson, + encodeSessionCallSignatureForJson, sessionCallSignatureFromJson, sessionCallSignatureFromParsed, - sessionCallSignatureToJson, + encodeSessionCallSignatures, + hashCallWithReplayProtection, } from '../src/session-signature.js' import { RSY } from '../src/signature.js' -import { Extensions } from '../src/index.js' +import { Attestation } from '../src/attestation.js' +import { SessionsTopology } from '../src/session-config.js' +import * as Payload from '../src/payload.js' +import { ChainId } from '../src/network.js' describe('Session Signature', () => { // Test data - const testAddress1: Address.Address = '0x742d35cc6635c0532925a3b8d563a6b35b7f05f1' - const testAddress2: Address.Address = '0x8ba1f109551bd432803012645aac136c776056c0' + const testAddress1 = '0x742d35cc6635c0532925a3b8d563a6b35b7f05f1' as Address.Address + const testAddress2 = '0x8ba1f109551bd432803012645aac136c776056c0' as Address.Address const testChainId = ChainId.MAINNET const testSpace = 0n const testNonce = 1n @@ -105,7 +102,7 @@ describe('Session Signature', () => { rules: [ { cumulative: false, - operation: ParameterOperation.EQUAL, + operation: 0, value: Bytes.fromHex('0x'), offset: 0n, mask: Bytes.fromHex('0xffffffff00000000000000000000000000000000000000000000000000000000'), @@ -279,50 +276,31 @@ describe('Session Signature', () => { }) }) - describe('Signature Encoding and Decoding', () => { - describe('encode / decodeSessionCallSignatures', () => { + describe('Signature Encoding', () => { + describe('encodeSessionCallSignatures', () => { it('should encode single explicit session call signature', () => { const callSignatures = [sampleExplicitSignature] - const result = encodeSessionSignature(callSignatures, completeTopology, testAddress1) + const result = encodeSessionCallSignatures(callSignatures, completeTopology) expect(result).toBeInstanceOf(Uint8Array) expect(result.length).toBeGreaterThan(0) - - const decoded = decodeSessionSignature(result) - expect(decoded.callSignatures.length).toBe(1) - const callSignature = decoded.callSignatures[0]! - if (!isExplicitSessionCallSignature(callSignature)) { - throw new Error('Call signature is not explicit') - } - expect(callSignature.permissionIndex).toBe(callSignatures[0]!.permissionIndex) - // The topology gets minimized during encoding, so we expect the minimized version - const minimizedTopology = minimiseSessionsTopology(completeTopology, [], [], testAddress1) - expect(decoded.topology).toEqual(minimizedTopology) }) // Skip implicit signature tests that cause encoding issues it.skip('should encode single implicit session call signature', () => { const callSignatures = [sampleImplicitSignature] - const result = encodeSessionSignature(callSignatures, completeTopology, testAddress1) + const result = encodeSessionCallSignatures(callSignatures, completeTopology) expect(result).toBeInstanceOf(Uint8Array) expect(result.length).toBeGreaterThan(0) - - const decoded = decodeSessionSignature(result) - expect(decoded.callSignatures).toEqual(callSignatures) - expect(decoded.topology).toEqual(completeTopology) }) it.skip('should encode multiple mixed session call signatures', () => { const callSignatures = [sampleImplicitSignature, sampleExplicitSignature] - const result = encodeSessionSignature(callSignatures, completeTopology, testAddress1) + const result = encodeSessionCallSignatures(callSignatures, completeTopology) expect(result).toBeInstanceOf(Uint8Array) expect(result.length).toBeGreaterThan(0) - - const decoded = decodeSessionSignature(result) - expect(decoded.callSignatures).toEqual(callSignatures) - expect(decoded.topology).toEqual(completeTopology) }) it.skip('should encode multiple implicit signatures with same attestation', () => { @@ -333,15 +311,10 @@ describe('Session Signature', () => { sessionSignature: sampleRSY2, // Different session signature }, ] - const result = encodeSessionSignature(callSignatures, completeTopology, testAddress1) + const result = encodeSessionCallSignatures(callSignatures, completeTopology) expect(result).toBeInstanceOf(Uint8Array) expect(result.length).toBeGreaterThan(0) - - const decoded = decodeSessionSignature(result) - expect(decoded.callSignatures).toEqual(callSignatures) - const minimizedTopology = minimiseSessionsTopology(completeTopology, [], [], testAddress1) - expect(decoded.topology).toEqual(minimizedTopology) }) it('should throw for incomplete topology', () => { @@ -362,8 +335,8 @@ describe('Session Signature', () => { rules: [ { cumulative: false, - operation: ParameterOperation.EQUAL, - value: Bytes.fromHex('0x0000000000000000000000000000000000000000000000000000000000000000'), + operation: 0, + value: Bytes.fromHex('0x'), offset: 0n, mask: Bytes.fromHex('0xffffffff00000000000000000000000000000000000000000000000000000000'), }, @@ -374,7 +347,7 @@ describe('Session Signature', () => { // Missing identity signer, but has 2 elements for valid SessionBranch ] - expect(() => encodeSessionSignature([sampleExplicitSignature], incompleteTopology, testAddress1)).toThrow( + expect(() => encodeSessionCallSignatures([sampleExplicitSignature], incompleteTopology)).toThrow( 'Incomplete topology', ) }) @@ -385,85 +358,68 @@ describe('Session Signature', () => { sessionSignature: sampleRSY, } - expect(() => encodeSessionSignature([largeIndexSignature], completeTopology, testAddress1)).toThrow( + expect(() => encodeSessionCallSignatures([largeIndexSignature], completeTopology)).toThrow( 'Permission index is too large', ) }) + it('should throw for too many attestations (simplified)', () => { + // Just test that we can create many explicit signatures instead + const callSignatures: ExplicitSessionCallSignature[] = Array(10) + .fill(null) + .map((_, i) => ({ + permissionIndex: BigInt(i), + sessionSignature: sampleRSY, + })) + + const result = encodeSessionCallSignatures(callSignatures, completeTopology) + expect(result).toBeInstanceOf(Uint8Array) + }) + it('should handle explicit signers parameter', () => { const callSignatures = [sampleExplicitSignature] - const result = encodeSessionSignature(callSignatures, completeTopology, testAddress1) + const result = encodeSessionCallSignatures(callSignatures, completeTopology, [testAddress1]) expect(result).toBeInstanceOf(Uint8Array) expect(result.length).toBeGreaterThan(0) - - const decoded = decodeSessionSignature(result) - expect(decoded.callSignatures.length).toBe(1) - const callSignature = decoded.callSignatures[0]! - if (!isExplicitSessionCallSignature(callSignature)) { - throw new Error('Call signature is not explicit') - } - expect(callSignature.permissionIndex).toBe(callSignatures[0]!.permissionIndex) - // The topology gets minimized during encoding, so we expect the minimized version - const minimizedTopology = minimiseSessionsTopology(completeTopology, [], [], testAddress1) - expect(decoded.topology).toEqual(minimizedTopology) }) it('should handle implicit signers parameter', () => { const callSignatures = [sampleExplicitSignature] - const result = encodeSessionSignature(callSignatures, completeTopology, testAddress1, [], [testAddress2]) + const result = encodeSessionCallSignatures(callSignatures, completeTopology, [], [testAddress2]) expect(result).toBeInstanceOf(Uint8Array) expect(result.length).toBeGreaterThan(0) - - const decoded = decodeSessionSignature(result) - expect(decoded.callSignatures.length).toBe(1) - const callSignature = decoded.callSignatures[0]! - if (!isExplicitSessionCallSignature(callSignature)) { - throw new Error('Call signature is not explicit') - } - expect(callSignature.permissionIndex).toBe(callSignatures[0]!.permissionIndex) - // The topology gets minimized during encoding, so we expect the minimized version - const minimizedTopology = minimiseSessionsTopology(completeTopology, [], [testAddress2], testAddress1) - expect(decoded.topology).toEqual(minimizedTopology) }) it('should throw for invalid call signature type', () => { const invalidSignature = {} as any - expect(() => encodeSessionSignature([invalidSignature], completeTopology, testAddress1)).toThrow( + expect(() => encodeSessionCallSignatures([invalidSignature], completeTopology)).toThrow( 'Invalid call signature', ) }) - - it('should throw for identity signer not found', () => { - const callSignatures = [sampleExplicitSignature] - expect(() => - encodeSessionSignature(callSignatures, completeTopology, testAddress2, [], [testAddress2]), - ).toThrow('Identity signer not found') - }) }) }) describe('Helper Functions', () => { - describe('hashPayloadWithCallIdx', () => { + describe('hashCallWithReplayProtection', () => { it('should hash call with replay protection parameters', () => { - const result = hashPayloadWithCallIdx(testAddress1, samplePayload, 0, testChainId) + const result = hashCallWithReplayProtection(samplePayload, 0, testChainId) expect(result).toMatch(/^0x[0-9a-f]{64}$/) // 32-byte hex string expect(Hex.size(result)).toBe(32) }) it('should produce different hashes for different chain IDs', () => { - const hash1 = hashPayloadWithCallIdx(testAddress1, samplePayload, 0, ChainId.MAINNET) - const hash2 = hashPayloadWithCallIdx(testAddress1, samplePayload, 0, ChainId.POLYGON) + const hash1 = hashCallWithReplayProtection(samplePayload, 0, ChainId.MAINNET) + const hash2 = hashCallWithReplayProtection(samplePayload, 0, ChainId.POLYGON) expect(hash1).not.toBe(hash2) }) it('should produce different hashes for different spaces', () => { - const hash1 = hashPayloadWithCallIdx(testAddress1, samplePayload, 0, testChainId) - const hash2 = hashPayloadWithCallIdx( - testAddress1, + const hash1 = hashCallWithReplayProtection(samplePayload, 0, testChainId) + const hash2 = hashCallWithReplayProtection( { ...samplePayload, space: samplePayload.space + 1n }, 0, testChainId, @@ -473,9 +429,8 @@ describe('Session Signature', () => { }) it('should produce different hashes for different nonces', () => { - const hash1 = hashPayloadWithCallIdx(testAddress1, samplePayload, 0, testChainId) - const hash2 = hashPayloadWithCallIdx( - testAddress1, + const hash1 = hashCallWithReplayProtection(samplePayload, 0, testChainId) + const hash2 = hashCallWithReplayProtection( { ...samplePayload, nonce: samplePayload.nonce + 1n }, 0, testChainId, @@ -491,51 +446,17 @@ describe('Session Signature', () => { } const payload2 = { ...samplePayload, calls: [call2] } - const hash1 = hashPayloadWithCallIdx(testAddress1, samplePayload, 0, testChainId) - const hash2 = hashPayloadWithCallIdx(testAddress1, payload2, 0, testChainId) - - expect(hash1).not.toBe(hash2) - }) - - it('should produce different hashes for different wallets', () => { - const payload = { ...samplePayload, calls: [sampleCall, sampleCall] } - - const hash1 = hashPayloadWithCallIdx(testAddress1, payload, 0, testChainId) - const hash2 = hashPayloadWithCallIdx(testAddress2, payload, 0, testChainId) - - expect(hash1).not.toBe(hash2) - }) - - it('should NOT produce different hashes for different wallets when using deprecated hash encoding for Dev1 and Dev2', () => { - // This is ONLY for backward compatibility with Dev1 and Dev2 - // This is exploitable and should not be used in practice - const payload = { ...samplePayload, calls: [sampleCall, sampleCall] } - - const hash1 = hashPayloadWithCallIdx(testAddress1, payload, 0, testChainId, Extensions.Dev1.sessions) - const hash2 = hashPayloadWithCallIdx(testAddress2, payload, 0, testChainId, Extensions.Dev2.sessions) - - expect(hash1).toBe(hash2) - }) - - it('should produce different hashes for different wallets when using deprecated hash encoding for Dev1/2, Rc3 and latest', () => { - // This is ONLY for backward compatibility with Rc3 - // This is exploitable and should not be used in practice - const payload = { ...samplePayload, calls: [sampleCall, sampleCall] } - - const hash1 = hashPayloadWithCallIdx(testAddress1, payload, 0, testChainId, Extensions.Dev1.sessions) - const hash2 = hashPayloadWithCallIdx(testAddress2, payload, 0, testChainId, Extensions.Rc3.sessions) - const hash3 = hashPayloadWithCallIdx(testAddress2, payload, 0, testChainId) + const hash1 = hashCallWithReplayProtection(samplePayload, 0, testChainId) + const hash2 = hashCallWithReplayProtection(payload2, 0, testChainId) expect(hash1).not.toBe(hash2) - expect(hash1).not.toBe(hash3) - expect(hash2).not.toBe(hash3) }) it('should produce different hashes for same call at different index', () => { const payload = { ...samplePayload, calls: [sampleCall, sampleCall] } - const hash1 = hashPayloadWithCallIdx(testAddress1, payload, 0, testChainId) - const hash2 = hashPayloadWithCallIdx(testAddress1, payload, 1, testChainId) + const hash1 = hashCallWithReplayProtection(payload, 0, testChainId) + const hash2 = hashCallWithReplayProtection(payload, 1, testChainId) expect(hash1).not.toBe(hash2) }) @@ -545,15 +466,15 @@ describe('Session Signature', () => { // This is exploitable and should not be used in practice const payload = { ...samplePayload, calls: [sampleCall, sampleCall] } - const hash1 = hashPayloadWithCallIdx(testAddress1, payload, 0, testChainId, Extensions.Dev1.sessions) - const hash2 = hashPayloadWithCallIdx(testAddress1, payload, 1, testChainId, Extensions.Dev1.sessions) + const hash1 = hashCallWithReplayProtection(payload, 0, testChainId, true) + const hash2 = hashCallWithReplayProtection(payload, 1, testChainId, true) expect(hash1).toBe(hash2) }) it('should be deterministic', () => { - const hash1 = hashPayloadWithCallIdx(testAddress1, samplePayload, 0, testChainId) - const hash2 = hashPayloadWithCallIdx(testAddress1, samplePayload, 0, testChainId) + const hash1 = hashCallWithReplayProtection(samplePayload, 0, testChainId) + const hash2 = hashCallWithReplayProtection(samplePayload, 0, testChainId) expect(hash1).toBe(hash2) }) @@ -563,8 +484,7 @@ describe('Session Signature', () => { const largeSpace = 2n ** 16n const largeNonce = 2n ** 24n - const result = hashPayloadWithCallIdx( - testAddress1, + const result = hashCallWithReplayProtection( { ...samplePayload, space: largeSpace, nonce: largeNonce }, 0, largeChainId, @@ -573,7 +493,7 @@ describe('Session Signature', () => { }) it('should handle zero values', () => { - const result = hashPayloadWithCallIdx(testAddress1, { ...samplePayload, space: 0n, nonce: 0n }, 0, 0) + const result = hashCallWithReplayProtection({ ...samplePayload, space: 0n, nonce: 0n }, 0, 0) expect(result).toMatch(/^0x[0-9a-f]{64}$/) }) @@ -584,7 +504,7 @@ describe('Session Signature', () => { } const payload = { ...samplePayload, calls: [callWithEmptyData] } - const result = hashPayloadWithCallIdx(testAddress1, payload, 0, testChainId) + const result = hashCallWithReplayProtection(payload, 0, testChainId) expect(result).toMatch(/^0x[0-9a-f]{64}$/) }) @@ -595,8 +515,8 @@ describe('Session Signature', () => { } const payload = { ...samplePayload, calls: [delegateCall] } - const hash1 = hashPayloadWithCallIdx(testAddress1, samplePayload, 0, testChainId) - const hash2 = hashPayloadWithCallIdx(testAddress1, payload, 0, testChainId) + const hash1 = hashCallWithReplayProtection(samplePayload, 0, testChainId) + const hash2 = hashCallWithReplayProtection(payload, 0, testChainId) expect(hash1).not.toBe(hash2) }) @@ -605,7 +525,7 @@ describe('Session Signature', () => { describe('Edge Cases and Error Handling', () => { it('should handle empty call signatures array', () => { - const result = encodeSessionSignature([], completeTopology, testAddress1) + const result = encodeSessionCallSignatures([], completeTopology) expect(result).toBeInstanceOf(Uint8Array) expect(result.length).toBeGreaterThan(0) // Should still contain topology }) @@ -616,7 +536,7 @@ describe('Session Signature', () => { sessionSignature: sampleRSY, } - const result = encodeSessionSignature([maxIndexSignature], completeTopology, testAddress1) + const result = encodeSessionCallSignatures([maxIndexSignature], completeTopology) expect(result).toBeInstanceOf(Uint8Array) }) @@ -626,7 +546,7 @@ describe('Session Signature', () => { sessionSignature: sampleRSY, } - const result = encodeSessionSignature([zeroIndexSignature], completeTopology, testAddress1) + const result = encodeSessionCallSignatures([zeroIndexSignature], completeTopology) expect(result).toBeInstanceOf(Uint8Array) }) @@ -659,9 +579,9 @@ describe('Session Signature', () => { it.skip('should handle attestation with minimal data', () => { const minimalAttestation: Attestation = { approvedSigner: testAddress1, - identityType: Bytes.fromHex('0x00000000'), - issuerHash: Bytes.fromHex('0x0000000000000000000000000000000000000000000000000000000000000000'), - audienceHash: Bytes.fromHex('0x0000000000000000000000000000000000000000000000000000000000000000'), + identityType: Bytes.fromHex('0x00'), + issuerHash: Bytes.fromHex(('0x' + '00'.repeat(32)) as Hex.Hex), + audienceHash: Bytes.fromHex(('0x' + '00'.repeat(32)) as Hex.Hex), applicationData: Bytes.fromArray([]), authData: { redirectUrl: '', @@ -675,7 +595,7 @@ describe('Session Signature', () => { sessionSignature: sampleRSY2, } - const result = encodeSessionSignature([minimalImplicitSignature], completeTopology, testAddress1) + const result = encodeSessionCallSignatures([minimalImplicitSignature], completeTopology) expect(result).toBeInstanceOf(Uint8Array) }) @@ -704,8 +624,8 @@ describe('Session Signature', () => { rules: [ { cumulative: false, - operation: ParameterOperation.EQUAL, - value: Bytes.fromHex('0x0000000000000000000000000000000000000000000000000000000000000000'), + operation: 0, + value: Bytes.fromHex('0x'), offset: 0n, mask: Bytes.fromHex('0xffffffff00000000000000000000000000000000000000000000000000000000'), }, @@ -719,7 +639,7 @@ describe('Session Signature', () => { // This test may not actually trigger the error since creating a 3-byte overflow is complex // We'll test that the function works with a large but valid topology - const result = encodeSessionSignature(callSignatures, largeTopology, testAddress1) + const result = encodeSessionCallSignatures(callSignatures, largeTopology) expect(result).toBeInstanceOf(Uint8Array) }) @@ -742,7 +662,7 @@ describe('Session Signature', () => { const callSignatures: ExplicitSessionCallSignature[] = [invalidExplicitSignature] expect(() => { - encodeSessionSignature(callSignatures, completeTopology, testAddress1) + encodeSessionCallSignatures(callSignatures, completeTopology) }).toThrow() // Should throw due to permission index validation }) }) @@ -758,7 +678,7 @@ describe('Session Signature', () => { ] // Encode - const encoded = encodeSessionSignature(callSignatures, completeTopology, testAddress1) + const encoded = encodeSessionCallSignatures(callSignatures, completeTopology, [testAddress1]) expect(encoded).toBeInstanceOf(Uint8Array) // Test encoding for each signature @@ -773,15 +693,12 @@ describe('Session Signature', () => { const calls: Payload.Call[] = [ sampleCall, { ...sampleCall, to: testAddress2 }, - { ...sampleCall, to: testAddress2 }, // Repeat call { ...sampleCall, value: 500000000000000000n }, ] const payload = { ...samplePayload, calls: calls } // Generate hashes for each call - const hashes = calls.map((call) => - hashPayloadWithCallIdx(testAddress1, payload, calls.indexOf(call), testChainId), - ) + const hashes = calls.map((call) => hashCallWithReplayProtection(payload, calls.indexOf(call), testChainId)) // All hashes should be valid and different for (let i = 0; i < hashes.length; i++) { @@ -809,7 +726,7 @@ describe('Session Signature', () => { }, ] - const result = encodeSessionSignature(callSignatures, completeTopology, testAddress1) + const result = encodeSessionCallSignatures(callSignatures, completeTopology) expect(result).toBeInstanceOf(Uint8Array) expect(result.length).toBeGreaterThan(0) }) diff --git a/packages/wallet/wdk/.env.test b/packages/wallet/wdk/.env.test new file mode 100644 index 0000000000..84a53e8c03 --- /dev/null +++ b/packages/wallet/wdk/.env.test @@ -0,0 +1,5 @@ +PRIVATE_KEY= +# When using an RPC, use cors-anywhere. docker run -d -p 8080:8080 redocly/cors-anywhere. http://localhost:8080/https... +RPC_URL= +RELAYER_PK= + diff --git a/packages/wallet/wdk/CHANGELOG.md b/packages/wallet/wdk/CHANGELOG.md deleted file mode 100644 index 5101c28c5a..0000000000 --- a/packages/wallet/wdk/CHANGELOG.md +++ /dev/null @@ -1,339 +0,0 @@ -# @0xsequence/wallet-wdk - -## 3.0.5 - -### Patch Changes - -- Account federation support -- Updated dependencies - - @0xsequence/guard@3.0.5 - - @0xsequence/identity-instrument@3.0.5 - - @0xsequence/relayer@3.0.5 - - @0xsequence/wallet-core@3.0.5 - - @0xsequence/wallet-primitives@3.0.5 - -## 3.0.4 - -### Patch Changes - -- id-token login support -- Updated dependencies - - @0xsequence/guard@3.0.4 - - @0xsequence/identity-instrument@3.0.4 - - @0xsequence/relayer@3.0.4 - - @0xsequence/wallet-core@3.0.4 - - @0xsequence/wallet-primitives@3.0.4 - -## 3.0.3 - -### Patch Changes - -- 3.0.3 -- Updated dependencies - - @0xsequence/guard@3.0.3 - - @0xsequence/identity-instrument@3.0.3 - - @0xsequence/relayer@3.0.3 - - @0xsequence/wallet-core@3.0.3 - - @0xsequence/wallet-primitives@3.0.3 - -## 3.0.2 - -### Patch Changes - -- allow native self transfer -- Updated dependencies - - @0xsequence/guard@3.0.2 - - @0xsequence/identity-instrument@3.0.2 - - @0xsequence/relayer@3.0.2 - - @0xsequence/wallet-core@3.0.2 - - @0xsequence/wallet-primitives@3.0.2 - -## 3.0.1 - -### Patch Changes - -- Network and session fixes -- Updated dependencies - - @0xsequence/guard@3.0.1 - - @0xsequence/identity-instrument@3.0.1 - - @0xsequence/relayer@3.0.1 - - @0xsequence/wallet-core@3.0.1 - - @0xsequence/wallet-primitives@3.0.1 - -## 3.0.0 - -### Patch Changes - -- f68be62: ethauth support -- 49d8a2f: New chains, minor fixes -- 3411232: Beta release with dapp connector fixes -- 23cb9e9: New chains, relayer rpc fix -- f5f6a7a: dapp-client updates -- e7de3b1: Fix signer 404 error, minor fixes -- 493836f: multicall3 optimization -- 30e1f1a: 3.0.0 beta -- d5017e8: Beta release for v3 -- 24a5fab: Final RC before 3.0.0 -- e5e1a03: Apple auth fixes -- 0b63113: Apple auth fix -- a89134a: Userdata service updates -- 7c6c811: 3.0.0-beta.3 with fixes -- 3.0.0 release -- 98ce38b: 3.0.0-beta.2 with identity instrument updates -- 747e6b5: Relayer fee options fix -- 40c19ff: dapp client updates for EOA login -- 6d5de25: 3.0.0-beta.1 -- 934acd1: RC5 upgrade -- Updated dependencies [f68be62] -- Updated dependencies [49d8a2f] -- Updated dependencies [3411232] -- Updated dependencies [23cb9e9] -- Updated dependencies [f5f6a7a] -- Updated dependencies [e7de3b1] -- Updated dependencies [493836f] -- Updated dependencies [30e1f1a] -- Updated dependencies [d5017e8] -- Updated dependencies [24a5fab] -- Updated dependencies [e5e1a03] -- Updated dependencies [0b63113] -- Updated dependencies [a89134a] -- Updated dependencies [7c6c811] -- Updated dependencies -- Updated dependencies [98ce38b] -- Updated dependencies [747e6b5] -- Updated dependencies [40c19ff] -- Updated dependencies [6d5de25] -- Updated dependencies [934acd1] - - @0xsequence/guard@3.0.0 - - @0xsequence/identity-instrument@3.0.0 - - @0xsequence/relayer@3.0.0 - - @0xsequence/wallet-core@3.0.0 - - @0xsequence/wallet-primitives@3.0.0 - -## 3.0.0-beta.19 - -### Patch Changes - -- Final RC before 3.0.0 -- Updated dependencies - - @0xsequence/guard@3.0.0-beta.19 - - @0xsequence/identity-instrument@3.0.0-beta.19 - - @0xsequence/relayer@3.0.0-beta.19 - - @0xsequence/wallet-core@3.0.0-beta.19 - - @0xsequence/wallet-primitives@3.0.0-beta.19 - -## 3.0.0-beta.18 - -### Patch Changes - -- multicall3 optimization -- Updated dependencies - - @0xsequence/guard@3.0.0-beta.18 - - @0xsequence/identity-instrument@3.0.0-beta.18 - - @0xsequence/relayer@3.0.0-beta.18 - - @0xsequence/wallet-core@3.0.0-beta.18 - - @0xsequence/wallet-primitives@3.0.0-beta.18 - -## 3.0.0-beta.17 - -### Patch Changes - -- New chains, relayer rpc fix -- Updated dependencies - - @0xsequence/guard@3.0.0-beta.17 - - @0xsequence/identity-instrument@3.0.0-beta.17 - - @0xsequence/relayer@3.0.0-beta.17 - - @0xsequence/wallet-core@3.0.0-beta.17 - - @0xsequence/wallet-primitives@3.0.0-beta.17 - -## 3.0.0-beta.16 - -### Patch Changes - -- ethauth support -- Updated dependencies - - @0xsequence/guard@3.0.0-beta.16 - - @0xsequence/identity-instrument@3.0.0-beta.16 - - @0xsequence/relayer@3.0.0-beta.16 - - @0xsequence/wallet-core@3.0.0-beta.16 - - @0xsequence/wallet-primitives@3.0.0-beta.16 - -## 3.0.0-beta.15 - -### Patch Changes - -- New chains, minor fixes -- Updated dependencies - - @0xsequence/guard@3.0.0-beta.15 - - @0xsequence/identity-instrument@3.0.0-beta.15 - - @0xsequence/relayer@3.0.0-beta.15 - - @0xsequence/wallet-core@3.0.0-beta.15 - - @0xsequence/wallet-primitives@3.0.0-beta.15 - -## 3.0.0-beta.14 - -### Patch Changes - -- Relayer fee options fix -- Updated dependencies - - @0xsequence/guard@3.0.0-beta.14 - - @0xsequence/identity-instrument@3.0.0-beta.14 - - @0xsequence/relayer@3.0.0-beta.14 - - @0xsequence/wallet-core@3.0.0-beta.14 - - @0xsequence/wallet-primitives@3.0.0-beta.14 - -## 3.0.0-beta.13 - -### Patch Changes - -- Userdata service updates -- Updated dependencies - - @0xsequence/guard@3.0.0-beta.13 - - @0xsequence/identity-instrument@3.0.0-beta.13 - - @0xsequence/relayer@3.0.0-beta.13 - - @0xsequence/wallet-core@3.0.0-beta.13 - - @0xsequence/wallet-primitives@3.0.0-beta.13 - -## 3.0.0-beta.12 - -### Patch Changes - -- Beta release with dapp connector fixes -- Updated dependencies - - @0xsequence/guard@3.0.0-beta.12 - - @0xsequence/identity-instrument@3.0.0-beta.12 - - @0xsequence/relayer@3.0.0-beta.12 - - @0xsequence/wallet-core@3.0.0-beta.12 - - @0xsequence/wallet-primitives@3.0.0-beta.12 - -## 3.0.0-beta.11 - -### Patch Changes - -- 3.0.0 beta -- Updated dependencies - - @0xsequence/guard@3.0.0-beta.11 - - @0xsequence/identity-instrument@3.0.0-beta.11 - - @0xsequence/relayer@3.0.0-beta.11 - - @0xsequence/wallet-core@3.0.0-beta.11 - - @0xsequence/wallet-primitives@3.0.0-beta.11 - -## 3.0.0-beta.10 - -### Patch Changes - -- dapp-client updates -- Updated dependencies - - @0xsequence/guard@3.0.0-beta.10 - - @0xsequence/identity-instrument@3.0.0-beta.10 - - @0xsequence/relayer@3.0.0-beta.10 - - @0xsequence/wallet-core@3.0.0-beta.10 - - @0xsequence/wallet-primitives@3.0.0-beta.10 - -## 3.0.0-beta.9 - -### Patch Changes - -- dapp client updates for EOA login -- Updated dependencies - - @0xsequence/guard@3.0.0-beta.9 - - @0xsequence/identity-instrument@3.0.0-beta.9 - - @0xsequence/relayer@3.0.0-beta.9 - - @0xsequence/wallet-core@3.0.0-beta.9 - - @0xsequence/wallet-primitives@3.0.0-beta.9 - -## 3.0.0-beta.8 - -### Patch Changes - -- Apple auth fixes -- Updated dependencies - - @0xsequence/guard@3.0.0-beta.8 - - @0xsequence/identity-instrument@3.0.0-beta.8 - - @0xsequence/relayer@3.0.0-beta.8 - - @0xsequence/wallet-core@3.0.0-beta.8 - - @0xsequence/wallet-primitives@3.0.0-beta.8 - -## 3.0.0-beta.7 - -### Patch Changes - -- Apple auth fix -- Updated dependencies - - @0xsequence/guard@3.0.0-beta.7 - - @0xsequence/identity-instrument@3.0.0-beta.7 - - @0xsequence/relayer@3.0.0-beta.7 - - @0xsequence/wallet-core@3.0.0-beta.7 - - @0xsequence/wallet-primitives@3.0.0-beta.7 - -## 3.0.0-beta.6 - -### Patch Changes - -- Fix signer 404 error, minor fixes -- Updated dependencies - - @0xsequence/guard@3.0.0-beta.6 - - @0xsequence/identity-instrument@3.0.0-beta.6 - - @0xsequence/relayer@3.0.0-beta.6 - - @0xsequence/wallet-core@3.0.0-beta.6 - - @0xsequence/wallet-primitives@3.0.0-beta.6 - -## 3.0.0-beta.5 - -### Patch Changes - -- Beta release for v3 -- Updated dependencies - - @0xsequence/guard@3.0.0-beta.5 - - @0xsequence/identity-instrument@3.0.0-beta.5 - - @0xsequence/relayer@3.0.0-beta.5 - - @0xsequence/wallet-core@3.0.0-beta.5 - - @0xsequence/wallet-primitives@3.0.0-beta.5 - -## 3.0.0-beta.4 - -### Patch Changes - -- RC5 upgrade -- Updated dependencies - - @0xsequence/guard@3.0.0-beta.4 - - @0xsequence/identity-instrument@3.0.0-beta.4 - - @0xsequence/relayer@3.0.0-beta.4 - - @0xsequence/wallet-core@3.0.0-beta.4 - - @0xsequence/wallet-primitives@3.0.0-beta.4 - -## 3.0.0-beta.3 - -### Patch Changes - -- 3.0.0-beta.3 with fixes -- Updated dependencies - - @0xsequence/guard@3.0.0-beta.3 - - @0xsequence/identity-instrument@3.0.0-beta.3 - - @0xsequence/relayer@3.0.0-beta.3 - - @0xsequence/wallet-core@3.0.0-beta.3 - - @0xsequence/wallet-primitives@3.0.0-beta.3 - -## 3.0.0-beta.2 - -### Patch Changes - -- 3.0.0-beta.2 with identity instrument updates -- Updated dependencies - - @0xsequence/guard@3.0.0-beta.2 - - @0xsequence/identity-instrument@3.0.0-beta.2 - - @0xsequence/relayer@3.0.0-beta.2 - - @0xsequence/wallet-core@3.0.0-beta.2 - - @0xsequence/wallet-primitives@3.0.0-beta.2 - -## 3.0.0-beta.1 - -### Patch Changes - -- 3.0.0-beta.1 -- Updated dependencies - - @0xsequence/guard@3.0.0-beta.1 - - @0xsequence/identity-instrument@3.0.0-beta.1 - - @0xsequence/relayer@3.0.0-beta.1 - - @0xsequence/wallet-core@3.0.0-beta.1 - - @0xsequence/wallet-primitives@3.0.0-beta.1 diff --git a/packages/wallet/wdk/src/dbs/auth-commitments.ts b/packages/wallet/wdk/src/dbs/auth-commitments.ts index 613d4bd574..a12826a0c8 100644 --- a/packages/wallet/wdk/src/dbs/auth-commitments.ts +++ b/packages/wallet/wdk/src/dbs/auth-commitments.ts @@ -10,7 +10,7 @@ export type CommitAuthArgs = export type AuthCommitment = { id: string - kind: 'google-pkce' | 'apple' | `custom-${string}` + kind: 'google-pkce' | 'apple' metadata: { [key: string]: string } verifier?: string challenge?: string diff --git a/packages/wallet/wdk/src/identity/signer.ts b/packages/wallet/wdk/src/identity/signer.ts index 0cb74bbbd6..41b4f676d2 100644 --- a/packages/wallet/wdk/src/identity/signer.ts +++ b/packages/wallet/wdk/src/identity/signer.ts @@ -22,7 +22,7 @@ export function toIdentityAuthKey(authKey: AuthKey, crypto?: CryptoLike): Identi hash: 'SHA-256', }, authKey.privateKey, - new Uint8Array(digest), + digest, ) return Hex.fromBytes(new Uint8Array(authKeySignature)) }, diff --git a/packages/wallet/wdk/src/sequence/guards.ts b/packages/wallet/wdk/src/sequence/guards.ts index a005a16190..c46f670904 100644 --- a/packages/wallet/wdk/src/sequence/guards.ts +++ b/packages/wallet/wdk/src/sequence/guards.ts @@ -1,8 +1,8 @@ -import { Address, Bytes } from 'ox' +import { Address, Secp256k1 } from 'ox' import { Shared } from './manager.js' import * as Guard from '@0xsequence/guard' import { Signers } from '@0xsequence/wallet-core' -import { Config, Constants } from '@0xsequence/wallet-primitives' +import { Config } from '@0xsequence/wallet-primitives' export type GuardRole = 'wallet' | 'sessions' @@ -28,28 +28,17 @@ export class Guards { return undefined } - topology(role: GuardRole): Config.Topology | undefined { + topology(role: GuardRole): Config.NestedLeaf | undefined { const guardAddress = this.shared.sequence.guardAddresses[role] if (!guardAddress) { return undefined } - const topology = Config.replaceAddress( - this.shared.sequence.defaultGuardTopology, - Constants.PlaceholderAddress, - guardAddress, - ) - - // If the imageHash did not change it means the replacement failed - if ( - Bytes.isEqual( - Config.hashConfiguration(topology), - Config.hashConfiguration(this.shared.sequence.defaultGuardTopology), - ) - ) { - throw new Error(`Guard address replacement failed for role ${role}`) + return { + type: 'nested', + weight: 1n, + threshold: 1n, + tree: { ...this.shared.sequence.defaultGuardTopology, address: guardAddress }, } - - return topology } } diff --git a/packages/wallet/wdk/src/sequence/handlers/guard.ts b/packages/wallet/wdk/src/sequence/handlers/guard.ts index b495c95d8b..26e56c98cc 100644 --- a/packages/wallet/wdk/src/sequence/handlers/guard.ts +++ b/packages/wallet/wdk/src/sequence/handlers/guard.ts @@ -1,30 +1,25 @@ import { Address, Hex } from 'ox' import * as Guard from '@0xsequence/guard' -import { Signers } from '@0xsequence/wallet-core' import { Handler } from './handler.js' import { BaseSignatureRequest, SignerUnavailable, SignerReady, SignerActionable, Kinds } from '../types/index.js' import { Signatures } from '../signatures.js' -import { Guards } from '../guards.js' - -type RespondFn = (token: Signers.GuardToken) => Promise - -export type PromptCodeHandler = ( - request: BaseSignatureRequest, - codeType: 'TOTP' | 'PIN', - respond: RespondFn, -) => Promise +import { GuardRole, Guards } from '../guards.js' export class GuardHandler implements Handler { kind = Kinds.Guard - private onPromptCode: undefined | PromptCodeHandler + private onPromptCode: + | undefined + | ((codeType: 'TOTP' | 'PIN', respond: (code: string) => Promise) => Promise) constructor( private readonly signatures: Signatures, private readonly guards: Guards, ) {} - public registerUI(onPromptCode: PromptCodeHandler) { + public registerUI( + onPromptCode: (codeType: 'TOTP' | 'PIN', respond: (code: string) => Promise) => Promise, + ) { this.onPromptCode = onPromptCode return () => { this.onPromptCode = undefined @@ -96,13 +91,17 @@ export class GuardHandler implements Handler { resolve(true) } catch (e) { if (e instanceof Guard.AuthRequiredError) { - const respond: RespondFn = async (token) => { - const signature = await guard.signEnvelope(request.envelope, token) - await this.signatures.addSignature(request.id, signature) - resolve(true) + const respond = async (code: string) => { + try { + const signature = await guard.signEnvelope(request.envelope, { id: e.id, code }) + await this.signatures.addSignature(request.id, signature) + resolve(true) + } catch (e) { + reject(e) + } } - await onPromptCode(request, e.id, respond) + await onPromptCode(e.id, respond) } else { reject(e) } diff --git a/packages/wallet/wdk/src/sequence/handlers/otp.ts b/packages/wallet/wdk/src/sequence/handlers/otp.ts index 42bf85c9e4..f44e7b54a9 100644 --- a/packages/wallet/wdk/src/sequence/handlers/otp.ts +++ b/packages/wallet/wdk/src/sequence/handlers/otp.ts @@ -12,18 +12,16 @@ import type { WdkEnv } from '../../env.js' type RespondFn = (otp: string) => Promise -export type PromptOtpHandler = (recipient: string, respond: RespondFn) => Promise - export class OtpHandler extends IdentityHandler implements Handler { kind = Kinds.LoginEmailOtp - private onPromptOtp: undefined | PromptOtpHandler + private onPromptOtp: undefined | ((recipient: string, respond: RespondFn) => Promise) constructor(nitro: Identity.IdentityInstrument, signatures: Signatures, authKeys: Db.AuthKeys, env?: WdkEnv) { super(nitro, authKeys, signatures, Identity.IdentityType.Email, env) } - public registerUI(onPromptOtp: PromptOtpHandler) { + public registerUI(onPromptOtp: (recipient: string, respond: RespondFn) => Promise) { this.onPromptOtp = onPromptOtp return () => { this.onPromptOtp = undefined @@ -94,14 +92,14 @@ export class OtpHandler extends IdentityHandler implements Handler { private handleAuth( challenge: Identity.OtpChallenge, - onPromptOtp: PromptOtpHandler, + onPromptOtp: (recipient: string, respond: RespondFn) => Promise, ): Promise<{ signer: Signers.Signer & Signers.Witnessable; email: string }> { // eslint-disable-next-line no-async-promise-executor return new Promise(async (resolve, reject) => { try { const { loginHint, challenge: codeChallenge } = await this.nitroCommitVerifier(challenge) - const respond: RespondFn = async (otp) => { + const respond = async (otp: string) => { try { const { signer, email: returnedEmail } = await this.nitroCompleteAuth( challenge.withAnswer(codeChallenge, otp), diff --git a/packages/wallet/wdk/src/sequence/transactions.ts b/packages/wallet/wdk/src/sequence/transactions.ts index 26bf21d34c..6a40cb1e15 100644 --- a/packages/wallet/wdk/src/sequence/transactions.ts +++ b/packages/wallet/wdk/src/sequence/transactions.ts @@ -1,5 +1,4 @@ -import { Envelope, Wallet, Bundler } from '@0xsequence/wallet-core' -import { Relayer } from '@0xsequence/relayer' +import { Envelope, Relayer, Wallet } from '@0xsequence/wallet-core' import { Constants, Payload } from '@0xsequence/wallet-primitives' import { Abi, AbiFunction, Address, Hex, Provider, RpcTransport } from 'ox' import { v7 as uuidv7 } from 'uuid' @@ -180,13 +179,11 @@ export class Transactions implements TransactionsInterface { } if (tx.status === 'relayed') { - let relayer: Relayer.Relayer | Bundler.Bundler | undefined = this.shared.sequence.relayers.find( + let relayer: Relayer.Relayer | Relayer.Bundler | undefined = this.shared.sequence.relayers.find( (relayer) => relayer.id === tx.relayerId, ) if (!relayer) { - const bundler: Bundler.Bundler | undefined = this.shared.sequence.bundlers.find( - (bundler) => bundler.id === tx.relayerId, - ) + const bundler = this.shared.sequence.bundlers.find((bundler) => bundler.id === tx.relayerId) if (!bundler) { console.warn('relayer or bundler not found', tx.id, tx.relayerId) continue @@ -354,7 +351,7 @@ export class Transactions implements TransactionsInterface { const feeOptions = await relayer.feeOptions(tx.wallet, tx.envelope.chainId, to, tx.envelope.payload.calls) if (feeOptions.options.length === 0) { - const { name, icon } = relayer instanceof Relayer.EIP6963.EIP6963Relayer ? relayer.info : {} + const { name, icon } = relayer instanceof Relayer.Standard.EIP6963.EIP6963Relayer ? relayer.info : {} return [ { @@ -368,7 +365,7 @@ export class Transactions implements TransactionsInterface { ] } - return feeOptions.options.map((feeOption: Relayer.FeeOption) => ({ + return feeOptions.options.map((feeOption) => ({ kind: 'standard', id: uuidv7(), feeOption, @@ -385,7 +382,7 @@ export class Transactions implements TransactionsInterface { } return Promise.all( - this.shared.sequence.bundlers.map(async (bundler: Bundler.Bundler): Promise => { + this.shared.sequence.bundlers.map(async (bundler): Promise => { const ifAvailable = await bundler.isAvailable(entrypoint, tx.envelope.chainId) if (!ifAvailable) { return [] @@ -587,7 +584,7 @@ export class Transactions implements TransactionsInterface { await this.shared.modules.signatures.complete(signature.id) } else if (isERC4337RelayerOption(tx.relayerOption)) { - if (!Bundler.isBundler(relayer)) { + if (!Relayer.isBundler(relayer)) { throw new Error(`Relayer ${tx.relayerOption.relayerId} is not a bundler`) } diff --git a/packages/wallet/wdk/src/sequence/types/module.ts b/packages/wallet/wdk/src/sequence/types/module.ts index 014a97ae69..df254a6482 100644 --- a/packages/wallet/wdk/src/sequence/types/module.ts +++ b/packages/wallet/wdk/src/sequence/types/module.ts @@ -3,5 +3,5 @@ import { Config } from '@0xsequence/wallet-primitives' export type Module = { weight: bigint sapientLeaf: Config.SapientSignerLeaf - guardLeaf?: Config.Topology + guardLeaf?: Config.NestedLeaf } diff --git a/packages/wallet/wdk/src/sequence/types/sessions.ts b/packages/wallet/wdk/src/sequence/types/sessions.ts deleted file mode 100644 index 1efef2490a..0000000000 --- a/packages/wallet/wdk/src/sequence/types/sessions.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { Hex } from 'ox' - -export type AuthorizeImplicitSessionArgs = { - target: string - applicationData?: Hex.Hex -} diff --git a/packages/wallet/wdk/src/sequence/types/signer.ts b/packages/wallet/wdk/src/sequence/types/signer.ts index eb46db52fd..0e431c26c0 100644 --- a/packages/wallet/wdk/src/sequence/types/signer.ts +++ b/packages/wallet/wdk/src/sequence/types/signer.ts @@ -12,7 +12,7 @@ export const Kinds = { Unknown: 'unknown', } as const -export type Kind = (typeof Kinds)[keyof typeof Kinds] | `custom-${string}` +export type Kind = (typeof Kinds)[keyof typeof Kinds] export type WitnessExtraSignerKind = { signerKind: string diff --git a/packages/wallet/wdk/src/sequence/types/transaction-request.ts b/packages/wallet/wdk/src/sequence/types/transaction-request.ts index 51160a0499..289bf5b645 100644 --- a/packages/wallet/wdk/src/sequence/types/transaction-request.ts +++ b/packages/wallet/wdk/src/sequence/types/transaction-request.ts @@ -1,7 +1,6 @@ -import { Envelope } from '@0xsequence/wallet-core' +import { Envelope, Relayer } from '@0xsequence/wallet-core' import { Payload } from '@0xsequence/wallet-primitives' import { Address, Hex } from 'ox' -import { Relayer } from '@0xsequence/relayer' export type TransactionRequest = { to: Address.Address diff --git a/packages/wallet/wdk/test/identity-auth-dbs.test.ts b/packages/wallet/wdk/test/identity-auth-dbs.test.ts index bba408ef36..bfb61e4680 100644 --- a/packages/wallet/wdk/test/identity-auth-dbs.test.ts +++ b/packages/wallet/wdk/test/identity-auth-dbs.test.ts @@ -1,7 +1,9 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' -import { Manager } from '../src/sequence/index.js' -import * as Db from '../src/dbs/index.js' -import { LOCAL_RPC_URL } from './constants.js' +import { Manager } from '../src/sequence' +import { Address, Hex, Bytes } from 'ox' +import { IdentityInstrument } from '@0xsequence/identity-instrument' +import * as Db from '../src/dbs' +import { LOCAL_RPC_URL } from './constants' import { State } from '@0xsequence/wallet-core' import { Network } from '@0xsequence/wallet-primitives' diff --git a/packages/wallet/wdk/test/messages.test.ts b/packages/wallet/wdk/test/messages.test.ts index 32d68ffe5e..9420ca0004 100644 --- a/packages/wallet/wdk/test/messages.test.ts +++ b/packages/wallet/wdk/test/messages.test.ts @@ -1,7 +1,7 @@ import { afterEach, beforeEach, describe, expect, it } from 'vitest' -import { Manager, SignerActionable } from '../src/sequence/index.js' +import { Manager, SignerActionable } from '../src/sequence' import { Mnemonic } from 'ox' -import { newManager } from './constants.js' +import { newManager } from './constants' import { Network } from '@0xsequence/wallet-primitives' describe('Messages', () => { @@ -41,13 +41,12 @@ describe('Messages', () => { // Verify message appears in list const messages = await manager.messages.list() expect(messages.length).toBe(1) - const message = messages[0]! - expect(message.wallet).toBe(wallet) - expect(message.message).toBe(testMessage) - expect(message.status).toBe('requested') - expect(message.signatureId).toBe(signatureId) - expect(message.source).toBe('unknown') - expect(message.id).toBeDefined() + expect(messages[0].wallet).toBe(wallet) + expect(messages[0].message).toBe(testMessage) + expect(messages[0].status).toBe('requested') + expect(messages[0].signatureId).toBe(signatureId) + expect(messages[0].source).toBe('unknown') + expect(messages[0].id).toBeDefined() }) it('Should create message request with custom source', async () => { @@ -64,11 +63,8 @@ describe('Messages', () => { const messages = await manager.messages.list() expect(messages.length).toBe(1) - - const message = messages[0]! - - expect(message.source).toBe(customSource) - expect(message.message).toBe(testMessage) + expect(messages[0].source).toBe(customSource) + expect(messages[0].message).toBe(testMessage) }) it('Should get message by ID', async () => { @@ -83,7 +79,7 @@ describe('Messages', () => { const messages = await manager.messages.list() expect(messages.length).toBe(1) - const messageId = messages[0]!.id + const messageId = messages[0].id // Get by message ID const retrievedMessage = await manager.messages.get(messageId) @@ -273,7 +269,7 @@ describe('Messages', () => { const signatureId = await manager.messages.request(wallet!, testMessage) const messages = await manager.messages.list() - const messageId = messages[0]!.id + const messageId = messages[0].id let updateCallCount = 0 let lastMessage: any @@ -319,7 +315,7 @@ describe('Messages', () => { await manager.messages.request(wallet!, testMessage) const messages = await manager.messages.list() - const messageId = messages[0]!.id + const messageId = messages[0].id let callCount = 0 let receivedMessage: any diff --git a/packages/wallet/wdk/test/passkeys.test.ts b/packages/wallet/wdk/test/passkeys.test.ts index e73d0f4e3a..6c21f67b84 100644 --- a/packages/wallet/wdk/test/passkeys.test.ts +++ b/packages/wallet/wdk/test/passkeys.test.ts @@ -3,10 +3,10 @@ import { Address, Hex } from 'ox' import { Network, Payload } from '@0xsequence/wallet-primitives' import { State } from '@0xsequence/wallet-core' import { Extensions } from '@0xsequence/wallet-primitives' -import { PasskeysHandler } from '../src/sequence/handlers/passkeys.js' -import { Signatures } from '../src/sequence/signatures.js' -import { BaseSignatureRequest } from '../src/sequence/types/signature-request.js' -import { Kinds } from '../src/sequence/types/signer.js' +import { PasskeysHandler } from '../src/sequence/handlers/passkeys' +import { Signatures } from '../src/sequence/signatures' +import { BaseSignatureRequest } from '../src/sequence/types/signature-request' +import { Kinds } from '../src/sequence/types/signer' // Mock dependencies with proper vi.fn() types const mockAddSignature = vi.fn() diff --git a/packages/wallet/wdk/test/recovery.test.ts b/packages/wallet/wdk/test/recovery.test.ts index ebaab9d3a5..5aae78cec2 100644 --- a/packages/wallet/wdk/test/recovery.test.ts +++ b/packages/wallet/wdk/test/recovery.test.ts @@ -1,8 +1,8 @@ import { describe, expect, it } from 'vitest' -import { QueuedRecoveryPayload, SignerReady, TransactionDefined } from '../src/sequence/index.js' +import { Manager, QueuedRecoveryPayload, SignerReady, TransactionDefined } from '../src/sequence' import { Bytes, Hex, Mnemonic, Provider, RpcTransport } from 'ox' import { Network, Payload } from '@0xsequence/wallet-primitives' -import { LOCAL_RPC_URL, newManager } from './constants.js' +import { LOCAL_RPC_URL, newManager } from './constants' describe('Recovery', () => { it('Should execute a recovery', async () => { @@ -159,7 +159,7 @@ describe('Recovery', () => { expect(tx.status).toBe('defined') expect((tx as TransactionDefined).relayerOptions.length).toBe(1) - const localRelayer = (tx as TransactionDefined).relayerOptions[0]! + const localRelayer = (tx as TransactionDefined).relayerOptions[0] expect(localRelayer).toBeDefined() expect(localRelayer.relayerId).toBe('local') @@ -332,7 +332,7 @@ describe('Recovery', () => { expect(Array.isArray(fetchedPayloads)).toBeTruthy() expect(fetchedPayloads.length).toBe(1) - const fetchedPayload = fetchedPayloads[0]! + const fetchedPayload = fetchedPayloads[0] expect(fetchedPayload).toBeDefined() expect(fetchedPayload.wallet).toBe(wallet) expect(fetchedPayload.chainId).toBe(Network.ChainId.ARBITRUM) @@ -390,8 +390,8 @@ describe('Recovery', () => { expect(updatedPayloads.length).toBe(fetchedPayloads2.length) if (updatedPayloads.length > 0 && fetchedPayloads.length > 0) { - const updated = updatedPayloads[0]! - const fetched = fetchedPayloads[0]! + const updated = updatedPayloads[0] + const fetched = fetchedPayloads[0] expect(updated.id).toBe(fetched.id) expect(updated.wallet).toBe(fetched.wallet) diff --git a/packages/wallet/wdk/test/setup.ts b/packages/wallet/wdk/test/setup.ts index 4aa336a55a..70482040c0 100644 --- a/packages/wallet/wdk/test/setup.ts +++ b/packages/wallet/wdk/test/setup.ts @@ -14,7 +14,7 @@ import { } from 'fake-indexeddb' import { Provider, RpcTransport } from 'ox' import { vi } from 'vitest' -import { LOCAL_RPC_URL } from './constants.js' +import { LOCAL_RPC_URL } from './constants' // Add IndexedDB support to the test environment using fake-indexeddb global.indexedDB = indexedDB diff --git a/packages/wallet/wdk/test/signers-kindof.test.ts b/packages/wallet/wdk/test/signers-kindof.test.ts deleted file mode 100644 index 06b01cb780..0000000000 --- a/packages/wallet/wdk/test/signers-kindof.test.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { describe, expect, it, vi } from 'vitest' - -import { Kinds } from '../src/sequence/index.js' -import { newManager } from './constants.js' - -describe('Signers.kindOf', () => { - it('does not probe Sessions/Witness for non-witnessable signers', async () => { - const getWitnessFor = vi.fn().mockResolvedValue(undefined) - const getWitnessForSapient = vi.fn().mockResolvedValue(undefined) - - const manager = newManager({ - stateProvider: { - getWitnessFor, - getWitnessForSapient, - } as any, - }) - - const signers = (manager as any).shared.modules.signers - const extensions = (manager as any).shared.sequence.extensions - - const wallet = '0x1111111111111111111111111111111111111111' - const imageHash = ('0x' + '00'.repeat(32)) as `0x${string}` - - // Sessions extension signer (sapient leaf) never publishes a witness. - await signers.kindOf(wallet, extensions.sessions, imageHash) - - // Passkeys module is a known sapient signer kind. - expect(await signers.kindOf(wallet, extensions.passkeys, imageHash)).toBe(Kinds.LoginPasskey) - - // Sequence dev multisig (default guard topology leaf) never publishes a witness. - await signers.kindOf(wallet, '0x007a47e6BF40C1e0ed5c01aE42fDC75879140bc4') - - expect(getWitnessFor).not.toHaveBeenCalled() - expect(getWitnessForSapient).not.toHaveBeenCalled() - - // Unknown signers still rely on a witness probe. - await signers.kindOf(wallet, '0x2222222222222222222222222222222222222222') - expect(getWitnessFor).toHaveBeenCalledTimes(1) - }) - - it('normalizes legacy Google PKCE signer kind to the canonical Google signer kind', async () => { - const getWitnessFor = vi.fn().mockResolvedValue({ - payload: { - type: 'message', - message: '0x' + Buffer.from(JSON.stringify({ signerKind: 'login-google-pkce' }), 'utf8').toString('hex'), - }, - }) - - const manager = newManager({ - stateProvider: { - getWitnessFor, - getWitnessForSapient: vi.fn(), - } as any, - }) - - const signers = (manager as any).shared.modules.signers - const wallet = '0x1111111111111111111111111111111111111111' - const signer = '0x2222222222222222222222222222222222222222' - - await expect(signers.kindOf(wallet, signer)).resolves.toBe(Kinds.LoginGoogle) - }) -}) diff --git a/packages/wallet/wdk/test/test-ssr-safety.js b/packages/wallet/wdk/test/test-ssr-safety.js deleted file mode 100644 index 71eb361702..0000000000 --- a/packages/wallet/wdk/test/test-ssr-safety.js +++ /dev/null @@ -1,314 +0,0 @@ -#!/usr/bin/env node -/* global console, process */ -/** - * Comprehensive SSR Safety Test (Runtime Execution) - * - * This script tests that the entire wdk package can be imported and used in a Node.js - * environment (SSR context) without throwing errors about missing window. - * - * It executes the code at runtime to catch any SSR issues. - * - * Run with: node test-ssr-comprehensive.mjs - */ - -import { readFile } from 'fs/promises' -import { fileURLToPath } from 'url' -import { dirname, join } from 'path' -import { createRequire } from 'module' - -const __filename = fileURLToPath(import.meta.url) -const __dirname = dirname(__filename) -const require = createRequire(import.meta.url) - -console.log('Testing SSR safety with runtime execution...\n') - -// Ensure we're in a Node.js environment (no window) -if (typeof window !== 'undefined') { - console.error('ERROR: window is defined! This should not happen in Node.js.') - process.exit(1) -} - -console.log('āœ“ window is undefined (as expected in Node.js)\n') - -const errors = [] -const warnings = [] - -// Read package.json to get package name and exports -let packageJson -try { - const packageJsonPath = join(__dirname, '..', 'package.json') - packageJson = JSON.parse(await readFile(packageJsonPath, 'utf-8')) -} catch (err) { - console.error('Failed to read package.json:', err.message) - process.exit(1) -} - -// Test 1: Import main module via package name -console.log('='.repeat(60)) -console.log('Test 1: Importing package via package name') -console.log('='.repeat(60)) - -let wdk -try { - // Use the package name from package.json - const packageName = packageJson.name - console.log(`Importing ${packageName}...`) - - // Try to resolve the package - const packagePath = require.resolve(packageName) - console.log(` Package resolved to: ${packagePath}`) - - // Import the package - wdk = await import(packageName) - console.log('āœ“ Successfully imported package') - console.log(' Top-level exports:', Object.keys(wdk)) -} catch (error) { - // Check if it's an SSR-related error - if ( - error.message.includes('window is not defined') || - error.message.includes('window') || - error.message.includes('document is not defined') || - error.message.includes('document') || - error.message.includes('localStorage') || - error.message.includes('sessionStorage') - ) { - errors.push(`SSR ERROR: Package accesses browser globals at module load time: ${error.message}`) - if (error.stack) { - console.error('\nError stack:') - console.error(error.stack) - } - } else { - errors.push(`Failed to import package: ${error.message}`) - if (error.stack) { - console.error('Stack:', error.stack) - } - } - - // Don't exit immediately - let the summary show the error - if (errors.length > 0) { - // Skip remaining tests if import failed - wdk = null - } -} - -// Test 2: Recursively access and test all exports -console.log('\n' + '='.repeat(60)) -console.log('Test 2: Accessing and testing all exports') -console.log('='.repeat(60)) - -if (!wdk) { - console.log('Skipping - package import failed') -} else { - async function testExports(obj, path = '', depth = 0) { - if (depth > 5) return // Prevent infinite recursion - - for (const [key, value] of Object.entries(obj)) { - const currentPath = path ? `${path}.${key}` : key - - try { - // Skip if it's a circular reference or already tested - if (value === null || value === undefined) { - continue - } - - // Test accessing the value (this executes any getters) - const accessed = value - - // Test different types - if (typeof accessed === 'function') { - // Try to get function properties - try { - const props = Object.getOwnPropertyNames(accessed) - if (props.length > 0 && depth < 3) { - // Test static properties on functions - for (const prop of props.slice(0, 3)) { - try { - const propValue = accessed[prop] - if (typeof propValue === 'object' && propValue !== null && depth < 2) { - await testExports(propValue, `${currentPath}.${prop}`, depth + 1) - } - } catch (err) { - if (err.message.includes('window') || err.message.includes('document')) { - errors.push(`${currentPath}.${prop}: ${err.message}`) - } - } - } - } - } catch (err) { - if (err.message.includes('window') || err.message.includes('document')) { - errors.push(`${currentPath}: ${err.message}`) - } - } - } else if (typeof accessed === 'object' && accessed !== null) { - // Test object properties - if (Array.isArray(accessed)) { - // Test array elements - for (let i = 0; i < Math.min(accessed.length, 3); i++) { - try { - const item = accessed[i] - if (typeof item === 'object' && item !== null && depth < 3) { - await testExports(item, `${currentPath}[${i}]`, depth + 1) - } - } catch (err) { - if (err.message.includes('window') || err.message.includes('document')) { - errors.push(`${currentPath}[${i}]: ${err.message}`) - } - } - } - } else { - // Test object properties recursively - await testExports(accessed, currentPath, depth + 1) - } - } - } catch (error) { - // Check if it's an SSR-related error - if ( - error.message.includes('window is not defined') || - error.message.includes('window') || - error.message.includes('document is not defined') || - error.message.includes('document') || - error.message.includes('localStorage') || - error.message.includes('sessionStorage') - ) { - errors.push(`${currentPath}: ${error.message}`) - } else { - // Other errors are warnings (might be expected, like missing dependencies) - warnings.push(`${currentPath}: ${error.message}`) - } - } - } - } - - // Test all top-level exports - console.log('Testing all exports recursively...') - await testExports(wdk) -} - -// Test 3: Try to access specific critical exports and use them -console.log('\n' + '='.repeat(60)) -console.log('Test 3: Testing critical exports with actual usage') -console.log('='.repeat(60)) - -if (!wdk) { - console.log('Skipping - package import failed') -} else { - // Test ManagerOptionsDefaults - try { - if (wdk.Sequence?.ManagerOptionsDefaults) { - console.log('Testing ManagerOptionsDefaults...') - const defaults = wdk.Sequence.ManagerOptionsDefaults - - // Access all properties - Object.keys(defaults).forEach((key) => { - try { - const value = defaults[key] - console.log(` āœ“ ${key}: ${typeof value}`) - - // If it's a function, try calling it - if (typeof value === 'function' && key === 'relayers') { - const result = value() - console.log( - ` Called ${key}(), returned:`, - Array.isArray(result) ? `${result.length} items` : typeof result, - ) - } - } catch (err) { - if (err.message.includes('window') || err.message.includes('document')) { - errors.push(`ManagerOptionsDefaults.${key}: ${err.message}`) - } - } - }) - } - } catch (err) { - if (err.message.includes('window') || err.message.includes('document')) { - errors.push(`ManagerOptionsDefaults: ${err.message}`) - } - } - - // Test applyManagerOptionsDefaults function - try { - if (wdk.Sequence?.applyManagerOptionsDefaults) { - console.log('Testing applyManagerOptionsDefaults...') - const result = wdk.Sequence.applyManagerOptionsDefaults() - console.log(' āœ“ Function executed successfully') - console.log(' Result keys:', Object.keys(result).slice(0, 5).join(', '), '...') - } - } catch (err) { - if (err.message.includes('window') || err.message.includes('document')) { - errors.push(`applyManagerOptionsDefaults: ${err.message}`) - } - } -} - -// Test 4: Try importing sub-modules that might be imported separately -console.log('\n' + '='.repeat(60)) -console.log('Test 4: Testing sub-module imports') -console.log('='.repeat(60)) - -if (!wdk) { - console.log('Skipping - package import failed') -} else { - // Get the package path and try importing from dist - try { - const packagePath = require.resolve(packageJson.name) - const packageDir = dirname(packagePath) - - // Try to import from the exports field if available - if (packageJson.exports) { - for (const [exportPath, exportConfig] of Object.entries(packageJson.exports)) { - if (exportPath === '.') { - const modulePath = exportConfig.default || exportConfig.types - if (modulePath) { - try { - const fullPath = join(packageDir, '..', modulePath) - console.log(`Testing import from ${exportPath}...`) - const subModule = await import(fullPath) - console.log(` āœ“ Imported successfully`) - - // Test accessing exports - const subExports = Object.keys(subModule) - if (subExports.length > 0) { - console.log(` Exports: ${subExports.slice(0, 5).join(', ')}${subExports.length > 5 ? '...' : ''}`) - } - } catch (err) { - if (err.message.includes('window') || err.message.includes('document')) { - errors.push(`Import ${exportPath}: ${err.message}`) - } else if (!err.message.includes('Cannot find module')) { - warnings.push(`Import ${exportPath}: ${err.message}`) - } - } - } - } - } - } - } catch (err) { - warnings.push(`Could not test sub-modules: ${err.message}`) - } -} - -// Summary -console.log('\n' + '='.repeat(60)) -console.log('Test Summary') -console.log('='.repeat(60)) - -if (errors.length === 0) { - console.log('\nāœ… All SSR Safety Tests PASSED!') - console.log('The package can be safely imported and used in a Node.js/SSR environment.') - if (warnings.length > 0) { - console.log(`\nāš ļø ${warnings.length} warning(s) (non-SSR related):`) - warnings.slice(0, 5).forEach((warn) => console.log(` - ${warn}`)) - if (warnings.length > 5) { - console.log(` ... and ${warnings.length - 5} more`) - } - } - process.exit(0) -} else { - console.log('\nāŒ ERRORS FOUND:') - errors.forEach((err) => console.log(` - ${err}`)) - console.log('\nāŒ SSR Safety Test FAILED!') - if (warnings.length > 0) { - console.log(`\nāš ļø ${warnings.length} warning(s):`) - warnings.slice(0, 5).forEach((warn) => console.log(` - ${warn}`)) - } - process.exit(1) -} diff --git a/packages/wallet/wdk/vitest.config.ts b/packages/wallet/wdk/vitest.config.ts index 9c2092c0c4..813dc499da 100644 --- a/packages/wallet/wdk/vitest.config.ts +++ b/packages/wallet/wdk/vitest.config.ts @@ -1,3 +1,4 @@ +import { BrowserNavigationCrossOriginPolicyEnum } from 'happy-dom' import { defineConfig } from 'vitest/config' export default defineConfig({ diff --git a/repo/eslint-config/CHANGELOG.md b/repo/eslint-config/CHANGELOG.md deleted file mode 100644 index 2df72f2e7a..0000000000 --- a/repo/eslint-config/CHANGELOG.md +++ /dev/null @@ -1,20 +0,0 @@ -# @repo/eslint-config - -## 0.0.1 - -### Patch Changes - -- d5017e8: Beta release for v3 -- 7c6c811: 3.0.0-beta.3 with fixes - -## 0.0.1-beta.1 - -### Patch Changes - -- Beta release for v3 - -## 0.0.1-beta.0 - -### Patch Changes - -- 3.0.0-beta.3 with fixes diff --git a/repo/typescript-config/CHANGELOG.md b/repo/typescript-config/CHANGELOG.md deleted file mode 100644 index 3e5ecbabf4..0000000000 --- a/repo/typescript-config/CHANGELOG.md +++ /dev/null @@ -1,20 +0,0 @@ -# @repo/typescript-config - -## 0.0.1 - -### Patch Changes - -- d5017e8: Beta release for v3 -- 7c6c811: 3.0.0-beta.3 with fixes - -## 0.0.1-beta.1 - -### Patch Changes - -- Beta release for v3 - -## 0.0.1-beta.0 - -### Patch Changes - -- 3.0.0-beta.3 with fixes diff --git a/repo/ui/CHANGELOG.md b/repo/ui/CHANGELOG.md deleted file mode 100644 index 232f9accb7..0000000000 --- a/repo/ui/CHANGELOG.md +++ /dev/null @@ -1,20 +0,0 @@ -# @repo/ui - -## 0.0.1 - -### Patch Changes - -- d5017e8: Beta release for v3 -- 7c6c811: 3.0.0-beta.3 with fixes - -## 0.0.1-beta.1 - -### Patch Changes - -- Beta release for v3 - -## 0.0.1-beta.0 - -### Patch Changes - -- 3.0.0-beta.3 with fixes