diff --git a/.changeset/cyan-radios-relax.md b/.changeset/cyan-radios-relax.md deleted file mode 100644 index ec408d6cd9..0000000000 --- a/.changeset/cyan-radios-relax.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -'@0xsequence/api': patch -'@0xsequence/builder': patch -'@0xsequence/guard': patch -'@0xsequence/identity-instrument': patch -'@0xsequence/indexer': patch -'@0xsequence/marketplace': patch -'@0xsequence/metadata': patch -'@0xsequence/relayer': patch -'@0xsequence/userdata': patch -'@0xsequence/abi': patch -'@0xsequence/wallet-core': patch -'@0xsequence/dapp-client': patch -'@0xsequence/wallet-primitives': patch -'@0xsequence/wallet-wdk': patch ---- - -Fix signer 404 error, minor fixes diff --git a/.changeset/goofy-laws-serve.md b/.changeset/goofy-laws-serve.md deleted file mode 100644 index 690a5f76b4..0000000000 --- a/.changeset/goofy-laws-serve.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -'@0xsequence/api': patch -'@0xsequence/builder': patch -'@0xsequence/guard': patch -'@0xsequence/identity-instrument': patch -'@0xsequence/indexer': patch -'@0xsequence/marketplace': patch -'@0xsequence/metadata': patch -'@0xsequence/relayer': patch -'@0xsequence/userdata': patch -'@0xsequence/abi': patch -'@0xsequence/wallet-core': patch -'@0xsequence/dapp-client': patch -'@0xsequence/wallet-primitives': patch -'@0xsequence/wallet-wdk': patch -'@repo/eslint-config': patch -'@repo/typescript-config': patch -'@repo/ui': patch ---- - -Beta release for v3 diff --git a/.changeset/new-turkeys-double.md b/.changeset/new-turkeys-double.md deleted file mode 100644 index 72f26beb9c..0000000000 --- a/.changeset/new-turkeys-double.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -'@0xsequence/api': patch -'@0xsequence/builder': patch -'@0xsequence/guard': patch -'@0xsequence/identity-instrument': patch -'@0xsequence/indexer': patch -'@0xsequence/marketplace': patch -'@0xsequence/metadata': patch -'@0xsequence/relayer': patch -'@0xsequence/userdata': patch -'@0xsequence/abi': patch -'@0xsequence/wallet-core': patch -'@0xsequence/dapp-client': patch -'@0xsequence/wallet-primitives': patch -'@0xsequence/wallet-wdk': patch ---- - -Apple auth fixes diff --git a/.changeset/nice-tips-slide.md b/.changeset/nice-tips-slide.md deleted file mode 100644 index 1595123e78..0000000000 --- a/.changeset/nice-tips-slide.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -'@0xsequence/api': patch -'@0xsequence/builder': patch -'@0xsequence/guard': patch -'@0xsequence/identity-instrument': patch -'@0xsequence/indexer': patch -'@0xsequence/marketplace': patch -'@0xsequence/metadata': patch -'@0xsequence/relayer': patch -'@0xsequence/userdata': patch -'@0xsequence/abi': patch -'@0xsequence/wallet-core': patch -'@0xsequence/dapp-client': patch -'@0xsequence/wallet-primitives': patch -'@0xsequence/wallet-wdk': patch ---- - -Apple auth fix diff --git a/.changeset/open-toes-marry.md b/.changeset/open-toes-marry.md deleted file mode 100644 index ec5bf32174..0000000000 --- a/.changeset/open-toes-marry.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -'@0xsequence/api': patch -'@0xsequence/builder': patch -'@0xsequence/guard': patch -'@0xsequence/identity-instrument': patch -'@0xsequence/indexer': patch -'@0xsequence/marketplace': patch -'@0xsequence/metadata': patch -'@0xsequence/relayer': patch -'@0xsequence/abi': patch -'@0xsequence/wallet-core': patch -'@0xsequence/dapp-client': patch -'@0xsequence/wallet-primitives': patch -'@0xsequence/wallet-wdk': patch -'@repo/eslint-config': patch -'@repo/typescript-config': patch -'@repo/ui': patch ---- - -3.0.0-beta.3 with fixes diff --git a/.changeset/plain-feet-stare.md b/.changeset/plain-feet-stare.md deleted file mode 100644 index c99c82026b..0000000000 --- a/.changeset/plain-feet-stare.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -'@0xsequence/api': patch -'@0xsequence/builder': patch -'@0xsequence/guard': patch -'@0xsequence/identity-instrument': patch -'@0xsequence/indexer': patch -'@0xsequence/marketplace': patch -'@0xsequence/metadata': patch -'@0xsequence/relayer': patch -'@0xsequence/abi': patch -'@0xsequence/wallet-core': patch -'@0xsequence/dapp-client': patch -'@0xsequence/wallet-primitives': patch -'@0xsequence/wallet-wdk': patch ---- - -3.0.0-beta.2 with identity instrument updates diff --git a/.changeset/pre.json b/.changeset/pre.json deleted file mode 100644 index 0284e14c52..0000000000 --- a/.changeset/pre.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "mode": "exit", - "tag": "beta", - "initialVersions": { - "docs": "0.1.0", - "web": "0.1.0", - "@0xsequence/api": "3.0.0-beta.8", - "@0xsequence/builder": "3.0.0-beta.8", - "@0xsequence/guard": "3.0.0-beta.8", - "@0xsequence/identity-instrument": "3.0.0-beta.8", - "@0xsequence/indexer": "3.0.0-beta.8", - "@0xsequence/marketplace": "3.0.0-beta.8", - "@0xsequence/metadata": "3.0.0-beta.8", - "@0xsequence/relayer": "3.0.0-beta.8", - "@0xsequence/userdata": "3.0.0-beta.8", - "@0xsequence/abi": "3.0.0-beta.8", - "@0xsequence/wallet-core": "3.0.0-beta.8", - "@0xsequence/dapp-client": "3.0.0-beta.8", - "@0xsequence/wallet-primitives": "3.0.0-beta.8", - "@0xsequence/wallet-wdk": "3.0.0-beta.8", - "@repo/eslint-config": "0.0.1-beta.1", - "@repo/typescript-config": "0.0.1-beta.1", - "@repo/ui": "0.0.1-beta.1" - }, - "changesets": [ - "cyan-radios-relax", - "goofy-laws-serve", - "new-turkeys-double", - "nice-tips-slide", - "open-toes-marry", - "plain-feet-stare", - "tiny-files-chew", - "wild-feet-carry", - "wise-heads-buy" - ] -} diff --git a/.changeset/tiny-files-chew.md b/.changeset/tiny-files-chew.md deleted file mode 100644 index 672546fd05..0000000000 --- a/.changeset/tiny-files-chew.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -'@0xsequence/api': patch -'@0xsequence/builder': patch -'@0xsequence/guard': patch -'@0xsequence/identity-instrument': patch -'@0xsequence/indexer': patch -'@0xsequence/marketplace': patch -'@0xsequence/metadata': patch -'@0xsequence/relayer': patch -'@0xsequence/userdata': patch -'@0xsequence/abi': patch -'@0xsequence/wallet-core': patch -'@0xsequence/dapp-client': patch -'@0xsequence/wallet-primitives': patch -'@0xsequence/wallet-wdk': patch ---- - -dapp client updates for EOA login diff --git a/.changeset/wild-feet-carry.md b/.changeset/wild-feet-carry.md deleted file mode 100644 index 962942831c..0000000000 --- a/.changeset/wild-feet-carry.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -'@0xsequence/api': patch -'@0xsequence/builder': patch -'@0xsequence/guard': patch -'@0xsequence/identity-instrument': patch -'@0xsequence/indexer': patch -'@0xsequence/marketplace': patch -'@0xsequence/metadata': patch -'@0xsequence/relayer': patch -'@0xsequence/abi': patch -'@0xsequence/wallet-core': patch -'@0xsequence/dapp-client': patch -'@0xsequence/wallet-primitives': patch -'@0xsequence/wallet-wdk': patch ---- - -3.0.0-beta.1 diff --git a/.changeset/wise-heads-buy.md b/.changeset/wise-heads-buy.md deleted file mode 100644 index 1c35a4d355..0000000000 --- a/.changeset/wise-heads-buy.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -'@0xsequence/api': patch -'@0xsequence/builder': patch -'@0xsequence/guard': patch -'@0xsequence/identity-instrument': patch -'@0xsequence/indexer': patch -'@0xsequence/marketplace': patch -'@0xsequence/metadata': patch -'@0xsequence/relayer': patch -'@0xsequence/abi': patch -'@0xsequence/wallet-core': patch -'@0xsequence/dapp-client': patch -'@0xsequence/wallet-primitives': patch -'@0xsequence/wallet-wdk': patch ---- - -RC5 upgrade diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 20d4777291..bb22f4c721 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -19,6 +19,8 @@ jobs: - uses: ./.github/actions/install-dependencies - run: pnpm clean - run: pnpm build + - run: pnpm typecheck + - run: pnpm lint tests: name: Run all tests diff --git a/extras/docs/package.json b/extras/docs/package.json index 29fbc4bc74..9c51ce6c11 100644 --- a/extras/docs/package.json +++ b/extras/docs/package.json @@ -13,14 +13,14 @@ }, "dependencies": { "@repo/ui": "workspace:^", - "next": "^15.5.9", + "next": "^15.5.10", "react": "^19.2.3", "react-dom": "^19.2.3" }, "devDependencies": { "@repo/eslint-config": "workspace:^", "@repo/typescript-config": "workspace:^", - "@types/node": "^25.0.2", + "@types/node": "^25.3.0", "@types/react": "^19.2.7", "@types/react-dom": "^19.2.3", "eslint": "^9.39.2", diff --git a/extras/web/package.json b/extras/web/package.json index b0b621e95f..e7fd226c08 100644 --- a/extras/web/package.json +++ b/extras/web/package.json @@ -13,14 +13,14 @@ }, "dependencies": { "@repo/ui": "workspace:^", - "next": "^15.5.9", + "next": "^15.5.10", "react": "^19.2.3", "react-dom": "^19.2.3" }, "devDependencies": { "@repo/eslint-config": "workspace:^", "@repo/typescript-config": "workspace:^", - "@types/node": "^25.0.2", + "@types/node": "^25.3.0", "@types/react": "^19.2.7", "@types/react-dom": "^19.2.3", "eslint": "^9.39.2", diff --git a/lefthook.yml b/lefthook.yml index 7b9926c50d..5402d7dc7d 100644 --- a/lefthook.yml +++ b/lefthook.yml @@ -3,6 +3,10 @@ pre-commit: prettier: glob: '**/*.{js,jsx,ts,tsx,json,md,yml,yaml}' run: pnpm prettier --write {staged_files} && git add {staged_files} + lint: + run: pnpm lint + typecheck: + run: pnpm typecheck syncpack: glob: - "package.json" diff --git a/package.json b/package.json index 53a8caae3e..92559c5103 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "build": "pnpm build:packages", "dev": "turbo dev", "test": "turbo test --concurrency=1", - "lint": "turbo lint", + "lint": "turbo lint --continue", "format": "prettier --list-different --write \"**/*.{ts,tsx,md}\"", "typecheck": "turbo typecheck", "postinstall": "lefthook install", @@ -16,16 +16,16 @@ "reinstall": "rimraf -g ./**/node_modules && pnpm install", "test:anvil": "anvil --fork-url https://nodes.sequence.app/arbitrum", "clean": "turbo clean", - "deps:lint": "syncpack list-mismatches", - "deps:fix": "syncpack fix-mismatches" + "deps:lint": "syncpack lint --dependency-types prod,dev", + "deps:fix": "syncpack fix" }, "devDependencies": { "@changesets/cli": "^2.29.8", - "lefthook": "^2.0.12", - "prettier": "^3.7.4", - "rimraf": "^6.1.2", - "syncpack": "^13.0.4", - "turbo": "^2.6.3", + "lefthook": "^2.1.1", + "prettier": "^3.8.1", + "rimraf": "^6.1.3", + "syncpack": "^14.0.0", + "turbo": "^2.8.10", "typescript": "^5.9.3" }, "pnpm": { diff --git a/packages/services/api/CHANGELOG.md b/packages/services/api/CHANGELOG.md index d0449f7f82..61bd11b9af 100644 --- a/packages/services/api/CHANGELOG.md +++ b/packages/services/api/CHANGELOG.md @@ -1,5 +1,90 @@ # @0xsequence/api +## 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 diff --git a/packages/wallet/dapp-client/eslint.config.mjs b/packages/services/api/eslint.config.js similarity index 100% rename from packages/wallet/dapp-client/eslint.config.mjs rename to packages/services/api/eslint.config.js diff --git a/packages/services/api/package.json b/packages/services/api/package.json index 4e464c6815..0d4b988b21 100644 --- a/packages/services/api/package.json +++ b/packages/services/api/package.json @@ -1,18 +1,20 @@ { "name": "@0xsequence/api", - "version": "3.0.0-beta.9", + "version": "3.0.0", "description": "api sub-package for Sequence", "repository": "https://github.com/0xsequence/sequence.js/tree/master/packages/services/api", - "author": "Sequence Platforms Inc.", + "author": "Sequence Platforms ULC", "license": "Apache-2.0", "publishConfig": { "access": "public" }, + "type": "module", "scripts": { "build": "tsc", "dev": "tsc --watch", "test": "echo", - "typecheck": "tsc --noEmit" + "typecheck": "tsc --noEmit", + "lint": "eslint . --max-warnings 0" }, "exports": { ".": { @@ -22,7 +24,8 @@ }, "devDependencies": { "@repo/typescript-config": "workspace:^", - "@types/node": "^25.0.2", + "@types/node": "^25.3.0", + "@repo/eslint-config": "workspace:^", "typescript": "^5.9.3" } } diff --git a/packages/services/api/src/api.gen.ts b/packages/services/api/src/api.gen.ts index bf07aa0399..b9d2e58703 100644 --- a/packages/services/api/src/api.gen.ts +++ b/packages/services/api/src/api.gen.ts @@ -1,5 +1,5 @@ /* eslint-disable */ -// sequence-api v0.4.0 d7026da603b2c29baf21c6aceeebc86eada372d8 +// sequence-api v0.4.0 3c15fa79614e43a5321cd2ac0c080e80af291bd1 // -- // Code generated by Webrpc-gen@v0.31.0 with typescript generator. DO NOT EDIT. // @@ -12,7 +12,7 @@ export const WebrpcVersion = 'v1' export const WebrpcSchemaVersion = 'v0.4.0' // Schema hash generated from your RIDL schema -export const WebrpcSchemaHash = 'd7026da603b2c29baf21c6aceeebc86eada372d8' +export const WebrpcSchemaHash = '3c15fa79614e43a5321cd2ac0c080e80af291bd1' // // Client interface @@ -47,14 +47,10 @@ export interface APIClient { sendPasswordlessLink( req: SendPasswordlessLinkRequest, headers?: object, - signal?: AbortSignal, + signal?: AbortSignal ): Promise - registerPublicKey( - req: RegisterPublicKeyRequest, - headers?: object, - signal?: AbortSignal, - ): Promise + registerPublicKey(req: RegisterPublicKeyRequest, headers?: object, signal?: AbortSignal): Promise getPublicKey(req: GetPublicKeyRequest, headers?: object, signal?: AbortSignal): Promise @@ -65,11 +61,7 @@ export interface APIClient { */ friendList(req: FriendListRequest, headers?: object, signal?: AbortSignal): Promise - getFriendByAddress( - req: GetFriendByAddressRequest, - headers?: object, - signal?: AbortSignal, - ): Promise + getFriendByAddress(req: GetFriendByAddressRequest, headers?: object, signal?: AbortSignal): Promise searchFriends(req: SearchFriendsRequest, headers?: object, signal?: AbortSignal): Promise @@ -78,7 +70,7 @@ export interface APIClient { updateFriendNickname( req: UpdateFriendNicknameRequest, headers?: object, - signal?: AbortSignal, + signal?: AbortSignal ): Promise removeFriend(req: RemoveFriendRequest, headers?: object, signal?: AbortSignal): Promise @@ -90,16 +82,12 @@ export interface APIClient { */ contractCall(req: ContractCallRequest, headers?: object, signal?: AbortSignal): Promise - decodeContractCall( - req: DecodeContractCallRequest, - headers?: object, - signal?: AbortSignal, - ): Promise + decodeContractCall(req: DecodeContractCallRequest, headers?: object, signal?: AbortSignal): Promise lookupContractCallSelectors( req: LookupContractCallSelectorsRequest, headers?: object, - signal?: AbortSignal, + signal?: AbortSignal ): Promise /** @@ -107,24 +95,16 @@ export interface APIClient { * User Storage * */ - userStorageFetch( - req: UserStorageFetchRequest, - headers?: object, - signal?: AbortSignal, - ): Promise + userStorageFetch(req: UserStorageFetchRequest, headers?: object, signal?: AbortSignal): Promise userStorageSave(req: UserStorageSaveRequest, headers?: object, signal?: AbortSignal): Promise - userStorageDelete( - req: UserStorageDeleteRequest, - headers?: object, - signal?: AbortSignal, - ): Promise + userStorageDelete(req: UserStorageDeleteRequest, headers?: object, signal?: AbortSignal): Promise userStorageFetchAll( req: UserStorageFetchAllRequest, headers?: object, - signal?: AbortSignal, + signal?: AbortSignal ): Promise /** @@ -137,38 +117,30 @@ export interface APIClient { /** * - IsUsingGoogleMail(domain: string) => (yes: bool) */ - resolveENSAddress( - req: ResolveENSAddressRequest, - headers?: object, - signal?: AbortSignal, - ): Promise + resolveENSAddress(req: ResolveENSAddressRequest, headers?: object, signal?: AbortSignal): Promise /** * TODO: we can add walletContext optional in the future when we need it * NOTE: chainId can be either a number or canonical name */ - isValidSignature( - req: IsValidSignatureRequest, - headers?: object, - signal?: AbortSignal, - ): Promise + isValidSignature(req: IsValidSignatureRequest, headers?: object, signal?: AbortSignal): Promise isValidMessageSignature( req: IsValidMessageSignatureRequest, headers?: object, - signal?: AbortSignal, + signal?: AbortSignal ): Promise isValidTypedDataSignature( req: IsValidTypedDataSignatureRequest, headers?: object, - signal?: AbortSignal, + signal?: AbortSignal ): Promise isValidETHAuthProof( req: IsValidETHAuthProofRequest, headers?: object, - signal?: AbortSignal, + signal?: AbortSignal ): Promise getOnRampURL(req: GetOnRampURLRequest, headers?: object, signal?: AbortSignal): Promise @@ -183,13 +155,13 @@ export interface APIClient { transakGetSupportedNFTCheckoutChains( headers?: object, - signal?: AbortSignal, + signal?: AbortSignal ): Promise transakGetWidgetURL( req: TransakGetWidgetURLRequest, headers?: object, - signal?: AbortSignal, + signal?: AbortSignal ): Promise /** @@ -202,7 +174,7 @@ export interface APIClient { getCollectiblePrices( req: GetCollectiblePricesRequest, headers?: object, - signal?: AbortSignal, + signal?: AbortSignal ): Promise /** @@ -231,26 +203,18 @@ export interface APIClient { /** * NOTE: we're still using this from SW-API to Sequence-API to claim invite code */ - isValidAccessCode( - req: IsValidAccessCodeRequest, - headers?: object, - signal?: AbortSignal, - ): Promise + isValidAccessCode(req: IsValidAccessCodeRequest, headers?: object, signal?: AbortSignal): Promise internalClaimAccessCode( req: InternalClaimAccessCodeRequest, headers?: object, - signal?: AbortSignal, + signal?: AbortSignal ): Promise /** * Utils */ - blockNumberAtTime( - req: BlockNumberAtTimeRequest, - headers?: object, - signal?: AbortSignal, - ): Promise + blockNumberAtTime(req: BlockNumberAtTimeRequest, headers?: object, signal?: AbortSignal): Promise /** * @@ -258,16 +222,12 @@ export interface APIClient { * TODO: deprecate in the future * */ - paperSessionSecret( - req: PaperSessionSecretRequest, - headers?: object, - signal?: AbortSignal, - ): Promise + paperSessionSecret(req: PaperSessionSecretRequest, headers?: object, signal?: AbortSignal): Promise paperSessionSecret2( req: PaperSessionSecret2Request, headers?: object, - signal?: AbortSignal, + signal?: AbortSignal ): Promise /** @@ -277,17 +237,9 @@ export interface APIClient { */ linkWallet(req: LinkWalletRequest, headers?: object, signal?: AbortSignal): Promise - getLinkedWallets( - req: GetLinkedWalletsRequest, - headers?: object, - signal?: AbortSignal, - ): Promise + getLinkedWallets(req: GetLinkedWalletsRequest, headers?: object, signal?: AbortSignal): Promise - removeLinkedWallet( - req: RemoveLinkedWalletRequest, - headers?: object, - signal?: AbortSignal, - ): Promise + removeLinkedWallet(req: RemoveLinkedWalletRequest, headers?: object, signal?: AbortSignal): Promise /** * NOTE: these methods are deprecated, please do not use them. We may resurface them in the future, but just wanted @@ -296,13 +248,13 @@ export interface APIClient { generateWaaSVerificationURL( req: GenerateWaaSVerificationURLRequest, headers?: object, - signal?: AbortSignal, + signal?: AbortSignal ): Promise validateWaaSVerificationNonce( req: ValidateWaaSVerificationNonceRequest, headers?: object, - signal?: AbortSignal, + signal?: AbortSignal ): Promise /** @@ -311,11 +263,7 @@ export interface APIClient { * WaaS child wallet adoption * */ - listAdoptedWallets( - req: ListAdoptedWalletsRequest, - headers?: object, - signal?: AbortSignal, - ): Promise + listAdoptedWallets(req: ListAdoptedWalletsRequest, headers?: object, signal?: AbortSignal): Promise getLifiChains(headers?: object, signal?: AbortSignal): Promise @@ -325,36 +273,9 @@ export interface APIClient { * All parameters except `params` are deprecated. * Use only the `params` object to pass values. */ - getLifiSwapRoutes( - req: GetLifiSwapRoutesRequest, - headers?: object, - signal?: AbortSignal, - ): Promise + getLifiSwapRoutes(req: GetLifiSwapRoutesRequest, headers?: object, signal?: AbortSignal): Promise - getLifiSwapQuote( - req: GetLifiSwapQuoteRequest, - headers?: object, - signal?: AbortSignal, - ): Promise - - /** - * - * Chain abstraction - * - */ - getIntentCallsPayloads( - req: GetIntentCallsPayloadsRequest, - headers?: object, - signal?: AbortSignal, - ): Promise - - commitIntentConfig( - req: CommitIntentConfigRequest, - headers?: object, - signal?: AbortSignal, - ): Promise - - getIntentConfig(req: GetIntentConfigRequest, headers?: object, signal?: AbortSignal): Promise + getLifiSwapQuote(req: GetLifiSwapQuoteRequest, headers?: object, signal?: AbortSignal): Promise /** * @@ -366,43 +287,43 @@ export interface APIClient { addOffchainInventory( req: AddOffchainInventoryRequest, headers?: object, - signal?: AbortSignal, + signal?: AbortSignal ): Promise getOffchainInventory( req: GetOffchainInventoryRequest, headers?: object, - signal?: AbortSignal, + signal?: AbortSignal ): Promise listOffchainInventories( req: ListOffchainInventoriesRequest, headers?: object, - signal?: AbortSignal, + signal?: AbortSignal ): Promise updateOffchainInventory( req: UpdateOffchainInventoryRequest, headers?: object, - signal?: AbortSignal, + signal?: AbortSignal ): Promise deleteOffchainInventory( req: DeleteOffchainInventoryRequest, headers?: object, - signal?: AbortSignal, + signal?: AbortSignal ): Promise requestOffchainPayment( req: RequestOffchainPaymentRequest, headers?: object, - signal?: AbortSignal, + signal?: AbortSignal ): Promise listOffchainPayments( req: ListOffchainPaymentsRequest, headers?: object, - signal?: AbortSignal, + signal?: AbortSignal ): Promise /** @@ -418,85 +339,39 @@ export interface APIClient { deletePack(req: DeletePackRequest, headers?: object, signal?: AbortSignal): Promise - updatePackContent( - req: UpdatePackContentRequest, - headers?: object, - signal?: AbortSignal, - ): Promise + updatePackContent(req: UpdatePackContentRequest, headers?: object, signal?: AbortSignal): Promise getRevealTxData(req: GetRevealTxDataRequest, headers?: object, signal?: AbortSignal): Promise checkoutOptionsPrimary( req: CheckoutOptionsPrimaryRequest, headers?: object, - signal?: AbortSignal, + signal?: AbortSignal ): Promise checkoutOptionsSecondary( req: CheckoutOptionsSecondaryRequest, headers?: object, - signal?: AbortSignal, + signal?: AbortSignal ): Promise checkoutOptionsGetTransakContractID( req: CheckoutOptionsGetTransakContractIDRequest, headers?: object, - signal?: AbortSignal, + signal?: AbortSignal ): Promise fortePayCreateIntent( req: FortePayCreateIntentRequest, headers?: object, - signal?: AbortSignal, + signal?: AbortSignal ): Promise fortePayGetPaymentStatuses( req: FortePayGetPaymentStatusesRequest, headers?: object, - signal?: AbortSignal, + signal?: AbortSignal ): Promise - - /** - * - * CCTP - * - */ - getCCTPTransfer(req: GetCCTPTransferRequest, headers?: object, signal?: AbortSignal): Promise - - queueCCTPTransfer( - req: QueueCCTPTransferRequest, - headers?: object, - signal?: AbortSignal, - ): Promise - - /** - * - * Intent Machine Worker - * - */ - queueIntentConfigExecution( - req: QueueIntentConfigExecutionRequest, - headers?: object, - signal?: AbortSignal, - ): Promise - - getIntentConfigExecutionStatus( - req: GetIntentConfigExecutionStatusRequest, - headers?: object, - signal?: AbortSignal, - ): Promise - - listIntentConfigs( - req: ListIntentConfigsRequest, - headers?: object, - signal?: AbortSignal, - ): Promise - - queueMetaTxnReceipt( - req: QueueMetaTxnReceiptRequest, - headers?: object, - signal?: AbortSignal, - ): Promise } // @@ -505,50 +380,50 @@ export interface APIClient { export enum SortOrder { DESC = 'DESC', - ASC = 'ASC', + ASC = 'ASC' } export enum GetLifiSwapRouteDirection { to = 'to', - from = 'from', + from = 'from' } export enum TokenType { ERC20 = 'ERC20', ERC721 = 'ERC721', - ERC1155 = 'ERC1155', + ERC1155 = 'ERC1155' } export enum TransakBuySell { UNKNOWN = 'UNKNOWN', BUY = 'BUY', - SELL = 'SELL', + SELL = 'SELL' } export enum TradeType { EXACT_INPUT = 'EXACT_INPUT', - EXACT_OUTPUT = 'EXACT_OUTPUT', + EXACT_OUTPUT = 'EXACT_OUTPUT' } export enum CheckoutOptionCrypto { none = 'none', partially = 'partially', - all = 'all', + all = 'all' } export enum CheckoutOptionNFTCheckoutProvider { unknown = 'unknown', - transak = 'transak', + transak = 'transak' } export enum CheckoutOptionOnRampProvider { unknown = 'unknown', - transak = 'transak', + transak = 'transak' } export enum CheckoutOptionSwapProvider { unknown = 'unknown', - lifi = 'lifi', + lifi = 'lifi' } export interface Version { @@ -632,38 +507,6 @@ export interface MetaTxn { input: string } -export interface Call { - to: string - value?: string - data?: string - gasLimit?: string - delegateCall?: boolean - onlyFallback?: boolean - behaviorOnError?: number -} - -export interface IntentCallsPayload { - chainId: string - space?: string - nonce?: string - calls: Array -} - -export interface IntentConfig { - id: number - configHash: string - originIntentAddress: string - destinationIntentAddress: string - mainSigner: string - calls: Array - preconditions: Array - executionStatus?: string - metaTxnId?: string - txnHash?: string - updatedAt?: string - createdAt?: string -} - export interface MetaTxnReceipt { metaTxID: string status: string @@ -703,30 +546,6 @@ export interface TupleComponent { value: any } -export interface AddressOverrides { - trailsLiFiSapientSignerAddress?: string - trailsRelaySapientSignerAddress?: string - trailsCCTPV2SapientSignerAddress?: string -} - -export interface TakerFee { - address: string - bps: number -} - -export interface OriginCall { - chainId: number - to: string - transactionData: string - transactionValue: string -} - -export interface IntentPrecondition { - type: string - chainId: string - data: any -} - export interface UserStorage { userAddress: string key: string @@ -866,18 +685,6 @@ export interface OffchainInventory { deletedAt?: string } -export interface CCTPTransfer { - id: string - sourceTxHash: string - sourceChainId: number - destinationChainId: number - message: string - attestation: string - status: string - createdAt: string - updatedAt: string -} - export interface OffchainPayment { id: number offchainInventoryId: number @@ -1228,33 +1035,6 @@ export interface ExecuteQuote { chainQuotes: Array } -export interface TrailsFee { - executeQuote: ExecuteQuote - crossChainFee?: CrossChainFee - takerFeeAmount?: string - takerFeeUSD?: number - trailsFixedFeeUSD: number - feeToken?: string - originTokenTotalAmount?: string - totalFeeAmount?: string - totalFeeUSD?: string - quoteProvider?: string -} - -export interface IntentQuote { - fromAmount: string - fromAmountMin: string - toAmount: string - toAmountMin: string - priceImpact: number - priceImpactUsd: string - maxSlippage: number - quoteProvider: string - quoteProviderRequestId: string - quoteProviderFeeUsd: string - feeQuotes: { [key: string]: string } -} - export interface PingRequest {} export interface PingResponse { @@ -1738,10 +1518,6 @@ export interface GetLifiTokensResponse { export interface GetLifiSwapRoutesRequest { params: GetLifiSwapRouteParams - chainId: number - toTokenAddress: string - toTokenAmount: string - walletAddress: string } export interface GetLifiSwapRoutesResponse { @@ -1756,57 +1532,6 @@ export interface GetLifiSwapQuoteResponse { quote: LifiSwapQuote } -export interface GetIntentCallsPayloadsRequest { - userAddress: string - destinationChainId: number - destinationTokenAddress: string - destinationTokenAmount: string - destinationToAddress: string - originChainId: number - originTokenAddress: string - originTokenAmount: string - destinationCallData?: string - destinationCallValue?: string - provider?: string - addressOverrides?: AddressOverrides - destinationSalt?: string - takerFee?: TakerFee - slippageTolerance?: number - tradeType?: TradeType -} - -export interface GetIntentCallsPayloadsResponse { - calls: Array - preconditions: Array - metaTxns: Array - trailsFee: TrailsFee - quote: IntentQuote - feeQuotes: { [key: string]: string } - originIntentAddress: string - destinationIntentAddress: string -} - -export interface CommitIntentConfigRequest { - originIntentAddress: string - destinationIntentAddress: string - mainSigner: string - calls: Array - preconditions: Array - addressOverrides?: AddressOverrides -} - -export interface CommitIntentConfigResponse { - config: IntentConfig -} - -export interface GetIntentConfigRequest { - intentAddress: string -} - -export interface GetIntentConfigResponse { - config: IntentConfig -} - export interface ListCurrencyGroupsRequest {} export interface ListCurrencyGroupsResponse { @@ -1975,59 +1700,6 @@ export interface FortePayGetPaymentStatusesResponse { statuses: Array } -export interface GetCCTPTransferRequest { - id: string -} - -export interface GetCCTPTransferResponse { - transfer: CCTPTransfer -} - -export interface QueueCCTPTransferRequest { - sourceTxHash?: string - metaTxHash?: string - sourceChainId: number - destinationChainId: number -} - -export interface QueueCCTPTransferResponse { - transfer: CCTPTransfer -} - -export interface QueueIntentConfigExecutionRequest { - intentConfigId: number -} - -export interface QueueIntentConfigExecutionResponse { - status: boolean -} - -export interface GetIntentConfigExecutionStatusRequest { - intentConfigId: number -} - -export interface GetIntentConfigExecutionStatusResponse { - executionStatus: string -} - -export interface ListIntentConfigsRequest { - page?: Page - executionStatus?: string -} - -export interface ListIntentConfigsResponse { - page: Page - intentConfigs: Array -} - -export interface QueueMetaTxnReceiptRequest { - metaTxID: string -} - -export interface QueueMetaTxnReceiptResponse { - status: boolean -} - // // Client // @@ -2075,8 +1747,7 @@ export class API implements APIClient { resolveENSAddress: (req: ResolveENSAddressRequest) => ['API', 'resolveENSAddress', req] as const, isValidSignature: (req: IsValidSignatureRequest) => ['API', 'isValidSignature', req] as const, isValidMessageSignature: (req: IsValidMessageSignatureRequest) => ['API', 'isValidMessageSignature', req] as const, - isValidTypedDataSignature: (req: IsValidTypedDataSignatureRequest) => - ['API', 'isValidTypedDataSignature', req] as const, + isValidTypedDataSignature: (req: IsValidTypedDataSignatureRequest) => ['API', 'isValidTypedDataSignature', req] as const, isValidETHAuthProof: (req: IsValidETHAuthProofRequest) => ['API', 'isValidETHAuthProof', req] as const, getOnRampURL: (req: GetOnRampURLRequest) => ['API', 'getOnRampURL', req] as const, transakGetCountries: () => ['API', 'transakGetCountries'] as const, @@ -2108,9 +1779,6 @@ export class API implements APIClient { getLifiTokens: (req: GetLifiTokensRequest) => ['API', 'getLifiTokens', req] as const, getLifiSwapRoutes: (req: GetLifiSwapRoutesRequest) => ['API', 'getLifiSwapRoutes', req] as const, getLifiSwapQuote: (req: GetLifiSwapQuoteRequest) => ['API', 'getLifiSwapQuote', req] as const, - getIntentCallsPayloads: (req: GetIntentCallsPayloadsRequest) => ['API', 'getIntentCallsPayloads', req] as const, - commitIntentConfig: (req: CommitIntentConfigRequest) => ['API', 'commitIntentConfig', req] as const, - getIntentConfig: (req: GetIntentConfigRequest) => ['API', 'getIntentConfig', req] as const, listCurrencyGroups: () => ['API', 'listCurrencyGroups'] as const, addOffchainInventory: (req: AddOffchainInventoryRequest) => ['API', 'addOffchainInventory', req] as const, getOffchainInventory: (req: GetOffchainInventoryRequest) => ['API', 'getOffchainInventory', req] as const, @@ -2126,1759 +1794,1315 @@ export class API implements APIClient { updatePackContent: (req: UpdatePackContentRequest) => ['API', 'updatePackContent', req] as const, getRevealTxData: (req: GetRevealTxDataRequest) => ['API', 'getRevealTxData', req] as const, checkoutOptionsPrimary: (req: CheckoutOptionsPrimaryRequest) => ['API', 'checkoutOptionsPrimary', req] as const, - checkoutOptionsSecondary: (req: CheckoutOptionsSecondaryRequest) => - ['API', 'checkoutOptionsSecondary', req] as const, + checkoutOptionsSecondary: (req: CheckoutOptionsSecondaryRequest) => ['API', 'checkoutOptionsSecondary', req] as const, checkoutOptionsGetTransakContractID: (req: CheckoutOptionsGetTransakContractIDRequest) => ['API', 'checkoutOptionsGetTransakContractID', req] as const, fortePayCreateIntent: (req: FortePayCreateIntentRequest) => ['API', 'fortePayCreateIntent', req] as const, - fortePayGetPaymentStatuses: (req: FortePayGetPaymentStatusesRequest) => - ['API', 'fortePayGetPaymentStatuses', req] as const, - getCCTPTransfer: (req: GetCCTPTransferRequest) => ['API', 'getCCTPTransfer', req] as const, - queueCCTPTransfer: (req: QueueCCTPTransferRequest) => ['API', 'queueCCTPTransfer', req] as const, - queueIntentConfigExecution: (req: QueueIntentConfigExecutionRequest) => - ['API', 'queueIntentConfigExecution', req] as const, - getIntentConfigExecutionStatus: (req: GetIntentConfigExecutionStatusRequest) => - ['API', 'getIntentConfigExecutionStatus', req] as const, - listIntentConfigs: (req: ListIntentConfigsRequest) => ['API', 'listIntentConfigs', req] as const, - queueMetaTxnReceipt: (req: QueueMetaTxnReceiptRequest) => ['API', 'queueMetaTxnReceipt', req] as const, + fortePayGetPaymentStatuses: (req: FortePayGetPaymentStatusesRequest) => ['API', 'fortePayGetPaymentStatuses', 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) => { + res => { + return buildResponse(res).then(_data => { return JsonDecode(_data, 'PingResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, + 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) => { + res => { + return buildResponse(res).then(_data => { return JsonDecode(_data, 'VersionResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, + 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) => { + res => { + return buildResponse(res).then(_data => { return JsonDecode(_data, 'RuntimeStatusResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } clock = (headers?: object, signal?: AbortSignal): Promise => { return this.fetch(this.url('Clock'), createHttpRequest('{}', headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { + res => { + return buildResponse(res).then(_data => { return JsonDecode(_data, 'ClockResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, + 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) => { + res => { + return buildResponse(res).then(_data => { return JsonDecode(_data, 'GetSequenceContextResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } getAuthToken = (req: GetAuthTokenRequest, headers?: object, signal?: AbortSignal): Promise => { - return this.fetch( - this.url('GetAuthToken'), - createHttpRequest(JsonEncode(req, 'GetAuthTokenRequest'), headers, signal), - ).then( - (res) => { - return buildResponse(res).then((_data) => { + return this.fetch(this.url('GetAuthToken'), createHttpRequest(JsonEncode(req, 'GetAuthTokenRequest'), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { return JsonDecode(_data, 'GetAuthTokenResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } - getAuthToken2 = ( - req: GetAuthToken2Request, - headers?: object, - signal?: AbortSignal, - ): Promise => { + getAuthToken2 = (req: GetAuthToken2Request, headers?: object, signal?: AbortSignal): Promise => { return this.fetch( this.url('GetAuthToken2'), - createHttpRequest(JsonEncode(req, 'GetAuthToken2Request'), headers, signal), + createHttpRequest(JsonEncode(req, 'GetAuthToken2Request'), headers, signal) ).then( - (res) => { - return buildResponse(res).then((_data) => { + res => { + return buildResponse(res).then(_data => { return JsonDecode(_data, 'GetAuthToken2Response') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } sendPasswordlessLink = ( req: SendPasswordlessLinkRequest, headers?: object, - signal?: AbortSignal, + signal?: AbortSignal ): Promise => { return this.fetch( this.url('SendPasswordlessLink'), - createHttpRequest(JsonEncode(req, 'SendPasswordlessLinkRequest'), headers, signal), + createHttpRequest(JsonEncode(req, 'SendPasswordlessLinkRequest'), headers, signal) ).then( - (res) => { - return buildResponse(res).then((_data) => { + res => { + return buildResponse(res).then(_data => { return JsonDecode(_data, 'SendPasswordlessLinkResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } registerPublicKey = ( req: RegisterPublicKeyRequest, headers?: object, - signal?: AbortSignal, + signal?: AbortSignal ): Promise => { return this.fetch( this.url('RegisterPublicKey'), - createHttpRequest(JsonEncode(req, 'RegisterPublicKeyRequest'), headers, signal), + createHttpRequest(JsonEncode(req, 'RegisterPublicKeyRequest'), headers, signal) ).then( - (res) => { - return buildResponse(res).then((_data) => { + res => { + return buildResponse(res).then(_data => { return JsonDecode(_data, 'RegisterPublicKeyResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } getPublicKey = (req: GetPublicKeyRequest, headers?: object, signal?: AbortSignal): Promise => { - return this.fetch( - this.url('GetPublicKey'), - createHttpRequest(JsonEncode(req, 'GetPublicKeyRequest'), headers, signal), - ).then( - (res) => { - return buildResponse(res).then((_data) => { + return this.fetch(this.url('GetPublicKey'), createHttpRequest(JsonEncode(req, 'GetPublicKeyRequest'), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { return JsonDecode(_data, 'GetPublicKeyResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } friendList = (req: FriendListRequest, headers?: object, signal?: AbortSignal): Promise => { - return this.fetch( - this.url('FriendList'), - createHttpRequest(JsonEncode(req, 'FriendListRequest'), headers, signal), - ).then( - (res) => { - return buildResponse(res).then((_data) => { + return this.fetch(this.url('FriendList'), createHttpRequest(JsonEncode(req, 'FriendListRequest'), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { return JsonDecode(_data, 'FriendListResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } getFriendByAddress = ( req: GetFriendByAddressRequest, headers?: object, - signal?: AbortSignal, + signal?: AbortSignal ): Promise => { return this.fetch( this.url('GetFriendByAddress'), - createHttpRequest(JsonEncode(req, 'GetFriendByAddressRequest'), headers, signal), + createHttpRequest(JsonEncode(req, 'GetFriendByAddressRequest'), headers, signal) ).then( - (res) => { - return buildResponse(res).then((_data) => { + res => { + return buildResponse(res).then(_data => { return JsonDecode(_data, 'GetFriendByAddressResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } - searchFriends = ( - req: SearchFriendsRequest, - headers?: object, - signal?: AbortSignal, - ): Promise => { + searchFriends = (req: SearchFriendsRequest, headers?: object, signal?: AbortSignal): Promise => { return this.fetch( this.url('SearchFriends'), - createHttpRequest(JsonEncode(req, 'SearchFriendsRequest'), headers, signal), + createHttpRequest(JsonEncode(req, 'SearchFriendsRequest'), headers, signal) ).then( - (res) => { - return buildResponse(res).then((_data) => { + res => { + return buildResponse(res).then(_data => { return JsonDecode(_data, 'SearchFriendsResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } addFriend = (req: AddFriendRequest, headers?: object, signal?: AbortSignal): Promise => { - return this.fetch( - this.url('AddFriend'), - createHttpRequest(JsonEncode(req, 'AddFriendRequest'), headers, signal), - ).then( - (res) => { - return buildResponse(res).then((_data) => { + return this.fetch(this.url('AddFriend'), createHttpRequest(JsonEncode(req, 'AddFriendRequest'), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { return JsonDecode(_data, 'AddFriendResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } updateFriendNickname = ( req: UpdateFriendNicknameRequest, headers?: object, - signal?: AbortSignal, + signal?: AbortSignal ): Promise => { return this.fetch( this.url('UpdateFriendNickname'), - createHttpRequest(JsonEncode(req, 'UpdateFriendNicknameRequest'), headers, signal), + createHttpRequest(JsonEncode(req, 'UpdateFriendNicknameRequest'), headers, signal) ).then( - (res) => { - return buildResponse(res).then((_data) => { + res => { + return buildResponse(res).then(_data => { return JsonDecode(_data, 'UpdateFriendNicknameResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } removeFriend = (req: RemoveFriendRequest, headers?: object, signal?: AbortSignal): Promise => { - return this.fetch( - this.url('RemoveFriend'), - createHttpRequest(JsonEncode(req, 'RemoveFriendRequest'), headers, signal), - ).then( - (res) => { - return buildResponse(res).then((_data) => { + return this.fetch(this.url('RemoveFriend'), createHttpRequest(JsonEncode(req, 'RemoveFriendRequest'), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { return JsonDecode(_data, 'RemoveFriendResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } contractCall = (req: ContractCallRequest, headers?: object, signal?: AbortSignal): Promise => { - return this.fetch( - this.url('ContractCall'), - createHttpRequest(JsonEncode(req, 'ContractCallRequest'), headers, signal), - ).then( - (res) => { - return buildResponse(res).then((_data) => { + return this.fetch(this.url('ContractCall'), createHttpRequest(JsonEncode(req, 'ContractCallRequest'), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { return JsonDecode(_data, 'ContractCallResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } decodeContractCall = ( req: DecodeContractCallRequest, headers?: object, - signal?: AbortSignal, + signal?: AbortSignal ): Promise => { return this.fetch( this.url('DecodeContractCall'), - createHttpRequest(JsonEncode(req, 'DecodeContractCallRequest'), headers, signal), + createHttpRequest(JsonEncode(req, 'DecodeContractCallRequest'), headers, signal) ).then( - (res) => { - return buildResponse(res).then((_data) => { + res => { + return buildResponse(res).then(_data => { return JsonDecode(_data, 'DecodeContractCallResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } lookupContractCallSelectors = ( req: LookupContractCallSelectorsRequest, headers?: object, - signal?: AbortSignal, + signal?: AbortSignal ): Promise => { return this.fetch( this.url('LookupContractCallSelectors'), - createHttpRequest(JsonEncode(req, 'LookupContractCallSelectorsRequest'), headers, signal), + createHttpRequest(JsonEncode(req, 'LookupContractCallSelectorsRequest'), headers, signal) ).then( - (res) => { - return buildResponse(res).then((_data) => { + res => { + return buildResponse(res).then(_data => { return JsonDecode(_data, 'LookupContractCallSelectorsResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } userStorageFetch = ( req: UserStorageFetchRequest, headers?: object, - signal?: AbortSignal, + signal?: AbortSignal ): Promise => { return this.fetch( this.url('UserStorageFetch'), - createHttpRequest(JsonEncode(req, 'UserStorageFetchRequest'), headers, signal), + createHttpRequest(JsonEncode(req, 'UserStorageFetchRequest'), headers, signal) ).then( - (res) => { - return buildResponse(res).then((_data) => { + res => { + return buildResponse(res).then(_data => { return JsonDecode(_data, 'UserStorageFetchResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } - userStorageSave = ( - req: UserStorageSaveRequest, - headers?: object, - signal?: AbortSignal, - ): Promise => { + userStorageSave = (req: UserStorageSaveRequest, headers?: object, signal?: AbortSignal): Promise => { return this.fetch( this.url('UserStorageSave'), - createHttpRequest(JsonEncode(req, 'UserStorageSaveRequest'), headers, signal), + createHttpRequest(JsonEncode(req, 'UserStorageSaveRequest'), headers, signal) ).then( - (res) => { - return buildResponse(res).then((_data) => { + res => { + return buildResponse(res).then(_data => { return JsonDecode(_data, 'UserStorageSaveResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } userStorageDelete = ( req: UserStorageDeleteRequest, headers?: object, - signal?: AbortSignal, + signal?: AbortSignal ): Promise => { return this.fetch( this.url('UserStorageDelete'), - createHttpRequest(JsonEncode(req, 'UserStorageDeleteRequest'), headers, signal), + createHttpRequest(JsonEncode(req, 'UserStorageDeleteRequest'), headers, signal) ).then( - (res) => { - return buildResponse(res).then((_data) => { + res => { + return buildResponse(res).then(_data => { return JsonDecode(_data, 'UserStorageDeleteResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } userStorageFetchAll = ( req: UserStorageFetchAllRequest, headers?: object, - signal?: AbortSignal, + signal?: AbortSignal ): Promise => { return this.fetch( this.url('UserStorageFetchAll'), - createHttpRequest(JsonEncode(req, 'UserStorageFetchAllRequest'), headers, signal), + createHttpRequest(JsonEncode(req, 'UserStorageFetchAllRequest'), headers, signal) ).then( - (res) => { - return buildResponse(res).then((_data) => { + res => { + return buildResponse(res).then(_data => { return JsonDecode(_data, 'UserStorageFetchAllResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } - getMoonpayLink = ( - req: GetMoonpayLinkRequest, - headers?: object, - signal?: AbortSignal, - ): Promise => { + getMoonpayLink = (req: GetMoonpayLinkRequest, headers?: object, signal?: AbortSignal): Promise => { return this.fetch( this.url('GetMoonpayLink'), - createHttpRequest(JsonEncode(req, 'GetMoonpayLinkRequest'), headers, signal), + createHttpRequest(JsonEncode(req, 'GetMoonpayLinkRequest'), headers, signal) ).then( - (res) => { - return buildResponse(res).then((_data) => { + res => { + return buildResponse(res).then(_data => { return JsonDecode(_data, 'GetMoonpayLinkResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } resolveENSAddress = ( req: ResolveENSAddressRequest, headers?: object, - signal?: AbortSignal, + signal?: AbortSignal ): Promise => { return this.fetch( this.url('ResolveENSAddress'), - createHttpRequest(JsonEncode(req, 'ResolveENSAddressRequest'), headers, signal), + createHttpRequest(JsonEncode(req, 'ResolveENSAddressRequest'), headers, signal) ).then( - (res) => { - return buildResponse(res).then((_data) => { + res => { + return buildResponse(res).then(_data => { return JsonDecode(_data, 'ResolveENSAddressResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } isValidSignature = ( req: IsValidSignatureRequest, headers?: object, - signal?: AbortSignal, + signal?: AbortSignal ): Promise => { return this.fetch( this.url('IsValidSignature'), - createHttpRequest(JsonEncode(req, 'IsValidSignatureRequest'), headers, signal), + createHttpRequest(JsonEncode(req, 'IsValidSignatureRequest'), headers, signal) ).then( - (res) => { - return buildResponse(res).then((_data) => { + res => { + return buildResponse(res).then(_data => { return JsonDecode(_data, 'IsValidSignatureResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } isValidMessageSignature = ( req: IsValidMessageSignatureRequest, headers?: object, - signal?: AbortSignal, + signal?: AbortSignal ): Promise => { return this.fetch( this.url('IsValidMessageSignature'), - createHttpRequest(JsonEncode(req, 'IsValidMessageSignatureRequest'), headers, signal), + createHttpRequest(JsonEncode(req, 'IsValidMessageSignatureRequest'), headers, signal) ).then( - (res) => { - return buildResponse(res).then((_data) => { + res => { + return buildResponse(res).then(_data => { return JsonDecode(_data, 'IsValidMessageSignatureResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } isValidTypedDataSignature = ( req: IsValidTypedDataSignatureRequest, headers?: object, - signal?: AbortSignal, + signal?: AbortSignal ): Promise => { return this.fetch( this.url('IsValidTypedDataSignature'), - createHttpRequest(JsonEncode(req, 'IsValidTypedDataSignatureRequest'), headers, signal), + createHttpRequest(JsonEncode(req, 'IsValidTypedDataSignatureRequest'), headers, signal) ).then( - (res) => { - return buildResponse(res).then((_data) => { + res => { + return buildResponse(res).then(_data => { return JsonDecode(_data, 'IsValidTypedDataSignatureResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } isValidETHAuthProof = ( req: IsValidETHAuthProofRequest, headers?: object, - signal?: AbortSignal, + signal?: AbortSignal ): Promise => { return this.fetch( this.url('IsValidETHAuthProof'), - createHttpRequest(JsonEncode(req, 'IsValidETHAuthProofRequest'), headers, signal), + createHttpRequest(JsonEncode(req, 'IsValidETHAuthProofRequest'), headers, signal) ).then( - (res) => { - return buildResponse(res).then((_data) => { + res => { + return buildResponse(res).then(_data => { return JsonDecode(_data, 'IsValidETHAuthProofResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } getOnRampURL = (req: GetOnRampURLRequest, headers?: object, signal?: AbortSignal): Promise => { - return this.fetch( - this.url('GetOnRampURL'), - createHttpRequest(JsonEncode(req, 'GetOnRampURLRequest'), headers, signal), - ).then( - (res) => { - return buildResponse(res).then((_data) => { + return this.fetch(this.url('GetOnRampURL'), createHttpRequest(JsonEncode(req, 'GetOnRampURLRequest'), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { return JsonDecode(_data, 'GetOnRampURLResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } transakGetCountries = (headers?: object, signal?: AbortSignal): Promise => { return this.fetch(this.url('TransakGetCountries'), createHttpRequest('{}', headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { + res => { + return buildResponse(res).then(_data => { return JsonDecode(_data, 'TransakGetCountriesResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } - transakGetCryptoCurrencies = ( - headers?: object, - signal?: AbortSignal, - ): Promise => { + transakGetCryptoCurrencies = (headers?: object, signal?: AbortSignal): Promise => { return this.fetch(this.url('TransakGetCryptoCurrencies'), createHttpRequest('{}', headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { + res => { + return buildResponse(res).then(_data => { return JsonDecode(_data, 'TransakGetCryptoCurrenciesResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } transakGetFiatCurrencies = (headers?: object, signal?: AbortSignal): Promise => { return this.fetch(this.url('TransakGetFiatCurrencies'), createHttpRequest('{}', headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { + res => { + return buildResponse(res).then(_data => { return JsonDecode(_data, 'TransakGetFiatCurrenciesResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } - transakGetPrice = ( - req: TransakGetPriceRequest, - headers?: object, - signal?: AbortSignal, - ): Promise => { + transakGetPrice = (req: TransakGetPriceRequest, headers?: object, signal?: AbortSignal): Promise => { return this.fetch( this.url('TransakGetPrice'), - createHttpRequest(JsonEncode(req, 'TransakGetPriceRequest'), headers, signal), + createHttpRequest(JsonEncode(req, 'TransakGetPriceRequest'), headers, signal) ).then( - (res) => { - return buildResponse(res).then((_data) => { + res => { + return buildResponse(res).then(_data => { return JsonDecode(_data, 'TransakGetPriceResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } transakGetSupportedNFTCheckoutChains = ( headers?: object, - signal?: AbortSignal, + signal?: AbortSignal ): Promise => { return this.fetch(this.url('TransakGetSupportedNFTCheckoutChains'), createHttpRequest('{}', headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return JsonDecode( - _data, - 'TransakGetSupportedNFTCheckoutChainsResponse', - ) - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'TransakGetSupportedNFTCheckoutChainsResponse') }) }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } transakGetWidgetURL = ( req: TransakGetWidgetURLRequest, headers?: object, - signal?: AbortSignal, + signal?: AbortSignal ): Promise => { return this.fetch( this.url('TransakGetWidgetURL'), - createHttpRequest(JsonEncode(req, 'TransakGetWidgetURLRequest'), headers, signal), + createHttpRequest(JsonEncode(req, 'TransakGetWidgetURLRequest'), headers, signal) ).then( - (res) => { - return buildResponse(res).then((_data) => { + res => { + return buildResponse(res).then(_data => { return JsonDecode(_data, 'TransakGetWidgetURLResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } - getCoinPrices = ( - req: GetCoinPricesRequest, - headers?: object, - signal?: AbortSignal, - ): Promise => { + getCoinPrices = (req: GetCoinPricesRequest, headers?: object, signal?: AbortSignal): Promise => { return this.fetch( this.url('GetCoinPrices'), - createHttpRequest(JsonEncode(req, 'GetCoinPricesRequest'), headers, signal), + createHttpRequest(JsonEncode(req, 'GetCoinPricesRequest'), headers, signal) ).then( - (res) => { - return buildResponse(res).then((_data) => { + res => { + return buildResponse(res).then(_data => { return JsonDecode(_data, 'GetCoinPricesResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } getCollectiblePrices = ( req: GetCollectiblePricesRequest, headers?: object, - signal?: AbortSignal, + signal?: AbortSignal ): Promise => { return this.fetch( this.url('GetCollectiblePrices'), - createHttpRequest(JsonEncode(req, 'GetCollectiblePricesRequest'), headers, signal), + createHttpRequest(JsonEncode(req, 'GetCollectiblePricesRequest'), headers, signal) ).then( - (res) => { - return buildResponse(res).then((_data) => { + res => { + return buildResponse(res).then(_data => { return JsonDecode(_data, 'GetCollectiblePricesResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } - getExchangeRate = ( - req: GetExchangeRateRequest, - headers?: object, - signal?: AbortSignal, - ): Promise => { + getExchangeRate = (req: GetExchangeRateRequest, headers?: object, signal?: AbortSignal): Promise => { return this.fetch( this.url('GetExchangeRate'), - createHttpRequest(JsonEncode(req, 'GetExchangeRateRequest'), headers, signal), + createHttpRequest(JsonEncode(req, 'GetExchangeRateRequest'), headers, signal) ).then( - (res) => { - return buildResponse(res).then((_data) => { + res => { + return buildResponse(res).then(_data => { return JsonDecode(_data, 'GetExchangeRateResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } memoryStore = (req: MemoryStoreRequest, headers?: object, signal?: AbortSignal): Promise => { - return this.fetch( - this.url('MemoryStore'), - createHttpRequest(JsonEncode(req, 'MemoryStoreRequest'), headers, signal), - ).then( - (res) => { - return buildResponse(res).then((_data) => { + return this.fetch(this.url('MemoryStore'), createHttpRequest(JsonEncode(req, 'MemoryStoreRequest'), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { return JsonDecode(_data, 'MemoryStoreResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } memoryLoad = (req: MemoryLoadRequest, headers?: object, signal?: AbortSignal): Promise => { - return this.fetch( - this.url('MemoryLoad'), - createHttpRequest(JsonEncode(req, 'MemoryLoadRequest'), headers, signal), - ).then( - (res) => { - return buildResponse(res).then((_data) => { + return this.fetch(this.url('MemoryLoad'), createHttpRequest(JsonEncode(req, 'MemoryLoadRequest'), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { return JsonDecode(_data, 'MemoryLoadResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } getInviteInfo = (headers?: object, signal?: AbortSignal): Promise => { return this.fetch(this.url('GetInviteInfo'), createHttpRequest('{}', headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { + res => { + return buildResponse(res).then(_data => { return JsonDecode(_data, 'GetInviteInfoResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } isValidAccessCode = ( req: IsValidAccessCodeRequest, headers?: object, - signal?: AbortSignal, + signal?: AbortSignal ): Promise => { return this.fetch( this.url('IsValidAccessCode'), - createHttpRequest(JsonEncode(req, 'IsValidAccessCodeRequest'), headers, signal), + createHttpRequest(JsonEncode(req, 'IsValidAccessCodeRequest'), headers, signal) ).then( - (res) => { - return buildResponse(res).then((_data) => { + res => { + return buildResponse(res).then(_data => { return JsonDecode(_data, 'IsValidAccessCodeResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } internalClaimAccessCode = ( req: InternalClaimAccessCodeRequest, headers?: object, - signal?: AbortSignal, + signal?: AbortSignal ): Promise => { return this.fetch( this.url('InternalClaimAccessCode'), - createHttpRequest(JsonEncode(req, 'InternalClaimAccessCodeRequest'), headers, signal), + createHttpRequest(JsonEncode(req, 'InternalClaimAccessCodeRequest'), headers, signal) ).then( - (res) => { - return buildResponse(res).then((_data) => { + res => { + return buildResponse(res).then(_data => { return JsonDecode(_data, 'InternalClaimAccessCodeResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } blockNumberAtTime = ( req: BlockNumberAtTimeRequest, headers?: object, - signal?: AbortSignal, + signal?: AbortSignal ): Promise => { return this.fetch( this.url('BlockNumberAtTime'), - createHttpRequest(JsonEncode(req, 'BlockNumberAtTimeRequest'), headers, signal), + createHttpRequest(JsonEncode(req, 'BlockNumberAtTimeRequest'), headers, signal) ).then( - (res) => { - return buildResponse(res).then((_data) => { + res => { + return buildResponse(res).then(_data => { return JsonDecode(_data, 'BlockNumberAtTimeResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } paperSessionSecret = ( req: PaperSessionSecretRequest, headers?: object, - signal?: AbortSignal, + signal?: AbortSignal ): Promise => { return this.fetch( this.url('PaperSessionSecret'), - createHttpRequest(JsonEncode(req, 'PaperSessionSecretRequest'), headers, signal), + createHttpRequest(JsonEncode(req, 'PaperSessionSecretRequest'), headers, signal) ).then( - (res) => { - return buildResponse(res).then((_data) => { + res => { + return buildResponse(res).then(_data => { return JsonDecode(_data, 'PaperSessionSecretResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } paperSessionSecret2 = ( req: PaperSessionSecret2Request, headers?: object, - signal?: AbortSignal, + signal?: AbortSignal ): Promise => { return this.fetch( this.url('PaperSessionSecret2'), - createHttpRequest(JsonEncode(req, 'PaperSessionSecret2Request'), headers, signal), + createHttpRequest(JsonEncode(req, 'PaperSessionSecret2Request'), headers, signal) ).then( - (res) => { - return buildResponse(res).then((_data) => { + res => { + return buildResponse(res).then(_data => { return JsonDecode(_data, 'PaperSessionSecret2Response') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } linkWallet = (req: LinkWalletRequest, headers?: object, signal?: AbortSignal): Promise => { - return this.fetch( - this.url('LinkWallet'), - createHttpRequest(JsonEncode(req, 'LinkWalletRequest'), headers, signal), - ).then( - (res) => { - return buildResponse(res).then((_data) => { + return this.fetch(this.url('LinkWallet'), createHttpRequest(JsonEncode(req, 'LinkWalletRequest'), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { return JsonDecode(_data, 'LinkWalletResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } getLinkedWallets = ( req: GetLinkedWalletsRequest, headers?: object, - signal?: AbortSignal, + signal?: AbortSignal ): Promise => { return this.fetch( this.url('GetLinkedWallets'), - createHttpRequest(JsonEncode(req, 'GetLinkedWalletsRequest'), headers, signal), + createHttpRequest(JsonEncode(req, 'GetLinkedWalletsRequest'), headers, signal) ).then( - (res) => { - return buildResponse(res).then((_data) => { + res => { + return buildResponse(res).then(_data => { return JsonDecode(_data, 'GetLinkedWalletsResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } removeLinkedWallet = ( req: RemoveLinkedWalletRequest, headers?: object, - signal?: AbortSignal, + signal?: AbortSignal ): Promise => { return this.fetch( this.url('RemoveLinkedWallet'), - createHttpRequest(JsonEncode(req, 'RemoveLinkedWalletRequest'), headers, signal), + createHttpRequest(JsonEncode(req, 'RemoveLinkedWalletRequest'), headers, signal) ).then( - (res) => { - return buildResponse(res).then((_data) => { + res => { + return buildResponse(res).then(_data => { return JsonDecode(_data, 'RemoveLinkedWalletResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } generateWaaSVerificationURL = ( req: GenerateWaaSVerificationURLRequest, headers?: object, - signal?: AbortSignal, + signal?: AbortSignal ): Promise => { return this.fetch( this.url('GenerateWaaSVerificationURL'), - createHttpRequest(JsonEncode(req, 'GenerateWaaSVerificationURLRequest'), headers, signal), + createHttpRequest(JsonEncode(req, 'GenerateWaaSVerificationURLRequest'), headers, signal) ).then( - (res) => { - return buildResponse(res).then((_data) => { + res => { + return buildResponse(res).then(_data => { return JsonDecode(_data, 'GenerateWaaSVerificationURLResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } validateWaaSVerificationNonce = ( req: ValidateWaaSVerificationNonceRequest, headers?: object, - signal?: AbortSignal, + signal?: AbortSignal ): Promise => { return this.fetch( this.url('ValidateWaaSVerificationNonce'), - createHttpRequest(JsonEncode(req, 'ValidateWaaSVerificationNonceRequest'), headers, signal), + createHttpRequest(JsonEncode(req, 'ValidateWaaSVerificationNonceRequest'), headers, signal) ).then( - (res) => { - return buildResponse(res).then((_data) => { + res => { + return buildResponse(res).then(_data => { return JsonDecode(_data, 'ValidateWaaSVerificationNonceResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } listAdoptedWallets = ( req: ListAdoptedWalletsRequest, headers?: object, - signal?: AbortSignal, + signal?: AbortSignal ): Promise => { return this.fetch( this.url('ListAdoptedWallets'), - createHttpRequest(JsonEncode(req, 'ListAdoptedWalletsRequest'), headers, signal), + createHttpRequest(JsonEncode(req, 'ListAdoptedWalletsRequest'), headers, signal) ).then( - (res) => { - return buildResponse(res).then((_data) => { + res => { + return buildResponse(res).then(_data => { return JsonDecode(_data, 'ListAdoptedWalletsResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } getLifiChains = (headers?: object, signal?: AbortSignal): Promise => { return this.fetch(this.url('GetLifiChains'), createHttpRequest('{}', headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { + res => { + return buildResponse(res).then(_data => { return JsonDecode(_data, 'GetLifiChainsResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } - getLifiTokens = ( - req: GetLifiTokensRequest, - headers?: object, - signal?: AbortSignal, - ): Promise => { + getLifiTokens = (req: GetLifiTokensRequest, headers?: object, signal?: AbortSignal): Promise => { return this.fetch( this.url('GetLifiTokens'), - createHttpRequest(JsonEncode(req, 'GetLifiTokensRequest'), headers, signal), + createHttpRequest(JsonEncode(req, 'GetLifiTokensRequest'), headers, signal) ).then( - (res) => { - return buildResponse(res).then((_data) => { + res => { + return buildResponse(res).then(_data => { return JsonDecode(_data, 'GetLifiTokensResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } getLifiSwapRoutes = ( req: GetLifiSwapRoutesRequest, headers?: object, - signal?: AbortSignal, + signal?: AbortSignal ): Promise => { return this.fetch( this.url('GetLifiSwapRoutes'), - createHttpRequest(JsonEncode(req, 'GetLifiSwapRoutesRequest'), headers, signal), + createHttpRequest(JsonEncode(req, 'GetLifiSwapRoutesRequest'), headers, signal) ).then( - (res) => { - return buildResponse(res).then((_data) => { + res => { + return buildResponse(res).then(_data => { return JsonDecode(_data, 'GetLifiSwapRoutesResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } getLifiSwapQuote = ( req: GetLifiSwapQuoteRequest, headers?: object, - signal?: AbortSignal, + signal?: AbortSignal ): Promise => { return this.fetch( this.url('GetLifiSwapQuote'), - createHttpRequest(JsonEncode(req, 'GetLifiSwapQuoteRequest'), headers, signal), + createHttpRequest(JsonEncode(req, 'GetLifiSwapQuoteRequest'), headers, signal) ).then( - (res) => { - return buildResponse(res).then((_data) => { + res => { + return buildResponse(res).then(_data => { return JsonDecode(_data, 'GetLifiSwapQuoteResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - getIntentCallsPayloads = ( - req: GetIntentCallsPayloadsRequest, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch( - this.url('GetIntentCallsPayloads'), - createHttpRequest(JsonEncode(req, 'GetIntentCallsPayloadsRequest'), headers, signal), - ).then( - (res) => { - return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'GetIntentCallsPayloadsResponse') - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - commitIntentConfig = ( - req: CommitIntentConfigRequest, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch( - this.url('CommitIntentConfig'), - createHttpRequest(JsonEncode(req, 'CommitIntentConfigRequest'), headers, signal), - ).then( - (res) => { - return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'CommitIntentConfigResponse') - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - getIntentConfig = ( - req: GetIntentConfigRequest, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch( - this.url('GetIntentConfig'), - createHttpRequest(JsonEncode(req, 'GetIntentConfigRequest'), headers, signal), - ).then( - (res) => { - return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'GetIntentConfigResponse') - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } listCurrencyGroups = (headers?: object, signal?: AbortSignal): Promise => { return this.fetch(this.url('ListCurrencyGroups'), createHttpRequest('{}', headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { + res => { + return buildResponse(res).then(_data => { return JsonDecode(_data, 'ListCurrencyGroupsResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } addOffchainInventory = ( req: AddOffchainInventoryRequest, headers?: object, - signal?: AbortSignal, + signal?: AbortSignal ): Promise => { return this.fetch( this.url('AddOffchainInventory'), - createHttpRequest(JsonEncode(req, 'AddOffchainInventoryRequest'), headers, signal), + createHttpRequest(JsonEncode(req, 'AddOffchainInventoryRequest'), headers, signal) ).then( - (res) => { - return buildResponse(res).then((_data) => { + res => { + return buildResponse(res).then(_data => { return JsonDecode(_data, 'AddOffchainInventoryResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } getOffchainInventory = ( req: GetOffchainInventoryRequest, headers?: object, - signal?: AbortSignal, + signal?: AbortSignal ): Promise => { return this.fetch( this.url('GetOffchainInventory'), - createHttpRequest(JsonEncode(req, 'GetOffchainInventoryRequest'), headers, signal), + createHttpRequest(JsonEncode(req, 'GetOffchainInventoryRequest'), headers, signal) ).then( - (res) => { - return buildResponse(res).then((_data) => { + res => { + return buildResponse(res).then(_data => { return JsonDecode(_data, 'GetOffchainInventoryResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } listOffchainInventories = ( req: ListOffchainInventoriesRequest, headers?: object, - signal?: AbortSignal, + signal?: AbortSignal ): Promise => { return this.fetch( this.url('ListOffchainInventories'), - createHttpRequest(JsonEncode(req, 'ListOffchainInventoriesRequest'), headers, signal), + createHttpRequest(JsonEncode(req, 'ListOffchainInventoriesRequest'), headers, signal) ).then( - (res) => { - return buildResponse(res).then((_data) => { + res => { + return buildResponse(res).then(_data => { return JsonDecode(_data, 'ListOffchainInventoriesResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } updateOffchainInventory = ( req: UpdateOffchainInventoryRequest, headers?: object, - signal?: AbortSignal, + signal?: AbortSignal ): Promise => { return this.fetch( this.url('UpdateOffchainInventory'), - createHttpRequest(JsonEncode(req, 'UpdateOffchainInventoryRequest'), headers, signal), + createHttpRequest(JsonEncode(req, 'UpdateOffchainInventoryRequest'), headers, signal) ).then( - (res) => { - return buildResponse(res).then((_data) => { + res => { + return buildResponse(res).then(_data => { return JsonDecode(_data, 'UpdateOffchainInventoryResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } deleteOffchainInventory = ( req: DeleteOffchainInventoryRequest, headers?: object, - signal?: AbortSignal, + signal?: AbortSignal ): Promise => { return this.fetch( this.url('DeleteOffchainInventory'), - createHttpRequest(JsonEncode(req, 'DeleteOffchainInventoryRequest'), headers, signal), + createHttpRequest(JsonEncode(req, 'DeleteOffchainInventoryRequest'), headers, signal) ).then( - (res) => { - return buildResponse(res).then((_data) => { + res => { + return buildResponse(res).then(_data => { return JsonDecode(_data, 'DeleteOffchainInventoryResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } requestOffchainPayment = ( req: RequestOffchainPaymentRequest, headers?: object, - signal?: AbortSignal, + signal?: AbortSignal ): Promise => { return this.fetch( this.url('RequestOffchainPayment'), - createHttpRequest(JsonEncode(req, 'RequestOffchainPaymentRequest'), headers, signal), + createHttpRequest(JsonEncode(req, 'RequestOffchainPaymentRequest'), headers, signal) ).then( - (res) => { - return buildResponse(res).then((_data) => { + res => { + return buildResponse(res).then(_data => { return JsonDecode(_data, 'RequestOffchainPaymentResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } listOffchainPayments = ( req: ListOffchainPaymentsRequest, headers?: object, - signal?: AbortSignal, + signal?: AbortSignal ): Promise => { return this.fetch( this.url('ListOffchainPayments'), - createHttpRequest(JsonEncode(req, 'ListOffchainPaymentsRequest'), headers, signal), + createHttpRequest(JsonEncode(req, 'ListOffchainPaymentsRequest'), headers, signal) ).then( - (res) => { - return buildResponse(res).then((_data) => { + res => { + return buildResponse(res).then(_data => { return JsonDecode(_data, 'ListOffchainPaymentsResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } savePack = (req: SavePackRequest, headers?: object, signal?: AbortSignal): Promise => { - return this.fetch( - this.url('SavePack'), - createHttpRequest(JsonEncode(req, 'SavePackRequest'), headers, signal), - ).then( - (res) => { - return buildResponse(res).then((_data) => { + return this.fetch(this.url('SavePack'), createHttpRequest(JsonEncode(req, 'SavePackRequest'), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { return JsonDecode(_data, 'SavePackResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } getPack = (req: GetPackRequest, headers?: object, signal?: AbortSignal): Promise => { return this.fetch(this.url('GetPack'), createHttpRequest(JsonEncode(req, 'GetPackRequest'), headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { + res => { + return buildResponse(res).then(_data => { return JsonDecode(_data, 'GetPackResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } getPackIds = (req: GetPackIdsRequest, headers?: object, signal?: AbortSignal): Promise => { - return this.fetch( - this.url('GetPackIds'), - createHttpRequest(JsonEncode(req, 'GetPackIdsRequest'), headers, signal), - ).then( - (res) => { - return buildResponse(res).then((_data) => { + return this.fetch(this.url('GetPackIds'), createHttpRequest(JsonEncode(req, 'GetPackIdsRequest'), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { return JsonDecode(_data, 'GetPackIdsResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } deletePack = (req: DeletePackRequest, headers?: object, signal?: AbortSignal): Promise => { - return this.fetch( - this.url('DeletePack'), - createHttpRequest(JsonEncode(req, 'DeletePackRequest'), headers, signal), - ).then( - (res) => { - return buildResponse(res).then((_data) => { + return this.fetch(this.url('DeletePack'), createHttpRequest(JsonEncode(req, 'DeletePackRequest'), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { return JsonDecode(_data, 'DeletePackResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } updatePackContent = ( req: UpdatePackContentRequest, headers?: object, - signal?: AbortSignal, + signal?: AbortSignal ): Promise => { return this.fetch( this.url('UpdatePackContent'), - createHttpRequest(JsonEncode(req, 'UpdatePackContentRequest'), headers, signal), + createHttpRequest(JsonEncode(req, 'UpdatePackContentRequest'), headers, signal) ).then( - (res) => { - return buildResponse(res).then((_data) => { + res => { + return buildResponse(res).then(_data => { return JsonDecode(_data, 'UpdatePackContentResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } - getRevealTxData = ( - req: GetRevealTxDataRequest, - headers?: object, - signal?: AbortSignal, - ): Promise => { + getRevealTxData = (req: GetRevealTxDataRequest, headers?: object, signal?: AbortSignal): Promise => { return this.fetch( this.url('GetRevealTxData'), - createHttpRequest(JsonEncode(req, 'GetRevealTxDataRequest'), headers, signal), + createHttpRequest(JsonEncode(req, 'GetRevealTxDataRequest'), headers, signal) ).then( - (res) => { - return buildResponse(res).then((_data) => { + res => { + return buildResponse(res).then(_data => { return JsonDecode(_data, 'GetRevealTxDataResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } checkoutOptionsPrimary = ( req: CheckoutOptionsPrimaryRequest, headers?: object, - signal?: AbortSignal, + signal?: AbortSignal ): Promise => { return this.fetch( this.url('CheckoutOptionsPrimary'), - createHttpRequest(JsonEncode(req, 'CheckoutOptionsPrimaryRequest'), headers, signal), + createHttpRequest(JsonEncode(req, 'CheckoutOptionsPrimaryRequest'), headers, signal) ).then( - (res) => { - return buildResponse(res).then((_data) => { + res => { + return buildResponse(res).then(_data => { return JsonDecode(_data, 'CheckoutOptionsPrimaryResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } checkoutOptionsSecondary = ( req: CheckoutOptionsSecondaryRequest, headers?: object, - signal?: AbortSignal, + signal?: AbortSignal ): Promise => { return this.fetch( this.url('CheckoutOptionsSecondary'), - createHttpRequest(JsonEncode(req, 'CheckoutOptionsSecondaryRequest'), headers, signal), + createHttpRequest(JsonEncode(req, 'CheckoutOptionsSecondaryRequest'), headers, signal) ).then( - (res) => { - return buildResponse(res).then((_data) => { + res => { + return buildResponse(res).then(_data => { return JsonDecode(_data, 'CheckoutOptionsSecondaryResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } checkoutOptionsGetTransakContractID = ( req: CheckoutOptionsGetTransakContractIDRequest, headers?: object, - signal?: AbortSignal, + signal?: AbortSignal ): Promise => { return this.fetch( this.url('CheckoutOptionsGetTransakContractID'), - createHttpRequest(JsonEncode(req, 'CheckoutOptionsGetTransakContractIDRequest'), headers, signal), + createHttpRequest(JsonEncode(req, 'CheckoutOptionsGetTransakContractIDRequest'), headers, signal) ).then( - (res) => { - return buildResponse(res).then((_data) => { - return JsonDecode( - _data, - 'CheckoutOptionsGetTransakContractIDResponse', - ) - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'CheckoutOptionsGetTransakContractIDResponse') }) }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } fortePayCreateIntent = ( req: FortePayCreateIntentRequest, headers?: object, - signal?: AbortSignal, + signal?: AbortSignal ): Promise => { return this.fetch( this.url('FortePayCreateIntent'), - createHttpRequest(JsonEncode(req, 'FortePayCreateIntentRequest'), headers, signal), + createHttpRequest(JsonEncode(req, 'FortePayCreateIntentRequest'), headers, signal) ).then( - (res) => { - return buildResponse(res).then((_data) => { + res => { + return buildResponse(res).then(_data => { return JsonDecode(_data, 'FortePayCreateIntentResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } fortePayGetPaymentStatuses = ( req: FortePayGetPaymentStatusesRequest, headers?: object, - signal?: AbortSignal, + signal?: AbortSignal ): Promise => { return this.fetch( this.url('FortePayGetPaymentStatuses'), - createHttpRequest(JsonEncode(req, 'FortePayGetPaymentStatusesRequest'), headers, signal), + createHttpRequest(JsonEncode(req, 'FortePayGetPaymentStatusesRequest'), headers, signal) ).then( - (res) => { - return buildResponse(res).then((_data) => { + res => { + return buildResponse(res).then(_data => { return JsonDecode(_data, 'FortePayGetPaymentStatusesResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - getCCTPTransfer = ( - req: GetCCTPTransferRequest, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch( - this.url('GetCCTPTransfer'), - createHttpRequest(JsonEncode(req, 'GetCCTPTransferRequest'), headers, signal), - ).then( - (res) => { - return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'GetCCTPTransferResponse') - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - queueCCTPTransfer = ( - req: QueueCCTPTransferRequest, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch( - this.url('QueueCCTPTransfer'), - createHttpRequest(JsonEncode(req, 'QueueCCTPTransferRequest'), headers, signal), - ).then( - (res) => { - return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'QueueCCTPTransferResponse') - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - queueIntentConfigExecution = ( - req: QueueIntentConfigExecutionRequest, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch( - this.url('QueueIntentConfigExecution'), - createHttpRequest(JsonEncode(req, 'QueueIntentConfigExecutionRequest'), headers, signal), - ).then( - (res) => { - return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'QueueIntentConfigExecutionResponse') - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - getIntentConfigExecutionStatus = ( - req: GetIntentConfigExecutionStatusRequest, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch( - this.url('GetIntentConfigExecutionStatus'), - createHttpRequest(JsonEncode(req, 'GetIntentConfigExecutionStatusRequest'), headers, signal), - ).then( - (res) => { - return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'GetIntentConfigExecutionStatusResponse') - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - listIntentConfigs = ( - req: ListIntentConfigsRequest, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch( - this.url('ListIntentConfigs'), - createHttpRequest(JsonEncode(req, 'ListIntentConfigsRequest'), headers, signal), - ).then( - (res) => { - return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'ListIntentConfigsResponse') - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - queueMetaTxnReceipt = ( - req: QueueMetaTxnReceiptRequest, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch( - this.url('QueueMetaTxnReceipt'), - createHttpRequest(JsonEncode(req, 'QueueMetaTxnReceiptRequest'), headers, signal), - ).then( - (res) => { - return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'QueueMetaTxnReceiptResponse') - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } } @@ -3887,20 +3111,20 @@ const createHttpRequest = (body: string = '{}', headers: object = {}, signal: Ab const reqHeaders: { [key: string]: string } = { ...headers, 'Content-Type': 'application/json', - [WebrpcHeader]: WebrpcHeaderValue, + [WebrpcHeader]: WebrpcHeaderValue } return { method: 'POST', headers: reqHeaders, body, signal } } const buildResponse = (res: Response): Promise => { - return res.text().then((text) => { + 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}`, + cause: `JSON.parse(): ${error instanceof Error ? error.message : String(error)}: response text: ${text}` }) } if (!res.ok) { @@ -4426,7 +3650,7 @@ export enum errors { Unavailable = 'Unavailable', QueryFailed = 'QueryFailed', NotFound = 'NotFound', - UnsupportedNetwork = 'UnsupportedNetwork', + UnsupportedNetwork = 'UnsupportedNetwork' } export enum WebrpcErrorCodes { @@ -4465,7 +3689,7 @@ export enum WebrpcErrorCodes { Unavailable = 2002, QueryFailed = 2003, NotFound = 3000, - UnsupportedNetwork = 3008, + UnsupportedNetwork = 3008 } export const webrpcErrorByCode: { [code: number]: any } = { @@ -4504,7 +3728,7 @@ export const webrpcErrorByCode: { [code: number]: any } = { [2002]: UnavailableError, [2003]: QueryFailedError, [3000]: NotFoundError, - [3008]: UnsupportedNetworkError, + [3008]: UnsupportedNetworkError } // @@ -4531,7 +3755,7 @@ export function VersionFromHeader(headers: Headers): WebrpcGenVersions { codeGenName: '', codeGenVersion: '', schemaName: '', - schemaVersion: '', + schemaVersion: '' } } @@ -4546,7 +3770,7 @@ function parseWebrpcGenVersions(header: string): WebrpcGenVersions { codeGenName: '', codeGenVersion: '', schemaName: '', - schemaVersion: '', + schemaVersion: '' } } @@ -4559,6 +3783,6 @@ function parseWebrpcGenVersions(header: string): WebrpcGenVersions { codeGenName: codeGenName ?? '', codeGenVersion: codeGenVersion ?? '', schemaName: schemaName ?? '', - schemaVersion: schemaVersion ?? '', + schemaVersion: schemaVersion ?? '' } } diff --git a/packages/services/api/src/index.ts b/packages/services/api/src/index.ts index 12656d2c08..14d83d8a13 100644 --- a/packages/services/api/src/index.ts +++ b/packages/services/api/src/index.ts @@ -1,6 +1,6 @@ -export * from './api.gen' +export * from './api.gen.js' -import { API as ApiRpc } from './api.gen' +import { API as ApiRpc } from './api.gen.js' export class SequenceAPIClient extends ApiRpc { constructor( @@ -15,7 +15,7 @@ export class SequenceAPIClient extends ApiRpc { _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: { [key: string]: any } = {} + const headers: Record = {} const jwtAuth = this.jwtAuth const projectAccessKey = this.projectAccessKey diff --git a/packages/services/builder/CHANGELOG.md b/packages/services/builder/CHANGELOG.md index af8df7f69c..a7a4c60d7a 100644 --- a/packages/services/builder/CHANGELOG.md +++ b/packages/services/builder/CHANGELOG.md @@ -1,5 +1,90 @@ # @0xsequence/builder +## 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 diff --git a/packages/wallet/primitives-cli/eslint.config.mjs b/packages/services/builder/eslint.config.js similarity index 100% rename from packages/wallet/primitives-cli/eslint.config.mjs rename to packages/services/builder/eslint.config.js diff --git a/packages/services/builder/package.json b/packages/services/builder/package.json index 013a525149..1aae80372d 100644 --- a/packages/services/builder/package.json +++ b/packages/services/builder/package.json @@ -1,18 +1,20 @@ { "name": "@0xsequence/builder", - "version": "3.0.0-beta.9", + "version": "3.0.0", "description": "builder sub-package for Sequence", "repository": "https://github.com/0xsequence/sequence.js/tree/master/packages/services/builder", - "author": "Sequence Platforms Inc.", + "author": "Sequence Platforms ULC", "license": "Apache-2.0", "publishConfig": { "access": "public" }, + "type": "module", "scripts": { "build": "tsc", "dev": "tsc --watch", "test": "echo", - "typecheck": "tsc --noEmit" + "typecheck": "tsc --noEmit", + "lint": "eslint . --max-warnings 0" }, "exports": { ".": { @@ -21,8 +23,9 @@ } }, "devDependencies": { + "@repo/eslint-config": "workspace:^", "@repo/typescript-config": "workspace:^", - "@types/node": "^25.0.2", + "@types/node": "^25.3.0", "typescript": "^5.9.3" } } diff --git a/packages/services/builder/src/index.ts b/packages/services/builder/src/index.ts index 7abe218550..18f13758de 100644 --- a/packages/services/builder/src/index.ts +++ b/packages/services/builder/src/index.ts @@ -1,6 +1,6 @@ -export * from './builder.gen' +export * from './builder.gen.js' -import { Builder as BuilderRpc } from './builder.gen' +import { Builder as BuilderRpc } from './builder.gen.js' export class SequenceBuilderClient extends BuilderRpc { constructor( @@ -15,7 +15,7 @@ export class SequenceBuilderClient extends BuilderRpc { _fetch = (input: RequestInfo, init?: RequestInit): Promise => { // automatically include access key auth header to requests // if its been set on the api client - const headers: { [key: string]: any } = {} + const headers: Record = {} const projectAccessKey = this.projectAccessKey if (projectAccessKey && projectAccessKey.length > 0) { diff --git a/packages/services/guard/CHANGELOG.md b/packages/services/guard/CHANGELOG.md index e4d2c0a2ea..4aa7f3b081 100644 --- a/packages/services/guard/CHANGELOG.md +++ b/packages/services/guard/CHANGELOG.md @@ -1,5 +1,90 @@ # @0xsequence/guard +## 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 diff --git a/packages/wallet/primitives/eslint.config.mjs b/packages/services/guard/eslint.config.js similarity index 100% rename from packages/wallet/primitives/eslint.config.mjs rename to packages/services/guard/eslint.config.js diff --git a/packages/services/guard/package.json b/packages/services/guard/package.json index c098ad0a15..e9e66b91ef 100644 --- a/packages/services/guard/package.json +++ b/packages/services/guard/package.json @@ -1,9 +1,9 @@ { "name": "@0xsequence/guard", - "version": "3.0.0-beta.9", + "version": "3.0.0", "description": "guard sub-package for Sequence", "repository": "https://github.com/0xsequence/sequence.js/tree/master/packages/services/guard", - "author": "Sequence Platforms Inc.", + "author": "Sequence Platforms ULC", "license": "Apache-2.0", "type": "module", "publishConfig": { @@ -15,7 +15,8 @@ "dev": "tsc --watch", "test": "vitest run", "test:coverage": "vitest run --coverage", - "typecheck": "tsc --noEmit" + "typecheck": "tsc --noEmit", + "lint": "eslint . --max-warnings 0" }, "exports": { ".": { @@ -24,10 +25,11 @@ } }, "devDependencies": { + "@repo/eslint-config": "workspace:^", "@repo/typescript-config": "workspace:^", - "@types/node": "^25.0.2", + "@types/node": "^25.3.0", "typescript": "^5.9.3", - "vitest": "^4.0.15" + "vitest": "^4.0.18" }, "dependencies": { "ox": "^0.9.17" diff --git a/packages/services/guard/src/local.ts b/packages/services/guard/src/local.ts index 3ef9ac7875..3eeb7b8d5d 100644 --- a/packages/services/guard/src/local.ts +++ b/packages/services/guard/src/local.ts @@ -1,4 +1,4 @@ -import { Address, Hex, Bytes, Secp256k1, Hash } from 'ox' +import { Address, Hex, Bytes, Secp256k1 } from 'ox' import * as Client from './client/guard.gen.js' import * as Types from './types.js' @@ -11,12 +11,13 @@ export class Guard implements Types.Guard { } async signPayload( - wallet: Address.Address, - chainId: number, - type: Client.PayloadType, + _wallet: Address.Address, + _chainId: number, + _type: Client.PayloadType, digest: Bytes.Bytes, - message: Bytes.Bytes, - signatures?: Client.Signature[], + _message: Bytes.Bytes, + _signatures?: Client.Signature[], + _token?: Client.AuthToken, ) { return Secp256k1.sign({ privateKey: this.privateKey, payload: digest }) } diff --git a/packages/services/guard/src/sequence.ts b/packages/services/guard/src/sequence.ts index fe1a003ce5..6c17b75520 100644 --- a/packages/services/guard/src/sequence.ts +++ b/packages/services/guard/src/sequence.ts @@ -1,4 +1,4 @@ -import { Address, Hex, Signature, Bytes, Hash } from 'ox' +import { Address, Hex, Signature, Bytes } from 'ox' import * as Client from './client/guard.gen.js' import * as Types from './types.js' diff --git a/packages/services/guard/test/sequence.test.ts b/packages/services/guard/test/sequence.test.ts index 5ac92a3780..45612d609f 100644 --- a/packages/services/guard/test/sequence.test.ts +++ b/packages/services/guard/test/sequence.test.ts @@ -1,11 +1,11 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' -import { Guard } from '../src/sequence' -import { PayloadType } from '../src/client/guard.gen' +import { Guard } from '../src/sequence.js' +import { PayloadType } from '../src/client/guard.gen.js' import { Address, Bytes, Hex } from 'ox' // Mock fetch globally for guard API calls const mockFetch = vi.fn() -global.fetch = mockFetch +globalThis.fetch = mockFetch describe('Sequence', () => { describe('GuardSigner', () => { @@ -86,7 +86,7 @@ describe('Sequence', () => { ok: true, }) - await guard.signPayload(testWallet, 1, PayloadType.ConfigUpdate, testMessageDigest, testMessage) + await guard.signPayload(testWallet, customChainId, PayloadType.ConfigUpdate, testMessageDigest, testMessage) const requestBody = JSON.parse(mockFetch.mock.calls[0][1].body) expect(requestBody.request.chainId).toBe(1) diff --git a/packages/services/identity-instrument/CHANGELOG.md b/packages/services/identity-instrument/CHANGELOG.md index b59c8f0177..46667619b3 100644 --- a/packages/services/identity-instrument/CHANGELOG.md +++ b/packages/services/identity-instrument/CHANGELOG.md @@ -1,5 +1,90 @@ # @0xsequence/identity-instrument +## 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 diff --git a/packages/services/identity-instrument/eslint.config.js b/packages/services/identity-instrument/eslint.config.js new file mode 100644 index 0000000000..cecf89b031 --- /dev/null +++ b/packages/services/identity-instrument/eslint.config.js @@ -0,0 +1,4 @@ +import { config as baseConfig } from "@repo/eslint-config/base" + +/** @type {import("eslint").Linter.Config} */ +export default baseConfig diff --git a/packages/services/identity-instrument/package.json b/packages/services/identity-instrument/package.json index 1243ba84c3..db656ed547 100644 --- a/packages/services/identity-instrument/package.json +++ b/packages/services/identity-instrument/package.json @@ -1,6 +1,6 @@ { "name": "@0xsequence/identity-instrument", - "version": "3.0.0-beta.9", + "version": "3.0.0", "license": "Apache-2.0", "type": "module", "publishConfig": { @@ -10,7 +10,9 @@ "scripts": { "build": "tsc", "dev": "tsc --watch", - "test": "vitest run" + "test": "vitest run", + "lint": "eslint . --max-warnings 0", + "typecheck": "tsc --noEmit" }, "exports": { ".": { @@ -19,10 +21,11 @@ } }, "devDependencies": { + "@repo/eslint-config": "workspace:^", "@repo/typescript-config": "workspace:^", - "@types/node": "^25.0.2", + "@types/node": "^25.3.0", "typescript": "^5.9.3", - "vitest": "^4.0.15" + "vitest": "^4.0.18" }, "dependencies": { "json-canonicalize": "^2.0.0", diff --git a/packages/services/indexer/CHANGELOG.md b/packages/services/indexer/CHANGELOG.md index fec6e59472..17f499fa53 100644 --- a/packages/services/indexer/CHANGELOG.md +++ b/packages/services/indexer/CHANGELOG.md @@ -1,5 +1,90 @@ # @0xsequence/indexer +## 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 diff --git a/packages/services/indexer/eslint.config.js b/packages/services/indexer/eslint.config.js new file mode 100644 index 0000000000..cecf89b031 --- /dev/null +++ b/packages/services/indexer/eslint.config.js @@ -0,0 +1,4 @@ +import { config as baseConfig } from "@repo/eslint-config/base" + +/** @type {import("eslint").Linter.Config} */ +export default baseConfig diff --git a/packages/services/indexer/package.json b/packages/services/indexer/package.json index 164097420e..c8629dc36d 100644 --- a/packages/services/indexer/package.json +++ b/packages/services/indexer/package.json @@ -1,18 +1,20 @@ { "name": "@0xsequence/indexer", - "version": "3.0.0-beta.9", + "version": "3.0.0", "description": "indexer sub-package for Sequence", "repository": "https://github.com/0xsequence/sequence.js/tree/master/packages/services/indexer", - "author": "Sequence Platforms Inc.", + "author": "Sequence Platforms ULC", "license": "Apache-2.0", "publishConfig": { "access": "public" }, + "type": "module", "scripts": { "build": "tsc", "dev": "tsc --watch", "test": "echo", - "typecheck": "tsc --noEmit" + "typecheck": "tsc --noEmit", + "lint": "eslint . --max-warnings 0" }, "exports": { ".": { @@ -21,8 +23,9 @@ } }, "devDependencies": { + "@repo/eslint-config": "workspace:^", "@repo/typescript-config": "workspace:^", - "@types/node": "^25.0.2", + "@types/node": "^25.3.0", "typescript": "^5.9.3" } } diff --git a/packages/services/indexer/src/index.ts b/packages/services/indexer/src/index.ts index a4588c71ec..15f28c2cb1 100644 --- a/packages/services/indexer/src/index.ts +++ b/packages/services/indexer/src/index.ts @@ -1,8 +1,8 @@ -export * from './indexer.gen' -export * as IndexerGateway from './indexergw.gen' +export * from './indexer.gen.js' +export * as IndexerGateway from './indexergw.gen.js' -import { Indexer as IndexerRpc } from './indexer.gen' -import { IndexerGateway as IndexerGatewayRpc } from './indexergw.gen' +import { Indexer as IndexerRpc } from './indexer.gen.js' +import { IndexerGateway as IndexerGatewayRpc } from './indexergw.gen.js' export class SequenceIndexer extends IndexerRpc { constructor( @@ -17,7 +17,7 @@ export class SequenceIndexer extends IndexerRpc { _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: { [key: string]: any } = {} + const headers: Record = {} const jwtAuth = this.jwtAuth const projectAccessKey = this.projectAccessKey @@ -50,7 +50,7 @@ export class SequenceIndexerGateway extends IndexerGatewayRpc { _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: { [key: string]: any } = {} + const headers: Record = {} const jwtAuth = this.jwtAuth const projectAccessKey = this.projectAccessKey diff --git a/packages/services/indexer/src/indexer.gen.ts b/packages/services/indexer/src/indexer.gen.ts index 89de725663..354ce47e26 100644 --- a/packages/services/indexer/src/indexer.gen.ts +++ b/packages/services/indexer/src/indexer.gen.ts @@ -1,79 +1,393 @@ /* eslint-disable */ -// sequence-indexer v0.4.0 546b527de7002f409ffa602ad35b5a3abe979088 +// sequence-indexer v0.4.0 2bca559c4c590bce7d70c33df115a58399efec82 // -- -// Code generated by webrpc-gen@v0.21.1 with typescript generator. DO NOT EDIT. +// Code generated by Webrpc-gen@v0.31.2 with typescript generator. DO NOT EDIT. // -// webrpc-gen -schema=indexer.ridl -service=Indexer -target=typescript -client -out=./clients/indexer.gen.ts +// webrpc-gen -schema=merged.gen.json -service=Indexer -target=typescript -client -out=./clients/indexer.gen.ts -export const WebrpcHeader = 'Webrpc' - -export const WebrpcHeaderValue = 'webrpc@v0.21.1;gen-typescript@v0.15.1;sequence-indexer@v0.4.0' - -// WebRPC description and code-gen version -export const WebRPCVersion = 'v1' +// Webrpc description and code-gen version +export const WebrpcVersion = 'v1' // Schema version of your RIDL schema -export const WebRPCSchemaVersion = 'v0.4.0' +export const WebrpcSchemaVersion = 'v0.4.0' // Schema hash generated from your RIDL schema -export const WebRPCSchemaHash = '546b527de7002f409ffa602ad35b5a3abe979088' +export const WebrpcSchemaHash = '2bca559c4c590bce7d70c33df115a58399efec82' -type WebrpcGenVersions = { - webrpcGenVersion: string - codeGenName: string - codeGenVersion: string - schemaName: string - schemaVersion: string -} +// +// Client interface +// -export function VersionFromHeader(headers: Headers): WebrpcGenVersions { - const headerValue = headers.get(WebrpcHeader) - if (!headerValue) { - return { - webrpcGenVersion: '', - codeGenName: '', - codeGenVersion: '', - schemaName: '', - schemaVersion: '', - } - } +export interface IndexerClient { + addWebhookListener(req: AddWebhookListenerRequest, headers?: object, signal?: AbortSignal): Promise - return parseWebrpcGenVersions(headerValue) -} + /** + * Fetches a single receipt and then will stop the subscription + */ + fetchTransactionReceipt( + req: FetchTransactionReceiptRequest, + headers?: object, + signal?: AbortSignal + ): Promise -function parseWebrpcGenVersions(header: string): WebrpcGenVersions { - const versions = header.split(';') - if (versions.length < 3) { - return { - webrpcGenVersion: '', - codeGenName: '', - codeGenVersion: '', - schemaName: '', - schemaVersion: '', - } - } + /** + * Fetches a single receipt with filter and then will stop the subscription + */ + fetchTransactionReceiptWithFilter( + req: FetchTransactionReceiptWithFilterRequest, + headers?: object, + signal?: AbortSignal + ): Promise - const [_, webrpcGenVersion] = versions[0]!.split('@') - const [codeGenName, codeGenVersion] = versions[1]!.split('@') - const [schemaName, schemaVersion] = versions[2]!.split('@') + /** + * Webhooks + */ + getAllWebhookListeners( + req: GetAllWebhookListenersRequest, + headers?: object, + signal?: AbortSignal + ): Promise + + /** + * Get balance update aggregate values -- useful for syncing balance details of a contract, ie. from Skyweaver. + * Also consider using SubscribeBalanceUpdates or SubscribeEvents as other alternatives. + */ + getBalanceUpdates(req: GetBalanceUpdatesRequest, headers?: object, signal?: AbortSignal): Promise + + /** + * Get the chain ID of the indexer + */ + getChainID(headers?: object, signal?: AbortSignal): Promise + + /** + * Queries an ethereum node for the latest and confirm ETH balances + * DEPRECATED: use GetNativeTokenBalance instead + * + * @deprecated GetNativeTokenBalance + */ + getEtherBalance(req: GetEtherBalanceRequest, headers?: object, signal?: AbortSignal): Promise + + /** + * GetMarketplaceOrders queries marketplace orders with filtering and pagination. + * + * Retrieves buy orders (offers) and sell orders (listings) from a specific marketplace + * and collection with comprehensive filtering options. + * + * Parameters: + * marketplaceContractAddress: Target marketplace contract (required) + * collectionAddress: NFT collection contract (required) + * filter: MarketplaceOrderFilter with options: + * - isListing: true=listings, false=offers, omit=both + * - userAddresses: Include specific users + * - currencyAddresses: Filter by currencies (empty=all) + * - orderIds: Filter by specific order ids (empty=all) + * - tokenIds: Filter by specific tokens (empty=all) + * - excludeUserAddresses: Exclude specific users + * - blockNumberGt: Orders greater than block number + * - createdAtAfter: Orders after timestamp + * - orderStatuses: Filter by status (OPEN, CLOSED, CANCELLED) + * - returnExpired: Include expired orders + * page: Pagination control (optional) + * + * Returns: Updated pagination info and array of matching orders + */ + getMarketplaceOrders( + req: GetMarketplaceOrdersRequest, + headers?: object, + signal?: AbortSignal + ): Promise + + /** + * GetMarketplaceTopOrders finds the most competitive orders for specific tokens. + * + * Optimized for price discovery, returns the best available orders for each token. + * Useful for displaying current market prices and finding trading opportunities. + * + * Parameters: + * marketplaceContractAddress: Target marketplace contract (required) + * collectionAddress: NFT collection contract (required) + * filter: MarketplaceTopOrdersFilter with options: + * - currencyAddresses: Consider specific currencies (empty=all) + * - tokenIds: Target token IDs (required, non-empty) + * - isListing: true=listings/sell orders, false=offers/buy orders + * - priceSort: ASC=lowest first, DESC=highest first + * - excludeUser: Hide orders from specific user + * + * Returns: Array of top-priced active orders, sorted by priceSort preference + */ + getMarketplaceTopOrders( + req: GetMarketplaceTopOrdersRequest, + headers?: object, + signal?: AbortSignal + ): Promise + + /** + * GetNativeTokenBalance queries an ethereum node for the latest native token account balance. + * The native token is the token of the chain the indexer is connected to, for example, ETH on Ethereum + * and POL on Polygon. + */ + getNativeTokenBalance( + req: GetNativeTokenBalanceRequest, + headers?: object, + signal?: AbortSignal + ): Promise + + /** + * GetTokenBalances returns a balance summary/details for a specific account. By default + * if accountAddress is left empty, it will use the account from the jwt session. + * + * Also, if contractAddress is undefined, then it will list all current user coins/collectibles. + * But, if contractAddress is provided, then it will return the token balances for the contract, this is + * only useful for 1155, but for other tokens, it can act as a filter for the single balance. + * + * DEPRECATED: use GetTokenBalancesSummary / GetTokenBalancesDetails + * + * @deprecated GetTokenBalancesSummary + */ + getTokenBalances(req: GetTokenBalancesRequest, headers?: object, signal?: AbortSignal): Promise + + /** + * GetTokenBalancesByContract returns a balances for a specific accounts and + * contracts. The collection ERC721 & ERC1155 tokens are represented as + * individual balances. + * + * If `filter` is not provided, it will error out as it requires at least + * contract address. + * + * If `filter.contractStatus` is not provided, it will include verified only + * tokens. + */ + getTokenBalancesByContract( + req: GetTokenBalancesByContractRequest, + headers?: object, + signal?: AbortSignal + ): Promise + + /** + * GetTokenBalancesDetails returns a detailed balance summary for a specific + * accounts. The collection ERC721 & ERC1155 tokens are represented as + * individual balances. + * + * If `filter` is not provided, it will use the filter with account from the + * jwt session. + * + * If `filter.contractStatus` is not provided, it will include verified only + * tokens. + */ + getTokenBalancesDetails( + req: GetTokenBalancesDetailsRequest, + headers?: object, + signal?: AbortSignal + ): Promise + + /** + * GetTokenBalancesSummary returns a summary of token balances for a specific + * accounts. The collection ERC721 & ERC1155 tokens are represented as a + * single aggregated balance. + * + * If `filter` is not provided, it will use the filter with account from the + * jwt session. + * + * If `filter.contractStatus` is not provided, it will include verified only + * tokens. + */ + getTokenBalancesSummary( + req: GetTokenBalancesSummaryRequest, + headers?: object, + signal?: AbortSignal + ): Promise + + /** + * GetTokenIDRanges returns the range of tokenIDs for a token collection contract. + * This is useful for ERC-721 and ERC-1155 contracts to get the range of valid tokenIDs. It is similar to + * GetTokenIDs, but returns the range of tokenIDs instead of the list of tokenIDs, which is more efficient + * for large collections and very easy to the caller to expand the range into a list of tokenIDs. + * + * NOTE: this method will only return up to 15,000 ranges, if there are more ranges, it will return + * a boolean to indicate there are more ranges beyond the first 15,000. Therefore, if `moreRanges` is + * false then you have all the ranges, but if true, you need to make a follow up call to fetch the next + * page of ranges. + * + * As an example, if a NFT collection of 100,000 tokens uses ids from 1,2,3,...,100_000 then this endpoint + * will return just a single range from [1,100_000], but if there are gaps between the sequence, then + * those will be broken into separate range entries. + */ + getTokenIDRanges(req: GetTokenIDRangesRequest, headers?: object, signal?: AbortSignal): Promise + + /** + * GetTokenIDs returns the list of each individual token id for a token collection contract. + * This is useful for ERC-721 and ERC-1155 contracts to get the list of valid tokenIDs. + */ + getTokenIDs(req: GetTokenIDsRequest, headers?: object, signal?: AbortSignal): Promise + + getTokenPrice(req: GetTokenPriceRequest, headers?: object, signal?: AbortSignal): Promise + + getTokenPrices(req: GetTokenPricesRequest, headers?: object, signal?: AbortSignal): Promise + + /** + * GetTokenSupplies returns the set of tokenIDs used by a contract address, supporting ERC-20, ERC-721, and ERC-1155 + * contracts, and their respective supply as well. + */ + getTokenSupplies(req: GetTokenSuppliesRequest, headers?: object, signal?: AbortSignal): Promise + + /** + * GetTokenSuppliesMap returns the token supplies of ERC-20 and ERC-1155 tokens as requested in the `tokenMap` + * represented as a map of contractAddress :: []tokenIDs. + * + * For an ERC-20 specify tokenIDs as an empty array or [0], for example, { '0xdef': [] } or { '0xdef': [0] } + * For ERC-1155 pass the array of tokens are strings, ie. { '0xabc': ['1', '2', '3'] } + */ + getTokenSuppliesMap( + req: GetTokenSuppliesMapRequest, + headers?: object, + signal?: AbortSignal + ): Promise - return { - webrpcGenVersion: webrpcGenVersion!, - codeGenName: codeGenName!, - codeGenVersion: codeGenVersion!, - schemaName: schemaName!, - schemaVersion: schemaVersion!, - } + /** + * History of mined transactions for the account which includes a list of token transfers (sent/recieved) + * and sent transactions from a Sequence wallet + */ + getTransactionHistory( + req: GetTransactionHistoryRequest, + headers?: object, + signal?: AbortSignal + ): Promise + + getWebhookListener(req: GetWebhookListenerRequest, headers?: object, signal?: AbortSignal): Promise + + listTokenPrices(req: ListTokenPricesRequest, headers?: object, signal?: AbortSignal): Promise + + pauseAllWebhookListeners( + req: PauseAllWebhookListenersRequest, + headers?: object, + signal?: AbortSignal + ): Promise + + /** + * Ping the indexer + */ + ping(headers?: object, signal?: AbortSignal): Promise + + removeAllWebhookListeners( + req: RemoveAllWebhookListenersRequest, + headers?: object, + signal?: AbortSignal + ): Promise + + removeWebhookListener( + req: RemoveWebhookListenerRequest, + headers?: object, + signal?: AbortSignal + ): Promise + + resumeAllWebhookListeners( + req: ResumeAllWebhookListenersRequest, + headers?: object, + signal?: AbortSignal + ): Promise + + /** + * Get the current runtime health status of the indexer + */ + runtimeStatus(headers?: object, signal?: AbortSignal): Promise + + /** + * SubscribeBalanceUpdates listens to balance updates for a specific contract address + */ + subscribeBalanceUpdates( + req: SubscribeBalanceUpdatesRequest, + options: WebrpcStreamOptions + ): WebrpcStreamController + + /** + * SubscribeEvents listens to events on-chain based on the filter criteria + * + * TODO: some additional options can be passed such as block, reorg true, etc. + * or stay behind, etc. + */ + subscribeEvents(req: SubscribeEventsRequest, options: WebrpcStreamOptions): WebrpcStreamController + + /** + * Listen to transaction receipts on-chain based on the filter criteria + */ + subscribeReceipts( + req: SubscribeReceiptsRequest, + options: WebrpcStreamOptions + ): WebrpcStreamController + + /** + * Re-sync an incorrect token balance with the correct on-chain balance + * NOTE: this method is almost never used, but we've marked it internal in case + * we ever want to use it again. This method was written a very long time ago in + * scenarios when the indexer had little bugs, but now its solid. + */ + syncBalance(req: SyncBalanceRequest, headers?: object, signal?: AbortSignal): Promise + + toggleWebhookListener( + req: ToggleWebhookListenerRequest, + headers?: object, + signal?: AbortSignal + ): Promise + + updateWebhookListener( + req: UpdateWebhookListenerRequest, + headers?: object, + signal?: AbortSignal + ): Promise + + /** + * Get the current version of the indexer + */ + version(headers?: object, signal?: AbortSignal): Promise } // -// Types +// Schema types // -export enum ResourceStatus { - NOT_AVAILABLE = 'NOT_AVAILABLE', - REFRESHING = 'REFRESHING', - AVAILABLE = 'AVAILABLE', +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 BackupMode { + INCREMENTAL = 'INCREMENTAL', + COMPLETE = 'COMPLETE' +} + +export interface BloomStats { + hitRatio: string + falsePositivesPercent: string + hitCount: number + missCount: number + falsePositives: number +} + +export interface BloomStatus { + enabled: boolean + initialized: boolean + bloomInitElapsedTime: string + stats: BloomStats +} + +export interface Bond { + pebble: PebbleMetrics + estimatedDiskUsagePerTable: any + estimatedDiskUsageTotal: string +} + +export interface ChainInfo { + chainId: number + chainName: string } export interface ContractInfo { @@ -93,56 +407,29 @@ export interface ContractInfo { status: ResourceStatus } -export interface ContractInfoExtensions { - link: string - description: string - categories: Array - ogImage: string - ogName: string - originChainId: number - originAddress: string - blacklist: boolean - verified: boolean - verifiedBy: string - featured: boolean - featureIndex: number +export interface ContractInfoExtensionBridgeInfo { + tokenAddress: string } -export interface TokenMetadata { - contractAddress?: string - tokenId: string - source: 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: ResourceStatus - queuedAt?: string - lastFetched?: string +export interface ContractInfoExtensionIndexingInfo { + useOnChainBalance: boolean } -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 ContractInfoExtensions { + link?: string + description?: string + categories?: Array + bridgeInfo?: { [key: string]: ContractInfoExtensionBridgeInfo } + indexingInfo?: ContractInfoExtensionIndexingInfo + ogImage?: string + ogName?: string + originChainId?: number + originAddress?: string + blacklist?: boolean + verified?: boolean + verifiedBy?: string + featured?: boolean + featureIndex?: number } export enum ContractType { @@ -156,72 +443,73 @@ export enum ContractType { ERC721_BRIDGE = 'ERC721_BRIDGE', ERC1155_BRIDGE = 'ERC1155_BRIDGE', SEQ_MARKETPLACE = 'SEQ_MARKETPLACE', + ERC6909 = 'ERC6909' } -export enum EventLogType { - UNKNOWN = 'UNKNOWN', - BLOCK_ADDED = 'BLOCK_ADDED', - BLOCK_REMOVED = 'BLOCK_REMOVED', -} - -export enum EventLogDataType { - EVENT = 'EVENT', - TOKEN_TRANSFER = 'TOKEN_TRANSFER', - NATIVE_TOKEN_TRANSFER = 'NATIVE_TOKEN_TRANSFER', - SEQUENCE_TXN = 'SEQUENCE_TXN', -} - -export enum OrderStatus { - OPEN = 'OPEN', - CLOSED = 'CLOSED', - CANCELLED = 'CANCELLED', +export enum ContractVerificationStatus { + VERIFIED = 'VERIFIED', + UNVERIFIED = 'UNVERIFIED', + ALL = 'ALL' } -export enum TxnTransferType { - UNKNOWN = 'UNKNOWN', - SEND = 'SEND', - RECEIVE = 'RECEIVE', +export interface DiskUsage { + humanReadable: string + used: number + size: number + percent: number + dirs: { [key: string]: string } } -export enum TransactionStatus { - FAILED = 'FAILED', - SUCCESSFUL = 'SUCCESSFUL', +export interface EtherBalance { + accountAddress: string + balanceWei: string } -export enum TransactionType { - LegacyTxnType = 'LegacyTxnType', - AccessListTxnType = 'AccessListTxnType', - DynamicFeeTxnType = 'DynamicFeeTxnType', +export interface EventDecoded { + topicHash: string + eventSig: string + types: Array + names: Array + values: Array } -export enum SortOrder { - DESC = 'DESC', - ASC = 'ASC', +export interface EventFilter { + events?: Array + contractAddresses?: Array + accounts?: Array + tokenIDs?: Array } -export enum ContractVerificationStatus { - VERIFIED = 'VERIFIED', - UNVERIFIED = 'UNVERIFIED', - ALL = 'ALL', +export interface EventLog { + id: number + uid: string + type: EventLogType + blockNumber: number + blockHash: string + parentBlockHash: string + contractAddress: string + contractType: ContractType + txnHash: string + txnIndex: number + txnLogIndex: number + logDataType: EventLogDataType + ts: string + txnInfo?: TxnInfo + rawLog?: { [key: string]: any } + event?: EventDecoded } -export interface Version { - webrpcVersion: string - schemaVersion: string - schemaHash: string - appVersion: string +export enum EventLogDataType { + EVENT = 'EVENT', + TOKEN_TRANSFER = 'TOKEN_TRANSFER', + NATIVE_TOKEN_TRANSFER = 'NATIVE_TOKEN_TRANSFER', + SEQUENCE_TXN = 'SEQUENCE_TXN' } -export interface RuntimeStatus { - healthOK: boolean - indexerEnabled: boolean - startTime: string - uptime: number - ver: string - branch: string - commitHash: string - chainID: number - checks: RuntimeChecks +export enum EventLogType { + UNKNOWN = 'UNKNOWN', + BLOCK_ADDED = 'BLOCK_ADDED', + BLOCK_REMOVED = 'BLOCK_REMOVED' } export interface GatewayBackendResponseTime { @@ -235,6 +523,30 @@ export interface GatewayBackendRuntimeStatus { responseTime: GatewayBackendResponseTime } +export interface GatewayEtherBalance { + chainId: number + errorReason?: string + result: EtherBalance +} + +export interface GatewayNativeTokenBalance { + chainId: number + errorReason?: string + result: NativeTokenBalance +} + +export interface GatewayNativeTokenBalances { + chainId: number + errorReason?: string + results: Array +} + +export interface GatewayPrice { + chainID: number + errorReason?: string + results: Array +} + export interface GatewayRuntimeStatus { healthOK: boolean startTime: string @@ -245,43 +557,115 @@ export interface GatewayRuntimeStatus { backends: Array } -export interface WALWriterRuntimeStatus { - healthOK: boolean - startTime: string - uptime: number - ver: string - branch: string - commitHash: string +export interface GatewayTokenBalance { + chainId: number + errorReason?: string + results: Array +} + +export interface GatewayTokenPriceQuery { chainID: number - percentWALWritten: number + queries: Array +} + +export interface GatewayTransaction { + chainId: number + errorReason?: string + results: Array +} + +export interface IndexState { + chainId: string + lastBlockNum: number + lastBlockHash: string +} + +export interface IndexedBlock { + blockNumber: number + blockShortHash: string +} + +export interface IndexerMetrics { + blocksPerSecond: number + eventsPerSecond: number +} + +export interface MarketplaceOrder { + orderId: string + tokenContract: string + tokenId: string + isListing: boolean + quantity: string + quantityRemaining: string + currencyAddress: string + pricePerToken: string + expiry: string + orderStatus: OrderStatus + createdBy: string + blockNumber: number + orderbookContractAddress: string + createdAt: number +} + +export interface MarketplaceOrderFilter { + isListing?: boolean + userAddresses?: Array + currencyAddresses: Array + orderIds: Array + tokenIds: Array + excludeUserAddresses?: Array + blockNumberGt: number + createdAtAfter: number + orderStatuses: Array + returnExpired: boolean +} + +export interface MarketplaceTopOrdersFilter { + currencyAddresses: Array + tokenIds: Array + isListing: boolean + priceSort: SortOrder + excludeUser?: string } -export interface RuntimeChecks { - running: boolean - runnables: any - cgoEnabled: boolean - quotaControlEnabled: boolean - syncMode: string - percentIndexed: number - lastBlockNum: number - lastBlockNumWithState: number - bloomStatus: BloomStatus - bond: Bond - diskUsage: DiskUsage +export interface MetadataOptions { + verifiedOnly?: boolean + unverifiedOnly?: boolean + includeContracts?: Array } -export interface DiskUsage { - humanReadable: string - used: number - size: number - percent: number - dirs: { [key: string]: string } +export interface NativeTokenBalance { + accountAddress: string + chainId: number + name: string + symbol: string + balance: string + balanceUSD: string + priceUSD: string + priceUpdatedAt?: string + errorReason?: string } -export interface Bond { - pebble: PebbleMetrics - estimatedDiskUsagePerTable: any - estimatedDiskUsageTotal: string +export enum NetworkType { + MAINNETS = 'MAINNETS', + TESTNETS = 'TESTNETS', + ALL = 'ALL' +} + +export enum OrderStatus { + OPEN = 'OPEN', + CLOSED = 'CLOSED', + CANCELLED = 'CANCELLED' +} + +export interface Page { + page?: number + column?: string + before?: any + after?: any + sort?: Array + pageSize?: number + more?: boolean } export interface PebbleMetrics { @@ -292,66 +676,54 @@ export interface PebbleMetrics { compactionMarkedFiles: number } -export interface BloomStatus { - enabled: boolean - initialized: boolean - bloomInitElapsedTime: string -} - -export interface EtherBalance { - accountAddress: string - balanceWei: string +export interface Price { + contractAddress: string + tokenID?: string + priceUSD: string + updatedAt?: string } -export interface NativeTokenBalance { - accountAddress: string - chainId: number - balance: string - error: string +export enum ResourceStatus { + NOT_AVAILABLE = 'NOT_AVAILABLE', + REFRESHING = 'REFRESHING', + AVAILABLE = 'AVAILABLE' } -export interface IndexState { - chainId: string +export interface RuntimeChecks { + running: boolean + runnables: any + cgoEnabled: boolean + quotaControlEnabled: boolean + syncMode: string + percentIndexed: number lastBlockNum: number - lastBlockHash: string -} - -export interface IndexedBlock { - blockNumber: number - blockShortHash: string + lastBlockNumWithState: number + bloomStatus: BloomStatus + bond: Bond + diskUsage: DiskUsage + metrics: IndexerMetrics } -export interface TxnInfo { - from: string - to: string - value: string +export interface RuntimeStatus { + healthOK: boolean + indexerEnabled: boolean + startTime: string + uptime: number + ver: string + branch: string + commitHash: string + chainID: number + checks: RuntimeChecks } -export interface EventLog { - id: number - uid: string - type: EventLogType - blockNumber: number - blockHash: string - parentBlockHash: string - contractAddress: string - contractType: ContractType - txnHash: string - txnIndex: number - txnLogIndex: number - logDataType: EventLogDataType - ts: string - txnInfo?: TxnInfo - rawLog?: { [key: string]: any } - event?: EventDecoded +export interface SortBy { + column: string + order: SortOrder } -export interface EventDecoded { - topicHash: string - eventSig: string - types: Array - names: Array - values: Array +export enum SortOrder { + DESC = 'DESC', + ASC = 'ASC' } export interface TokenBalance { @@ -360,6 +732,9 @@ export interface TokenBalance { accountAddress: string tokenID?: string balance: string + balanceUSD: string + priceUSD: string + priceUpdatedAt?: string blockHash: string blockNumber: number chainId: number @@ -369,39 +744,32 @@ export interface TokenBalance { tokenMetadata?: TokenMetadata } -export interface OrderbookOrder { - orderId: string - tokenContract: string - tokenId: string - isListing: boolean - quantity: string - quantityRemaining: string - currencyAddress: string - pricePerToken: string - expiry: string - orderStatus: OrderStatus - createdBy: string - blockNumber: number - orderbookContractAddress: string - createdAt: number +export interface TokenBalanceFilter { + contractAddress: string + sinceBlockNumber: number } -export interface OrderbookOrderFilter { - isListing?: boolean - userAddresses?: Array - tokenIds: Array - excludeUserAddresses?: Array - afterBlockNumber: number - afterCreatedAt: number - beforeExpiry: number - userAddress?: string - excludeUserAddress?: string +export interface TokenBalancesByContractFilter { + contractAddresses: Array + accountAddresses?: Array + contractStatus?: ContractVerificationStatus + tokenIDs?: Array +} + +export interface TokenBalancesFilter { + accountAddresses: Array + contractStatus?: ContractVerificationStatus + contractTypes?: Array + contractWhitelist?: Array + contractBlacklist?: Array + omitNativeBalances: boolean + omitPrices?: boolean + tokenIDs?: Array } export interface TokenHistory { blockNumber: number blockHash: string - accountAddress: string contractAddress: string contractType: ContractType fromAddress: string @@ -409,12 +777,45 @@ export interface TokenHistory { txnHash: string txnIndex: number txnLogIndex: number - logData: string tokenIDs: string - Amounts: string + amounts: string ts: string } +export interface TokenIDRange { + start: string + end: string +} + +export interface TokenMetadata { + chainId?: number + contractAddress?: string + tokenId: string + source: 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: ResourceStatus + queuedAt?: string + lastFetched?: string +} + +export interface TokenPriceQuery { + contractAddress: string + tokenID?: string +} + export interface TokenSupply { tokenID: string supply: string @@ -433,17 +834,12 @@ export interface Transaction { timestamp: string } -export interface TxnTransfer { - transferType: TxnTransferType - contractAddress: string - contractType: ContractType - from: string - to: string - tokenIds?: Array - amounts: Array - logIndex: number - contractInfo?: ContractInfo - tokenMetadata?: { [key: string]: TokenMetadata } +export interface TransactionFilter { + txnHash?: string + from?: string + to?: string + contractAddress?: string + event?: string } export interface TransactionHistoryFilter { @@ -456,14 +852,14 @@ export interface TransactionHistoryFilter { fromBlock?: number toBlock?: number tokenID?: string + omitPrices?: boolean } -export interface TransactionFilter { - txnHash?: string - from?: string - to?: string - contractAddress?: string - event?: string +export interface TransactionLog { + contractAddress: string + topics: Array + data: string + index: number } export interface TransactionReceipt { @@ -482,31 +878,60 @@ export interface TransactionReceipt { reorged: boolean } -export interface TransactionLog { - contractAddress: string - topics: Array - data: string - index: number +export enum TransactionStatus { + FAILED = 'FAILED', + SUCCESSFUL = 'SUCCESSFUL' } -export interface TokenIDRange { - start: string - end: string +export enum TransactionType { + LegacyTxnType = 'LegacyTxnType', + AccessListTxnType = 'AccessListTxnType', + DynamicFeeTxnType = 'DynamicFeeTxnType' +} + +export interface TxnInfo { + from: string + to: string + value: string +} + +export interface TxnTransfer { + transferType: TxnTransferType + contractAddress: string + contractType: ContractType + from: string + to: string + tokenIds?: Array + amounts: Array + logIndex: number + amountsUSD?: Array + pricesUSD?: Array + contractInfo?: ContractInfo + tokenMetadata?: { [key: string]: TokenMetadata } } -export interface Page { - page?: number - column?: string - before?: any - after?: any - sort?: Array - pageSize?: number - more?: boolean +export enum TxnTransferType { + UNKNOWN = 'UNKNOWN', + SEND = 'SEND', + RECEIVE = 'RECEIVE' } -export interface SortBy { - column: string - order: SortOrder +export interface Version { + webrpcVersion: string + schemaVersion: string + schemaHash: string + appVersion: string +} + +export interface WALWriterRuntimeStatus { + healthOK: boolean + startTime: string + uptime: number + ver: string + branch: string + commitHash: string + chainID: number + percentWALWritten: number } export interface WebhookListener { @@ -519,469 +944,345 @@ export interface WebhookListener { active: boolean } -export interface EventFilter { - events?: Array - contractAddresses?: Array - accounts?: Array - tokenIDs?: Array +export interface AddWebhookListenerRequest { + url: string + filters: EventFilter + projectId?: number } -export interface TokenBalanceFilter { - contractAddress: string - sinceBlockNumber: number +export interface AddWebhookListenerResponse { + status: boolean + listener: WebhookListener } -export interface MetadataOptions { - verifiedOnly?: boolean - unverifiedOnly?: boolean - includeContracts?: Array +export interface FetchTransactionReceiptRequest { + txnHash: string + maxBlockWait?: number } -export interface TokenBalancesFilter { - accountAddresses: Array - contractStatus?: ContractVerificationStatus - contractTypes?: Array - contractWhitelist?: Array - contractBlacklist?: Array - omitNativeBalances: boolean +export interface FetchTransactionReceiptResponse { + receipt: TransactionReceipt } -export interface TokenBalancesByContractFilter { - contractAddresses: Array - accountAddresses?: Array - contractStatus?: ContractVerificationStatus +export interface FetchTransactionReceiptWithFilterRequest { + filter: TransactionFilter + maxBlockWait?: number } -export interface GatewayEtherBalance { - chainId: number - error: string - result: EtherBalance +export interface FetchTransactionReceiptWithFilterResponse { + receipt: TransactionReceipt } -export interface GatewayNativeTokenBalance { - chainId: number - error: string - result: NativeTokenBalance +export interface GetAllWebhookListenersRequest { + projectId?: number } -export interface GatewayNativeTokenBalances { - chainId: number - error: string - results: Array +export interface GetAllWebhookListenersResponse { + listeners: Array } -export interface GatewayTokenBalance { - chainId: number - error: string - results: Array +export interface GetBalanceUpdatesRequest { + contractAddress: string + lastBlockNumber: number + lastBlockHash?: string + page?: Page } -export interface Indexer { - ping(headers?: object, signal?: AbortSignal): Promise - version(headers?: object, signal?: AbortSignal): Promise - runtimeStatus(headers?: object, signal?: AbortSignal): Promise - getChainID(headers?: object, signal?: AbortSignal): Promise - getEtherBalance(args: GetEtherBalanceArgs, headers?: object, signal?: AbortSignal): Promise - getNativeTokenBalance( - args: GetNativeTokenBalanceArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - getTokenBalancesSummary( - args: GetTokenBalancesSummaryArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - getTokenBalancesDetails( - args: GetTokenBalancesDetailsArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - getTokenBalancesByContract( - args: GetTokenBalancesByContractArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - getTokenBalances(args: GetTokenBalancesArgs, headers?: object, signal?: AbortSignal): Promise - getTokenSupplies(args: GetTokenSuppliesArgs, headers?: object, signal?: AbortSignal): Promise - getTokenSuppliesMap( - args: GetTokenSuppliesMapArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - getTokenIDs(args: GetTokenIDsArgs, headers?: object, signal?: AbortSignal): Promise - getTokenIDRanges(args: GetTokenIDRangesArgs, headers?: object, signal?: AbortSignal): Promise - getBalanceUpdates( - args: GetBalanceUpdatesArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - getTransactionHistory( - args: GetTransactionHistoryArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - fetchTransactionReceipt( - args: FetchTransactionReceiptArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - fetchTransactionReceiptWithFilter( - args: FetchTransactionReceiptWithFilterArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - subscribeReceipts(args: SubscribeReceiptsArgs, options: WebrpcStreamOptions): Promise - subscribeEvents(args: SubscribeEventsArgs, options: WebrpcStreamOptions): Promise - subscribeBalanceUpdates( - args: SubscribeBalanceUpdatesArgs, - options: WebrpcStreamOptions, - ): Promise - syncBalance(args: SyncBalanceArgs, headers?: object, signal?: AbortSignal): Promise - getAllWebhookListeners( - args: GetAllWebhookListenersArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - getWebhookListener( - args: GetWebhookListenerArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - addWebhookListener( - args: AddWebhookListenerArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - updateWebhookListener( - args: UpdateWebhookListenerArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - removeWebhookListener( - args: RemoveWebhookListenerArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - removeAllWebhookListeners( - args: RemoveAllWebhookListenersArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - toggleWebhookListener( - args: ToggleWebhookListenerArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - pauseAllWebhookListeners( - args: PauseAllWebhookListenersArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - resumeAllWebhookListeners( - args: ResumeAllWebhookListenersArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - getOrderbookOrders( - args: GetOrderbookOrdersArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - getTopOrders(args: GetTopOrdersArgs, headers?: object, signal?: AbortSignal): Promise +export interface GetBalanceUpdatesResponse { + page: Page + balances: Array } -export interface PingArgs {} +export interface GetChainIDRequest {} -export interface PingReturn { - status: boolean +export interface GetChainIDResponse { + chainID: number } -export interface VersionArgs {} -export interface VersionReturn { - version: Version +export interface GetEtherBalanceRequest { + accountAddress?: string } -export interface RuntimeStatusArgs {} -export interface RuntimeStatusReturn { - status: RuntimeStatus +export interface GetEtherBalanceResponse { + balance: EtherBalance } -export interface GetChainIDArgs {} -export interface GetChainIDReturn { - chainID: number +export interface GetMarketplaceOrdersRequest { + marketplaceContractAddress: string + collectionAddress: string + filter?: MarketplaceOrderFilter + page?: Page } -export interface GetEtherBalanceArgs { - accountAddress?: string + +export interface GetMarketplaceOrdersResponse { + page?: Page + orders: Array } -export interface GetEtherBalanceReturn { - balance: EtherBalance +export interface GetMarketplaceTopOrdersRequest { + marketplaceContractAddress: string + collectionAddress: string + filter: MarketplaceTopOrdersFilter +} + +export interface GetMarketplaceTopOrdersResponse { + orders: Array } -export interface GetNativeTokenBalanceArgs { + +export interface GetNativeTokenBalanceRequest { accountAddress?: string + omitPrices?: boolean } -export interface GetNativeTokenBalanceReturn { +export interface GetNativeTokenBalanceResponse { balance: NativeTokenBalance } -export interface GetTokenBalancesSummaryArgs { - filter: TokenBalancesFilter - omitMetadata?: boolean + +export interface GetTokenBalancesRequest { + accountAddress?: string + contractAddress?: string + tokenID?: string + includeMetadata?: boolean + metadataOptions?: MetadataOptions + includeCollectionTokens?: boolean page?: Page } -export interface GetTokenBalancesSummaryReturn { +export interface GetTokenBalancesResponse { page: Page - nativeBalances: Array balances: Array } -export interface GetTokenBalancesDetailsArgs { - filter: TokenBalancesFilter + +export interface GetTokenBalancesByContractRequest { + filter: TokenBalancesByContractFilter omitMetadata?: boolean page?: Page } -export interface GetTokenBalancesDetailsReturn { +export interface GetTokenBalancesByContractResponse { page: Page - nativeBalances: Array balances: Array } -export interface GetTokenBalancesByContractArgs { - filter: TokenBalancesByContractFilter + +export interface GetTokenBalancesDetailsRequest { + filter: TokenBalancesFilter omitMetadata?: boolean page?: Page } -export interface GetTokenBalancesByContractReturn { +export interface GetTokenBalancesDetailsResponse { page: Page + nativeBalances: Array balances: Array } -export interface GetTokenBalancesArgs { - accountAddress?: string - contractAddress?: string - tokenID?: string - includeMetadata?: boolean - metadataOptions?: MetadataOptions - includeCollectionTokens?: boolean + +export interface GetTokenBalancesSummaryRequest { + filter: TokenBalancesFilter + omitMetadata?: boolean page?: Page } -export interface GetTokenBalancesReturn { +export interface GetTokenBalancesSummaryResponse { page: Page + nativeBalances: Array balances: Array } -export interface GetTokenSuppliesArgs { + +export interface GetTokenIDRangesRequest { contractAddress: string - includeMetadata?: boolean - metadataOptions?: MetadataOptions - page?: Page + lastTokenID?: string } -export interface GetTokenSuppliesReturn { - page: Page +export interface GetTokenIDRangesResponse { contractType: ContractType - tokenIDs: Array -} -export interface GetTokenSuppliesMapArgs { - tokenMap: { [key: string]: Array } - includeMetadata?: boolean - metadataOptions?: MetadataOptions + tokenIDRanges: Array + moreRanges: boolean } -export interface GetTokenSuppliesMapReturn { - supplies: { [key: string]: Array } -} -export interface GetTokenIDsArgs { +export interface GetTokenIDsRequest { contractAddress: string page?: Page } -export interface GetTokenIDsReturn { +export interface GetTokenIDsResponse { page: Page contractType: ContractType tokenIDs: Array } -export interface GetTokenIDRangesArgs { - contractAddress: string + +export interface GetTokenPriceRequest { + q: TokenPriceQuery } -export interface GetTokenIDRangesReturn { - contractType: ContractType - tokenIDRanges: Array - moreRanges: boolean +export interface GetTokenPriceResponse { + price: Price +} + +export interface GetTokenPricesRequest { + q: Array +} + +export interface GetTokenPricesResponse { + prices: Array } -export interface GetBalanceUpdatesArgs { + +export interface GetTokenSuppliesRequest { contractAddress: string - lastBlockNumber: number - lastBlockHash?: string + includeMetadata?: boolean page?: Page } -export interface GetBalanceUpdatesReturn { +export interface GetTokenSuppliesResponse { page: Page - balances: Array + contractType: ContractType + tokenIDs: Array +} + +export interface GetTokenSuppliesMapRequest { + tokenMap: { [key: string]: Array } + includeMetadata?: boolean +} + +export interface GetTokenSuppliesMapResponse { + supplies: { [key: string]: Array } } -export interface GetTransactionHistoryArgs { + +export interface GetTransactionHistoryRequest { filter: TransactionHistoryFilter page?: Page includeMetadata?: boolean metadataOptions?: MetadataOptions } -export interface GetTransactionHistoryReturn { +export interface GetTransactionHistoryResponse { page: Page transactions: Array } -export interface FetchTransactionReceiptArgs { - txnHash: string - maxBlockWait?: number -} -export interface FetchTransactionReceiptReturn { - receipt: TransactionReceipt -} -export interface FetchTransactionReceiptWithFilterArgs { - filter: TransactionFilter - maxBlockWait?: number +export interface GetWebhookListenerRequest { + id: number + projectId?: number } -export interface FetchTransactionReceiptWithFilterReturn { - receipt: TransactionReceipt -} -export interface SubscribeReceiptsArgs { - filter: TransactionFilter +export interface GetWebhookListenerResponse { + listener: WebhookListener } -export interface SubscribeReceiptsReturn { - receipt: TransactionReceipt -} -export interface SubscribeEventsArgs { - filter: EventFilter +export interface ListTokenPricesRequest { + page?: Page } -export interface SubscribeEventsReturn { - log: EventLog +export interface ListTokenPricesResponse { + page: Page + prices: Array } -export interface SubscribeBalanceUpdatesArgs { - contractAddress: string + +export interface PauseAllWebhookListenersRequest { + projectId?: number } -export interface SubscribeBalanceUpdatesReturn { - balance: TokenBalance +export interface PauseAllWebhookListenersResponse { + status: boolean } -export interface SyncBalanceArgs { - accountAddress: string - contractAddress: string - tokenID?: string + +export interface PingRequest {} + +export interface PingResponse { + status: boolean } -export interface SyncBalanceReturn {} -export interface GetAllWebhookListenersArgs { +export interface RemoveAllWebhookListenersRequest { projectId?: number } -export interface GetAllWebhookListenersReturn { - listeners: Array +export interface RemoveAllWebhookListenersResponse { + status: boolean } -export interface GetWebhookListenerArgs { + +export interface RemoveWebhookListenerRequest { id: number projectId?: number } -export interface GetWebhookListenerReturn { - listener: WebhookListener +export interface RemoveWebhookListenerResponse { + status: boolean } -export interface AddWebhookListenerArgs { - url: string - filters: EventFilter + +export interface ResumeAllWebhookListenersRequest { projectId?: number } -export interface AddWebhookListenerReturn { +export interface ResumeAllWebhookListenersResponse { status: boolean - listener: WebhookListener } -export interface UpdateWebhookListenerArgs { - listener: WebhookListener - projectId?: number + +export interface RuntimeStatusRequest {} + +export interface RuntimeStatusResponse { + status: RuntimeStatus } -export interface UpdateWebhookListenerReturn { - status: boolean +export interface SubscribeBalanceUpdatesRequest { + contractAddress: string } -export interface RemoveWebhookListenerArgs { - id: number - projectId?: number + +export interface SubscribeBalanceUpdatesResponse { + balance: TokenBalance +} + +export interface SubscribeEventsRequest { + filter: EventFilter +} + +export interface SubscribeEventsResponse { + log: EventLog } -export interface RemoveWebhookListenerReturn { - status: boolean +export interface SubscribeReceiptsRequest { + filter: TransactionFilter } -export interface RemoveAllWebhookListenersArgs { - projectId?: number + +export interface SubscribeReceiptsResponse { + receipt: TransactionReceipt } -export interface RemoveAllWebhookListenersReturn { - status: boolean +export interface SyncBalanceRequest { + accountAddress: string + contractAddress: string + tokenID?: string } -export interface ToggleWebhookListenerArgs { + +export interface SyncBalanceResponse {} + +export interface ToggleWebhookListenerRequest { id: number projectId?: number } -export interface ToggleWebhookListenerReturn { +export interface ToggleWebhookListenerResponse { webhookListener: WebhookListener } -export interface PauseAllWebhookListenersArgs { - projectId?: number -} -export interface PauseAllWebhookListenersReturn { - status: boolean -} -export interface ResumeAllWebhookListenersArgs { +export interface UpdateWebhookListenerRequest { + listener: WebhookListener projectId?: number } -export interface ResumeAllWebhookListenersReturn { +export interface UpdateWebhookListenerResponse { status: boolean } -export interface GetOrderbookOrdersArgs { - page?: Page - orderbookContractAddress: string - collectionAddress: string - currencyAddresses: Array - filter: OrderbookOrderFilter - orderStatuses: Array - filters: Array - beforeExpiryTimestamp: number - blockNumberAfter: number - createdAtAfter: number -} -export interface GetOrderbookOrdersReturn { - page?: Page - orders: Array -} -export interface GetTopOrdersArgs { - orderbookContractAddress: string - collectionAddress: string - currencyAddresses: Array - tokenIDs: Array - isListing: boolean - priceSort: SortOrder - excludeUser?: string -} +export interface VersionRequest {} -export interface GetTopOrdersReturn { - orders: Array +export interface VersionResponse { + version: Version } // // Client // -export class Indexer implements Indexer { + +export class Indexer implements IndexerClient { protected hostname: string protected fetch: Fetch protected path = '/rpc/Indexer/' @@ -995,601 +1296,652 @@ export class Indexer implements Indexer { 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, - } + queryKey = { + addWebhookListener: (req: AddWebhookListenerRequest) => ['Indexer', 'addWebhookListener', req] as const, + fetchTransactionReceipt: (req: FetchTransactionReceiptRequest) => ['Indexer', 'fetchTransactionReceipt', req] as const, + fetchTransactionReceiptWithFilter: (req: FetchTransactionReceiptWithFilterRequest) => + ['Indexer', 'fetchTransactionReceiptWithFilter', req] as const, + getAllWebhookListeners: (req: GetAllWebhookListenersRequest) => ['Indexer', 'getAllWebhookListeners', req] as const, + getBalanceUpdates: (req: GetBalanceUpdatesRequest) => ['Indexer', 'getBalanceUpdates', req] as const, + getChainID: () => ['Indexer', 'getChainID'] as const, + getEtherBalance: (req: GetEtherBalanceRequest) => ['Indexer', 'getEtherBalance', req] as const, + getMarketplaceOrders: (req: GetMarketplaceOrdersRequest) => ['Indexer', 'getMarketplaceOrders', req] as const, + getMarketplaceTopOrders: (req: GetMarketplaceTopOrdersRequest) => ['Indexer', 'getMarketplaceTopOrders', req] as const, + getNativeTokenBalance: (req: GetNativeTokenBalanceRequest) => ['Indexer', 'getNativeTokenBalance', req] as const, + getTokenBalances: (req: GetTokenBalancesRequest) => ['Indexer', 'getTokenBalances', req] as const, + getTokenBalancesByContract: (req: GetTokenBalancesByContractRequest) => + ['Indexer', 'getTokenBalancesByContract', req] as const, + getTokenBalancesDetails: (req: GetTokenBalancesDetailsRequest) => ['Indexer', 'getTokenBalancesDetails', req] as const, + getTokenBalancesSummary: (req: GetTokenBalancesSummaryRequest) => ['Indexer', 'getTokenBalancesSummary', req] as const, + getTokenIDRanges: (req: GetTokenIDRangesRequest) => ['Indexer', 'getTokenIDRanges', req] as const, + getTokenIDs: (req: GetTokenIDsRequest) => ['Indexer', 'getTokenIDs', req] as const, + getTokenPrice: (req: GetTokenPriceRequest) => ['Indexer', 'getTokenPrice', req] as const, + getTokenPrices: (req: GetTokenPricesRequest) => ['Indexer', 'getTokenPrices', req] as const, + getTokenSupplies: (req: GetTokenSuppliesRequest) => ['Indexer', 'getTokenSupplies', req] as const, + getTokenSuppliesMap: (req: GetTokenSuppliesMapRequest) => ['Indexer', 'getTokenSuppliesMap', req] as const, + getTransactionHistory: (req: GetTransactionHistoryRequest) => ['Indexer', 'getTransactionHistory', req] as const, + getWebhookListener: (req: GetWebhookListenerRequest) => ['Indexer', 'getWebhookListener', req] as const, + listTokenPrices: (req: ListTokenPricesRequest) => ['Indexer', 'listTokenPrices', req] as const, + pauseAllWebhookListeners: (req: PauseAllWebhookListenersRequest) => ['Indexer', 'pauseAllWebhookListeners', req] as const, + ping: () => ['Indexer', 'ping'] as const, + removeAllWebhookListeners: (req: RemoveAllWebhookListenersRequest) => ['Indexer', 'removeAllWebhookListeners', req] as const, + removeWebhookListener: (req: RemoveWebhookListenerRequest) => ['Indexer', 'removeWebhookListener', req] as const, + resumeAllWebhookListeners: (req: ResumeAllWebhookListenersRequest) => ['Indexer', 'resumeAllWebhookListeners', req] as const, + runtimeStatus: () => ['Indexer', 'runtimeStatus'] as const, + subscribeBalanceUpdates: (req: SubscribeBalanceUpdatesRequest) => ['Indexer', 'subscribeBalanceUpdates', req] as const, + subscribeEvents: (req: SubscribeEventsRequest) => ['Indexer', 'subscribeEvents', req] as const, + subscribeReceipts: (req: SubscribeReceiptsRequest) => ['Indexer', 'subscribeReceipts', req] as const, + syncBalance: (req: SyncBalanceRequest) => ['Indexer', 'syncBalance', req] as const, + toggleWebhookListener: (req: ToggleWebhookListenerRequest) => ['Indexer', 'toggleWebhookListener', req] as const, + updateWebhookListener: (req: UpdateWebhookListenerRequest) => ['Indexer', 'updateWebhookListener', req] as const, + version: () => ['Indexer', 'version'] as const + } + + addWebhookListener = ( + req: AddWebhookListenerRequest, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('AddWebhookListener'), createHttpRequest(JsonEncode(req), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'AddWebhookListenerResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) - }, + 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 { - version: _data.version, - } + fetchTransactionReceipt = ( + req: FetchTransactionReceiptRequest, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('FetchTransactionReceipt'), createHttpRequest(JsonEncode(req), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'FetchTransactionReceiptResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) - }, + 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 { - status: _data.status, - } + fetchTransactionReceiptWithFilter = ( + req: FetchTransactionReceiptWithFilterRequest, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('FetchTransactionReceiptWithFilter'), createHttpRequest(JsonEncode(req), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'FetchTransactionReceiptWithFilterResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) - }, + 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 { - chainID: _data.chainID, - } + getAllWebhookListeners = ( + req: GetAllWebhookListenersRequest, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('GetAllWebhookListeners'), createHttpRequest(JsonEncode(req), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'GetAllWebhookListenersResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } - getEtherBalance = ( - args: GetEtherBalanceArgs, + getBalanceUpdates = ( + req: GetBalanceUpdatesRequest, headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch(this.url('GetEtherBalance'), createHTTPRequest(args, headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return { - balance: _data.balance, - } + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('GetBalanceUpdates'), createHttpRequest(JsonEncode(req), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'GetBalanceUpdatesResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } - getNativeTokenBalance = ( - args: GetNativeTokenBalanceArgs, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch(this.url('GetNativeTokenBalance'), createHTTPRequest(args, headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return { - balance: _data.balance, - } + 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, 'GetChainIDResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } + ) + } + + getEtherBalance = (req: GetEtherBalanceRequest, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('GetEtherBalance'), createHttpRequest(JsonEncode(req), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'GetEtherBalanceResponse') + }) }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } - getTokenBalancesSummary = ( - args: GetTokenBalancesSummaryArgs, + getMarketplaceOrders = ( + req: GetMarketplaceOrdersRequest, headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch(this.url('GetTokenBalancesSummary'), createHTTPRequest(args, headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return { - page: _data.page, - nativeBalances: >_data.nativeBalances, - balances: >_data.balances, - } + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('GetMarketplaceOrders'), createHttpRequest(JsonEncode(req), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'GetMarketplaceOrdersResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } - getTokenBalancesDetails = ( - args: GetTokenBalancesDetailsArgs, + getMarketplaceTopOrders = ( + req: GetMarketplaceTopOrdersRequest, headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch(this.url('GetTokenBalancesDetails'), createHTTPRequest(args, headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return { - page: _data.page, - nativeBalances: >_data.nativeBalances, - balances: >_data.balances, - } + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('GetMarketplaceTopOrders'), createHttpRequest(JsonEncode(req), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'GetMarketplaceTopOrdersResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } - getTokenBalancesByContract = ( - args: GetTokenBalancesByContractArgs, + getNativeTokenBalance = ( + req: GetNativeTokenBalanceRequest, headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch(this.url('GetTokenBalancesByContract'), createHTTPRequest(args, headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return { - page: _data.page, - balances: >_data.balances, - } + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('GetNativeTokenBalance'), createHttpRequest(JsonEncode(req), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'GetNativeTokenBalanceResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } getTokenBalances = ( - args: GetTokenBalancesArgs, + req: GetTokenBalancesRequest, headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch(this.url('GetTokenBalances'), createHTTPRequest(args, headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return { - page: _data.page, - balances: >_data.balances, - } + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('GetTokenBalances'), createHttpRequest(JsonEncode(req), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'GetTokenBalancesResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } - getTokenSupplies = ( - args: GetTokenSuppliesArgs, + getTokenBalancesByContract = ( + req: GetTokenBalancesByContractRequest, headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch(this.url('GetTokenSupplies'), createHTTPRequest(args, headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return { - page: _data.page, - contractType: _data.contractType, - tokenIDs: >_data.tokenIDs, - } + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('GetTokenBalancesByContract'), createHttpRequest(JsonEncode(req), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'GetTokenBalancesByContractResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } - getTokenSuppliesMap = ( - args: GetTokenSuppliesMapArgs, + getTokenBalancesDetails = ( + req: GetTokenBalancesDetailsRequest, headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch(this.url('GetTokenSuppliesMap'), createHTTPRequest(args, headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return { - supplies: <{ [key: string]: Array }>_data.supplies, - } + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('GetTokenBalancesDetails'), createHttpRequest(JsonEncode(req), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'GetTokenBalancesDetailsResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } - getTokenIDs = (args: GetTokenIDsArgs, headers?: object, signal?: AbortSignal): Promise => { - return this.fetch(this.url('GetTokenIDs'), createHTTPRequest(args, headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return { - page: _data.page, - contractType: _data.contractType, - tokenIDs: >_data.tokenIDs, - } + getTokenBalancesSummary = ( + req: GetTokenBalancesSummaryRequest, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('GetTokenBalancesSummary'), createHttpRequest(JsonEncode(req), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'GetTokenBalancesSummaryResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } getTokenIDRanges = ( - args: GetTokenIDRangesArgs, + req: GetTokenIDRangesRequest, headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch(this.url('GetTokenIDRanges'), createHTTPRequest(args, headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return { - contractType: _data.contractType, - tokenIDRanges: >_data.tokenIDRanges, - moreRanges: _data.moreRanges, - } + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('GetTokenIDRanges'), createHttpRequest(JsonEncode(req), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'GetTokenIDRangesResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } - getBalanceUpdates = ( - args: GetBalanceUpdatesArgs, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch(this.url('GetBalanceUpdates'), createHTTPRequest(args, headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return { - page: _data.page, - balances: >_data.balances, - } + getTokenIDs = (req: GetTokenIDsRequest, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('GetTokenIDs'), createHttpRequest(JsonEncode(req), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'GetTokenIDsResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } - getTransactionHistory = ( - args: GetTransactionHistoryArgs, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch(this.url('GetTransactionHistory'), createHTTPRequest(args, headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return { - page: _data.page, - transactions: >_data.transactions, - } + getTokenPrice = (req: GetTokenPriceRequest, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('GetTokenPrice'), createHttpRequest(JsonEncode(req), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'GetTokenPriceResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } - fetchTransactionReceipt = ( - args: FetchTransactionReceiptArgs, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch(this.url('FetchTransactionReceipt'), createHTTPRequest(args, headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return { - receipt: _data.receipt, - } + getTokenPrices = (req: GetTokenPricesRequest, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('GetTokenPrices'), createHttpRequest(JsonEncode(req), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'GetTokenPricesResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } - fetchTransactionReceiptWithFilter = ( - args: FetchTransactionReceiptWithFilterArgs, + getTokenSupplies = ( + req: GetTokenSuppliesRequest, headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch(this.url('FetchTransactionReceiptWithFilter'), createHTTPRequest(args, headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return { - receipt: _data.receipt, - } + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('GetTokenSupplies'), createHttpRequest(JsonEncode(req), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'GetTokenSuppliesResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } - subscribeReceipts = ( - args: SubscribeReceiptsArgs, - options: WebrpcStreamOptions, - ): Promise => { - const _fetch = () => - this.fetch(this.url('SubscribeReceipts'), createHTTPRequest(args, options.headers, options.signal)).then( - async (res) => { - await sseResponse(res, options, _fetch) - }, - (error) => { - options.onError(error, _fetch) - }, - ) - return _fetch() - } - subscribeEvents = (args: SubscribeEventsArgs, options: WebrpcStreamOptions): Promise => { - const _fetch = () => - this.fetch(this.url('SubscribeEvents'), createHTTPRequest(args, options.headers, options.signal)).then( - async (res) => { - await sseResponse(res, options, _fetch) - }, - (error) => { - options.onError(error, _fetch) - }, - ) - return _fetch() - } - subscribeBalanceUpdates = ( - args: SubscribeBalanceUpdatesArgs, - options: WebrpcStreamOptions, - ): Promise => { - const _fetch = () => - this.fetch(this.url('SubscribeBalanceUpdates'), createHTTPRequest(args, options.headers, options.signal)).then( - async (res) => { - await sseResponse(res, options, _fetch) - }, - (error) => { - options.onError(error, _fetch) - }, - ) - return _fetch() - } - syncBalance = (args: SyncBalanceArgs, headers?: object, signal?: AbortSignal): Promise => { - return this.fetch(this.url('SyncBalance'), createHTTPRequest(args, headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return {} + getTokenSuppliesMap = ( + req: GetTokenSuppliesMapRequest, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('GetTokenSuppliesMap'), createHttpRequest(JsonEncode(req), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'GetTokenSuppliesMapResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } - getAllWebhookListeners = ( - args: GetAllWebhookListenersArgs, + getTransactionHistory = ( + req: GetTransactionHistoryRequest, headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch(this.url('GetAllWebhookListeners'), createHTTPRequest(args, headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return { - listeners: >_data.listeners, - } + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('GetTransactionHistory'), createHttpRequest(JsonEncode(req), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'GetTransactionHistoryResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } getWebhookListener = ( - args: GetWebhookListenerArgs, + req: GetWebhookListenerRequest, headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch(this.url('GetWebhookListener'), createHTTPRequest(args, headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return { - listener: _data.listener, - } + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('GetWebhookListener'), createHttpRequest(JsonEncode(req), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'GetWebhookListenerResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } + ) + } + + listTokenPrices = (req: ListTokenPricesRequest, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('ListTokenPrices'), createHttpRequest(JsonEncode(req), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'ListTokenPricesResponse') + }) }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } - addWebhookListener = ( - args: AddWebhookListenerArgs, + pauseAllWebhookListeners = ( + req: PauseAllWebhookListenersRequest, headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch(this.url('AddWebhookListener'), createHTTPRequest(args, headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return { - status: _data.status, - listener: _data.listener, - } + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('PauseAllWebhookListeners'), createHttpRequest(JsonEncode(req), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'PauseAllWebhookListenersResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } + ) + } + + 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, 'PingResponse') + }) }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } - updateWebhookListener = ( - args: UpdateWebhookListenerArgs, + removeAllWebhookListeners = ( + req: RemoveAllWebhookListenersRequest, headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch(this.url('UpdateWebhookListener'), createHTTPRequest(args, headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return { - status: _data.status, - } + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('RemoveAllWebhookListeners'), createHttpRequest(JsonEncode(req), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'RemoveAllWebhookListenersResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } removeWebhookListener = ( - args: RemoveWebhookListenerArgs, + req: RemoveWebhookListenerRequest, headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch(this.url('RemoveWebhookListener'), createHTTPRequest(args, headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return { - status: _data.status, - } + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('RemoveWebhookListener'), createHttpRequest(JsonEncode(req), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'RemoveWebhookListenerResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } - removeAllWebhookListeners = ( - args: RemoveAllWebhookListenersArgs, + resumeAllWebhookListeners = ( + req: ResumeAllWebhookListenersRequest, headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch(this.url('RemoveAllWebhookListeners'), createHTTPRequest(args, headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return { - status: _data.status, - } + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('ResumeAllWebhookListeners'), createHttpRequest(JsonEncode(req), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'ResumeAllWebhookListenersResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } - toggleWebhookListener = ( - args: ToggleWebhookListenerArgs, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch(this.url('ToggleWebhookListener'), createHTTPRequest(args, headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return { - webhookListener: _data.webhookListener, - } + 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, 'RuntimeStatusResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } - pauseAllWebhookListeners = ( - args: PauseAllWebhookListenersArgs, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch(this.url('PauseAllWebhookListeners'), createHTTPRequest(args, headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return { - status: _data.status, - } + subscribeBalanceUpdates = ( + req: SubscribeBalanceUpdatesRequest, + options: WebrpcStreamOptions + ): WebrpcStreamController => { + const abortController = new AbortController() + const abortSignal = abortController.signal + + if (options.signal) { + abortSignal.addEventListener('abort', () => abortController.abort(options.signal?.reason), { + signal: options.signal + }) + } + + const _fetch = () => + this.fetch(this.url('SubscribeBalanceUpdates'), createHttpRequest(JsonEncode(req), options.headers, abortSignal)).then( + async res => { + await sseResponse(res, options, _fetch) + }, + error => { + options.onError(error, _fetch) + } + ) + + const resp = _fetch() + return { + abort: abortController.abort.bind(abortController), + closed: resp + } + } + subscribeEvents = ( + req: SubscribeEventsRequest, + options: WebrpcStreamOptions + ): WebrpcStreamController => { + const abortController = new AbortController() + const abortSignal = abortController.signal + + if (options.signal) { + abortSignal.addEventListener('abort', () => abortController.abort(options.signal?.reason), { + signal: options.signal + }) + } + + const _fetch = () => + this.fetch(this.url('SubscribeEvents'), createHttpRequest(JsonEncode(req), options.headers, abortSignal)).then( + async res => { + await sseResponse(res, options, _fetch) + }, + error => { + options.onError(error, _fetch) + } + ) + + const resp = _fetch() + return { + abort: abortController.abort.bind(abortController), + closed: resp + } + } + subscribeReceipts = ( + req: SubscribeReceiptsRequest, + options: WebrpcStreamOptions + ): WebrpcStreamController => { + const abortController = new AbortController() + const abortSignal = abortController.signal + + if (options.signal) { + abortSignal.addEventListener('abort', () => abortController.abort(options.signal?.reason), { + signal: options.signal + }) + } + + const _fetch = () => + this.fetch(this.url('SubscribeReceipts'), createHttpRequest(JsonEncode(req), options.headers, abortSignal)).then( + async res => { + await sseResponse(res, options, _fetch) + }, + error => { + options.onError(error, _fetch) + } + ) + + const resp = _fetch() + return { + abort: abortController.abort.bind(abortController), + closed: resp + } + } + syncBalance = (req: SyncBalanceRequest, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('SyncBalance'), createHttpRequest(JsonEncode(req), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'SyncBalanceResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } - resumeAllWebhookListeners = ( - args: ResumeAllWebhookListenersArgs, + toggleWebhookListener = ( + req: ToggleWebhookListenerRequest, headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch(this.url('ResumeAllWebhookListeners'), createHTTPRequest(args, headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return { - status: _data.status, - } + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('ToggleWebhookListener'), createHttpRequest(JsonEncode(req), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'ToggleWebhookListenerResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } - getOrderbookOrders = ( - args: GetOrderbookOrdersArgs, + updateWebhookListener = ( + req: UpdateWebhookListenerRequest, headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch(this.url('GetOrderbookOrders'), createHTTPRequest(args, headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return { - page: _data.page, - orders: >_data.orders, - } + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('UpdateWebhookListener'), createHttpRequest(JsonEncode(req), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'UpdateWebhookListenerResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } - getTopOrders = (args: GetTopOrdersArgs, headers?: object, signal?: AbortSignal): Promise => { - return this.fetch(this.url('GetTopOrders'), createHTTPRequest(args, headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return { - orders: >_data.orders, - } + 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, 'VersionResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } } @@ -1611,9 +1963,9 @@ const sseResponse = async (res: Response, options: WebrpcStreamOptions, ret onError( WebrpcBadResponseError.new({ status: res.status, - cause: 'Invalid response, missing body', + cause: 'Invalid response, missing body' }), - retryFetch, + retryFetch ) return } @@ -1643,27 +1995,22 @@ const sseResponse = async (res: Response, options: WebrpcStreamOptions, ret lastReadTime = Date.now() buffer += decoder.decode(value, { stream: true }) } catch (error) { - let message = '' - if (error instanceof Error) { - message = error.message - } - if (error instanceof DOMException && error.name === 'AbortError') { onError( - WebrpcRequestFailedError.new({ + WebrpcClientAbortedError.new({ message: 'AbortError', - cause: `AbortError: ${message}`, + cause: `AbortError: ${error instanceof Error ? error.message : String(error)}` }), () => { throw new Error('Abort signal cannot be used to reconnect') - }, + } ) } else { onError( WebrpcStreamLostError.new({ - cause: `reader.read(): ${message}`, + cause: `reader.read(): ${error instanceof Error ? error.message : String(error)}` }), - retryFetch, + retryFetch ) } return @@ -1671,12 +2018,13 @@ const sseResponse = async (res: Response, options: WebrpcStreamOptions, ret let lines = buffer.split('\n') for (let i = 0; i < lines.length - 1; i++) { - if (lines[i]!.length == 0) { + const line = lines[i] + if (line?.length === 0) { continue } let data: any try { - data = JSON.parse(lines[i]!) + data = JSON.parse(line) if (data.hasOwnProperty('webrpcError')) { const error = data.webrpcError const code: number = typeof error.code === 'number' ? error.code : 0 @@ -1690,17 +2038,17 @@ const sseResponse = async (res: Response, options: WebrpcStreamOptions, ret onError( WebrpcBadResponseError.new({ status: res.status, - // @ts-ignore - cause: `JSON.parse(): ${error.message}`, + cause: `JSON.parse(): ${error instanceof Error ? error.message : String(error)}` }), - retryFetch, + retryFetch ) } onMessage(data) } if (!done) { - buffer = lines[lines.length - 1]! + const lastLine = lines[lines.length - 1] + buffer = lastLine || '' continue } @@ -1709,31 +2057,24 @@ const sseResponse = async (res: Response, options: WebrpcStreamOptions, ret } } -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 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) => { + 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}`, + cause: `JSON.parse(): ${error instanceof Error ? error.message : String(error)}: response text: ${text}` }) } if (!res.ok) { @@ -1744,518 +2085,511 @@ const buildResponse = (res: Response): Promise => { }) } +export type Fetch = (input: RequestInfo, init?: RequestInit) => Promise + +export interface WebrpcStreamOptions extends WebrpcOptions { + onMessage: (message: T) => void + onError: (error: WebrpcError, reconnect: () => void) => void + onOpen?: () => void + onClose?: () => void +} + +export interface WebrpcOptions { + headers?: HeadersInit + signal?: AbortSignal +} + +export interface WebrpcStreamController { + abort: (reason?: any) => void + closed: Promise +} + +export const JsonEncode = (obj: T): 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 - 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 + + 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(payload.error, payload.code, payload.message || payload.msg, payload.status, payload.cause) + return new this({ message: payload.message, code: payload.code, status: payload.status, cause: 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) + 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( - name: string = 'WebrpcRequestFailed', - code: number = -1, - message: string = 'request failed', - status: number = 0, - cause?: string, - ) { - super(name, code, message, status, cause) + 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( - name: string = 'WebrpcBadRoute', - code: number = -2, - message: string = 'bad route', - status: number = 0, - cause?: string, - ) { - super(name, code, message, status, cause) + 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( - name: string = 'WebrpcBadMethod', - code: number = -3, - message: string = 'bad method', - status: number = 0, - cause?: string, - ) { - super(name, code, message, status, cause) + 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( - name: string = 'WebrpcBadRequest', - code: number = -4, - message: string = 'bad request', - status: number = 0, - cause?: string, - ) { - super(name, code, message, status, cause) + 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( - name: string = 'WebrpcBadResponse', - code: number = -5, - message: string = 'bad response', - status: number = 0, - cause?: string, - ) { - super(name, code, message, status, cause) + 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( - name: string = 'WebrpcServerPanic', - code: number = -6, - message: string = 'server panic', - status: number = 0, - cause?: string, - ) { - super(name, code, message, status, cause) + 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( - name: string = 'WebrpcInternalError', - code: number = -7, - message: string = 'internal error', - status: number = 0, - cause?: string, - ) { - super(name, code, message, status, cause) + 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 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 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( - name: string = 'WebrpcStreamLost', - code: number = -9, - message: string = 'stream lost', - status: number = 0, - cause?: string, - ) { - super(name, code, message, status, cause) + 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( - name: string = 'WebrpcStreamFinished', - code: number = -10, - message: string = 'stream finished', - status: number = 0, - cause?: string, - ) { - super(name, code, message, status, cause) + 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( - 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 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 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 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 : 409 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, AccessKeyMismatchError.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 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 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 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 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 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 AbortedError extends WebrpcError { - constructor( - name: string = 'Aborted', - code: number = 1005, - message: string = 'Request aborted', - status: number = 0, - cause?: string, - ) { - super(name, code, message, status, cause) - Object.setPrototypeOf(this, AbortedError.prototype) +export class InvalidArgumentError extends WebrpcError { + constructor(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 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 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 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 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 ProjectNotFoundError extends WebrpcError { - constructor( - name: string = 'ProjectNotFound', - code: number = 1100, - message: string = 'Project not found', - status: number = 0, - cause?: string, - ) { - super(name, code, message, status, cause) - Object.setPrototypeOf(this, ProjectNotFoundError.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 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 MetadataCallFailedError extends WebrpcError { + constructor(error: WebrpcErrorParams = {}) { + super(error) + this.name = error.name || 'MetadataCallFailed' + this.code = typeof error.code === 'number' ? error.code : 3003 + this.message = error.message || `Metadata service call failed` + this.status = typeof error.status === 'number' ? error.status : 400 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, MetadataCallFailedError.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 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 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 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 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 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 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 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 QuotaExceededError extends WebrpcError { - constructor( - name: string = 'QuotaExceeded', - code: number = 1200, - message: string = 'Quota exceeded', - status: number = 0, - cause?: string, - ) { - super(name, code, message, status, cause) - Object.setPrototypeOf(this, QuotaExceededError.prototype) +export class ProjectNotFoundError extends WebrpcError { + constructor(error: WebrpcErrorParams = {}) { + super(error) + this.name = error.name || 'ProjectNotFound' + this.code = typeof error.code === 'number' ? error.code : 1100 + 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 RateLimitError extends WebrpcError { - constructor( - name: string = 'RateLimit', - code: number = 1201, - message: string = 'Rate limit exceeded', - status: number = 0, - cause?: string, - ) { - super(name, code, message, status, cause) - Object.setPrototypeOf(this, RateLimitError.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 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 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 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 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 RateLimitError extends WebrpcError { + constructor(error: WebrpcErrorParams = {}) { + super(error) + this.name = error.name || 'RateLimit' + this.code = typeof error.code === 'number' ? error.code : 1201 + this.message = error.message || `Rate limit exceeded` + this.status = typeof error.status === 'number' ? error.status : 429 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, RateLimitError.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 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 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 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 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 ResourceExhaustedError extends WebrpcError { + constructor(error: WebrpcErrorParams = {}) { + super(error) + this.name = error.name || 'ResourceExhausted' + this.code = typeof error.code === 'number' ? error.code : 2004 + this.message = error.message || `Resource exhausted` + this.status = typeof error.status === 'number' ? error.status : 400 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, ResourceExhaustedError.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 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 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 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 ResourceExhaustedError extends WebrpcError { - constructor( - name: string = 'ResourceExhausted', - code: number = 2004, - message: string = 'Resource exhausted', - status: number = 0, - cause?: string, - ) { - super(name, code, message, status, cause) - Object.setPrototypeOf(this, ResourceExhaustedError.prototype) +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 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 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 MetadataCallFailedError extends WebrpcError { - constructor( - name: string = 'MetadataCallFailed', - code: number = 3003, - message: string = 'Metadata service call failed', - status: number = 0, - cause?: string, - ) { - super(name, code, message, status, cause) - Object.setPrototypeOf(this, MetadataCallFailedError.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) } } @@ -2268,38 +2602,78 @@ export enum errors { WebrpcBadResponse = 'WebrpcBadResponse', WebrpcServerPanic = 'WebrpcServerPanic', WebrpcInternalError = 'WebrpcInternalError', - WebrpcClientDisconnected = 'WebrpcClientDisconnected', + 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', + AccessKeyNotFound = 'AccessKeyNotFound', + AtLeastOneKey = 'AtLeastOneKey', + Geoblocked = 'Geoblocked', + InvalidArgument = 'InvalidArgument', InvalidOrigin = 'InvalidOrigin', InvalidService = 'InvalidService', - UnauthorizedUser = 'UnauthorizedUser', - QuotaExceeded = 'QuotaExceeded', - RateLimit = 'RateLimit', - NoDefaultKey = 'NoDefaultKey', MaxAccessKeys = 'MaxAccessKeys', - AtLeastOneKey = 'AtLeastOneKey', - Timeout = 'Timeout', - InvalidArgument = 'InvalidArgument', - Unavailable = 'Unavailable', + MetadataCallFailed = 'MetadataCallFailed', + MethodNotFound = 'MethodNotFound', + NoDefaultKey = 'NoDefaultKey', + NotFound = 'NotFound', + PermissionDenied = 'PermissionDenied', + ProjectNotFound = 'ProjectNotFound', QueryFailed = 'QueryFailed', + QuotaExceeded = 'QuotaExceeded', + RateLimit = 'RateLimit', + RateLimited = 'RateLimited', + RequestConflict = 'RequestConflict', ResourceExhausted = 'ResourceExhausted', - NotFound = 'NotFound', - MetadataCallFailed = 'MetadataCallFailed', -} - -const webrpcErrorByCode: { [code: number]: any } = { + SessionExpired = 'SessionExpired', + Timeout = 'Timeout', + Unauthorized = 'Unauthorized', + UnauthorizedUser = 'UnauthorizedUser', + Unavailable = 'Unavailable' +} + +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, + Aborted = 1005, + AccessKeyMismatch = 1102, + AccessKeyNotFound = 1101, + AtLeastOneKey = 1302, + Geoblocked = 1006, + InvalidArgument = 2001, + InvalidOrigin = 1103, + InvalidService = 1104, + MaxAccessKeys = 1301, + MetadataCallFailed = 3003, + MethodNotFound = 1003, + NoDefaultKey = 1300, + NotFound = 3000, + PermissionDenied = 1001, + ProjectNotFound = 1100, + QueryFailed = 2003, + QuotaExceeded = 1200, + RateLimit = 1201, + RateLimited = 1007, + RequestConflict = 1004, + ResourceExhausted = 2004, + SessionExpired = 1002, + Timeout = 1900, + Unauthorized = 1000, + UnauthorizedUser = 1105, + Unavailable = 2002 +} + +export const webrpcErrorByCode: { [code: number]: any } = { [0]: WebrpcEndpointError, [-1]: WebrpcRequestFailedError, [-2]: WebrpcBadRouteError, @@ -2308,46 +2682,89 @@ const webrpcErrorByCode: { [code: number]: any } = { [-5]: WebrpcBadResponseError, [-6]: WebrpcServerPanicError, [-7]: WebrpcInternalErrorError, - [-8]: WebrpcClientDisconnectedError, + [-8]: WebrpcClientAbortedError, [-9]: WebrpcStreamLostError, [-10]: WebrpcStreamFinishedError, - [1000]: UnauthorizedError, - [1001]: PermissionDeniedError, - [1002]: SessionExpiredError, - [1003]: MethodNotFoundError, - [1004]: RequestConflictError, [1005]: AbortedError, - [1006]: GeoblockedError, - [1007]: RateLimitedError, - [1100]: ProjectNotFoundError, - [1101]: AccessKeyNotFoundError, [1102]: AccessKeyMismatchError, + [1101]: AccessKeyNotFoundError, + [1302]: AtLeastOneKeyError, + [1006]: GeoblockedError, + [2001]: InvalidArgumentError, [1103]: InvalidOriginError, [1104]: InvalidServiceError, - [1105]: UnauthorizedUserError, - [1200]: QuotaExceededError, - [1201]: RateLimitError, - [1300]: NoDefaultKeyError, [1301]: MaxAccessKeysError, - [1302]: AtLeastOneKeyError, - [1900]: TimeoutError, - [2001]: InvalidArgumentError, - [2002]: UnavailableError, + [3003]: MetadataCallFailedError, + [1003]: MethodNotFoundError, + [1300]: NoDefaultKeyError, + [3000]: NotFoundError, + [1001]: PermissionDeniedError, + [1100]: ProjectNotFoundError, [2003]: QueryFailedError, + [1200]: QuotaExceededError, + [1201]: RateLimitError, + [1007]: RateLimitedError, + [1004]: RequestConflictError, [2004]: ResourceExhaustedError, - [3000]: NotFoundError, - [3003]: MetadataCallFailedError, + [1002]: SessionExpiredError, + [1900]: TimeoutError, + [1000]: UnauthorizedError, + [1105]: UnauthorizedUserError, + [2002]: UnavailableError } -export type Fetch = (input: RequestInfo, init?: RequestInit) => Promise +// +// Webrpc +// -export interface WebrpcStreamOptions extends WebrpcOptions { - onMessage: (message: T) => void - onError: (error: WebrpcError, reconnect: () => void) => void - onOpen?: () => void - onClose?: () => void +export const WebrpcHeader = 'Webrpc' + +export const WebrpcHeaderValue = 'webrpc@v0.31.2;gen-typescript@v0.23.1;sequence-indexer@v0.4.0' + +type WebrpcGenVersions = { + WebrpcGenVersion: string + codeGenName: string + codeGenVersion: string + schemaName: string + schemaVersion: string } -export interface WebrpcOptions { - headers?: HeadersInit - signal?: AbortSignal + +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/indexer/src/indexergw.gen.ts b/packages/services/indexer/src/indexergw.gen.ts index 92f85b2c8c..618a50217c 100644 --- a/packages/services/indexer/src/indexergw.gen.ts +++ b/packages/services/indexer/src/indexergw.gen.ts @@ -1,79 +1,166 @@ /* eslint-disable */ -// sequence-indexer v0.4.0 5be4a3e78d9c7e0cc378c675ec01c518e83772e3 +// sequence-indexer v0.4.0 212120aad9a46e88ead9a2183c5717e9902d8c2b // -- -// Code generated by webrpc-gen@v0.21.1 with typescript generator. DO NOT EDIT. +// Code generated by Webrpc-gen@v0.31.2 with typescript generator. DO NOT EDIT. // -// webrpc-gen -schema=indexer.ridl -service=IndexerGateway -target=typescript -client -out=./clients/indexergw.gen.ts +// webrpc-gen -schema=merged.gen.json -service=IndexerGateway -target=typescript -client -out=./clients/indexergw.gen.ts -export const WebrpcHeader = 'Webrpc' - -export const WebrpcHeaderValue = 'webrpc@v0.21.1;gen-typescript@v0.15.1;sequence-indexer@v0.4.0' - -// WebRPC description and code-gen version -export const WebRPCVersion = 'v1' +// Webrpc description and code-gen version +export const WebrpcVersion = 'v1' // Schema version of your RIDL schema -export const WebRPCSchemaVersion = 'v0.4.0' +export const WebrpcSchemaVersion = 'v0.4.0' // Schema hash generated from your RIDL schema -export const WebRPCSchemaHash = '5be4a3e78d9c7e0cc378c675ec01c518e83772e3' +export const WebrpcSchemaHash = '212120aad9a46e88ead9a2183c5717e9902d8c2b' -type WebrpcGenVersions = { - webrpcGenVersion: string - codeGenName: string - codeGenVersion: string - schemaName: string - schemaVersion: string -} +// +// Client interface +// -export function VersionFromHeader(headers: Headers): WebrpcGenVersions { - const headerValue = headers.get(WebrpcHeader) - if (!headerValue) { - return { - webrpcGenVersion: '', - codeGenName: '', - codeGenVersion: '', - schemaName: '', - schemaVersion: '', - } - } +export interface IndexerGatewayClient { + /** + * GetTokenBalances returns a balance summary/details for an specific account + * on all indexer nodes. By default if accountAddress is left empty, it will + * use the account from the jwt session. + */ + getBalanceUpdates(req: GetBalanceUpdatesRequest, headers?: object, signal?: AbortSignal): Promise + + /** + * GetChains returns a list of chains with their ID and name + */ + getChains(req: GetChainsRequest, headers?: object, signal?: AbortSignal): Promise + + /** + * GetNativeTokenBalance queries indexer nodes for the latest native token + * account balance. + */ + getNativeTokenBalance( + req: GetNativeTokenBalanceRequest, + headers?: object, + signal?: AbortSignal + ): Promise + + /** + * GetTokenBalances returns a balance summary/details for a specific account + * on all indexer nodes. By default if accountAddress is left empty, it will + * use the account from the jwt session. + * + * @deprecated Use GetTokenBalancesSummary or GetTokenBalancesDetails instead. + */ + getTokenBalances(req: GetTokenBalancesRequest, headers?: object, signal?: AbortSignal): Promise + + /** + * GetTokenBalancesByContract returns a balances for specific accounts and + * contracts on all indexer nodes. The collection ERC721 & ERC1155 tokens are + * represented as individual balances. + */ + getTokenBalancesByContract( + req: GetTokenBalancesByContractRequest, + headers?: object, + signal?: AbortSignal + ): Promise + + /** + * GetTokenBalancesDetails returns a detailed balance summary for the given + * accounts on all indexer nodes. The collection ERC721 & ERC1155 tokens are + * represented as individual balances. + */ + getTokenBalancesDetails( + req: GetTokenBalancesDetailsRequest, + headers?: object, + signal?: AbortSignal + ): Promise + + /** + * GetTokenBalancesSummary returns a summary of token balances for the given + * accounts on all indexer nodes. The collection ERC721 & ERC1155 tokens are + * represented as a single aggregated balance. + */ + getTokenBalancesSummary( + req: GetTokenBalancesSummaryRequest, + headers?: object, + signal?: AbortSignal + ): Promise - return parseWebrpcGenVersions(headerValue) -} + getTokenPrice(req: GetTokenPriceRequest, headers?: object, signal?: AbortSignal): Promise -function parseWebrpcGenVersions(header: string): WebrpcGenVersions { - const versions = header.split(';') - if (versions.length < 3) { - return { - webrpcGenVersion: '', - codeGenName: '', - codeGenVersion: '', - schemaName: '', - schemaVersion: '', - } - } + getTokenPrices(req: GetTokenPricesRequest, headers?: object, signal?: AbortSignal): Promise - const [_, webrpcGenVersion] = versions[0]!.split('@') - const [codeGenName, codeGenVersion] = versions[1]!.split('@') - const [schemaName, schemaVersion] = versions[2]!.split('@') + /** + * GetTransactionHistory returns the history of mined transactions for the + * given account on all indexer nodes, which includes a list of token transfer + * (sent/received) , and sent transactions from a Sequence wallet. + */ + getTransactionHistory( + req: GetTransactionHistoryRequest, + headers?: object, + signal?: AbortSignal + ): Promise - return { - webrpcGenVersion: webrpcGenVersion!, - codeGenName: codeGenName!, - codeGenVersion: codeGenVersion!, - schemaName: schemaName!, - schemaVersion: schemaVersion!, - } + /** + * Ping the indexer + */ + ping(headers?: object, signal?: AbortSignal): Promise + + /** + * Get the current runtime health status of the indexer gatewya + */ + runtimeStatus(headers?: object, signal?: AbortSignal): Promise + + /** + * Get the current version of the indexer + */ + version(headers?: object, signal?: AbortSignal): Promise } // -// Types +// Schema types // -export enum ResourceStatus { - NOT_AVAILABLE = 'NOT_AVAILABLE', - REFRESHING = 'REFRESHING', - AVAILABLE = 'AVAILABLE', +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 BackupMode { + INCREMENTAL = 'INCREMENTAL', + COMPLETE = 'COMPLETE' +} + +export interface BloomStats { + hitRatio: string + falsePositivesPercent: string + hitCount: number + missCount: number + falsePositives: number +} + +export interface BloomStatus { + enabled: boolean + initialized: boolean + bloomInitElapsedTime: string + stats: BloomStats +} + +export interface Bond { + pebble: PebbleMetrics + estimatedDiskUsagePerTable: any + estimatedDiskUsageTotal: string +} + +export interface ChainInfo { + chainId: number + chainName: string } export interface ContractInfo { @@ -93,56 +180,29 @@ export interface ContractInfo { status: ResourceStatus } -export interface ContractInfoExtensions { - link: string - description: string - categories: Array - ogImage: string - ogName: string - originChainId: number - originAddress: string - blacklist: boolean - verified: boolean - verifiedBy: string - featured: boolean - featureIndex: number +export interface ContractInfoExtensionBridgeInfo { + tokenAddress: string } -export interface TokenMetadata { - contractAddress?: string - tokenId: string - source: 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: ResourceStatus - queuedAt?: string - lastFetched?: string +export interface ContractInfoExtensionIndexingInfo { + useOnChainBalance: boolean } -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 ContractInfoExtensions { + link?: string + description?: string + categories?: Array + bridgeInfo?: { [key: string]: ContractInfoExtensionBridgeInfo } + indexingInfo?: ContractInfoExtensionIndexingInfo + ogImage?: string + ogName?: string + originChainId?: number + originAddress?: string + blacklist?: boolean + verified?: boolean + verifiedBy?: string + featured?: boolean + featureIndex?: number } export enum ContractType { @@ -156,72 +216,73 @@ export enum ContractType { ERC721_BRIDGE = 'ERC721_BRIDGE', ERC1155_BRIDGE = 'ERC1155_BRIDGE', SEQ_MARKETPLACE = 'SEQ_MARKETPLACE', + ERC6909 = 'ERC6909' } -export enum EventLogType { - UNKNOWN = 'UNKNOWN', - BLOCK_ADDED = 'BLOCK_ADDED', - BLOCK_REMOVED = 'BLOCK_REMOVED', -} - -export enum EventLogDataType { - EVENT = 'EVENT', - TOKEN_TRANSFER = 'TOKEN_TRANSFER', - NATIVE_TOKEN_TRANSFER = 'NATIVE_TOKEN_TRANSFER', - SEQUENCE_TXN = 'SEQUENCE_TXN', -} - -export enum OrderStatus { - OPEN = 'OPEN', - CLOSED = 'CLOSED', - CANCELLED = 'CANCELLED', +export enum ContractVerificationStatus { + VERIFIED = 'VERIFIED', + UNVERIFIED = 'UNVERIFIED', + ALL = 'ALL' } -export enum TxnTransferType { - UNKNOWN = 'UNKNOWN', - SEND = 'SEND', - RECEIVE = 'RECEIVE', +export interface DiskUsage { + humanReadable: string + used: number + size: number + percent: number + dirs: { [key: string]: string } } -export enum TransactionStatus { - FAILED = 'FAILED', - SUCCESSFUL = 'SUCCESSFUL', +export interface EtherBalance { + accountAddress: string + balanceWei: string } -export enum TransactionType { - LegacyTxnType = 'LegacyTxnType', - AccessListTxnType = 'AccessListTxnType', - DynamicFeeTxnType = 'DynamicFeeTxnType', +export interface EventDecoded { + topicHash: string + eventSig: string + types: Array + names: Array + values: Array } -export enum SortOrder { - DESC = 'DESC', - ASC = 'ASC', +export interface EventFilter { + events?: Array + contractAddresses?: Array + accounts?: Array + tokenIDs?: Array } -export enum ContractVerificationStatus { - VERIFIED = 'VERIFIED', - UNVERIFIED = 'UNVERIFIED', - ALL = 'ALL', +export interface EventLog { + id: number + uid: string + type: EventLogType + blockNumber: number + blockHash: string + parentBlockHash: string + contractAddress: string + contractType: ContractType + txnHash: string + txnIndex: number + txnLogIndex: number + logDataType: EventLogDataType + ts: string + txnInfo?: TxnInfo + rawLog?: { [key: string]: any } + event?: EventDecoded } -export interface Version { - webrpcVersion: string - schemaVersion: string - schemaHash: string - appVersion: string +export enum EventLogDataType { + EVENT = 'EVENT', + TOKEN_TRANSFER = 'TOKEN_TRANSFER', + NATIVE_TOKEN_TRANSFER = 'NATIVE_TOKEN_TRANSFER', + SEQUENCE_TXN = 'SEQUENCE_TXN' } -export interface RuntimeStatus { - healthOK: boolean - indexerEnabled: boolean - startTime: string - uptime: number - ver: string - branch: string - commitHash: string - chainID: number - checks: RuntimeChecks +export enum EventLogType { + UNKNOWN = 'UNKNOWN', + BLOCK_ADDED = 'BLOCK_ADDED', + BLOCK_REMOVED = 'BLOCK_REMOVED' } export interface GatewayBackendResponseTime { @@ -235,6 +296,30 @@ export interface GatewayBackendRuntimeStatus { responseTime: GatewayBackendResponseTime } +export interface GatewayEtherBalance { + chainId: number + errorReason?: string + result: EtherBalance +} + +export interface GatewayNativeTokenBalance { + chainId: number + errorReason?: string + result: NativeTokenBalance +} + +export interface GatewayNativeTokenBalances { + chainId: number + errorReason?: string + results: Array +} + +export interface GatewayPrice { + chainID: number + errorReason?: string + results: Array +} + export interface GatewayRuntimeStatus { healthOK: boolean startTime: string @@ -245,113 +330,173 @@ export interface GatewayRuntimeStatus { backends: Array } -export interface WALWriterRuntimeStatus { - healthOK: boolean - startTime: string - uptime: number - ver: string - branch: string - commitHash: string +export interface GatewayTokenBalance { + chainId: number + errorReason?: string + results: Array +} + +export interface GatewayTokenPriceQuery { chainID: number - percentWALWritten: number + queries: Array } -export interface RuntimeChecks { - running: boolean - runnables: any - cgoEnabled: boolean - quotaControlEnabled: boolean - syncMode: string - percentIndexed: number +export interface GatewayTransaction { + chainId: number + errorReason?: string + results: Array +} + +export interface IndexState { + chainId: string lastBlockNum: number - lastBlockNumWithState: number - bloomStatus: BloomStatus - bond: Bond - diskUsage: DiskUsage + lastBlockHash: string } -export interface DiskUsage { - humanReadable: string - used: number - size: number - percent: number - dirs: { [key: string]: string } +export interface IndexedBlock { + blockNumber: number + blockShortHash: string } -export interface Bond { - pebble: PebbleMetrics - estimatedDiskUsagePerTable: any - estimatedDiskUsageTotal: string +export interface IndexerMetrics { + blocksPerSecond: number + eventsPerSecond: number } -export interface PebbleMetrics { - compactionCount: number - compactionEstimatedDebt: number - compactionInProgressBytes: number - compactionNumInProgress: number - compactionMarkedFiles: number +export interface MarketplaceOrder { + orderId: string + tokenContract: string + tokenId: string + isListing: boolean + quantity: string + quantityRemaining: string + currencyAddress: string + pricePerToken: string + expiry: string + orderStatus: OrderStatus + createdBy: string + blockNumber: number + orderbookContractAddress: string + createdAt: number } -export interface BloomStatus { - enabled: boolean - initialized: boolean - bloomInitElapsedTime: string +export interface MarketplaceOrderFilter { + isListing?: boolean + userAddresses?: Array + currencyAddresses: Array + orderIds: Array + tokenIds: Array + excludeUserAddresses?: Array + blockNumberGt: number + createdAtAfter: number + orderStatuses: Array + returnExpired: boolean } -export interface EtherBalance { - accountAddress: string - balanceWei: string +export interface MarketplaceTopOrdersFilter { + currencyAddresses: Array + tokenIds: Array + isListing: boolean + priceSort: SortOrder + excludeUser?: string +} + +export interface MetadataOptions { + verifiedOnly?: boolean + unverifiedOnly?: boolean + includeContracts?: Array } export interface NativeTokenBalance { accountAddress: string chainId: number + name: string + symbol: string balance: string - error: string + balanceUSD: string + priceUSD: string + priceUpdatedAt?: string + errorReason?: string } -export interface IndexState { - chainId: string - lastBlockNum: number - lastBlockHash: string +export enum NetworkType { + MAINNETS = 'MAINNETS', + TESTNETS = 'TESTNETS', + ALL = 'ALL' } -export interface IndexedBlock { - blockNumber: number - blockShortHash: string +export enum OrderStatus { + OPEN = 'OPEN', + CLOSED = 'CLOSED', + CANCELLED = 'CANCELLED' } -export interface TxnInfo { - from: string - to: string - value: string +export interface Page { + page?: number + column?: string + before?: any + after?: any + sort?: Array + pageSize?: number + more?: boolean } -export interface EventLog { - id: number - uid: string - type: EventLogType - blockNumber: number - blockHash: string - parentBlockHash: string +export interface PebbleMetrics { + compactionCount: number + compactionEstimatedDebt: number + compactionInProgressBytes: number + compactionNumInProgress: number + compactionMarkedFiles: number +} + +export interface Price { contractAddress: string - contractType: ContractType - txnHash: string - txnIndex: number - txnLogIndex: number - logDataType: EventLogDataType - ts: string - txnInfo?: TxnInfo - rawLog?: { [key: string]: any } - event?: EventDecoded + tokenID?: string + priceUSD: string + updatedAt?: string } -export interface EventDecoded { - topicHash: string - eventSig: string - types: Array - names: Array - values: Array +export enum ResourceStatus { + NOT_AVAILABLE = 'NOT_AVAILABLE', + REFRESHING = 'REFRESHING', + AVAILABLE = 'AVAILABLE' +} + +export interface RuntimeChecks { + running: boolean + runnables: any + cgoEnabled: boolean + quotaControlEnabled: boolean + syncMode: string + percentIndexed: number + lastBlockNum: number + lastBlockNumWithState: number + bloomStatus: BloomStatus + bond: Bond + diskUsage: DiskUsage + metrics: IndexerMetrics +} + +export interface RuntimeStatus { + healthOK: boolean + indexerEnabled: boolean + startTime: string + uptime: number + ver: string + branch: string + commitHash: string + chainID: number + checks: RuntimeChecks +} + +export interface SortBy { + column: string + order: SortOrder +} + +export enum SortOrder { + DESC = 'DESC', + ASC = 'ASC' } export interface TokenBalance { @@ -360,6 +505,9 @@ export interface TokenBalance { accountAddress: string tokenID?: string balance: string + balanceUSD: string + priceUSD: string + priceUpdatedAt?: string blockHash: string blockNumber: number chainId: number @@ -369,39 +517,32 @@ export interface TokenBalance { tokenMetadata?: TokenMetadata } -export interface OrderbookOrder { - orderId: string - tokenContract: string - tokenId: string - isListing: boolean - quantity: string - quantityRemaining: string - currencyAddress: string - pricePerToken: string - expiry: string - orderStatus: OrderStatus - createdBy: string - blockNumber: number - orderbookContractAddress: string - createdAt: number +export interface TokenBalanceFilter { + contractAddress: string + sinceBlockNumber: number } -export interface OrderbookOrderFilter { - isListing?: boolean - userAddresses?: Array - tokenIds: Array - excludeUserAddresses?: Array - afterBlockNumber: number - afterCreatedAt: number - beforeExpiry: number - userAddress?: string - excludeUserAddress?: string +export interface TokenBalancesByContractFilter { + contractAddresses: Array + accountAddresses?: Array + contractStatus?: ContractVerificationStatus + tokenIDs?: Array +} + +export interface TokenBalancesFilter { + accountAddresses: Array + contractStatus?: ContractVerificationStatus + contractTypes?: Array + contractWhitelist?: Array + contractBlacklist?: Array + omitNativeBalances: boolean + omitPrices?: boolean + tokenIDs?: Array } export interface TokenHistory { blockNumber: number blockHash: string - accountAddress: string contractAddress: string contractType: ContractType fromAddress: string @@ -409,12 +550,45 @@ export interface TokenHistory { txnHash: string txnIndex: number txnLogIndex: number - logData: string tokenIDs: string - Amounts: string + amounts: string ts: string } +export interface TokenIDRange { + start: string + end: string +} + +export interface TokenMetadata { + chainId?: number + contractAddress?: string + tokenId: string + source: 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: ResourceStatus + queuedAt?: string + lastFetched?: string +} + +export interface TokenPriceQuery { + contractAddress: string + tokenID?: string +} + export interface TokenSupply { tokenID: string supply: string @@ -433,17 +607,12 @@ export interface Transaction { timestamp: string } -export interface TxnTransfer { - transferType: TxnTransferType - contractAddress: string - contractType: ContractType - from: string - to: string - tokenIds?: Array - amounts: Array - logIndex: number - contractInfo?: ContractInfo - tokenMetadata?: { [key: string]: TokenMetadata } +export interface TransactionFilter { + txnHash?: string + from?: string + to?: string + contractAddress?: string + event?: string } export interface TransactionHistoryFilter { @@ -456,14 +625,14 @@ export interface TransactionHistoryFilter { fromBlock?: number toBlock?: number tokenID?: string + omitPrices?: boolean } -export interface TransactionFilter { - txnHash?: string - from?: string - to?: string - contractAddress?: string - event?: string +export interface TransactionLog { + contractAddress: string + topics: Array + data: string + index: number } export interface TransactionReceipt { @@ -482,31 +651,60 @@ export interface TransactionReceipt { reorged: boolean } -export interface TransactionLog { +export enum TransactionStatus { + FAILED = 'FAILED', + SUCCESSFUL = 'SUCCESSFUL' +} + +export enum TransactionType { + LegacyTxnType = 'LegacyTxnType', + AccessListTxnType = 'AccessListTxnType', + DynamicFeeTxnType = 'DynamicFeeTxnType' +} + +export interface TxnInfo { + from: string + to: string + value: string +} + +export interface TxnTransfer { + transferType: TxnTransferType contractAddress: string - topics: Array - data: string - index: number + contractType: ContractType + from: string + to: string + tokenIds?: Array + amounts: Array + logIndex: number + amountsUSD?: Array + pricesUSD?: Array + contractInfo?: ContractInfo + tokenMetadata?: { [key: string]: TokenMetadata } } -export interface TokenIDRange { - start: string - end: string +export enum TxnTransferType { + UNKNOWN = 'UNKNOWN', + SEND = 'SEND', + RECEIVE = 'RECEIVE' } -export interface Page { - page?: number - column?: string - before?: any - after?: any - sort?: Array - pageSize?: number - more?: boolean +export interface Version { + webrpcVersion: string + schemaVersion: string + schemaHash: string + appVersion: string } -export interface SortBy { - column: string - order: SortOrder +export interface WALWriterRuntimeStatus { + healthOK: boolean + startTime: string + uptime: number + ver: string + branch: string + commitHash: string + chainID: number + percentWALWritten: number } export interface WebhookListener { @@ -519,109 +717,45 @@ export interface WebhookListener { active: boolean } -export interface EventFilter { - events?: Array - contractAddresses?: Array - accounts?: Array - tokenIDs?: Array -} - -export interface TokenBalanceFilter { +export interface GetBalanceUpdatesRequest { + chainIds?: Array + networks?: Array + networkType?: NetworkType contractAddress: string - sinceBlockNumber: number -} - -export interface MetadataOptions { - verifiedOnly?: boolean - unverifiedOnly?: boolean - includeContracts?: Array -} - -export interface TokenBalancesFilter { - accountAddresses: Array - contractStatus?: ContractVerificationStatus - contractTypes?: Array - contractWhitelist?: Array - contractBlacklist?: Array - omitNativeBalances: boolean -} - -export interface TokenBalancesByContractFilter { - contractAddresses: Array - accountAddresses?: Array - contractStatus?: ContractVerificationStatus -} - -export interface GatewayEtherBalance { - chainId: number - error: string - result: EtherBalance -} - -export interface GatewayNativeTokenBalance { - chainId: number - error: string - result: NativeTokenBalance + lastBlockNumber: number + lastBlockHash?: string + page?: Page } -export interface GatewayNativeTokenBalances { - chainId: number - error: string - results: Array +export interface GetBalanceUpdatesResponse { + page: Page + balances: Array } -export interface GatewayTokenBalance { - chainId: number - error: string - results: Array +export interface GetChainsRequest { + networkType?: NetworkType } -export interface IndexerGateway { - getNativeTokenBalance( - args: GetNativeTokenBalanceArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - getTokenBalances(args: GetTokenBalancesArgs, headers?: object, signal?: AbortSignal): Promise - getTokenBalancesSummary( - args: GetTokenBalancesSummaryArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - getTokenBalancesDetails( - args: GetTokenBalancesDetailsArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - getTokenBalancesByContract( - args: GetTokenBalancesByContractArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - getBalanceUpdates( - args: GetBalanceUpdatesArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - ping(headers?: object, signal?: AbortSignal): Promise - version(headers?: object, signal?: AbortSignal): Promise - runtimeStatus(headers?: object, signal?: AbortSignal): Promise +export interface GetChainsResponse { + chains: Array } -export interface GetNativeTokenBalanceArgs { +export interface GetNativeTokenBalanceRequest { chainIds?: Array networks?: Array - testnets?: boolean + networkType?: NetworkType accountAddress?: string + omitPrices?: boolean } -export interface GetNativeTokenBalanceReturn { +export interface GetNativeTokenBalanceResponse { balances: Array } -export interface GetTokenBalancesArgs { + +export interface GetTokenBalancesRequest { chainIds?: Array networks?: Array - testnets?: boolean + networkType?: NetworkType accountAddress?: string contractAddress?: string tokenID?: string @@ -631,85 +765,109 @@ export interface GetTokenBalancesArgs { page?: Page } -export interface GetTokenBalancesReturn { +export interface GetTokenBalancesResponse { page: Page balances: Array } -export interface GetTokenBalancesSummaryArgs { + +export interface GetTokenBalancesByContractRequest { chainIds?: Array networks?: Array - testnets?: boolean - filter: TokenBalancesFilter + networkType?: NetworkType + filter: TokenBalancesByContractFilter omitMetadata?: boolean page?: Page } -export interface GetTokenBalancesSummaryReturn { +export interface GetTokenBalancesByContractResponse { page: Page - nativeBalances: Array balances: Array } -export interface GetTokenBalancesDetailsArgs { + +export interface GetTokenBalancesDetailsRequest { chainIds?: Array networks?: Array - testnets?: boolean + networkType?: NetworkType filter: TokenBalancesFilter omitMetadata?: boolean page?: Page } -export interface GetTokenBalancesDetailsReturn { +export interface GetTokenBalancesDetailsResponse { page: Page nativeBalances: Array balances: Array } -export interface GetTokenBalancesByContractArgs { + +export interface GetTokenBalancesSummaryRequest { chainIds?: Array networks?: Array - testnets?: boolean - filter: TokenBalancesByContractFilter + networkType?: NetworkType + filter: TokenBalancesFilter omitMetadata?: boolean page?: Page } -export interface GetTokenBalancesByContractReturn { +export interface GetTokenBalancesSummaryResponse { page: Page + nativeBalances: Array balances: Array } -export interface GetBalanceUpdatesArgs { + +export interface GetTokenPriceRequest { + q: GatewayTokenPriceQuery +} + +export interface GetTokenPriceResponse { + price: GatewayPrice +} + +export interface GetTokenPricesRequest { + q: Array +} + +export interface GetTokenPricesResponse { + prices: Array +} + +export interface GetTransactionHistoryRequest { chainIds?: Array networks?: Array - testnets?: boolean - contractAddress: string - lastBlockNumber: number - lastBlockHash?: string + networkType?: NetworkType + filter: TransactionHistoryFilter + includeMetadata?: boolean + metadataOptions?: MetadataOptions page?: Page } -export interface GetBalanceUpdatesReturn { +export interface GetTransactionHistoryResponse { page: Page - balances: Array + transactions: Array } -export interface PingArgs {} -export interface PingReturn { +export interface PingRequest {} + +export interface PingResponse { status: boolean } -export interface VersionArgs {} -export interface VersionReturn { - version: Version -} -export interface RuntimeStatusArgs {} +export interface RuntimeStatusRequest {} -export interface RuntimeStatusReturn { +export interface RuntimeStatusResponse { status: GatewayRuntimeStatus } +export interface VersionRequest {} + +export interface VersionResponse { + version: Version +} + // // Client // -export class IndexerGateway implements IndexerGateway { + +export class IndexerGateway implements IndexerGatewayClient { protected hostname: string protected fetch: Fetch protected path = '/rpc/IndexerGateway/' @@ -723,198 +881,239 @@ export class IndexerGateway implements IndexerGateway { return this.hostname + this.path + name } - getNativeTokenBalance = ( - args: GetNativeTokenBalanceArgs, + queryKey = { + getBalanceUpdates: (req: GetBalanceUpdatesRequest) => ['IndexerGateway', 'getBalanceUpdates', req] as const, + getChains: (req: GetChainsRequest) => ['IndexerGateway', 'getChains', req] as const, + getNativeTokenBalance: (req: GetNativeTokenBalanceRequest) => ['IndexerGateway', 'getNativeTokenBalance', req] as const, + getTokenBalances: (req: GetTokenBalancesRequest) => ['IndexerGateway', 'getTokenBalances', req] as const, + getTokenBalancesByContract: (req: GetTokenBalancesByContractRequest) => + ['IndexerGateway', 'getTokenBalancesByContract', req] as const, + getTokenBalancesDetails: (req: GetTokenBalancesDetailsRequest) => ['IndexerGateway', 'getTokenBalancesDetails', req] as const, + getTokenBalancesSummary: (req: GetTokenBalancesSummaryRequest) => ['IndexerGateway', 'getTokenBalancesSummary', req] as const, + getTokenPrice: (req: GetTokenPriceRequest) => ['IndexerGateway', 'getTokenPrice', req] as const, + getTokenPrices: (req: GetTokenPricesRequest) => ['IndexerGateway', 'getTokenPrices', req] as const, + getTransactionHistory: (req: GetTransactionHistoryRequest) => ['IndexerGateway', 'getTransactionHistory', req] as const, + ping: () => ['IndexerGateway', 'ping'] as const, + runtimeStatus: () => ['IndexerGateway', 'runtimeStatus'] as const, + version: () => ['IndexerGateway', 'version'] as const + } + + getBalanceUpdates = ( + req: GetBalanceUpdatesRequest, headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch(this.url('GetNativeTokenBalance'), createHTTPRequest(args, headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return { - balances: >_data.balances, - } + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('GetBalanceUpdates'), createHttpRequest(JsonEncode(req), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'GetBalanceUpdatesResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } + ) + } + + getChains = (req: GetChainsRequest, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('GetChains'), createHttpRequest(JsonEncode(req), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'GetChainsResponse') + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } + ) + } + + getNativeTokenBalance = ( + req: GetNativeTokenBalanceRequest, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('GetNativeTokenBalance'), createHttpRequest(JsonEncode(req), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'GetNativeTokenBalanceResponse') + }) }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } getTokenBalances = ( - args: GetTokenBalancesArgs, + req: GetTokenBalancesRequest, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('GetTokenBalances'), createHttpRequest(JsonEncode(req), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'GetTokenBalancesResponse') + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } + ) + } + + getTokenBalancesByContract = ( + req: GetTokenBalancesByContractRequest, headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch(this.url('GetTokenBalances'), createHTTPRequest(args, headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return { - page: _data.page, - balances: >_data.balances, - } + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('GetTokenBalancesByContract'), createHttpRequest(JsonEncode(req), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'GetTokenBalancesByContractResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } + ) + } + + getTokenBalancesDetails = ( + req: GetTokenBalancesDetailsRequest, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('GetTokenBalancesDetails'), createHttpRequest(JsonEncode(req), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'GetTokenBalancesDetailsResponse') + }) }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } getTokenBalancesSummary = ( - args: GetTokenBalancesSummaryArgs, + req: GetTokenBalancesSummaryRequest, headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch(this.url('GetTokenBalancesSummary'), createHTTPRequest(args, headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return { - page: _data.page, - nativeBalances: >_data.nativeBalances, - balances: >_data.balances, - } + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('GetTokenBalancesSummary'), createHttpRequest(JsonEncode(req), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'GetTokenBalancesSummaryResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } - getTokenBalancesDetails = ( - args: GetTokenBalancesDetailsArgs, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch(this.url('GetTokenBalancesDetails'), createHTTPRequest(args, headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return { - page: _data.page, - nativeBalances: >_data.nativeBalances, - balances: >_data.balances, - } + getTokenPrice = (req: GetTokenPriceRequest, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('GetTokenPrice'), createHttpRequest(JsonEncode(req), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'GetTokenPriceResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } - getTokenBalancesByContract = ( - args: GetTokenBalancesByContractArgs, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch(this.url('GetTokenBalancesByContract'), createHTTPRequest(args, headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return { - page: _data.page, - balances: >_data.balances, - } + getTokenPrices = (req: GetTokenPricesRequest, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('GetTokenPrices'), createHttpRequest(JsonEncode(req), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'GetTokenPricesResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } - getBalanceUpdates = ( - args: GetBalanceUpdatesArgs, + getTransactionHistory = ( + req: GetTransactionHistoryRequest, headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch(this.url('GetBalanceUpdates'), createHTTPRequest(args, headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return { - page: _data.page, - balances: >_data.balances, - } + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('GetTransactionHistory'), createHttpRequest(JsonEncode(req), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'GetTransactionHistoryResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } - 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, - } + 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, 'PingResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) - }, + 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 { - version: _data.version, - } + 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, 'RuntimeStatusResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) - }, + 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 { - status: _data.status, - } + 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, 'VersionResponse') }) }, - (error) => { - throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) - }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } ) } } -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 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) => { + 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}`, + cause: `JSON.parse(): ${error instanceof Error ? error.message : String(error)}: response text: ${text}` }) } if (!res.ok) { @@ -925,518 +1124,494 @@ const buildResponse = (res: Response): Promise => { }) } +export type Fetch = (input: RequestInfo, init?: RequestInit) => Promise + +export const JsonEncode = (obj: T): 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 - 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 + + 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(payload.error, payload.code, payload.message || payload.msg, payload.status, payload.cause) + return new this({ message: payload.message, code: payload.code, status: payload.status, cause: 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) + 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( - name: string = 'WebrpcRequestFailed', - code: number = -1, - message: string = 'request failed', - status: number = 0, - cause?: string, - ) { - super(name, code, message, status, cause) + 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( - name: string = 'WebrpcBadRoute', - code: number = -2, - message: string = 'bad route', - status: number = 0, - cause?: string, - ) { - super(name, code, message, status, cause) + 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( - name: string = 'WebrpcBadMethod', - code: number = -3, - message: string = 'bad method', - status: number = 0, - cause?: string, - ) { - super(name, code, message, status, cause) + 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( - name: string = 'WebrpcBadRequest', - code: number = -4, - message: string = 'bad request', - status: number = 0, - cause?: string, - ) { - super(name, code, message, status, cause) + 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( - name: string = 'WebrpcBadResponse', - code: number = -5, - message: string = 'bad response', - status: number = 0, - cause?: string, - ) { - super(name, code, message, status, cause) + 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( - name: string = 'WebrpcServerPanic', - code: number = -6, - message: string = 'server panic', - status: number = 0, - cause?: string, - ) { - super(name, code, message, status, cause) + 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( - name: string = 'WebrpcInternalError', - code: number = -7, - message: string = 'internal error', - status: number = 0, - cause?: string, - ) { - super(name, code, message, status, cause) + 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 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 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( - name: string = 'WebrpcStreamLost', - code: number = -9, - message: string = 'stream lost', - status: number = 0, - cause?: string, - ) { - super(name, code, message, status, cause) + 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( - name: string = 'WebrpcStreamFinished', - code: number = -10, - message: string = 'stream finished', - status: number = 0, - cause?: string, - ) { - super(name, code, message, status, cause) + 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( - 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 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 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 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 : 409 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, AccessKeyMismatchError.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 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 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 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 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 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 AbortedError extends WebrpcError { - constructor( - name: string = 'Aborted', - code: number = 1005, - message: string = 'Request aborted', - status: number = 0, - cause?: string, - ) { - super(name, code, message, status, cause) - Object.setPrototypeOf(this, AbortedError.prototype) +export class InvalidArgumentError extends WebrpcError { + constructor(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 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 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 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 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 ProjectNotFoundError extends WebrpcError { - constructor( - name: string = 'ProjectNotFound', - code: number = 1100, - message: string = 'Project not found', - status: number = 0, - cause?: string, - ) { - super(name, code, message, status, cause) - Object.setPrototypeOf(this, ProjectNotFoundError.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 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 MetadataCallFailedError extends WebrpcError { + constructor(error: WebrpcErrorParams = {}) { + super(error) + this.name = error.name || 'MetadataCallFailed' + this.code = typeof error.code === 'number' ? error.code : 3003 + this.message = error.message || `Metadata service call failed` + this.status = typeof error.status === 'number' ? error.status : 400 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, MetadataCallFailedError.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 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 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 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 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 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 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 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 QuotaExceededError extends WebrpcError { - constructor( - name: string = 'QuotaExceeded', - code: number = 1200, - message: string = 'Quota exceeded', - status: number = 0, - cause?: string, - ) { - super(name, code, message, status, cause) - Object.setPrototypeOf(this, QuotaExceededError.prototype) +export class ProjectNotFoundError extends WebrpcError { + constructor(error: WebrpcErrorParams = {}) { + super(error) + this.name = error.name || 'ProjectNotFound' + this.code = typeof error.code === 'number' ? error.code : 1100 + 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 RateLimitError extends WebrpcError { - constructor( - name: string = 'RateLimit', - code: number = 1201, - message: string = 'Rate limit exceeded', - status: number = 0, - cause?: string, - ) { - super(name, code, message, status, cause) - Object.setPrototypeOf(this, RateLimitError.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 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 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 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 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 RateLimitError extends WebrpcError { + constructor(error: WebrpcErrorParams = {}) { + super(error) + this.name = error.name || 'RateLimit' + this.code = typeof error.code === 'number' ? error.code : 1201 + this.message = error.message || `Rate limit exceeded` + this.status = typeof error.status === 'number' ? error.status : 429 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, RateLimitError.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 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 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 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 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 ResourceExhaustedError extends WebrpcError { + constructor(error: WebrpcErrorParams = {}) { + super(error) + this.name = error.name || 'ResourceExhausted' + this.code = typeof error.code === 'number' ? error.code : 2004 + this.message = error.message || `Resource exhausted` + this.status = typeof error.status === 'number' ? error.status : 400 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, ResourceExhaustedError.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 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 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 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 ResourceExhaustedError extends WebrpcError { - constructor( - name: string = 'ResourceExhausted', - code: number = 2004, - message: string = 'Resource exhausted', - status: number = 0, - cause?: string, - ) { - super(name, code, message, status, cause) - Object.setPrototypeOf(this, ResourceExhaustedError.prototype) +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 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 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 MetadataCallFailedError extends WebrpcError { - constructor( - name: string = 'MetadataCallFailed', - code: number = 3003, - message: string = 'Metadata service call failed', - status: number = 0, - cause?: string, - ) { - super(name, code, message, status, cause) - Object.setPrototypeOf(this, MetadataCallFailedError.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) } } @@ -1449,38 +1624,78 @@ export enum errors { WebrpcBadResponse = 'WebrpcBadResponse', WebrpcServerPanic = 'WebrpcServerPanic', WebrpcInternalError = 'WebrpcInternalError', - WebrpcClientDisconnected = 'WebrpcClientDisconnected', + 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', + AccessKeyNotFound = 'AccessKeyNotFound', + AtLeastOneKey = 'AtLeastOneKey', + Geoblocked = 'Geoblocked', + InvalidArgument = 'InvalidArgument', InvalidOrigin = 'InvalidOrigin', InvalidService = 'InvalidService', - UnauthorizedUser = 'UnauthorizedUser', - QuotaExceeded = 'QuotaExceeded', - RateLimit = 'RateLimit', - NoDefaultKey = 'NoDefaultKey', MaxAccessKeys = 'MaxAccessKeys', - AtLeastOneKey = 'AtLeastOneKey', - Timeout = 'Timeout', - InvalidArgument = 'InvalidArgument', - Unavailable = 'Unavailable', + MetadataCallFailed = 'MetadataCallFailed', + MethodNotFound = 'MethodNotFound', + NoDefaultKey = 'NoDefaultKey', + NotFound = 'NotFound', + PermissionDenied = 'PermissionDenied', + ProjectNotFound = 'ProjectNotFound', QueryFailed = 'QueryFailed', + QuotaExceeded = 'QuotaExceeded', + RateLimit = 'RateLimit', + RateLimited = 'RateLimited', + RequestConflict = 'RequestConflict', ResourceExhausted = 'ResourceExhausted', - NotFound = 'NotFound', - MetadataCallFailed = 'MetadataCallFailed', -} - -const webrpcErrorByCode: { [code: number]: any } = { + SessionExpired = 'SessionExpired', + Timeout = 'Timeout', + Unauthorized = 'Unauthorized', + UnauthorizedUser = 'UnauthorizedUser', + Unavailable = 'Unavailable' +} + +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, + Aborted = 1005, + AccessKeyMismatch = 1102, + AccessKeyNotFound = 1101, + AtLeastOneKey = 1302, + Geoblocked = 1006, + InvalidArgument = 2001, + InvalidOrigin = 1103, + InvalidService = 1104, + MaxAccessKeys = 1301, + MetadataCallFailed = 3003, + MethodNotFound = 1003, + NoDefaultKey = 1300, + NotFound = 3000, + PermissionDenied = 1001, + ProjectNotFound = 1100, + QueryFailed = 2003, + QuotaExceeded = 1200, + RateLimit = 1201, + RateLimited = 1007, + RequestConflict = 1004, + ResourceExhausted = 2004, + SessionExpired = 1002, + Timeout = 1900, + Unauthorized = 1000, + UnauthorizedUser = 1105, + Unavailable = 2002 +} + +export const webrpcErrorByCode: { [code: number]: any } = { [0]: WebrpcEndpointError, [-1]: WebrpcRequestFailedError, [-2]: WebrpcBadRouteError, @@ -1489,35 +1704,89 @@ const webrpcErrorByCode: { [code: number]: any } = { [-5]: WebrpcBadResponseError, [-6]: WebrpcServerPanicError, [-7]: WebrpcInternalErrorError, - [-8]: WebrpcClientDisconnectedError, + [-8]: WebrpcClientAbortedError, [-9]: WebrpcStreamLostError, [-10]: WebrpcStreamFinishedError, - [1000]: UnauthorizedError, - [1001]: PermissionDeniedError, - [1002]: SessionExpiredError, - [1003]: MethodNotFoundError, - [1004]: RequestConflictError, [1005]: AbortedError, - [1006]: GeoblockedError, - [1007]: RateLimitedError, - [1100]: ProjectNotFoundError, - [1101]: AccessKeyNotFoundError, [1102]: AccessKeyMismatchError, + [1101]: AccessKeyNotFoundError, + [1302]: AtLeastOneKeyError, + [1006]: GeoblockedError, + [2001]: InvalidArgumentError, [1103]: InvalidOriginError, [1104]: InvalidServiceError, - [1105]: UnauthorizedUserError, - [1200]: QuotaExceededError, - [1201]: RateLimitError, - [1300]: NoDefaultKeyError, [1301]: MaxAccessKeysError, - [1302]: AtLeastOneKeyError, - [1900]: TimeoutError, - [2001]: InvalidArgumentError, - [2002]: UnavailableError, + [3003]: MetadataCallFailedError, + [1003]: MethodNotFoundError, + [1300]: NoDefaultKeyError, + [3000]: NotFoundError, + [1001]: PermissionDeniedError, + [1100]: ProjectNotFoundError, [2003]: QueryFailedError, + [1200]: QuotaExceededError, + [1201]: RateLimitError, + [1007]: RateLimitedError, + [1004]: RequestConflictError, [2004]: ResourceExhaustedError, - [3000]: NotFoundError, - [3003]: MetadataCallFailedError, + [1002]: SessionExpiredError, + [1900]: TimeoutError, + [1000]: UnauthorizedError, + [1105]: UnauthorizedUserError, + [2002]: UnavailableError } -export type Fetch = (input: RequestInfo, init?: RequestInit) => Promise +// +// Webrpc +// + +export const WebrpcHeader = 'Webrpc' + +export const WebrpcHeaderValue = 'webrpc@v0.31.2;gen-typescript@v0.23.1;sequence-indexer@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 ?? '' + } +} diff --git a/packages/services/indexer/tsconfig.json b/packages/services/indexer/tsconfig.json index fed9c77b49..8623be1c02 100644 --- a/packages/services/indexer/tsconfig.json +++ b/packages/services/indexer/tsconfig.json @@ -3,7 +3,9 @@ "compilerOptions": { "rootDir": "src", "outDir": "dist", - "types": ["node"] + "types": ["node"], + // TODO: enable when webrpc codegen handles noUncheckedIndexedAccess + "noUncheckedIndexedAccess": false }, "include": ["src"], "exclude": ["node_modules", "dist"] diff --git a/packages/services/marketplace/CHANGELOG.md b/packages/services/marketplace/CHANGELOG.md index d180788d1d..321e03b85b 100644 --- a/packages/services/marketplace/CHANGELOG.md +++ b/packages/services/marketplace/CHANGELOG.md @@ -1,5 +1,90 @@ # @0xsequence/marketplace +## 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 diff --git a/packages/services/marketplace/eslint.config.js b/packages/services/marketplace/eslint.config.js new file mode 100644 index 0000000000..cecf89b031 --- /dev/null +++ b/packages/services/marketplace/eslint.config.js @@ -0,0 +1,4 @@ +import { config as baseConfig } from "@repo/eslint-config/base" + +/** @type {import("eslint").Linter.Config} */ +export default baseConfig diff --git a/packages/services/marketplace/package.json b/packages/services/marketplace/package.json index 2f7a1aa36a..39c6be2b68 100644 --- a/packages/services/marketplace/package.json +++ b/packages/services/marketplace/package.json @@ -1,18 +1,20 @@ { "name": "@0xsequence/marketplace", - "version": "3.0.0-beta.9", + "version": "3.0.0", "description": "marketplace sub-package for Sequence", "repository": "https://github.com/0xsequence/sequence.js/tree/master/packages/services/marketplace", - "author": "Sequence Platforms Inc.", + "author": "Sequence Platforms ULC", "license": "Apache-2.0", "publishConfig": { "access": "public" }, + "type": "module", "scripts": { "build": "tsc", "dev": "tsc --watch", "test": "echo", - "typecheck": "tsc --noEmit" + "typecheck": "tsc --noEmit", + "lint": "eslint . --max-warnings 0" }, "exports": { ".": { @@ -21,8 +23,9 @@ } }, "devDependencies": { + "@repo/eslint-config": "workspace:^", "@repo/typescript-config": "workspace:^", - "@types/node": "^25.0.2", + "@types/node": "^25.3.0", "typescript": "^5.9.3" } } diff --git a/packages/services/marketplace/src/index.ts b/packages/services/marketplace/src/index.ts index f7ec2b0d3a..3b67f6f2d6 100644 --- a/packages/services/marketplace/src/index.ts +++ b/packages/services/marketplace/src/index.ts @@ -1,6 +1,6 @@ -export * from './marketplace.gen' +export * from './marketplace.gen.js' -import { Marketplace as MarketplaceRpc } from './marketplace.gen' +import { Marketplace as MarketplaceRpc } from './marketplace.gen.js' export class MarketplaceIndexer extends MarketplaceRpc { constructor( @@ -15,7 +15,7 @@ export class MarketplaceIndexer extends MarketplaceRpc { _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: { [key: string]: any } = {} + const headers: Record = {} const jwtAuth = this.jwtAuth const projectAccessKey = this.projectAccessKey diff --git a/packages/services/metadata/CHANGELOG.md b/packages/services/metadata/CHANGELOG.md index c304a5485b..ca7f29c5d2 100644 --- a/packages/services/metadata/CHANGELOG.md +++ b/packages/services/metadata/CHANGELOG.md @@ -1,5 +1,90 @@ # @0xsequence/metadata +## 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 diff --git a/packages/services/metadata/eslint.config.js b/packages/services/metadata/eslint.config.js new file mode 100644 index 0000000000..cecf89b031 --- /dev/null +++ b/packages/services/metadata/eslint.config.js @@ -0,0 +1,4 @@ +import { config as baseConfig } from "@repo/eslint-config/base" + +/** @type {import("eslint").Linter.Config} */ +export default baseConfig diff --git a/packages/services/metadata/package.json b/packages/services/metadata/package.json index c59c27f41b..d700c0630a 100644 --- a/packages/services/metadata/package.json +++ b/packages/services/metadata/package.json @@ -1,18 +1,20 @@ { "name": "@0xsequence/metadata", - "version": "3.0.0-beta.9", + "version": "3.0.0", "publishConfig": { "access": "public" }, "description": "metadata sub-package for Sequence", "repository": "https://github.com/0xsequence/sequence.js/tree/master/packages/services/metadata", - "author": "Sequence Platforms Inc.", + "author": "Sequence Platforms ULC", "license": "Apache-2.0", + "type": "module", "scripts": { "build": "tsc", "dev": "tsc --watch", "test": "echo", - "typecheck": "tsc --noEmit" + "typecheck": "tsc --noEmit", + "lint": "eslint . --max-warnings 0" }, "exports": { ".": { @@ -21,8 +23,9 @@ } }, "devDependencies": { + "@repo/eslint-config": "workspace:^", "@repo/typescript-config": "workspace:^", - "@types/node": "^25.0.2", + "@types/node": "^25.3.0", "typescript": "^5.9.3" } } diff --git a/packages/services/metadata/src/index.ts b/packages/services/metadata/src/index.ts index 8c620b4246..f9a1a600cc 100644 --- a/packages/services/metadata/src/index.ts +++ b/packages/services/metadata/src/index.ts @@ -1,6 +1,6 @@ -export * from './metadata.gen' +export * from './metadata.gen.js' -import { Metadata as MetadataRpc, Collections as CollectionsRpc } from './metadata.gen' +import { Metadata as MetadataRpc, Collections as CollectionsRpc } from './metadata.gen.js' export class SequenceMetadata extends MetadataRpc { constructor( @@ -15,7 +15,7 @@ export class SequenceMetadata extends MetadataRpc { _fetch = (input: RequestInfo, init?: RequestInit): Promise => { // automatically include jwt and access key auth header to requests // if its been set on the client - const headers: { [key: string]: any } = {} + const headers: Record = {} const jwtAuth = this.jwtAuth const projectAccessKey = this.projectAccessKey @@ -47,7 +47,7 @@ export class SequenceCollections extends CollectionsRpc { _fetch = (input: RequestInfo, init?: RequestInit): Promise => { // automatically include jwt auth header to requests // if its been set on the client - const headers: { [key: string]: any } = {} + const headers: Record = {} const jwtAuth = this.jwtAuth diff --git a/packages/services/relayer/CHANGELOG.md b/packages/services/relayer/CHANGELOG.md index 9fecf4b9cf..c718a845d3 100644 --- a/packages/services/relayer/CHANGELOG.md +++ b/packages/services/relayer/CHANGELOG.md @@ -1,5 +1,131 @@ # @0xsequence/relayer +## 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/wallet-primitives@3.0.0 + +## 3.0.0-beta.19 + +### Patch Changes + +- Final RC before 3.0.0 +- Updated dependencies + - @0xsequence/wallet-primitives@3.0.0-beta.19 + +## 3.0.0-beta.18 + +### Patch Changes + +- multicall3 optimization +- Updated dependencies + - @0xsequence/wallet-primitives@3.0.0-beta.18 + +## 3.0.0-beta.17 + +### Patch Changes + +- New chains, relayer rpc fix +- Updated dependencies + - @0xsequence/wallet-primitives@3.0.0-beta.17 + +## 3.0.0-beta.16 + +### Patch Changes + +- ethauth support +- Updated dependencies + - @0xsequence/wallet-primitives@3.0.0-beta.16 + +## 3.0.0-beta.15 + +### Patch Changes + +- New chains, minor fixes +- Updated dependencies + - @0xsequence/wallet-primitives@3.0.0-beta.15 + +## 3.0.0-beta.14 + +### Patch Changes + +- Relayer fee options fix +- Updated dependencies + - @0xsequence/wallet-primitives@3.0.0-beta.14 + +## 3.0.0-beta.13 + +### Patch Changes + +- Userdata service updates +- Updated dependencies + - @0xsequence/wallet-primitives@3.0.0-beta.13 + +## 3.0.0-beta.12 + +### Patch Changes + +- Beta release with dapp connector fixes +- Updated dependencies + - @0xsequence/wallet-primitives@3.0.0-beta.12 + +## 3.0.0-beta.11 + +### Patch Changes + +- 3.0.0 beta +- Updated dependencies + - @0xsequence/wallet-primitives@3.0.0-beta.11 + +## 3.0.0-beta.10 + +### Patch Changes + +- dapp-client updates +- Updated dependencies + - @0xsequence/wallet-primitives@3.0.0-beta.10 + ## 3.0.0-beta.9 ### Patch Changes diff --git a/packages/services/relayer/eslint.config.js b/packages/services/relayer/eslint.config.js new file mode 100644 index 0000000000..cecf89b031 --- /dev/null +++ b/packages/services/relayer/eslint.config.js @@ -0,0 +1,4 @@ +import { config as baseConfig } from "@repo/eslint-config/base" + +/** @type {import("eslint").Linter.Config} */ +export default baseConfig diff --git a/packages/services/relayer/package.json b/packages/services/relayer/package.json index 4f30550c16..ab7f8d8cb0 100644 --- a/packages/services/relayer/package.json +++ b/packages/services/relayer/package.json @@ -1,13 +1,13 @@ { "name": "@0xsequence/relayer", - "version": "3.0.0-beta.9", + "version": "3.0.0", "type": "module", "publishConfig": { "access": "public" }, "description": "relayer sub-package for Sequence", "repository": "https://github.com/0xsequence/sequence.js/tree/master/packages/services/relayer", - "author": "Sequence Platforms Inc.", + "author": "Sequence Platforms ULC", "license": "Apache-2.0", "scripts": { "build": "tsc", @@ -17,7 +17,8 @@ "old-test:file": "NODE_OPTIONS='--import tsx' mocha --timeout 60000", "old-test:concurrently": "concurrently -k --success first 'pnpm start:hardhat > /dev/null' ", "start:hardhat": "pnpm hardhat node --port 9547", - "typecheck": "tsc --noEmit" + "typecheck": "tsc --noEmit", + "lint": "eslint . --max-warnings 0" }, "exports": { ".": { @@ -26,10 +27,11 @@ } }, "devDependencies": { + "@repo/eslint-config": "workspace:^", "@repo/typescript-config": "workspace:^", - "@types/node": "^25.0.2", + "@types/node": "^25.3.0", "typescript": "^5.9.3", - "vitest": "^4.0.15" + "vitest": "^4.0.18" }, "dependencies": { "@0xsequence/wallet-primitives": "workspace:^", diff --git a/packages/services/relayer/src/preconditions/codec.ts b/packages/services/relayer/src/preconditions/codec.ts index 74f83154be..b59fae6d67 100644 --- a/packages/services/relayer/src/preconditions/codec.ts +++ b/packages/services/relayer/src/preconditions/codec.ts @@ -36,6 +36,11 @@ export function decodePrecondition(p: TransactionPrecondition): Precondition | u return undefined } + if (typeof p.minAmount !== 'bigint') { + console.warn(`Failed to decode precondition: minAmount must be a bigint`) + return undefined + } + let precondition: Precondition | undefined try { @@ -118,73 +123,92 @@ export function decodePrecondition(p: TransactionPrecondition): Precondition | u } export function encodePrecondition(p: Precondition): string { - const data: any = {} - switch (p.type()) { case 'native-balance': { const native = p as NativeBalancePrecondition - data.address = native.address.toString() - if (native.min !== undefined) data.min = native.min.toString() - if (native.max !== undefined) data.max = native.max.toString() - break + const data = { + address: native.address.toString(), + ...(native.min !== undefined && { min: native.min.toString() }), + ...(native.max !== undefined && { max: native.max.toString() }), + } + + return JSON.stringify(data) } case 'erc20-balance': { const erc20 = p as Erc20BalancePrecondition - data.address = erc20.address.toString() - data.token = erc20.token.toString() - if (erc20.min !== undefined) data.min = erc20.min.toString() - if (erc20.max !== undefined) data.max = erc20.max.toString() - break + const data = { + address: erc20.address.toString(), + token: erc20.token.toString(), + ...(erc20.min !== undefined && { min: erc20.min.toString() }), + ...(erc20.max !== undefined && { max: erc20.max.toString() }), + } + + return JSON.stringify(data) } case 'erc20-approval': { const erc20 = p as Erc20ApprovalPrecondition - data.address = erc20.address.toString() - data.token = erc20.token.toString() - data.operator = erc20.operator.toString() - data.min = erc20.min.toString() - break + const data = { + address: erc20.address.toString(), + token: erc20.token.toString(), + operator: erc20.operator.toString(), + min: erc20.min.toString(), + } + + return JSON.stringify(data) } case 'erc721-ownership': { const erc721 = p as Erc721OwnershipPrecondition - data.address = erc721.address.toString() - data.token = erc721.token.toString() - data.tokenId = erc721.tokenId.toString() - if (erc721.owned !== undefined) data.owned = erc721.owned - break + const data = { + address: erc721.address.toString(), + token: erc721.token.toString(), + tokenId: erc721.tokenId.toString(), + ...(erc721.owned !== undefined && { owned: erc721.owned }), + } + + return JSON.stringify(data) } case 'erc721-approval': { const erc721 = p as Erc721ApprovalPrecondition - data.address = erc721.address.toString() - data.token = erc721.token.toString() - data.tokenId = erc721.tokenId.toString() - data.operator = erc721.operator.toString() - break + const data = { + address: erc721.address.toString(), + token: erc721.token.toString(), + tokenId: erc721.tokenId.toString(), + operator: erc721.operator.toString(), + } + + return JSON.stringify(data) } case 'erc1155-balance': { const erc1155 = p as Erc1155BalancePrecondition - data.address = erc1155.address.toString() - data.token = erc1155.token.toString() - data.tokenId = erc1155.tokenId.toString() - if (erc1155.min !== undefined) data.min = erc1155.min.toString() - if (erc1155.max !== undefined) data.max = erc1155.max.toString() - break + const data = { + address: erc1155.address.toString(), + token: erc1155.token.toString(), + tokenId: erc1155.tokenId.toString(), + ...(erc1155.min !== undefined && { min: erc1155.min.toString() }), + ...(erc1155.max !== undefined && { max: erc1155.max.toString() }), + } + + return JSON.stringify(data) } case 'erc1155-approval': { const erc1155 = p as Erc1155ApprovalPrecondition - data.address = erc1155.address.toString() - data.token = erc1155.token.toString() - data.tokenId = erc1155.tokenId.toString() - data.operator = erc1155.operator.toString() - data.min = erc1155.min.toString() - break + const data = { + address: erc1155.address.toString(), + token: erc1155.token.toString(), + tokenId: erc1155.tokenId.toString(), + operator: erc1155.operator.toString(), + min: erc1155.min.toString(), + } + + return JSON.stringify(data) } } - return JSON.stringify(data) + return JSON.stringify({}) } diff --git a/packages/services/relayer/src/relayer/relayer.ts b/packages/services/relayer/src/relayer/relayer.ts index 3ed5a69627..f685368200 100644 --- a/packages/services/relayer/src/relayer/relayer.ts +++ b/packages/services/relayer/src/relayer/relayer.ts @@ -16,6 +16,7 @@ export interface Relayer { feeOptions( wallet: Address.Address, chainId: number, + to: Address.Address, calls: Payload.Call[], ): Promise<{ options: FeeOption[]; quote?: FeeQuote }> @@ -26,8 +27,10 @@ export interface Relayer { checkPrecondition(precondition: Precondition.Precondition): Promise } -export function isRelayer(relayer: any): relayer is Relayer { +export function isRelayer(relayer: unknown): relayer is Relayer { return ( + typeof relayer === 'object' && + relayer !== null && 'isAvailable' in relayer && 'feeOptions' in relayer && 'relay' in relayer && diff --git a/packages/services/relayer/src/relayer/rpc-relayer/index.ts b/packages/services/relayer/src/relayer/rpc-relayer/index.ts index 04db6aa40c..e045b996e0 100644 --- a/packages/services/relayer/src/relayer/rpc-relayer/index.ts +++ b/packages/services/relayer/src/relayer/rpc-relayer/index.ts @@ -7,10 +7,19 @@ import { TransactionPrecondition, ETHTxnStatus, } from './relayer.gen.js' -import { Address, Hex, Bytes, AbiFunction } from 'ox' +import { Address, Hex, AbiFunction } from 'ox' import { Constants, Payload, Network } from '@0xsequence/wallet-primitives' import { FeeOption, FeeQuote, OperationStatus, Relayer } from '../index.js' -import { decodePrecondition } from '../../preconditions/index.js' +import { + decodePrecondition, + Erc1155ApprovalPrecondition, + Erc1155BalancePrecondition, + Erc20ApprovalPrecondition, + Erc20BalancePrecondition, + Erc721ApprovalPrecondition, + Erc721OwnershipPrecondition, + NativeBalancePrecondition, +} from '../../preconditions/index.js' import { erc20BalanceOf, erc20Allowance, @@ -49,12 +58,14 @@ const networkToChain = (network: Network.Network): Chain => { }, } : undefined, - contracts: network.ensAddress - ? { - ensUniversalResolver: { - address: network.ensAddress as `0x${string}`, + contracts: network.contracts + ? Object.entries(network.contracts).reduce( + (acc, [name, address]) => { + acc[name] = { address } + return acc }, - } + {} as Record, + ) : undefined, } as Chain } @@ -67,7 +78,9 @@ export const getChain = (chainId: number): Chain => { } // Fall back to viem's built-in chains - const viemChain = Object.values(chains).find((c: any) => typeof c === 'object' && 'id' in c && c.id === chainId) + const viemChain = Object.values(chains).find( + (c: unknown) => typeof c === 'object' && c !== null && 'id' in c && c.id === chainId, + ) if (viemChain) { return viemChain as Chain } @@ -76,7 +89,7 @@ export const getChain = (chainId: number): Chain => { } export class RpcRelayer implements Relayer { - public readonly kind: 'relayer' = 'relayer' + public readonly kind = 'relayer' public readonly type = 'rpc' public readonly id: string public readonly chainId: number @@ -134,17 +147,24 @@ export class RpcRelayer implements Relayer { async feeOptions( wallet: Address.Address, chainId: number, + to: Address.Address, calls: Payload.Call[], ): Promise<{ options: FeeOption[]; quote?: FeeQuote }> { + // IMPORTANT: + // The relayer FeeOptions endpoint simulates `eth_call(to, data)`. + // wallet-webapp-v3 requests FeeOptions with `to = wallet` and `data = Payload.encode(calls, self=wallet)`. + // This works for undeployed wallets and avoids guest-module simulation pitfalls. const callsStruct: Payload.Calls = { type: 'call', space: 0n, nonce: 0n, calls: calls } - const data = Payload.encode(callsStruct) + + const feeOptionsTo = wallet + const data = Payload.encode(callsStruct, wallet) try { const result = await this.client.feeOptions( { - wallet: wallet, - to: wallet, - data: Bytes.toHex(data), + wallet, + to: feeOptionsTo, + data: Hex.fromBytes(data), }, { ...(this.projectAccessKey ? { 'X-Access-Key': this.projectAccessKey } : undefined) }, ) @@ -230,7 +250,7 @@ export class RpcRelayer implements Relayer { return { opHash: `0x${result.txnHash}` } } - async status(opHash: Hex.Hex, chainId: number): Promise { + async status(opHash: Hex.Hex, _chainId: number): Promise { try { const cleanedOpHash = opHash.startsWith('0x') ? opHash.substring(2) : opHash const result = await this.client.getMetaTxnReceipt({ metaTxID: cleanedOpHash }) @@ -282,9 +302,9 @@ export class RpcRelayer implements Relayer { switch (decoded.type()) { case 'native-balance': { - const native = decoded as any + const native = decoded as NativeBalancePrecondition try { - const balance = await this.provider.getBalance({ address: native.address.toString() as `0x${string}` }) + const balance = await this.provider.getBalance({ address: native.address }) const minWei = native.min !== undefined ? BigInt(native.min) : undefined const maxWei = native.max !== undefined ? BigInt(native.max) : undefined @@ -307,9 +327,9 @@ export class RpcRelayer implements Relayer { } case 'erc20-balance': { - const erc20 = decoded as any + const erc20 = decoded as Erc20BalancePrecondition try { - const data = AbiFunction.encodeData(erc20BalanceOf, [erc20.address.toString()]) + const data = AbiFunction.encodeData(erc20BalanceOf, [erc20.address]) const result = await this.provider.call({ to: erc20.token.toString() as `0x${string}`, data: data as `0x${string}`, @@ -336,9 +356,9 @@ export class RpcRelayer implements Relayer { } case 'erc20-approval': { - const erc20 = decoded as any + const erc20 = decoded as Erc20ApprovalPrecondition try { - const data = AbiFunction.encodeData(erc20Allowance, [erc20.address.toString(), erc20.operator.toString()]) + const data = AbiFunction.encodeData(erc20Allowance, [erc20.address, erc20.operator]) const result = await this.provider.call({ to: erc20.token.toString() as `0x${string}`, data: data as `0x${string}`, @@ -353,12 +373,12 @@ export class RpcRelayer implements Relayer { } case 'erc721-ownership': { - const erc721 = decoded as any + const erc721 = decoded as Erc721OwnershipPrecondition try { const data = AbiFunction.encodeData(erc721OwnerOf, [erc721.tokenId]) const result = await this.provider.call({ - to: erc721.token.toString() as `0x${string}`, - data: data as `0x${string}`, + to: erc721.token, + data: data, }) const resultHex = result.toString() as `0x${string}` const owner = resultHex.slice(-40) @@ -372,7 +392,7 @@ export class RpcRelayer implements Relayer { } case 'erc721-approval': { - const erc721 = decoded as any + const erc721 = decoded as Erc721ApprovalPrecondition try { const data = AbiFunction.encodeData(erc721GetApproved, [erc721.tokenId]) const result = await this.provider.call({ @@ -389,9 +409,9 @@ export class RpcRelayer implements Relayer { } case 'erc1155-balance': { - const erc1155 = decoded as any + const erc1155 = decoded as Erc1155BalancePrecondition try { - const data = AbiFunction.encodeData(erc1155BalanceOf, [erc1155.address.toString(), erc1155.tokenId]) + const data = AbiFunction.encodeData(erc1155BalanceOf, [erc1155.address, erc1155.tokenId]) const result = await this.provider.call({ to: erc1155.token.toString() as `0x${string}`, data: data as `0x${string}`, @@ -418,15 +438,12 @@ export class RpcRelayer implements Relayer { } case 'erc1155-approval': { - const erc1155 = decoded as any + const erc1155 = decoded as Erc1155ApprovalPrecondition try { - const data = AbiFunction.encodeData(erc1155IsApprovedForAll, [ - erc1155.address.toString(), - erc1155.operator.toString(), - ]) + const data = AbiFunction.encodeData(erc1155IsApprovedForAll, [erc1155.address, erc1155.operator]) const result = await this.provider.call({ - to: erc1155.token.toString() as `0x${string}`, - data: data as `0x${string}`, + to: erc1155.token, + data: data, }) return BigInt(result.toString()) === 1n } catch (error) { diff --git a/packages/services/relayer/src/relayer/standard/eip6963.ts b/packages/services/relayer/src/relayer/standard/eip6963.ts index 9d48613633..a290b2c6f9 100644 --- a/packages/services/relayer/src/relayer/standard/eip6963.ts +++ b/packages/services/relayer/src/relayer/standard/eip6963.ts @@ -6,7 +6,7 @@ import { Payload } from '@0xsequence/wallet-primitives' import { FeeToken, TransactionPrecondition } from '../rpc-relayer/relayer.gen.js' export class EIP6963Relayer implements Relayer { - public readonly kind: 'relayer' = 'relayer' + public readonly kind = 'relayer' public readonly type = 'eip6963' public readonly id: string public readonly info: EIP6963ProviderInfo @@ -30,9 +30,10 @@ export class EIP6963Relayer implements Relayer { feeOptions( wallet: Address.Address, chainId: number, + to: Address.Address, calls: Payload.Call[], ): Promise<{ options: FeeOption[]; quote?: FeeQuote }> { - return this.relayer.feeOptions(wallet, chainId, calls) + return this.relayer.feeOptions(wallet, chainId, to, calls) } async relay(to: Address.Address, data: Hex.Hex, chainId: number, _?: FeeQuote): Promise<{ opHash: Hex.Hex }> { @@ -58,7 +59,7 @@ export function getEIP6963Store() { return store } -let relayers: Map = new Map() +const relayers: Map = new Map() export function getRelayers(): EIP6963Relayer[] { const store = getEIP6963Store() diff --git a/packages/services/relayer/src/relayer/standard/local.ts b/packages/services/relayer/src/relayer/standard/local.ts index 14d697aa23..4135af3b30 100644 --- a/packages/services/relayer/src/relayer/standard/local.ts +++ b/packages/services/relayer/src/relayer/standard/local.ts @@ -1,9 +1,18 @@ -import { Constants, Payload } from '@0xsequence/wallet-primitives' +import { Payload } from '@0xsequence/wallet-primitives' import { EIP1193Provider } from 'mipd' -import { AbiFunction, Address, Bytes, Hex, TransactionReceipt } from 'ox' +import { AbiFunction, Address, Hex, TransactionReceipt } from 'ox' import { FeeOption, FeeQuote, OperationStatus, Relayer } from '../index.js' import { FeeToken, TransactionPrecondition } from '../rpc-relayer/relayer.gen.js' -import { decodePrecondition } from '../../preconditions/index.js' +import { + decodePrecondition, + Erc1155ApprovalPrecondition, + Erc1155BalancePrecondition, + Erc20ApprovalPrecondition, + Erc20BalancePrecondition, + Erc721ApprovalPrecondition, + Erc721OwnershipPrecondition, + NativeBalancePrecondition, +} from '../../preconditions/index.js' import { erc20BalanceOf, erc20Allowance, @@ -23,7 +32,7 @@ export interface GenericProvider { } export class LocalRelayer implements Relayer { - public readonly kind: 'relayer' = 'relayer' + public readonly kind = 'relayer' public readonly type = 'local' public readonly id = 'local' @@ -34,7 +43,7 @@ export class LocalRelayer implements Relayer { } static createFromWindow(window: Window): LocalRelayer | undefined { - const eth = (window as any).ethereum + const eth = (window as { ethereum?: EIP1193Provider }).ethereum if (!eth) { console.warn('Window.ethereum not found, skipping local relayer') return undefined @@ -54,27 +63,14 @@ export class LocalRelayer implements Relayer { } feeOptions( - wallet: Address.Address, - chainId: number, - calls: Payload.Call[], + _wallet: Address.Address, + _chainId: number, + _to: Address.Address, + _calls: Payload.Call[], ): Promise<{ options: FeeOption[]; quote?: FeeQuote }> { return Promise.resolve({ options: [] }) } - private decodeCalls(data: Hex.Hex): Payload.Calls { - const executeSelector = AbiFunction.getSelector(Constants.EXECUTE) - - let packedPayload - if (data.startsWith(executeSelector)) { - const decode = AbiFunction.decodeData(Constants.EXECUTE, data) - packedPayload = decode[0] - } else { - packedPayload = data - } - - return Payload.decode(Bytes.fromHex(packedPayload)) - } - async relay( to: Address.Address, data: Hex.Hex, @@ -177,8 +173,8 @@ export class LocalRelayer implements Relayer { switch (decoded.type()) { case 'native-balance': { - const native = decoded as any - const balance = await this.provider.getBalance(native.address.toString()) + const native = decoded as NativeBalancePrecondition + const balance = await this.provider.getBalance(native.address) if (native.min !== undefined && balance < native.min) { return false } @@ -189,10 +185,10 @@ export class LocalRelayer implements Relayer { } case 'erc20-balance': { - const erc20 = decoded as any - const data = AbiFunction.encodeData(erc20BalanceOf, [erc20.address.toString()]) + const erc20 = decoded as Erc20BalancePrecondition + const data = AbiFunction.encodeData(erc20BalanceOf, [erc20.address]) const result = await this.provider.call({ - to: erc20.token.toString(), + to: erc20.token, data, }) const balance = BigInt(result) @@ -206,10 +202,10 @@ export class LocalRelayer implements Relayer { } case 'erc20-approval': { - const erc20 = decoded as any - const data = AbiFunction.encodeData(erc20Allowance, [erc20.address.toString(), erc20.operator.toString()]) + const erc20 = decoded as Erc20ApprovalPrecondition + const data = AbiFunction.encodeData(erc20Allowance, [erc20.address, erc20.operator]) const result = await this.provider.call({ - to: erc20.token.toString(), + to: erc20.token, data, }) const allowance = BigInt(result) @@ -217,10 +213,10 @@ export class LocalRelayer implements Relayer { } case 'erc721-ownership': { - const erc721 = decoded as any + const erc721 = decoded as Erc721OwnershipPrecondition const data = AbiFunction.encodeData(erc721OwnerOf, [erc721.tokenId]) const result = await this.provider.call({ - to: erc721.token.toString(), + to: erc721.token, data, }) const owner = '0x' + result.slice(26) @@ -229,10 +225,10 @@ export class LocalRelayer implements Relayer { } case 'erc721-approval': { - const erc721 = decoded as any + const erc721 = decoded as Erc721ApprovalPrecondition const data = AbiFunction.encodeData(erc721GetApproved, [erc721.tokenId]) const result = await this.provider.call({ - to: erc721.token.toString(), + to: erc721.token, data, }) const approved = '0x' + result.slice(26) @@ -240,10 +236,10 @@ export class LocalRelayer implements Relayer { } case 'erc1155-balance': { - const erc1155 = decoded as any - const data = AbiFunction.encodeData(erc1155BalanceOf, [erc1155.address.toString(), erc1155.tokenId]) + const erc1155 = decoded as Erc1155BalancePrecondition + const data = AbiFunction.encodeData(erc1155BalanceOf, [erc1155.address, erc1155.tokenId]) const result = await this.provider.call({ - to: erc1155.token.toString(), + to: erc1155.token, data, }) const balance = BigInt(result) @@ -257,13 +253,10 @@ export class LocalRelayer implements Relayer { } case 'erc1155-approval': { - const erc1155 = decoded as any - const data = AbiFunction.encodeData(erc1155IsApprovedForAll, [ - erc1155.address.toString(), - erc1155.operator.toString(), - ]) + const erc1155 = decoded as Erc1155ApprovalPrecondition + const data = AbiFunction.encodeData(erc1155IsApprovedForAll, [erc1155.address, erc1155.operator]) const result = await this.provider.call({ - to: erc1155.token.toString(), + to: erc1155.token, data, }) return BigInt(result) === 1n @@ -340,7 +333,7 @@ export class EIP1193ProviderAdapter implements GenericProvider { const rpcReceipt = await this.provider.request({ method: 'eth_getTransactionReceipt', params: [txHash] }) if (rpcReceipt) { - const receipt = TransactionReceipt.fromRpc(rpcReceipt as any) + const receipt = TransactionReceipt.fromRpc(rpcReceipt as Parameters[0]) if (receipt?.status === 'success') { return 'success' } else if (receipt?.status === 'reverted') { diff --git a/packages/services/relayer/src/relayer/standard/pk-relayer.ts b/packages/services/relayer/src/relayer/standard/pk-relayer.ts index 37b2e5a08a..b1d420a586 100644 --- a/packages/services/relayer/src/relayer/standard/pk-relayer.ts +++ b/packages/services/relayer/src/relayer/standard/pk-relayer.ts @@ -5,7 +5,7 @@ import { FeeOption, FeeQuote, OperationStatus, Relayer } from '../index.js' import { FeeToken } from '../rpc-relayer/relayer.gen.js' export class PkRelayer implements Relayer { - public readonly kind: 'relayer' = 'relayer' + public readonly kind = 'relayer' public readonly type = 'pk' public readonly id = 'pk' private readonly relayer: LocalRelayer @@ -114,9 +114,10 @@ export class PkRelayer implements Relayer { feeOptions( wallet: Address.Address, chainId: number, + to: Address.Address, calls: Payload.Call[], ): Promise<{ options: FeeOption[]; quote?: FeeQuote }> { - return this.relayer.feeOptions(wallet, chainId, calls) + return this.relayer.feeOptions(wallet, chainId, to, calls) } async relay(to: Address.Address, data: Hex.Hex, chainId: number, _?: FeeQuote): Promise<{ opHash: Hex.Hex }> { @@ -131,7 +132,7 @@ export class PkRelayer implements Relayer { return this.relayer.status(opHash, chainId) } - async checkPrecondition(precondition: Precondition.Precondition): Promise { + async checkPrecondition(_precondition: Precondition.Precondition): Promise { // TODO: Implement precondition check return true } diff --git a/packages/services/relayer/src/relayer/standard/sequence.ts b/packages/services/relayer/src/relayer/standard/sequence.ts index 5c0bd16632..bb55a97262 100644 --- a/packages/services/relayer/src/relayer/standard/sequence.ts +++ b/packages/services/relayer/src/relayer/standard/sequence.ts @@ -3,7 +3,7 @@ import { Payload } from '@0xsequence/wallet-primitives' import { AbiFunction, Address, Bytes, Hex } from 'ox' import { FeeOption, FeeQuote, OperationStatus, Relayer } from '../index.js' export class SequenceRelayer implements Relayer { - public readonly kind: 'relayer' = 'relayer' + public readonly kind = 'relayer' public readonly type = 'sequence' readonly id = 'sequence' @@ -36,9 +36,9 @@ export class SequenceRelayer implements Relayer { async feeOptions( wallet: Address.Address, _chainId: number, + to: Address.Address, calls: Payload.Call[], ): Promise<{ options: FeeOption[]; quote?: FeeQuote }> { - const to = wallet // TODO: this might be the guest module const execute = AbiFunction.from('function execute(bytes calldata _payload, bytes calldata _signature)') const payload = Payload.encode({ type: 'call', space: 0n, nonce: 0n, calls }, to) const signature = '0x0001' // TODO: use a stub signature @@ -52,7 +52,7 @@ export class SequenceRelayer implements Relayer { } } - async checkPrecondition(precondition: TransactionPrecondition): Promise { + async checkPrecondition(_precondition: TransactionPrecondition): Promise { // TODO: implement return false } diff --git a/packages/services/relayer/test/preconditions/codec.test.ts b/packages/services/relayer/test/preconditions/codec.test.ts index 88d442510a..a5ba279d39 100644 --- a/packages/services/relayer/test/preconditions/codec.test.ts +++ b/packages/services/relayer/test/preconditions/codec.test.ts @@ -36,8 +36,8 @@ describe('Preconditions Codec', () => { describe('decodePrecondition', () => { it('should return undefined for null/undefined input', () => { - expect(decodePrecondition(null as any)).toBeUndefined() - expect(decodePrecondition(undefined as any)).toBeUndefined() + expect(decodePrecondition(null as unknown as TransactionPrecondition)).toBeUndefined() + expect(decodePrecondition(undefined as unknown as TransactionPrecondition)).toBeUndefined() }) it('should decode native balance precondition with only min', () => { @@ -231,8 +231,8 @@ describe('Preconditions Codec', () => { it('should handle malformed addresses gracefully', () => { const intent: TransactionPrecondition = { type: 'native-balance', - ownerAddress: 'invalid-address' as any, - tokenAddress: NATIVE_TOKEN_ADDRESS, + ownerAddress: 'invalid-address', + tokenAddress: NATIVE_TOKEN_ADDRESS.toString(), chainId: ARBITRUM_CHAIN_ID, minAmount: BigInt('1000000000000000000'), } @@ -243,13 +243,13 @@ describe('Preconditions Codec', () => { }) it('should handle malformed BigInt values gracefully', () => { - const intent: TransactionPrecondition = { + const intent = { type: 'native-balance', - ownerAddress: TEST_ADDRESS, - tokenAddress: NATIVE_TOKEN_ADDRESS, + ownerAddress: TEST_ADDRESS.toString(), + tokenAddress: NATIVE_TOKEN_ADDRESS.toString(), chainId: ARBITRUM_CHAIN_ID, - minAmount: 'not-a-number' as any, - } + minAmount: 'not-a-number', + } as unknown as TransactionPrecondition const result = decodePrecondition(intent) expect(result).toBeUndefined() @@ -316,8 +316,8 @@ describe('Preconditions Codec', () => { }, { type: 'native-balance', - ownerAddress: 'invalid-address' as any, - tokenAddress: NATIVE_TOKEN_ADDRESS, + ownerAddress: 'invalid-address', + tokenAddress: NATIVE_TOKEN_ADDRESS.toString(), chainId: ARBITRUM_CHAIN_ID, minAmount: BigInt('1000000000000000000'), }, diff --git a/packages/services/relayer/test/preconditions/preconditions.test.ts b/packages/services/relayer/test/preconditions/preconditions.test.ts index e4975daaf9..0fd12b7f77 100644 --- a/packages/services/relayer/test/preconditions/preconditions.test.ts +++ b/packages/services/relayer/test/preconditions/preconditions.test.ts @@ -1,4 +1,4 @@ -import { Address, Provider, RpcTransport, Secp256k1 } from 'ox' +import { Address, Hex, Secp256k1 } from 'ox' import { describe, expect, it, vi } from 'vitest' import { Erc1155ApprovalPrecondition, @@ -9,49 +9,50 @@ import { Erc721OwnershipPrecondition, NativeBalancePrecondition, } from '../../src/preconditions/types.js' -import { LocalRelayer } from '../../src/standard/local.js' -import { CAN_RUN_LIVE, RPC_URL } from '../../../../wallet/core/test/constants' +import { + LocalRelayer, + type GenericProvider, +} from '../../src/relayer/standard/local.js' import { Network } from '@0xsequence/wallet-primitives' +const CAN_RUN_LIVE = false +const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000' const ERC20_IMPLICIT_MINT_CONTRACT = '0x041E0CDC028050519C8e6485B2d9840caf63773F' function randomAddress(): Address.Address { return Address.fromPublicKey(Secp256k1.getPublicKey({ privateKey: Secp256k1.randomPrivateKey() })) } +function createMockProvider(): GenericProvider { + return { + sendTransaction: vi.fn(), + getBalance: vi.fn(), + call: vi.fn(), + getTransactionReceipt: vi.fn(), + } +} + describe('Preconditions', () => { - const getProvider = async (): Promise<{ provider: Provider.Provider; chainId: number }> => { - let provider: Provider.Provider - let chainId: number = Network.ChainId.MAINNET + const getProvider = async (): Promise<{ provider: GenericProvider; chainId: number }> => { + const chainId = Network.ChainId.MAINNET if (CAN_RUN_LIVE) { - provider = Provider.from(RpcTransport.fromHttp(RPC_URL!!)) - chainId = Number(await provider.request({ method: 'eth_chainId' })) - } else { - provider = { - request: vi.fn(), - on: vi.fn(), - removeListener: vi.fn(), - call: vi.fn(), - sendTransaction: vi.fn(), - getBalance: vi.fn(), - } as unknown as Provider.Provider + throw new Error('Live tests not configured: set up RPC and GenericProvider adapter') } - - return { provider: provider!, chainId } + const provider = createMockProvider() + return { provider, chainId } } const testWalletAddress = randomAddress() - const requireContractDeployed = async (provider: Provider.Provider, contract: Address.Address) => { - const code = await provider.request({ method: 'eth_getCode', params: [contract, 'latest'] }) - if (code === '0x') { - throw new Error(`Contract ${contract} not deployed`) + const requireContractDeployed = async (_provider: GenericProvider, _contract: Address.Address) => { + if (CAN_RUN_LIVE) { + throw new Error('Live contract check not implemented') } } it('should create and check native balance precondition', async () => { const { provider, chainId } = await getProvider() - const relayer = new LocalRelayer(provider as any) + const relayer = new LocalRelayer(provider) const precondition = new NativeBalancePrecondition( testWalletAddress, @@ -59,225 +60,183 @@ describe('Preconditions', () => { 2000000000000000000n, // 2 ETH max ) - const intentPrecondition = { + const transactionPrecondition = { type: precondition.type(), - chainId: chainId.toString(), - data: JSON.stringify({ - address: precondition.address.toString(), - min: precondition.min?.toString(), - max: precondition.max?.toString(), - }), + chainId, + ownerAddress: precondition.address.toString(), + tokenAddress: ZERO_ADDRESS, + minAmount: precondition.min ?? 0n, } - if (!CAN_RUN_LIVE) { - // Mock the balance check - ;(provider as any).request.mockResolvedValue('0x16345785d8a0000') // 1.5 ETH in hex - } + vi.mocked(provider.getBalance).mockResolvedValue(1500000000000000000n) // 1.5 ETH - const isValid = await relayer.checkPrecondition(intentPrecondition) + const isValid = await relayer.checkPrecondition(transactionPrecondition) expect(isValid).toBe(true) }) it('should create and check ERC20 balance precondition', async () => { const { provider, chainId } = await getProvider() - const relayer = new LocalRelayer(provider as any) - await requireContractDeployed(provider, ERC20_IMPLICIT_MINT_CONTRACT) + const relayer = new LocalRelayer(provider) + await requireContractDeployed(provider, Address.from(ERC20_IMPLICIT_MINT_CONTRACT)) const precondition = new Erc20BalancePrecondition( testWalletAddress, - ERC20_IMPLICIT_MINT_CONTRACT, + Address.from(ERC20_IMPLICIT_MINT_CONTRACT), 1000000n, // 1 token min 2000000n, // 2 tokens max ) - const intentPrecondition = { + const transactionPrecondition = { type: precondition.type(), - chainId: chainId.toString(), - data: JSON.stringify({ - address: precondition.address.toString(), - token: precondition.token.toString(), - min: precondition.min?.toString(), - max: precondition.max?.toString(), - }), + chainId, + ownerAddress: precondition.address.toString(), + tokenAddress: precondition.token.toString(), + minAmount: precondition.min ?? 0n, } - if (!CAN_RUN_LIVE) { - // Mock the balanceOf call - ;(provider as any).call.mockResolvedValue('0x1e8480') // 1.5 tokens in hex - } + vi.mocked(provider.call).mockResolvedValue('0x1e8480' as Hex.Hex) // 1.5 tokens in hex - const isValid = await relayer.checkPrecondition(intentPrecondition) + const isValid = await relayer.checkPrecondition(transactionPrecondition) expect(isValid).toBe(true) }) it('should create and check ERC20 approval precondition', async () => { const { provider, chainId } = await getProvider() - const relayer = new LocalRelayer(provider as any) - await requireContractDeployed(provider, ERC20_IMPLICIT_MINT_CONTRACT) + const relayer = new LocalRelayer(provider) + await requireContractDeployed(provider, Address.from(ERC20_IMPLICIT_MINT_CONTRACT)) const operator = randomAddress() const precondition = new Erc20ApprovalPrecondition( testWalletAddress, - ERC20_IMPLICIT_MINT_CONTRACT, + Address.from(ERC20_IMPLICIT_MINT_CONTRACT), operator, 1000000n, // 1 token min approval ) - const intentPrecondition = { + const transactionPrecondition = { type: precondition.type(), - chainId: chainId.toString(), - data: JSON.stringify({ - address: precondition.address.toString(), - token: precondition.token.toString(), - operator: precondition.operator.toString(), - min: precondition.min.toString(), - }), + chainId, + ownerAddress: precondition.address.toString(), + tokenAddress: precondition.token.toString(), + minAmount: precondition.min, } - if (!CAN_RUN_LIVE) { - // Mock the allowance call - ;(provider as any).call.mockResolvedValue('0x1e8480') // 1.5 tokens in hex - } + vi.mocked(provider.call).mockResolvedValue('0x1e8480' as Hex.Hex) // 1.5 tokens in hex - const isValid = await relayer.checkPrecondition(intentPrecondition) + const isValid = await relayer.checkPrecondition(transactionPrecondition) expect(isValid).toBe(true) }) it('should create and check ERC721 ownership precondition', async () => { const { provider, chainId } = await getProvider() - const relayer = new LocalRelayer(provider as any) - await requireContractDeployed(provider, ERC20_IMPLICIT_MINT_CONTRACT) + const relayer = new LocalRelayer(provider) + await requireContractDeployed(provider, Address.from(ERC20_IMPLICIT_MINT_CONTRACT)) const precondition = new Erc721OwnershipPrecondition( testWalletAddress, - ERC20_IMPLICIT_MINT_CONTRACT, + Address.from(ERC20_IMPLICIT_MINT_CONTRACT), 1n, // tokenId true, // must own ) - const intentPrecondition = { + const transactionPrecondition = { type: precondition.type(), - chainId: chainId.toString(), - data: JSON.stringify({ - address: precondition.address.toString(), - token: precondition.token.toString(), - tokenId: precondition.tokenId.toString(), - owned: precondition.owned, - }), + chainId, + ownerAddress: precondition.address.toString(), + tokenAddress: precondition.token.toString(), + minAmount: 0n, } - if (!CAN_RUN_LIVE) { - // Mock the ownerOf call - ;(provider as any).call.mockResolvedValue( - '0x000000000000000000000000' + testWalletAddress.toString().slice(2).toLowerCase(), - ) - } + vi.mocked(provider.call).mockResolvedValue( + ('0x000000000000000000000000' + testWalletAddress.toString().slice(2).toLowerCase()) as Hex.Hex, + ) - const isValid = await relayer.checkPrecondition(intentPrecondition) + const isValid = await relayer.checkPrecondition(transactionPrecondition) expect(isValid).toBe(true) }) it('should create and check ERC721 approval precondition', async () => { const { provider, chainId } = await getProvider() - const relayer = new LocalRelayer(provider as any) - await requireContractDeployed(provider, ERC20_IMPLICIT_MINT_CONTRACT) + const relayer = new LocalRelayer(provider) + await requireContractDeployed(provider, Address.from(ERC20_IMPLICIT_MINT_CONTRACT)) const operator = randomAddress() const precondition = new Erc721ApprovalPrecondition( testWalletAddress, - ERC20_IMPLICIT_MINT_CONTRACT, + Address.from(ERC20_IMPLICIT_MINT_CONTRACT), 1n, // tokenId operator, ) - const intentPrecondition = { + const transactionPrecondition = { type: precondition.type(), - chainId: chainId.toString(), - data: JSON.stringify({ - address: precondition.address.toString(), - token: precondition.token.toString(), - tokenId: precondition.tokenId.toString(), - operator: precondition.operator.toString(), - }), + chainId, + ownerAddress: precondition.address.toString(), + tokenAddress: precondition.token.toString(), + minAmount: 0n, } - if (!CAN_RUN_LIVE) { - // Mock the getApproved call - ;(provider as any).call.mockResolvedValue( - '0x000000000000000000000000' + operator.toString().slice(2).toLowerCase(), - ) - } + // getApproved returns 32-byte word: 12 zero bytes + 20-byte address. Codec uses ownerAddress as operator. + const approvedHex = + '0x' + '0'.repeat(24) + testWalletAddress.toString().slice(2).toLowerCase() + vi.mocked(provider.call).mockResolvedValue(approvedHex as Hex.Hex) - const isValid = await relayer.checkPrecondition(intentPrecondition) + const isValid = await relayer.checkPrecondition(transactionPrecondition) expect(isValid).toBe(true) }) it('should create and check ERC1155 balance precondition', async () => { const { provider, chainId } = await getProvider() - const relayer = new LocalRelayer(provider as any) - await requireContractDeployed(provider, ERC20_IMPLICIT_MINT_CONTRACT) + const relayer = new LocalRelayer(provider) + await requireContractDeployed(provider, Address.from(ERC20_IMPLICIT_MINT_CONTRACT)) const precondition = new Erc1155BalancePrecondition( testWalletAddress, - ERC20_IMPLICIT_MINT_CONTRACT, + Address.from(ERC20_IMPLICIT_MINT_CONTRACT), 1n, // tokenId 1000000n, // 1 token min 2000000n, // 2 tokens max ) - const intentPrecondition = { + const transactionPrecondition = { type: precondition.type(), - chainId: chainId.toString(), - data: JSON.stringify({ - address: precondition.address.toString(), - token: precondition.token.toString(), - tokenId: precondition.tokenId.toString(), - min: precondition.min?.toString(), - max: precondition.max?.toString(), - }), + chainId, + ownerAddress: precondition.address.toString(), + tokenAddress: precondition.token.toString(), + minAmount: precondition.min ?? 0n, } - if (!CAN_RUN_LIVE) { - // Mock the balanceOf call - ;(provider as any).call.mockResolvedValue('0x1e8480') // 1.5 tokens in hex - } + vi.mocked(provider.call).mockResolvedValue('0x1e8480' as Hex.Hex) // 1.5 tokens in hex - const isValid = await relayer.checkPrecondition(intentPrecondition) + const isValid = await relayer.checkPrecondition(transactionPrecondition) expect(isValid).toBe(true) }) it('should create and check ERC1155 approval precondition', async () => { const { provider, chainId } = await getProvider() - const relayer = new LocalRelayer(provider as any) - await requireContractDeployed(provider, ERC20_IMPLICIT_MINT_CONTRACT) + const relayer = new LocalRelayer(provider) + await requireContractDeployed(provider, Address.from(ERC20_IMPLICIT_MINT_CONTRACT)) const operator = randomAddress() const precondition = new Erc1155ApprovalPrecondition( testWalletAddress, - ERC20_IMPLICIT_MINT_CONTRACT, + Address.from(ERC20_IMPLICIT_MINT_CONTRACT), 1n, // tokenId operator, 1000000n, // 1 token min approval ) - const intentPrecondition = { + const transactionPrecondition = { type: precondition.type(), - chainId: chainId.toString(), - data: JSON.stringify({ - address: precondition.address.toString(), - token: precondition.token.toString(), - tokenId: precondition.tokenId.toString(), - operator: precondition.operator.toString(), - min: precondition.min.toString(), - }), + chainId, + ownerAddress: precondition.address.toString(), + tokenAddress: precondition.token.toString(), + minAmount: precondition.min, } - if (!CAN_RUN_LIVE) { - // Mock the isApprovedForAll call - ;(provider as any).call.mockResolvedValue('0x1') // true - } + vi.mocked(provider.call).mockResolvedValue('0x1' as Hex.Hex) // true - const isValid = await relayer.checkPrecondition(intentPrecondition) + const isValid = await relayer.checkPrecondition(transactionPrecondition) expect(isValid).toBe(true) }) }) diff --git a/packages/services/relayer/test/preconditions/selectors.test.ts b/packages/services/relayer/test/preconditions/selectors.test.ts index 7fdc008add..0cacc0e285 100644 --- a/packages/services/relayer/test/preconditions/selectors.test.ts +++ b/packages/services/relayer/test/preconditions/selectors.test.ts @@ -15,104 +15,71 @@ import { } from '../../src/preconditions/types.js' import { Network } from '@0xsequence/wallet-primitives' -// Test addresses -const TEST_ADDRESS = Address.from('0x1234567890123456789012345678901234567890') -const TOKEN_ADDRESS = Address.from('0xabcdefabcdefabcdefabcdefabcdefabcdefabcd') +// Test addresses (strings for TransactionPrecondition) +const TEST_ADDRESS = '0x1234567890123456789012345678901234567890' +const TOKEN_ADDRESS = '0xabcdefabcdefabcdefabcdefabcdefabcdefabcd' +const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000' + +function nativePrecondition(overrides: Partial = {}): TransactionPrecondition { + return { + type: 'native-balance', + chainId: Network.ChainId.MAINNET, + ownerAddress: TEST_ADDRESS, + tokenAddress: ZERO_ADDRESS, + minAmount: 1000000000000000000n, + ...overrides, + } +} + +function erc20Precondition(overrides: Partial = {}): TransactionPrecondition { + return { + type: 'erc20-balance', + chainId: Network.ChainId.MAINNET, + ownerAddress: TEST_ADDRESS, + tokenAddress: TOKEN_ADDRESS, + minAmount: 1000000n, + ...overrides, + } +} + +function erc721OwnershipPrecondition(overrides: Partial = {}): TransactionPrecondition { + return { + type: 'erc721-ownership', + chainId: Network.ChainId.MAINNET, + ownerAddress: TEST_ADDRESS, + tokenAddress: TOKEN_ADDRESS, + minAmount: 0n, + ...overrides, + } +} describe('Preconditions Selectors', () => { describe('extractChainID', () => { it('should extract chainID from valid precondition data', () => { - const precondition: TransactionPrecondition = { - type: 'native-balance', - data: JSON.stringify({ - address: TEST_ADDRESS, - chainID: '1', - min: '1000000000000000000', - }), - } - + const precondition = nativePrecondition({ chainId: Network.ChainId.MAINNET }) const chainId = extractChainID(precondition) expect(chainId).toBe(Network.ChainId.MAINNET) }) it('should extract large chainID values', () => { - const precondition: TransactionPrecondition = { - type: 'native-balance', - data: JSON.stringify({ - address: TEST_ADDRESS, - chainID: '42161', // Arbitrum chainID - }), - } - + const precondition = nativePrecondition({ chainId: Network.ChainId.ARBITRUM }) const chainId = extractChainID(precondition) expect(chainId).toBe(Network.ChainId.ARBITRUM) }) it('should return undefined when chainID is not present', () => { - const precondition: TransactionPrecondition = { - type: 'native-balance', - data: JSON.stringify({ - address: TEST_ADDRESS, - min: '1000000000000000000', - }), - } - - const chainId = extractChainID(precondition) - expect(chainId).toBeUndefined() - }) - - it('should return undefined when chainID is falsy', () => { - const precondition: TransactionPrecondition = { - type: 'native-balance', - data: JSON.stringify({ - address: TEST_ADDRESS, - chainID: '', - min: '1000000000000000000', - }), - } - - const chainId = extractChainID(precondition) - expect(chainId).toBeUndefined() - }) - - it('should return undefined when chainID is null', () => { - const precondition: TransactionPrecondition = { - type: 'native-balance', - data: JSON.stringify({ - address: TEST_ADDRESS, - chainID: null, - min: '1000000000000000000', - }), - } - + const precondition = { type: 'native-balance', ownerAddress: TEST_ADDRESS, tokenAddress: ZERO_ADDRESS, minAmount: 1n } as TransactionPrecondition const chainId = extractChainID(precondition) expect(chainId).toBeUndefined() }) it('should return undefined for null/undefined precondition', () => { - expect(extractChainID(null as any)).toBeUndefined() - expect(extractChainID(undefined as any)).toBeUndefined() - }) - - it('should return undefined for invalid JSON', () => { - const precondition: TransactionPrecondition = { - type: 'native-balance', - data: 'invalid json', - } - - const chainId = extractChainID(precondition) - expect(chainId).toBeUndefined() + expect(extractChainID(null as unknown as TransactionPrecondition)).toBeUndefined() + expect(extractChainID(undefined as unknown as TransactionPrecondition)).toBeUndefined() }) it('should handle chainID with value 0', () => { - const precondition: TransactionPrecondition = { - type: 'native-balance', - data: JSON.stringify({ - address: TEST_ADDRESS, - chainID: '0', - }), - } - + const precondition = nativePrecondition({ chainId: 0 }) const chainId = extractChainID(precondition) expect(chainId).toBe(0) }) @@ -121,21 +88,8 @@ describe('Preconditions Selectors', () => { describe('extractSupportedPreconditions', () => { it('should extract valid preconditions', () => { const intents: TransactionPrecondition[] = [ - { - type: 'native-balance', - data: JSON.stringify({ - address: TEST_ADDRESS, - min: '1000000000000000000', - }), - }, - { - type: 'erc20-balance', - data: JSON.stringify({ - address: TEST_ADDRESS, - token: TOKEN_ADDRESS, - min: '1000000', - }), - }, + nativePrecondition(), + erc20Precondition(), ] const results = extractSupportedPreconditions(intents) @@ -146,21 +100,9 @@ describe('Preconditions Selectors', () => { it('should filter out invalid preconditions', () => { const intents: TransactionPrecondition[] = [ - { - type: 'native-balance', - data: JSON.stringify({ - address: TEST_ADDRESS, - min: '1000000000000000000', - }), - }, - { - type: 'unknown-type', - data: JSON.stringify({ address: TEST_ADDRESS }), - }, - { - type: 'native-balance', - data: 'invalid json', - }, + nativePrecondition(), + { type: 'unknown-type', chainId: 1, ownerAddress: TEST_ADDRESS, tokenAddress: ZERO_ADDRESS, minAmount: 0n } as TransactionPrecondition, + nativePrecondition({ ownerAddress: '' }), ] const results = extractSupportedPreconditions(intents) @@ -169,8 +111,8 @@ describe('Preconditions Selectors', () => { }) it('should return empty array for null/undefined input', () => { - expect(extractSupportedPreconditions(null as any)).toEqual([]) - expect(extractSupportedPreconditions(undefined as any)).toEqual([]) + expect(extractSupportedPreconditions(null as unknown as TransactionPrecondition[])).toEqual([]) + expect(extractSupportedPreconditions(undefined as unknown as TransactionPrecondition[])).toEqual([]) }) it('should return empty array for empty input', () => { @@ -180,25 +122,9 @@ describe('Preconditions Selectors', () => { it('should handle mixed valid and invalid preconditions', () => { const intents: TransactionPrecondition[] = [ - { - type: 'native-balance', - data: JSON.stringify({ - address: TEST_ADDRESS, - min: '1000000000000000000', - }), - }, - { - type: 'erc721-ownership', - data: JSON.stringify({ - address: TEST_ADDRESS, - token: TOKEN_ADDRESS, - tokenId: '123', - }), - }, - { - type: 'invalid-type', - data: JSON.stringify({ address: TEST_ADDRESS }), - }, + nativePrecondition(), + erc721OwnershipPrecondition(), + { type: 'invalid-type', chainId: 1, ownerAddress: TEST_ADDRESS, tokenAddress: ZERO_ADDRESS, minAmount: 0n } as TransactionPrecondition, ] const results = extractSupportedPreconditions(intents) @@ -211,58 +137,23 @@ describe('Preconditions Selectors', () => { describe('extractNativeBalancePreconditions', () => { it('should extract only native balance preconditions', () => { const intents: TransactionPrecondition[] = [ - { - type: 'native-balance', - data: JSON.stringify({ - address: TEST_ADDRESS, - min: '1000000000000000000', - }), - }, - { - type: 'erc20-balance', - data: JSON.stringify({ - address: TEST_ADDRESS, - token: TOKEN_ADDRESS, - min: '1000000', - }), - }, - { - type: 'native-balance', - data: JSON.stringify({ - address: TEST_ADDRESS, - max: '2000000000000000000', - }), - }, + nativePrecondition({ minAmount: 1000000000000000000n }), + erc20Precondition(), + nativePrecondition({ minAmount: 2000000000000000000n }), ] const results = extractNativeBalancePreconditions(intents) expect(results).toHaveLength(2) expect(results[0]).toBeInstanceOf(NativeBalancePrecondition) expect(results[1]).toBeInstanceOf(NativeBalancePrecondition) - - // Verify the specific properties expect(results[0].min).toBe(1000000000000000000n) - expect(results[1].max).toBe(2000000000000000000n) + expect(results[1].min).toBe(2000000000000000000n) }) it('should return empty array when no native balance preconditions exist', () => { const intents: TransactionPrecondition[] = [ - { - type: 'erc20-balance', - data: JSON.stringify({ - address: TEST_ADDRESS, - token: TOKEN_ADDRESS, - min: '1000000', - }), - }, - { - type: 'erc721-ownership', - data: JSON.stringify({ - address: TEST_ADDRESS, - token: TOKEN_ADDRESS, - tokenId: '123', - }), - }, + erc20Precondition(), + erc721OwnershipPrecondition(), ] const results = extractNativeBalancePreconditions(intents) @@ -270,8 +161,8 @@ describe('Preconditions Selectors', () => { }) it('should return empty array for null/undefined input', () => { - expect(extractNativeBalancePreconditions(null as any)).toEqual([]) - expect(extractNativeBalancePreconditions(undefined as any)).toEqual([]) + expect(extractNativeBalancePreconditions(null as unknown as TransactionPrecondition[])).toEqual([]) + expect(extractNativeBalancePreconditions(undefined as unknown as TransactionPrecondition[])).toEqual([]) }) it('should return empty array for empty input', () => { @@ -281,24 +172,8 @@ describe('Preconditions Selectors', () => { it('should filter out invalid native balance preconditions', () => { const intents: TransactionPrecondition[] = [ - { - type: 'native-balance', - data: JSON.stringify({ - address: TEST_ADDRESS, - min: '1000000000000000000', - }), - }, - { - type: 'native-balance', - data: 'invalid json', // This will be filtered out - }, - { - type: 'native-balance', - data: JSON.stringify({ - // Missing address - this will be filtered out - min: '1000000000000000000', - }), - }, + nativePrecondition({ minAmount: 1000000000000000000n }), + nativePrecondition({ ownerAddress: '' }), ] const results = extractNativeBalancePreconditions(intents) @@ -311,60 +186,25 @@ describe('Preconditions Selectors', () => { describe('extractERC20BalancePreconditions', () => { it('should extract only ERC20 balance preconditions', () => { const intents: TransactionPrecondition[] = [ - { - type: 'native-balance', - data: JSON.stringify({ - address: TEST_ADDRESS, - min: '1000000000000000000', - }), - }, - { - type: 'erc20-balance', - data: JSON.stringify({ - address: TEST_ADDRESS, - token: TOKEN_ADDRESS, - min: '1000000', - }), - }, - { - type: 'erc20-balance', - data: JSON.stringify({ - address: TEST_ADDRESS, - token: TOKEN_ADDRESS, - max: '2000000', - }), - }, + nativePrecondition(), + erc20Precondition({ minAmount: 1000000n }), + erc20Precondition({ minAmount: 2000000n }), ] const results = extractERC20BalancePreconditions(intents) expect(results).toHaveLength(2) expect(results[0]).toBeInstanceOf(Erc20BalancePrecondition) expect(results[1]).toBeInstanceOf(Erc20BalancePrecondition) - - // Verify the specific properties expect(results[0].min).toBe(1000000n) - expect(results[1].max).toBe(2000000n) - expect(results[0].token).toBe(TOKEN_ADDRESS) - expect(results[1].token).toBe(TOKEN_ADDRESS) + expect(results[1].min).toBe(2000000n) + expect(results[0].token).toEqual(Address.from(TOKEN_ADDRESS)) + expect(results[1].token).toEqual(Address.from(TOKEN_ADDRESS)) }) it('should return empty array when no ERC20 balance preconditions exist', () => { const intents: TransactionPrecondition[] = [ - { - type: 'native-balance', - data: JSON.stringify({ - address: TEST_ADDRESS, - min: '1000000000000000000', - }), - }, - { - type: 'erc721-ownership', - data: JSON.stringify({ - address: TEST_ADDRESS, - token: TOKEN_ADDRESS, - tokenId: '123', - }), - }, + nativePrecondition(), + erc721OwnershipPrecondition(), ] const results = extractERC20BalancePreconditions(intents) @@ -372,8 +212,8 @@ describe('Preconditions Selectors', () => { }) it('should return empty array for null/undefined input', () => { - expect(extractERC20BalancePreconditions(null as any)).toEqual([]) - expect(extractERC20BalancePreconditions(undefined as any)).toEqual([]) + expect(extractERC20BalancePreconditions(null as unknown as TransactionPrecondition[])).toEqual([]) + expect(extractERC20BalancePreconditions(undefined as unknown as TransactionPrecondition[])).toEqual([]) }) it('should return empty array for empty input', () => { @@ -383,33 +223,15 @@ describe('Preconditions Selectors', () => { it('should filter out invalid ERC20 balance preconditions', () => { const intents: TransactionPrecondition[] = [ - { - type: 'erc20-balance', - data: JSON.stringify({ - address: TEST_ADDRESS, - token: TOKEN_ADDRESS, - min: '1000000', - }), - }, - { - type: 'erc20-balance', - data: 'invalid json', // This will be filtered out - }, - { - type: 'erc20-balance', - data: JSON.stringify({ - address: TEST_ADDRESS, - // Missing token address - this will be filtered out - min: '1000000', - }), - }, + erc20Precondition({ minAmount: 1000000n }), + erc20Precondition({ tokenAddress: '' }), ] const results = extractERC20BalancePreconditions(intents) expect(results).toHaveLength(1) expect(results[0]).toBeInstanceOf(Erc20BalancePrecondition) expect(results[0].min).toBe(1000000n) - expect(results[0].token).toBe(TOKEN_ADDRESS) + expect(results[0].token).toEqual(Address.from(TOKEN_ADDRESS)) }) }) }) diff --git a/packages/services/relayer/test/preconditions/types.test.ts b/packages/services/relayer/test/preconditions/types.test.ts index a4ecda1d9d..a479676b58 100644 --- a/packages/services/relayer/test/preconditions/types.test.ts +++ b/packages/services/relayer/test/preconditions/types.test.ts @@ -179,7 +179,7 @@ describe('Preconditions Types', () => { TEST_ADDRESS, TOKEN_ADDRESS, OPERATOR_ADDRESS, - undefined as any, + undefined as unknown as bigint, ) const error = precondition.isValid() @@ -224,7 +224,7 @@ describe('Preconditions Types', () => { }) it('should validate tokenId is required', () => { - const precondition = new Erc721OwnershipPrecondition(TEST_ADDRESS, TOKEN_ADDRESS, undefined as any) + const precondition = new Erc721OwnershipPrecondition(TEST_ADDRESS, TOKEN_ADDRESS, undefined as unknown as bigint) const error = precondition.isValid() expect(error).toBeInstanceOf(Error) @@ -271,7 +271,7 @@ describe('Preconditions Types', () => { const precondition = new Erc721ApprovalPrecondition( TEST_ADDRESS, TOKEN_ADDRESS, - undefined as any, + undefined as unknown as bigint, OPERATOR_ADDRESS, ) @@ -319,7 +319,7 @@ describe('Preconditions Types', () => { }) it('should validate tokenId is required', () => { - const precondition = new Erc1155BalancePrecondition(TEST_ADDRESS, TOKEN_ADDRESS, undefined as any) + const precondition = new Erc1155BalancePrecondition(TEST_ADDRESS, TOKEN_ADDRESS, undefined as unknown as bigint) const error = precondition.isValid() expect(error).toBeInstanceOf(Error) @@ -402,7 +402,7 @@ describe('Preconditions Types', () => { const precondition = new Erc1155ApprovalPrecondition( TEST_ADDRESS, TOKEN_ADDRESS, - undefined as any, + undefined as unknown as bigint, OPERATOR_ADDRESS, 1000000n, ) @@ -432,7 +432,7 @@ describe('Preconditions Types', () => { TOKEN_ADDRESS, 123n, OPERATOR_ADDRESS, - undefined as any, + undefined as unknown as bigint, ) const error = precondition.isValid() diff --git a/packages/services/relayer/test/relayer/relayer.test.ts b/packages/services/relayer/test/relayer/relayer.test.ts index adbadd236c..716cd11d65 100644 --- a/packages/services/relayer/test/relayer/relayer.test.ts +++ b/packages/services/relayer/test/relayer/relayer.test.ts @@ -1,7 +1,7 @@ import { describe, expect, it, vi, beforeEach } from 'vitest' import { Address, Hex } from 'ox' import { Network, Payload } from '@0xsequence/wallet-primitives' -import { Relayer, RelayerGen } from '@0xsequence/relayer' +import { Relayer, RpcRelayerGen } from '@0xsequence/relayer' // Test addresses and data const TEST_WALLET_ADDRESS = Address.from('0x1234567890123456789012345678901234567890') @@ -127,7 +127,7 @@ describe('Relayer', () => { symbol: 'ETH', decimals: 18, logoURL: 'https://example.com/eth.png', - type: 'NATIVE' as RelayerGen.FeeTokenType, + type: 'NATIVE' as RpcRelayerGen.FeeTokenType, contractAddress: undefined, }, to: TEST_TO_ADDRESS, @@ -310,7 +310,7 @@ describe('Relayer', () => { const isAvailable = await mockRelayer.isAvailable(TEST_WALLET_ADDRESS, TEST_CHAIN_ID) expect(isAvailable).toBe(true) - const feeOptions = await mockRelayer.feeOptions(TEST_WALLET_ADDRESS, TEST_CHAIN_ID, []) + const feeOptions = await mockRelayer.feeOptions(TEST_WALLET_ADDRESS, TEST_CHAIN_ID, TEST_TO_ADDRESS, []) expect(feeOptions.options).toEqual([]) const relayResult = await mockRelayer.relay(TEST_TO_ADDRESS, TEST_DATA, TEST_CHAIN_ID) @@ -319,7 +319,7 @@ describe('Relayer', () => { const statusResult = await mockRelayer.status(TEST_OP_HASH, TEST_CHAIN_ID) expect(statusResult.status).toBe('confirmed') - const preconditionResult = await mockRelayer.checkPrecondition({} as any) + const preconditionResult = await mockRelayer.checkPrecondition({} as { type: string }) expect(preconditionResult).toBe(true) }) }) diff --git a/packages/services/userdata/CHANGELOG.md b/packages/services/userdata/CHANGELOG.md index f9a97c1265..abea2c174f 100644 --- a/packages/services/userdata/CHANGELOG.md +++ b/packages/services/userdata/CHANGELOG.md @@ -1,5 +1,86 @@ # @0xsequence/userdata +## 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 diff --git a/packages/services/userdata/eslint.config.js b/packages/services/userdata/eslint.config.js new file mode 100644 index 0000000000..cecf89b031 --- /dev/null +++ b/packages/services/userdata/eslint.config.js @@ -0,0 +1,4 @@ +import { config as baseConfig } from "@repo/eslint-config/base" + +/** @type {import("eslint").Linter.Config} */ +export default baseConfig diff --git a/packages/services/userdata/package.json b/packages/services/userdata/package.json index 6c4427fa7c..6cef1fe591 100644 --- a/packages/services/userdata/package.json +++ b/packages/services/userdata/package.json @@ -1,18 +1,20 @@ { "name": "@0xsequence/userdata", - "version": "3.0.0-beta.9", + "version": "3.0.0", "description": "userdata sub-package for Sequence", "repository": "https://github.com/0xsequence/sequence.js/tree/master/packages/services/userdata", - "author": "Sequence Platforms Inc.", + "author": "Sequence Platforms ULC", "license": "Apache-2.0", "publishConfig": { "access": "public" }, + "type": "module", "scripts": { "build": "tsc", "dev": "tsc --watch", "test": "echo", - "typecheck": "tsc --noEmit" + "typecheck": "tsc --noEmit", + "lint": "eslint . --max-warnings 0" }, "exports": { ".": { @@ -21,8 +23,9 @@ } }, "devDependencies": { + "@repo/eslint-config": "workspace:^", "@repo/typescript-config": "workspace:^", - "@types/node": "^25.0.2", + "@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 index af76930fc8..63b8559678 100644 --- a/packages/services/userdata/src/index.ts +++ b/packages/services/userdata/src/index.ts @@ -1,6 +1,6 @@ -export * from './userdata.gen' +export * from './userdata.gen.js' -import { UserData as UserdataRpc } from './userdata.gen' +import { UserData as UserdataRpc } from './userdata.gen.js' export class SequenceUserdataClient extends UserdataRpc { constructor( @@ -15,7 +15,7 @@ export class SequenceUserdataClient extends UserdataRpc { _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: { [key: string]: any } = {} + const headers: Record = {} const jwtAuth = this.jwtAuth const projectAccessKey = this.projectAccessKey diff --git a/packages/services/userdata/src/userdata.gen.ts b/packages/services/userdata/src/userdata.gen.ts index a26fdb9950..d671010bed 100644 --- a/packages/services/userdata/src/userdata.gen.ts +++ b/packages/services/userdata/src/userdata.gen.ts @@ -1,5 +1,5 @@ /* eslint-disable */ -// userdata v0.1.0 99a19ff0218eda6f5e544642d0fd72f66736bdaf +// userdata v0.1.0 88764bb5f99353e11d849a1aa8f8a998501ffedb // -- // Code generated by Webrpc-gen@v0.30.2 with typescript generator. DO NOT EDIT. // @@ -12,7 +12,7 @@ export const WebrpcVersion = 'v1' export const WebrpcSchemaVersion = 'v0.1.0' // Schema hash generated from your RIDL schema -export const WebrpcSchemaHash = '99a19ff0218eda6f5e544642d0fd72f66736bdaf' +export const WebrpcSchemaHash = '88764bb5f99353e11d849a1aa8f8a998501ffedb' // // Client interface @@ -28,26 +28,175 @@ export interface UserDataClient { 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 + ecosystem?: number + preferences: WalletPreferences + updatedAt: string + createdAt: string } -export interface Signer { - address: string - kind: string - email?: 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 { @@ -60,11 +209,91 @@ export interface Session { 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 { @@ -90,6 +319,237 @@ 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 // @@ -112,6 +572,33 @@ export class UserData implements UserDataClient { 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 => { @@ -172,6 +659,562 @@ export class UserData implements UserDataClient { }, ) } + + 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 => { diff --git a/packages/utils/abi/CHANGELOG.md b/packages/utils/abi/CHANGELOG.md index 9ddc564622..25e7590b46 100644 --- a/packages/utils/abi/CHANGELOG.md +++ b/packages/utils/abi/CHANGELOG.md @@ -1,5 +1,90 @@ # @0xsequence/abi +## 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 diff --git a/packages/utils/abi/eslint.config.js b/packages/utils/abi/eslint.config.js new file mode 100644 index 0000000000..cecf89b031 --- /dev/null +++ b/packages/utils/abi/eslint.config.js @@ -0,0 +1,4 @@ +import { config as baseConfig } from "@repo/eslint-config/base" + +/** @type {import("eslint").Linter.Config} */ +export default baseConfig diff --git a/packages/utils/abi/package.json b/packages/utils/abi/package.json index 1eb722f85b..4efa48abe8 100644 --- a/packages/utils/abi/package.json +++ b/packages/utils/abi/package.json @@ -1,18 +1,20 @@ { "name": "@0xsequence/abi", - "version": "3.0.0-beta.9", + "version": "3.0.0", "description": "abi sub-package for Sequence", "repository": "https://github.com/0xsequence/sequence.js/tree/master/packages/utils/abi", - "author": "Sequence Platforms Inc.", + "author": "Sequence Platforms ULC", "license": "Apache-2.0", "publishConfig": { "access": "public" }, + "type": "module", "scripts": { "build": "tsc", "dev": "tsc --watch", "test": "echo", - "typecheck": "tsc --noEmit" + "typecheck": "tsc --noEmit", + "lint": "eslint . --max-warnings 0" }, "exports": { ".": { @@ -21,8 +23,9 @@ } }, "devDependencies": { + "@repo/eslint-config": "workspace:^", "@repo/typescript-config": "workspace:^", - "@types/node": "^25.0.2", + "@types/node": "^25.3.0", "typescript": "^5.9.3" } } diff --git a/packages/utils/abi/src/index.ts b/packages/utils/abi/src/index.ts index db6dfa2929..39336c543c 100644 --- a/packages/utils/abi/src/index.ts +++ b/packages/utils/abi/src/index.ts @@ -1,22 +1,22 @@ -export { abi as erc5719Abi } from './wallet/erc5719' -export { abi as erc1271Abi } from './wallet/erc1271' -export { abi as erc6492Abi } from './wallet/erc6492' -export { abi as factoryAbi } from './wallet/factory' -export { abi as mainModuleAbi } from './wallet/mainModule' -export { abi as mainModuleUpgradableAbi } from './wallet/mainModuleUpgradable' -export { abi as moduleHooksAbi } from './wallet/moduleHooks' -export { abi as sequenceUtilsAbi } from './wallet/sequenceUtils' -export { abi as requireFreshSignerAbi } from './wallet/libs/requireFreshSigners' -export { abi as walletProxyHookAbi } from './wallet/walletProxyHook' +export { abi as erc5719Abi } from './wallet/erc5719.js' +export { abi as erc1271Abi } from './wallet/erc1271.js' +export { abi as erc6492Abi } from './wallet/erc6492.js' +export { abi as factoryAbi } from './wallet/factory.js' +export { abi as mainModuleAbi } from './wallet/mainModule.js' +export { abi as mainModuleUpgradableAbi } from './wallet/mainModuleUpgradable.js' +export { abi as moduleHooksAbi } from './wallet/moduleHooks.js' +export { abi as sequenceUtilsAbi } from './wallet/sequenceUtils.js' +export { abi as requireFreshSignerAbi } from './wallet/libs/requireFreshSigners.js' +export { abi as walletProxyHookAbi } from './wallet/walletProxyHook.js' -export { walletContracts } from './wallet' +export { walletContracts } from './wallet/index.js' -export { ERC1155_ABI } from './tokens/erc1155' -export { ERC1155_ITEMS_ABI } from './tokens/erc1155Items' -export { ERC20_ABI } from './tokens/erc20' -export { ERC6909_ABI } from './tokens/erc6909' -export { ERC721_ABI } from './tokens/erc721' -export { ERC721_ITEMS_ABI } from './tokens/erc721Items' +export { ERC1155_ABI } from './tokens/erc1155.js' +export { ERC1155_ITEMS_ABI } from './tokens/erc1155Items.js' +export { ERC20_ABI } from './tokens/erc20.js' +export { ERC6909_ABI } from './tokens/erc6909.js' +export { ERC721_ABI } from './tokens/erc721.js' +export { ERC721_ITEMS_ABI } from './tokens/erc721Items.js' -export { ERC1155_SALE_ABI } from './sale/erc1155Sale' -export { ERC721_SALE_ABI } from './sale/erc721Sale' +export { ERC1155_SALE_ABI } from './sale/erc1155Sale.js' +export { ERC721_SALE_ABI } from './sale/erc721Sale.js' diff --git a/packages/utils/abi/src/wallet/index.ts b/packages/utils/abi/src/wallet/index.ts index 0ceae0a350..50b567e71c 100644 --- a/packages/utils/abi/src/wallet/index.ts +++ b/packages/utils/abi/src/wallet/index.ts @@ -1,13 +1,13 @@ -import * as erc5719 from './erc5719' -import * as erc1271 from './erc1271' -import * as erc6492 from './erc6492' -import * as factory from './factory' -import * as mainModule from './mainModule' -import * as mainModuleUpgradable from './mainModuleUpgradable' -import * as moduleHooks from './moduleHooks' -import * as sequenceUtils from './sequenceUtils' -import * as requireFreshSigner from './libs/requireFreshSigners' -import * as walletProxyHook from './walletProxyHook' +import * as erc5719 from './erc5719.js' +import * as erc1271 from './erc1271.js' +import * as erc6492 from './erc6492.js' +import * as factory from './factory.js' +import * as mainModule from './mainModule.js' +import * as mainModuleUpgradable from './mainModuleUpgradable.js' +import * as moduleHooks from './moduleHooks.js' +import * as sequenceUtils from './sequenceUtils.js' +import * as requireFreshSigner from './libs/requireFreshSigners.js' +import * as walletProxyHook from './walletProxyHook.js' /** * @deprecated import directly from @0xsequence/abi/* instead, omitting "walletContracts" diff --git a/packages/wallet/core/CHANGELOG.md b/packages/wallet/core/CHANGELOG.md index 32e56d2389..be05bec0b5 100644 --- a/packages/wallet/core/CHANGELOG.md +++ b/packages/wallet/core/CHANGELOG.md @@ -1,5 +1,153 @@ # @0xsequence/wallet-core +## 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 diff --git a/packages/wallet/core/eslint.config.js b/packages/wallet/core/eslint.config.js new file mode 100644 index 0000000000..d10bbd1e97 --- /dev/null +++ b/packages/wallet/core/eslint.config.js @@ -0,0 +1,12 @@ +import { config as baseConfig } from '@repo/eslint-config/base' + +/** @type {import("eslint").Linter.Config} */ +export default [ + ...baseConfig, + { + // files: ['**/*.{test,spec}.ts'], + rules: { + '@typescript-eslint/no-explicit-any': 'off', + }, + }, +] diff --git a/packages/wallet/core/package.json b/packages/wallet/core/package.json index e2978f593a..a5ced0086f 100644 --- a/packages/wallet/core/package.json +++ b/packages/wallet/core/package.json @@ -1,6 +1,6 @@ { "name": "@0xsequence/wallet-core", - "version": "3.0.0-beta.9", + "version": "3.0.0", "license": "Apache-2.0", "type": "module", "publishConfig": { @@ -13,7 +13,8 @@ "test": "vitest run", "test:coverage": "vitest run --coverage", "typecheck": "tsc --noEmit", - "clean": "rimraf dist" + "clean": "rimraf dist", + "lint": "eslint . --max-warnings 0" }, "exports": { ".": { @@ -22,13 +23,14 @@ } }, "devDependencies": { + "@repo/eslint-config": "workspace:^", "@repo/typescript-config": "workspace:^", - "@types/node": "^25.0.2", - "@vitest/coverage-v8": "^4.0.15", - "dotenv": "^17.2.3", + "@types/node": "^25.3.0", + "@vitest/coverage-v8": "^4.0.18", + "dotenv": "^17.3.1", "fake-indexeddb": "^6.2.5", "typescript": "^5.9.3", - "vitest": "^4.0.15" + "vitest": "^4.0.18" }, "dependencies": { "@0xsequence/guard": "workspace:^", diff --git a/packages/wallet/core/src/bundler/bundlers/pimlico.ts b/packages/wallet/core/src/bundler/bundlers/pimlico.ts index e2d95ec331..4837babee0 100644 --- a/packages/wallet/core/src/bundler/bundlers/pimlico.ts +++ b/packages/wallet/core/src/bundler/bundlers/pimlico.ts @@ -16,16 +16,22 @@ type PimlicoGasPrice = { } export class PimlicoBundler implements Bundler { - public readonly kind: 'bundler' = 'bundler' + public readonly kind = 'bundler' public readonly id: string public readonly provider: Provider.Provider public readonly bundlerRpcUrl: string + private readonly fetcher: typeof fetch - constructor(bundlerRpcUrl: string, provider: Provider.Provider | string) { + constructor(bundlerRpcUrl: string, provider: Provider.Provider | string, fetcher?: typeof fetch) { this.id = `pimlico-erc4337-${bundlerRpcUrl}` this.provider = typeof provider === 'string' ? Provider.from(RpcTransport.fromHttp(provider)) : provider this.bundlerRpcUrl = bundlerRpcUrl + const resolvedFetch = fetcher ?? (globalThis as any).fetch + if (!resolvedFetch) { + throw new Error('fetch is not available') + } + this.fetcher = resolvedFetch } async isAvailable(entrypoint: Address.Address, chainId: number): Promise { @@ -113,7 +119,7 @@ export class PimlicoBundler implements Bundler { let pimlico: PimlicoStatusResp | undefined try { pimlico = await this.bundlerRpc('pimlico_getUserOperationStatus', [opHash]) - } catch (_) { + } catch { /* ignore - not Pimlico or endpoint down */ } @@ -165,7 +171,7 @@ export class PimlicoBundler implements Bundler { private async bundlerRpc(method: string, params: any[]): Promise { const body = JSON.stringify({ jsonrpc: '2.0', id: 1, method, params }) - const res = await fetch(this.bundlerRpcUrl, { + const res = await this.fetcher(this.bundlerRpcUrl, { method: 'POST', headers: { 'content-type': 'application/json' }, body, diff --git a/packages/wallet/core/src/env.ts b/packages/wallet/core/src/env.ts new file mode 100644 index 0000000000..0a463dd1d8 --- /dev/null +++ b/packages/wallet/core/src/env.ts @@ -0,0 +1,68 @@ +export type StorageLike = { + getItem: (key: string) => string | null + setItem: (key: string, value: string) => void + removeItem: (key: string) => void +} + +export type CryptoLike = { + subtle: SubtleCrypto + getRandomValues: (array: T) => T +} + +export type TextEncodingLike = { + TextEncoder: typeof TextEncoder + TextDecoder: typeof TextDecoder +} + +export type CoreEnv = { + fetch?: typeof fetch + crypto?: CryptoLike + storage?: StorageLike + indexedDB?: IDBFactory + text?: Partial +} + +function isStorageLike(value: unknown): value is StorageLike { + if (!value || typeof value !== 'object') return false + const candidate = value as StorageLike + return ( + typeof candidate.getItem === 'function' && + typeof candidate.setItem === 'function' && + typeof candidate.removeItem === 'function' + ) +} + +export function resolveCoreEnv(env?: CoreEnv): CoreEnv { + const globalObj = globalThis as any + const windowObj = typeof window !== 'undefined' ? window : (globalObj.window ?? {}) + let storage: StorageLike | undefined + let text: Partial | undefined + + if (isStorageLike(env?.storage)) { + storage = env.storage + } else if (isStorageLike(windowObj.localStorage)) { + storage = windowObj.localStorage + } else if (isStorageLike(globalObj.localStorage)) { + storage = globalObj.localStorage + } + + if (env?.text) { + if (!env.text.TextEncoder || !env.text.TextDecoder) { + throw new Error('env.text must provide both TextEncoder and TextDecoder') + } + text = env.text + } else { + text = { + TextEncoder: windowObj.TextEncoder ?? globalObj.TextEncoder, + TextDecoder: windowObj.TextDecoder ?? globalObj.TextDecoder, + } + } + + return { + fetch: env?.fetch ?? windowObj.fetch ?? globalObj.fetch, + crypto: env?.crypto ?? windowObj.crypto ?? globalObj.crypto, + storage, + indexedDB: env?.indexedDB ?? windowObj.indexedDB ?? globalObj.indexedDB, + text, + } +} diff --git a/packages/wallet/core/src/index.ts b/packages/wallet/core/src/index.ts index b36e917cae..27c54b8f53 100644 --- a/packages/wallet/core/src/index.ts +++ b/packages/wallet/core/src/index.ts @@ -5,6 +5,7 @@ export * as State from './state/index.js' export * as Bundler from './bundler/index.js' export * as Envelope from './envelope.js' export * as Utils from './utils/index.js' +export * from './env.js' export { type ExplicitSessionConfig, type ExplicitSession, diff --git a/packages/wallet/core/src/signers/index.ts b/packages/wallet/core/src/signers/index.ts index 80ccc07f10..28a8815b20 100644 --- a/packages/wallet/core/src/signers/index.ts +++ b/packages/wallet/core/src/signers/index.ts @@ -31,7 +31,7 @@ export interface SapientSigner { } export interface Witnessable { - witness: (stateWriter: State.Writer, wallet: Address.Address, extra?: Object) => Promise + witness: (stateWriter: State.Writer, wallet: Address.Address, extra?: object) => Promise } type MaybePromise = T | Promise diff --git a/packages/wallet/core/src/signers/passkey.ts b/packages/wallet/core/src/signers/passkey.ts index 0cc7cacaba..770b6b1811 100644 --- a/packages/wallet/core/src/signers/passkey.ts +++ b/packages/wallet/core/src/signers/passkey.ts @@ -5,12 +5,15 @@ import { WebAuthnP256 } from 'ox' import { State } from '../index.js' import { SapientSigner, Witnessable } from './index.js' +export type WebAuthnLike = Pick + export type PasskeyOptions = { extensions: Pick publicKey: Extensions.Passkeys.PublicKey credentialId: string embedMetadata?: boolean metadata?: Extensions.Passkeys.PasskeyMetadata + webauthn?: WebAuthnLike } export type CreatePasskeyOptions = { @@ -18,6 +21,11 @@ export type CreatePasskeyOptions = { requireUserVerification?: boolean credentialName?: string embedMetadata?: boolean + webauthn?: WebAuthnLike +} + +export type FindPasskeyOptions = { + webauthn?: WebAuthnLike } export type WitnessMessage = { @@ -45,6 +53,7 @@ export class Passkey implements SapientSigner, Witnessable { public readonly imageHash: Hex.Hex public readonly embedMetadata: boolean public readonly metadata?: Extensions.Passkeys.PasskeyMetadata + private readonly webauthn: WebAuthnLike constructor(options: PasskeyOptions) { this.address = options.extensions.passkeys @@ -53,6 +62,7 @@ export class Passkey implements SapientSigner, Witnessable { this.embedMetadata = options.embedMetadata ?? false this.imageHash = Extensions.Passkeys.rootFor(options.publicKey) this.metadata = options.metadata + this.webauthn = options.webauthn ?? WebAuthnP256 } static async loadFromWitness( @@ -60,6 +70,7 @@ export class Passkey implements SapientSigner, Witnessable { extensions: Pick, wallet: Address.Address, imageHash: Hex.Hex, + options?: FindPasskeyOptions, ) { // In the witness we will find the public key, and may find the credential id const witness = await stateReader.getWitnessForSapient(wallet, extensions.passkeys, imageHash) @@ -90,13 +101,15 @@ export class Passkey implements SapientSigner, Witnessable { publicKey: message.publicKey, embedMetadata: decodedSignature.embedMetadata, metadata, + webauthn: options?.webauthn, }) } static async create(extensions: Pick, options?: CreatePasskeyOptions) { + const webauthn = options?.webauthn ?? WebAuthnP256 const name = options?.credentialName ?? `Sequence (${Date.now()})` - const credential = await WebAuthnP256.createCredential({ + const credential = await webauthn.createCredential({ user: { name, }, @@ -120,6 +133,7 @@ export class Passkey implements SapientSigner, Witnessable { }, embedMetadata: options?.embedMetadata, metadata, + webauthn, }) if (options?.stateProvider) { @@ -132,8 +146,10 @@ export class Passkey implements SapientSigner, Witnessable { static async find( stateReader: State.Reader, extensions: Pick, + options?: FindPasskeyOptions, ): Promise { - const response = await WebAuthnP256.sign({ challenge: Hex.random(32) }) + const webauthn = options?.webauthn ?? WebAuthnP256 + const response = await webauthn.sign({ challenge: Hex.random(32) }) if (!response.raw) throw new Error('No credential returned') const authenticatorDataBytes = Bytes.fromHex(response.metadata.authenticatorData) @@ -218,7 +234,7 @@ export class Passkey implements SapientSigner, Witnessable { console.warn('Multiple signers found for passkey', flattened) } - return Passkey.loadFromWitness(stateReader, extensions, flattened[0]!.wallet, flattened[0]!.imageHash) + return Passkey.loadFromWitness(stateReader, extensions, flattened[0]!.wallet, flattened[0]!.imageHash, options) } async signSapient( @@ -234,7 +250,7 @@ export class Passkey implements SapientSigner, Witnessable { const challenge = Hex.fromBytes(Payload.hash(wallet, chainId, payload)) - const response = await WebAuthnP256.sign({ + const response = await this.webauthn.sign({ challenge, credentialId: this.credentialId, userVerification: this.publicKey.requireUserVerification ? 'required' : 'discouraged', @@ -260,7 +276,7 @@ export class Passkey implements SapientSigner, Witnessable { } } - async witness(stateWriter: State.Writer, wallet: Address.Address, extra?: Object): Promise { + async witness(stateWriter: State.Writer, wallet: Address.Address, extra?: object): Promise { const payload = Payload.fromMessage( Hex.fromString( JSON.stringify({ diff --git a/packages/wallet/core/src/signers/pk/encrypted.ts b/packages/wallet/core/src/signers/pk/encrypted.ts index c75bc57f93..dce0eb3cc7 100644 --- a/packages/wallet/core/src/signers/pk/encrypted.ts +++ b/packages/wallet/core/src/signers/pk/encrypted.ts @@ -1,4 +1,5 @@ import { Hex, Address, PublicKey, Secp256k1, Bytes } from 'ox' +import { resolveCoreEnv, type CoreEnv, type CryptoLike, type StorageLike, type TextEncodingLike } from '../../env.js' import { PkStore } from './index.js' export interface EncryptedData { @@ -17,6 +18,7 @@ export class EncryptedPksDb { constructor( private readonly localStorageKeyPrefix: string = 'e_pk_key_', tableName: string = 'e_pk', + private readonly env?: CoreEnv, ) { this.tableName = tableName } @@ -25,9 +27,59 @@ export class EncryptedPksDb { return `pk_${address.toLowerCase()}` } + private getIndexedDB(): IDBFactory { + const globalObj = globalThis as any + const indexedDb = this.env?.indexedDB ?? globalObj.indexedDB ?? globalObj.window?.indexedDB + if (!indexedDb) { + throw new Error('indexedDB is not available') + } + return indexedDb + } + + private getStorage(): StorageLike { + const storage = resolveCoreEnv(this.env).storage + if (!storage) { + throw new Error('storage is not available') + } + return storage + } + + private getCrypto(): CryptoLike { + const globalObj = globalThis as any + const crypto = this.env?.crypto ?? globalObj.crypto ?? globalObj.window?.crypto + if (!crypto?.subtle || !crypto?.getRandomValues) { + throw new Error('crypto.subtle is not available') + } + return crypto + } + + private getTextEncoderCtor(): TextEncodingLike['TextEncoder'] { + const globalObj = globalThis as any + if (this.env?.text && (!this.env.text.TextEncoder || !this.env.text.TextDecoder)) { + throw new Error('env.text must provide both TextEncoder and TextDecoder') + } + const encoderCtor = this.env?.text?.TextEncoder ?? globalObj.TextEncoder ?? globalObj.window?.TextEncoder + if (!encoderCtor) { + throw new Error('TextEncoder is not available') + } + return encoderCtor + } + + private getTextDecoderCtor(): TextEncodingLike['TextDecoder'] { + const globalObj = globalThis as any + if (this.env?.text && (!this.env.text.TextEncoder || !this.env.text.TextDecoder)) { + throw new Error('env.text must provide both TextEncoder and TextDecoder') + } + const decoderCtor = this.env?.text?.TextDecoder ?? globalObj.TextDecoder ?? globalObj.window?.TextDecoder + if (!decoderCtor) { + throw new Error('TextDecoder is not available') + } + return decoderCtor + } + private openDB(): Promise { return new Promise((resolve, reject) => { - const request = indexedDB.open(this.dbName, this.dbVersion) + const request = this.getIndexedDB().open(this.dbName, this.dbVersion) request.onupgradeneeded = () => { const db = request.result if (!db.objectStoreNames.contains(this.tableName)) { @@ -73,7 +125,11 @@ export class EncryptedPksDb { } async generateAndStore(): Promise { - const encryptionKey = await window.crypto.subtle.generateKey({ name: 'AES-GCM', length: 256 }, true, [ + const crypto = this.getCrypto() + const storage = this.getStorage() + const TextEncoderCtor = this.getTextEncoderCtor() + + const encryptionKey = await crypto.subtle.generateKey({ name: 'AES-GCM', length: 256 }, true, [ 'encrypt', 'decrypt', ]) @@ -84,13 +140,13 @@ export class EncryptedPksDb { const address = Address.fromPublicKey(publicKey) const keyPointer = this.localStorageKeyPrefix + address - const exportedKey = await window.crypto.subtle.exportKey('jwk', encryptionKey) - window.localStorage.setItem(keyPointer, JSON.stringify(exportedKey)) + const exportedKey = await crypto.subtle.exportKey('jwk', encryptionKey) + storage.setItem(keyPointer, JSON.stringify(exportedKey)) - const encoder = new TextEncoder() + const encoder = new TextEncoderCtor() const encodedPk = encoder.encode(privateKey) - const iv = window.crypto.getRandomValues(new Uint8Array(12)) - const encryptedBuffer = await window.crypto.subtle.encrypt({ name: 'AES-GCM', iv }, encryptionKey, encodedPk) + const iv = crypto.getRandomValues(new Uint8Array(12)) + const encryptedBuffer = await crypto.subtle.encrypt({ name: 'AES-GCM', iv }, encryptionKey, encodedPk) const encrypted: EncryptedData = { iv, @@ -113,7 +169,7 @@ export class EncryptedPksDb { async getEncryptedPkStore(address: Address.Address): Promise { const entry = await this.getEncryptedEntry(address) if (!entry) return - return new EncryptedPkStore(entry) + return new EncryptedPkStore(entry, this.env) } async listAddresses(): Promise { @@ -125,12 +181,41 @@ export class EncryptedPksDb { const dbKey = this.computeDbKey(address) await this.putData(dbKey, undefined) const keyPointer = this.localStorageKeyPrefix + address - window.localStorage.removeItem(keyPointer) + this.getStorage().removeItem(keyPointer) } } export class EncryptedPkStore implements PkStore { - constructor(private readonly encrypted: EncryptedData) {} + constructor( + private readonly encrypted: EncryptedData, + private readonly env?: CoreEnv, + ) {} + + private getStorage(): StorageLike { + const storage = resolveCoreEnv(this.env).storage + if (!storage) { + throw new Error('storage is not available') + } + return storage + } + + private getCrypto(): CryptoLike { + const globalObj = globalThis as any + const crypto = this.env?.crypto ?? globalObj.crypto ?? globalObj.window?.crypto + if (!crypto?.subtle) { + throw new Error('crypto.subtle is not available') + } + return crypto + } + + private getTextDecoderCtor(): TextEncodingLike['TextDecoder'] { + const globalObj = globalThis as any + const decoderCtor = this.env?.text?.TextDecoder ?? globalObj.TextDecoder ?? globalObj.window?.TextDecoder + if (!decoderCtor) { + throw new Error('TextDecoder is not available') + } + return decoderCtor + } address(): Address.Address { return this.encrypted.address @@ -141,16 +226,20 @@ export class EncryptedPkStore implements PkStore { } async signDigest(digest: Bytes.Bytes): Promise<{ r: bigint; s: bigint; yParity: number }> { - const keyJson = window.localStorage.getItem(this.encrypted.keyPointer) + const storage = this.getStorage() + const crypto = this.getCrypto() + const TextDecoderCtor = this.getTextDecoderCtor() + + const keyJson = storage.getItem(this.encrypted.keyPointer) if (!keyJson) throw new Error('Encryption key not found in localStorage') const jwk = JSON.parse(keyJson) - const encryptionKey = await window.crypto.subtle.importKey('jwk', jwk, { name: 'AES-GCM' }, false, ['decrypt']) - const decryptedBuffer = await window.crypto.subtle.decrypt( + const encryptionKey = await crypto.subtle.importKey('jwk', jwk, { name: 'AES-GCM' }, false, ['decrypt']) + const decryptedBuffer = await crypto.subtle.decrypt( { name: 'AES-GCM', iv: this.encrypted.iv }, encryptionKey, this.encrypted.data, ) - const decoder = new TextDecoder() + const decoder = new TextDecoderCtor() const privateKey = decoder.decode(decryptedBuffer) as Hex.Hex return Secp256k1.sign({ payload: digest, privateKey }) } diff --git a/packages/wallet/core/src/signers/pk/index.ts b/packages/wallet/core/src/signers/pk/index.ts index 5c26b1dcb9..b15fb3ecbd 100644 --- a/packages/wallet/core/src/signers/pk/index.ts +++ b/packages/wallet/core/src/signers/pk/index.ts @@ -52,7 +52,7 @@ export class Pk implements SignerInterface, Witnessable { return { ...signature, type: 'hash' } } - async witness(stateWriter: State.Writer, wallet: Address.Address, extra?: Object): Promise { + async witness(stateWriter: State.Writer, wallet: Address.Address, extra?: object): Promise { const payload = Payload.fromMessage( Hex.fromString( JSON.stringify({ diff --git a/packages/wallet/core/src/signers/session/explicit.ts b/packages/wallet/core/src/signers/session/explicit.ts index cd72b2256f..b7ad087b4f 100644 --- a/packages/wallet/core/src/signers/session/explicit.ts +++ b/packages/wallet/core/src/signers/session/explicit.ts @@ -1,11 +1,4 @@ -import { - Constants, - Extensions, - Payload, - Permission, - SessionConfig, - SessionSignature, -} from '@0xsequence/wallet-primitives' +import { Constants, Payload, Permission, SessionConfig, SessionSignature } from '@0xsequence/wallet-primitives' import { AbiFunction, AbiParameters, Address, Bytes, Hash, Hex, Provider } from 'ox' import { MemoryPkStore, PkStore } from '../pk/index.js' import { ExplicitSessionSigner, SessionSignerValidity, UsageLimit } from './session.js' @@ -323,7 +316,7 @@ export class Explicit implements ExplicitSessionSigner { Bytes.fromHex(call.data).slice(Number(rule.offset), Number(rule.offset) + 32), 32, ) - let value: Bytes.Bytes = callDataValue.map((b, i) => b & rule.mask[i]!) + const value: Bytes.Bytes = callDataValue.map((b, i) => b & rule.mask[i]!) if (Bytes.toBigInt(value) === 0n) continue // Add to list diff --git a/packages/wallet/core/src/signers/session/implicit.ts b/packages/wallet/core/src/signers/session/implicit.ts index 71b1128650..8eb765808a 100644 --- a/packages/wallet/core/src/signers/session/implicit.ts +++ b/packages/wallet/core/src/signers/session/implicit.ts @@ -1,6 +1,5 @@ import { Attestation, - Extensions, Payload, Signature as SequenceSignature, SessionConfig, @@ -96,7 +95,7 @@ export class Implicit implements ImplicitSessionSigner { ) const expectedResult = Bytes.toHex(Attestation.generateImplicitRequestMagic(this._attestation, wallet)) return acceptImplicitRequest === expectedResult - } catch (error) { + } catch { // console.log('implicit signer unsupported call', call, error) return false } diff --git a/packages/wallet/core/src/state/local/index.ts b/packages/wallet/core/src/state/local/index.ts index b3200c8445..282de20e0a 100644 --- a/packages/wallet/core/src/state/local/index.ts +++ b/packages/wallet/core/src/state/local/index.ts @@ -203,7 +203,7 @@ export class Provider implements ProviderInterface { fromImageHash: Hex.Hex, options?: { allUpdates?: boolean }, ): Promise<{ imageHash: Hex.Hex; signature: Signature.RawSignature }[]> { - let fromConfig = await this.store.loadConfig(fromImageHash) + const fromConfig = await this.store.loadConfig(fromImageHash) if (!fromConfig) { return [] } @@ -384,7 +384,7 @@ export class Provider implements ProviderInterface { if (Signature.isSignatureOfSapientSignerLeaf(topology.signature)) { switch (topology.signature.address.toLowerCase()) { - case this.extensions.passkeys.toLowerCase(): + case this.extensions.passkeys.toLowerCase(): { const decoded = Extensions.Passkeys.decode(Bytes.fromHex(topology.signature.data)) if (!Extensions.Passkeys.isValidSignature(subdigest, decoded)) { @@ -397,6 +397,8 @@ export class Provider implements ProviderInterface { Extensions.Passkeys.rootFor(decoded.publicKey), topology.signature, ) + } + default: throw new Error(`Unsupported sapient signer: ${topology.signature.address}`) } diff --git a/packages/wallet/core/src/state/local/indexed-db.ts b/packages/wallet/core/src/state/local/indexed-db.ts index 98a43743c2..eeb5cd346f 100644 --- a/packages/wallet/core/src/state/local/indexed-db.ts +++ b/packages/wallet/core/src/state/local/indexed-db.ts @@ -1,5 +1,6 @@ import { Context, Payload, Signature, Config, GenericTree } from '@0xsequence/wallet-primitives' import { Address, Hex } from 'ox' +import type { CoreEnv } from '../../env.js' import { Store } from './index.js' const DB_VERSION = 1 @@ -16,15 +17,27 @@ export class IndexedDbStore implements Store { private _db: IDBDatabase | null = null private dbName: string - constructor(dbName: string = 'sequence-indexeddb') { + constructor( + dbName: string = 'sequence-indexeddb', + private readonly env?: CoreEnv, + ) { this.dbName = dbName } + private getIndexedDB(): IDBFactory { + const globalObj = globalThis as any + const indexedDb = this.env?.indexedDB ?? globalObj.indexedDB ?? globalObj.window?.indexedDB + if (!indexedDb) { + throw new Error('indexedDB is not available') + } + return indexedDb + } + private async openDB(): Promise { if (this._db) return this._db return new Promise((resolve, reject) => { - const request = indexedDB.open(this.dbName, DB_VERSION) + const request = this.getIndexedDB().open(this.dbName, DB_VERSION) request.onupgradeneeded = () => { const db = request.result diff --git a/packages/wallet/core/src/state/remote/dev-http.ts b/packages/wallet/core/src/state/remote/dev-http.ts index d7fe0f4921..7c288e050a 100644 --- a/packages/wallet/core/src/state/remote/dev-http.ts +++ b/packages/wallet/core/src/state/remote/dev-http.ts @@ -4,10 +4,16 @@ import { Provider } from '../index.js' export class DevHttpProvider implements Provider { private readonly baseUrl: string + private readonly fetcher: typeof fetch - constructor(baseUrl: string) { + constructor(baseUrl: string, fetcher?: typeof fetch) { // Remove trailing slash if present this.baseUrl = baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl + const resolvedFetch = fetcher ?? (globalThis as any).fetch + if (!resolvedFetch) { + throw new Error('fetch is not available') + } + this.fetcher = resolvedFetch } private async request(method: 'GET' | 'POST', path: string, body?: any): Promise { @@ -24,7 +30,7 @@ export class DevHttpProvider implements Provider { let response: Response try { - response = await fetch(url, options) + response = await this.fetcher(url, options) } catch (networkError) { // Handle immediate network errors (e.g., DNS resolution failure, refused connection) console.error(`Network error during ${method} request to ${url}:`, networkError) @@ -38,12 +44,12 @@ export class DevHttpProvider implements Provider { const errorText = await response.text() const errorJson = await Utils.fromJSON(errorText) errorPayload = { ...errorPayload, ...errorJson } - } catch (e) { + } catch { try { // If JSON parsing fails, try getting text for better error message const errorText = await response.text() errorPayload.body = errorText - } catch (textErr) { + } catch { // Ignore if reading text also fails } } @@ -99,7 +105,7 @@ export class DevHttpProvider implements Provider { throw new Error( `Failed to parse JSON response from server. Status: ${response.status}. Body: "${text}". Original error: ${error instanceof Error ? error.message : String(error)}`, ) - } catch (readError) { + } catch { throw new Error( `Failed to parse JSON response from server and could not read response body as text. Status: ${response.status}. Original error: ${error instanceof Error ? error.message : String(error)}`, ) diff --git a/packages/wallet/core/src/state/sequence/index.ts b/packages/wallet/core/src/state/sequence/index.ts index 3712f2aa55..0842111530 100644 --- a/packages/wallet/core/src/state/sequence/index.ts +++ b/packages/wallet/core/src/state/sequence/index.ts @@ -9,13 +9,17 @@ import { TransactionRequest, } from 'ox' import { normalizeAddressKeys, Provider as ProviderInterface } from '../index.js' -import { Sessions, SignatureType } from './sessions.gen.js' +import { Sessions, SignatureType, type Fetch } from './sessions.gen.js' export class Provider implements ProviderInterface { private readonly service: Sessions - constructor(host = 'https://keymachine.sequence.app') { - this.service = new Sessions(host, fetch) + constructor(host = 'https://keymachine.sequence.app', fetcher?: Fetch) { + const resolvedFetch = fetcher ?? (globalThis as any).fetch + if (!resolvedFetch) { + throw new Error('fetch is not available') + } + this.service = new Sessions(host, resolvedFetch) } async getConfiguration(imageHash: Hex.Hex): Promise { @@ -186,7 +190,9 @@ export class Provider implements ProviderInterface { case SignatureType.SapientCompact: throw new Error(`unexpected compact sapient signature by ${signer}`) } - } catch {} + } catch { + // ignore + } } async getWitnessForSapient( @@ -221,7 +227,9 @@ export class Provider implements ProviderInterface { signature: { type: 'sapient_compact', address: signer, data: witness.signature }, } } - } catch {} + } catch { + // ignore + } } async getConfigurationUpdates( @@ -380,7 +388,7 @@ const recoverSapientSignatureCompactFunction = AbiFunction.from(recoverSapientSi class PasskeySignatureValidator implements oxProvider.Provider { request: oxProvider.Provider['request'] = (async (request) => { switch (request.method) { - case 'eth_call': + case 'eth_call': { if (!request.params || !Array.isArray(request.params) || request.params.length === 0) { throw new Error('eth_call requires transaction parameters') } @@ -406,6 +414,7 @@ class PasskeySignatureValidator implements oxProvider.Provider { } else { throw new Error(`invalid passkey signature ${signature} for digest ${digest}`) } + } default: throw new Error(`method ${request.method} not implemented`) diff --git a/packages/wallet/core/src/wallet.ts b/packages/wallet/core/src/wallet.ts index 05a02da09e..0377dd336b 100644 --- a/packages/wallet/core/src/wallet.ts +++ b/packages/wallet/core/src/wallet.ts @@ -355,7 +355,7 @@ export class Wallet { throw new Error('4337 is not enabled in this wallet') } - const noncePromise = this.get4337Nonce(provider, status.context.capabilities?.erc4337?.entrypoint!, space) + const noncePromise = this.get4337Nonce(provider, status.context.capabilities.erc4337.entrypoint, space) // If the wallet is not deployed, then we need to include the initCode on // the 4337 transaction @@ -570,7 +570,7 @@ export class Wallet { if (typeof message !== 'string') { encodedMessage = TypedData.encode(message) } else { - let hexMessage = Hex.validate(message) ? message : Hex.fromString(message) + const hexMessage = Hex.validate(message) ? message : Hex.fromString(message) const messageSize = Hex.size(hexMessage) encodedMessage = Hex.concat(Hex.fromString(`${`\x19Ethereum Signed Message:\n${messageSize}`}`), hexMessage) } diff --git a/packages/wallet/core/test/constants.ts b/packages/wallet/core/test/constants.ts index 493bf6bf21..63e862f380 100644 --- a/packages/wallet/core/test/constants.ts +++ b/packages/wallet/core/test/constants.ts @@ -1,6 +1,7 @@ import { config as dotenvConfig } from 'dotenv' import { Abi, AbiEvent, Address } from 'ox' +// eslint-disable-next-line turbo/no-undeclared-env-vars const envFile = process.env.CI ? '.env.test' : '.env.test.local' dotenvConfig({ path: envFile }) @@ -16,4 +17,5 @@ export const EMITTER_EVENT_TOPICS = [ export const USDC_ADDRESS: Address.Address = '0xaf88d065e77c8cc2239327c5edb3a432268e5831' // Environment variables +// eslint-disable-next-line turbo/no-undeclared-env-vars export const LOCAL_RPC_URL = process.env.LOCAL_RPC_URL || 'http://localhost:8545' diff --git a/packages/wallet/core/test/envelope.test.ts b/packages/wallet/core/test/envelope.test.ts index 8ecc0e2824..c92cf900eb 100644 --- a/packages/wallet/core/test/envelope.test.ts +++ b/packages/wallet/core/test/envelope.test.ts @@ -6,7 +6,6 @@ import * as Envelope from '../src/envelope.js' // Test addresses and data const TEST_ADDRESS_1 = Address.from('0x1234567890123456789012345678901234567890') -const TEST_ADDRESS_2 = Address.from('0xabcdefabcdefabcdefabcdefabcdefabcdefabcd') const TEST_ADDRESS_3 = Address.from('0x9876543210987654321098765432109876543210') const TEST_WALLET = Address.from('0xfedcbafedcbafedcbafedcbafedcbafedcbafe00') const TEST_IMAGE_HASH = Hex.from('0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef') diff --git a/packages/wallet/core/test/signers-pk.test.ts b/packages/wallet/core/test/signers-pk.test.ts index 4121ffb685..7a696cf6c2 100644 --- a/packages/wallet/core/test/signers-pk.test.ts +++ b/packages/wallet/core/test/signers-pk.test.ts @@ -143,7 +143,7 @@ describe('Private Key Signers', () => { await pk.witness(mockStateWriter, testWallet) expect(mockStateWriter.saveWitnesses).toHaveBeenCalledTimes(1) - const [wallet, chainId, payload, witness] = vi.mocked(mockStateWriter.saveWitnesses).mock.calls[0] + const [wallet, chainId, _payload, witness] = vi.mocked(mockStateWriter.saveWitnesses).mock.calls[0] expect(wallet).toBe(testWallet) expect(chainId).toBe(0) diff --git a/packages/wallet/core/test/signers-session-implicit.test.ts b/packages/wallet/core/test/signers-session-implicit.test.ts index ed66a50afc..5b0a370823 100644 --- a/packages/wallet/core/test/signers-session-implicit.test.ts +++ b/packages/wallet/core/test/signers-session-implicit.test.ts @@ -236,7 +236,6 @@ describe('Implicit Session', () => { }, } const identitySignature = createValidIdentitySignature(attestation) - const topology = createValidTopology() // This should throw an error during construction due to future issued time expect(() => { @@ -250,7 +249,6 @@ describe('Implicit Session', () => { approvedSigner: randomAddress(), // Different approved signer } const identitySignature = createValidIdentitySignature(attestation) - const topology = createValidTopology() // This should throw an error during construction due to mismatched approved signer expect(() => { diff --git a/packages/wallet/core/test/state/debug.test.ts b/packages/wallet/core/test/state/debug.test.ts index 4824297abb..6882f45a20 100644 --- a/packages/wallet/core/test/state/debug.test.ts +++ b/packages/wallet/core/test/state/debug.test.ts @@ -5,7 +5,6 @@ import { multiplex } from '../../src/state/debug.js' // Test data const TEST_ADDRESS = Address.from('0x1234567890123456789012345678901234567890') -const TEST_HEX = Hex.from('0xabcdef123456') const TEST_UINT8ARRAY = new Uint8Array([171, 205, 239, 18, 52, 86]) describe('State Debug', () => { @@ -241,13 +240,13 @@ describe('State Debug', () => { } const complexRef: ComplexInterface = { - async complexMethod(data) { + async complexMethod() { return 'complex-ref' }, } const complexCand: ComplexInterface = { - async complexMethod(data) { + async complexMethod() { return 'complex-cand' }, } diff --git a/packages/wallet/dapp-client/CHANGELOG.md b/packages/wallet/dapp-client/CHANGELOG.md index 322d41ff77..92d9641edb 100644 --- a/packages/wallet/dapp-client/CHANGELOG.md +++ b/packages/wallet/dapp-client/CHANGELOG.md @@ -1,5 +1,164 @@ # @0xsequence/dapp-client +## 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 diff --git a/packages/wallet/dapp-client/eslint.config.js b/packages/wallet/dapp-client/eslint.config.js new file mode 100644 index 0000000000..cecf89b031 --- /dev/null +++ b/packages/wallet/dapp-client/eslint.config.js @@ -0,0 +1,4 @@ +import { config as baseConfig } from "@repo/eslint-config/base" + +/** @type {import("eslint").Linter.Config} */ +export default baseConfig diff --git a/packages/wallet/dapp-client/package.json b/packages/wallet/dapp-client/package.json index 4b76c39dee..afe59a0bc9 100644 --- a/packages/wallet/dapp-client/package.json +++ b/packages/wallet/dapp-client/package.json @@ -1,6 +1,6 @@ { "name": "@0xsequence/dapp-client", - "version": "3.0.0-beta.9", + "version": "3.0.0", "license": "Apache-2.0", "type": "module", "publishConfig": { @@ -11,7 +11,8 @@ "build": "tsc", "dev": "tsc --watch", "typecheck": "tsc --noEmit", - "clean": "rimraf dist" + "clean": "rimraf dist", + "lint": "eslint . --max-warnings 0" }, "exports": { ".": { @@ -20,14 +21,15 @@ } }, "devDependencies": { + "@repo/eslint-config": "workspace:^", "@repo/typescript-config": "workspace:^", - "@types/node": "^25.0.2", - "@vitest/coverage-v8": "^4.0.15", - "dotenv": "^17.2.3", + "@types/node": "^25.3.0", + "@vitest/coverage-v8": "^4.0.18", + "dotenv": "^17.3.1", "fake-indexeddb": "^6.2.5", - "happy-dom": "^20.0.11", + "happy-dom": "^20.7.0", "typescript": "^5.9.3", - "vitest": "^4.0.15" + "vitest": "^4.0.18" }, "dependencies": { "@0xsequence/guard": "workspace:^", diff --git a/packages/wallet/dapp-client/src/ChainSessionManager.ts b/packages/wallet/dapp-client/src/ChainSessionManager.ts index cd67c6b609..a57e2c2324 100644 --- a/packages/wallet/dapp-client/src/ChainSessionManager.ts +++ b/packages/wallet/dapp-client/src/ChainSessionManager.ts @@ -37,12 +37,14 @@ import { TransportMode, GuardConfig, CreateNewSessionPayload, + EthAuthSettings, ModifyExplicitSessionPayload, SessionResponse, AddExplicitSessionPayload, FeeOption, OperationFailedStatus, OperationStatus, + ETHAuthProof, } from './types/index.js' import { CACHE_DB_NAME, VALUE_FORWARDER_ADDRESS } from './utils/constants.js' import { ExplicitSession, ImplicitSession, ExplicitSessionConfig } from './index.js' @@ -84,6 +86,11 @@ export class ChainSessionManager { public loginMethod: LoginMethod | null = null public userEmail: string | null = null private guard?: GuardConfig + private lastSignedCallCache?: { + fingerprint: string + signedCall: { to: Address.Address; data: Hex.Hex } + createdAtMs: number + } /** * @param chainId The ID of the chain this manager is responsible for. @@ -151,11 +158,11 @@ export class ChainSessionManager { listener: ChainSessionManagerEventMap[K], ): () => void { if (!this.eventListeners[event]) { - this.eventListeners[event] = new Set() as any + this.eventListeners[event] = new Set() } - ;(this.eventListeners[event] as any).add(listener) + this.eventListeners[event].add(listener) return () => { - ;(this.eventListeners[event] as any)?.delete(listener) + this.eventListeners[event]?.delete(listener) } } @@ -280,6 +287,7 @@ export class ChainSessionManager { preferredLoginMethod?: LoginMethod email?: string includeImplicitSession?: boolean + ethAuth?: EthAuthSettings } = {}, ): Promise { if (this.isInitialized) { @@ -306,6 +314,7 @@ export class ChainSessionManager { origin, session: completeSession as ExplicitSession | undefined, includeImplicitSession: options.includeImplicitSession ?? false, + ethAuth: options.ethAuth, preferredLoginMethod: options.preferredLoginMethod, email: options.preferredLoginMethod === 'email' ? options.email : undefined, } @@ -372,6 +381,10 @@ export class ChainSessionManager { this.guard = guard } + if (payload.ethAuth) { + await this._saveEthAuthProofIfProvided(connectResponse.ethAuthProof) + } + if (this.transport.mode === TransportMode.POPUP) { this.transport.closeWallet() } @@ -591,6 +604,10 @@ export class ChainSessionManager { this.userEmail = userEmail ?? null this.guard = guard } + + if (savedPayload?.ethAuth) { + await this._saveEthAuthProofIfProvided(connectResponse.ethAuthProof) + } } else if (response.action === RequestActionType.ADD_EXPLICIT_SESSION) { if (!this.walletAddress || !Address.isEqual(receivedAddress, this.walletAddress)) { throw new InitializationError('Received an explicit session for a wallet that is not active.') @@ -811,19 +828,6 @@ export class ChainSessionManager { await this.sessionManager.findSignersForCalls(this.wallet.address, this.chainId, calls) return true } catch (error) { - if (error instanceof Error && error.message.includes('Signer supporting call is expired')) { - // Extract the expired signer address from the message with address regex - const expiredSignerAddress = error.message.match(/(0x[0-9a-fA-F]{40})/)?.[1] - if (expiredSignerAddress) { - // Refresh the session - await this._refreshExplicitSession(Address.from(expiredSignerAddress)) - // Retry the permission check - return this.hasPermission(transactions) - } else { - // Could not parse error message. Rethrow as this shouldn't happen. - throw error - } - } // An error from findSignersForCalls indicates a permission failure. console.warn( `Permission check failed for chain ${this.chainId}:`, @@ -851,7 +855,17 @@ export class ChainSessionManager { })) try { const signedCall = await this._buildAndSignCalls(callsToSend) - const feeOptions = await this.relayer.feeOptions(signedCall.to, this.chainId, callsToSend) + const fingerprint = this._fingerprintCalls(callsToSend) + if (fingerprint) { + this.lastSignedCallCache = { + fingerprint, + signedCall, + createdAtMs: Date.now(), + } + } + const walletAddress = this.walletAddress + if (!walletAddress) throw new InitializationError('Wallet is not initialized.') + const feeOptions = await this.relayer.feeOptions(walletAddress, this.chainId, signedCall.to, callsToSend) return feeOptions.options } catch (err) { throw new FeeOptionError(`Failed to get fee options: ${err instanceof Error ? err.message : String(err)}`) @@ -907,7 +921,7 @@ export class ChainSessionManager { callsToSend.unshift(transferCall) } } - const signedCalls = await this._buildAndSignCalls(callsToSend) + const signedCalls = this._getCachedSignedCall(callsToSend) ?? (await this._buildAndSignCalls(callsToSend)) const hash = await this.relayer.relay(signedCalls.to, signedCalls.data, this.chainId) const status = await this._waitForTransactionReceipt(hash.opHash, this.chainId) if (status.status === 'confirmed') { @@ -1101,4 +1115,49 @@ export class ChainSessionManager { await this.sequenceStorage.clearExplicitSessions() await this.sequenceStorage.clearSessionlessConnection() } + + private async _saveEthAuthProofIfProvided(ethAuthProof?: ETHAuthProof): Promise { + if (!ethAuthProof) { + return + } + await this.sequenceStorage.saveEthAuthProof(ethAuthProof) + } + + private _getCachedSignedCall(calls: Payload.Call[]): { to: Address.Address; data: Hex.Hex } | null { + if (!this.lastSignedCallCache) { + return null + } + const ttlMs = 30_000 + if (Date.now() - this.lastSignedCallCache.createdAtMs > ttlMs) { + this.lastSignedCallCache = undefined + return null + } + const fingerprint = this._fingerprintCalls(calls) + if (!fingerprint) { + return null + } + if (fingerprint !== this.lastSignedCallCache.fingerprint) { + return null + } + return this.lastSignedCallCache.signedCall + } + + private _fingerprintCalls(calls: Payload.Call[]): string | null { + try { + return JSON.stringify( + calls.map((call) => ({ + to: call.to, + value: call.value?.toString() ?? '0', + data: call.data ?? '0x', + gasLimit: call.gasLimit?.toString() ?? '0', + delegateCall: call.delegateCall ?? false, + onlyFallback: call.onlyFallback ?? false, + behaviorOnError: call.behaviorOnError ?? 'revert', + })), + ) + } catch (error) { + console.warn('ChainSessionManager._fingerprintCalls failed:', error) + return null + } + } } diff --git a/packages/wallet/dapp-client/src/DappClient.ts b/packages/wallet/dapp-client/src/DappClient.ts index 3c5a29cba9..e580bd9127 100644 --- a/packages/wallet/dapp-client/src/DappClient.ts +++ b/packages/wallet/dapp-client/src/DappClient.ts @@ -14,8 +14,10 @@ import { GetFeeTokensResponse, GuardConfig, LoginMethod, + EthAuthSettings, RandomPrivateKeyFn, RequestActionType, + ETHAuthProof, SendWalletTransactionPayload, SequenceSessionStorage, SignMessagePayload, @@ -30,7 +32,7 @@ import { KEYMACHINE_URL, NODES_URL, RELAYER_URL } from './utils/constants.js' import { getRelayerUrl, getRpcUrl } from './utils/index.js' import { Relayer } from '@0xsequence/relayer' -export type DappClientEventListener = (data?: any) => void +export type DappClientEventListener = (data?: unknown) => void interface DappClientEventMap { sessionsUpdated: () => void @@ -180,11 +182,12 @@ export class DappClient { */ public on(event: K, listener: DappClientEventMap[K]): () => void { if (!this.eventListeners[event]) { - this.eventListeners[event] = new Set() as any + // @ts-expect-error - indexing into evenListeners will improperly create a union of all the possible types + this.eventListeners[event] = new Set() } - ;(this.eventListeners[event] as any).add(listener) + this.eventListeners[event].add(listener) return () => { - ;(this.eventListeners[event] as any)?.delete(listener) + this.eventListeners[event]?.delete(listener) } } @@ -407,6 +410,13 @@ export class DappClient { } } + /** + * Returns the latest persisted ETHAuth proof, if one has been received from the wallet. + */ + public async getEthAuthProof(): Promise { + return this.sequenceStorage.getEthAuthProof() + } + /** * Restores a sessionless connection that was previously persisted via {@link disconnect} or a connect flow. * @returns A promise that resolves to true if a sessionless connection was applied. @@ -559,6 +569,7 @@ export class DappClient { preferredLoginMethod?: LoginMethod email?: string includeImplicitSession?: boolean + ethAuth?: EthAuthSettings } = {}, ): Promise { if (this.isInitialized) { @@ -614,6 +625,7 @@ export class DappClient { preferredLoginMethod?: LoginMethod email?: string includeImplicitSession?: boolean + ethAuth?: EthAuthSettings } = {}, ): Promise { if (!this.isInitialized || !this.hasSessionlessConnection || !this.walletAddress) { @@ -965,8 +977,6 @@ export class DappClient { async disconnect(options?: { keepSessionlessConnection?: boolean }): Promise { const keepSessionlessConnection = options?.keepSessionlessConnection ?? true - const transportMode = this.transportMode - if (this.transport) { this.transport.destroy() } diff --git a/packages/wallet/dapp-client/src/DappTransport.ts b/packages/wallet/dapp-client/src/DappTransport.ts index 502c238bd3..090b1070b8 100644 --- a/packages/wallet/dapp-client/src/DappTransport.ts +++ b/packages/wallet/dapp-client/src/DappTransport.ts @@ -378,10 +378,7 @@ export class DappTransport { return } - const isPotentiallyValidSource = - this.walletWindow && (event.source === this.walletWindow || !this.walletWindow.closed) - - if (!isPotentiallyValidSource && event.data?.type !== MessageType.WALLET_OPENED) { + if (!this.walletWindow || event.source !== this.walletWindow) { return } diff --git a/packages/wallet/dapp-client/src/index.ts b/packages/wallet/dapp-client/src/index.ts index c2315b1384..ce976c13d4 100644 --- a/packages/wallet/dapp-client/src/index.ts +++ b/packages/wallet/dapp-client/src/index.ts @@ -24,6 +24,8 @@ export type { FeeToken, FeeOption, TransportMessage, + EthAuthSettings, + ETHAuthProof, } from './types/index.js' export { RequestActionType, TransportMode, MessageType } from './types/index.js' export { diff --git a/packages/wallet/dapp-client/src/types/index.ts b/packages/wallet/dapp-client/src/types/index.ts index 6a0eb08daf..0f023c2bb8 100644 --- a/packages/wallet/dapp-client/src/types/index.ts +++ b/packages/wallet/dapp-client/src/types/index.ts @@ -28,12 +28,32 @@ export interface GuardConfig { moduleAddresses: Map } +export interface EthAuthSettings { + app?: string + /** expiry number (in seconds) that is used for ETHAuth proof. Default is 1 week in seconds. */ + expiry?: number + /** origin hint of the dapp's host opening the wallet. This value will automatically + * be determined and verified for integrity, and can be omitted. */ + origin?: string + /** authorizeNonce is an optional number to be passed as ETHAuth's nonce claim for replay protection. **/ + nonce?: number +} + +export interface ETHAuthProof { + // eip712 typed-data payload for ETHAuth domain as input + typedData: Payload.TypedDataToSign + + // signature encoded in an ETHAuth proof string + ewtString: string +} + // --- Payloads for Transport --- export interface CreateNewSessionPayload { origin?: string session?: ExplicitSession includeImplicitSession?: boolean + ethAuth?: EthAuthSettings preferredLoginMethod?: LoginMethod email?: string } @@ -81,6 +101,7 @@ export interface CreateNewSessionResponse { userEmail?: string loginMethod?: LoginMethod guard?: GuardConfig + ethAuthProof?: ETHAuthProof } export interface SignatureResponse { diff --git a/packages/wallet/dapp-client/src/utils/storage.ts b/packages/wallet/dapp-client/src/utils/storage.ts index 8928d354e5..8a56015ba9 100644 --- a/packages/wallet/dapp-client/src/utils/storage.ts +++ b/packages/wallet/dapp-client/src/utils/storage.ts @@ -5,6 +5,7 @@ import { SignMessagePayload, SignTypedDataPayload, GuardConfig, + ETHAuthProof, SendWalletTransactionPayload, ModifyExplicitSessionPayload, CreateNewSessionPayload, @@ -81,6 +82,10 @@ export interface SequenceStorage { getSessionlessConnection(): Promise clearSessionlessConnection(): Promise + saveEthAuthProof(proof: ETHAuthProof): Promise + getEthAuthProof(): Promise + clearEthAuthProof(): Promise + saveSessionlessConnectionSnapshot?(sessionData: SessionlessConnectionData): Promise getSessionlessConnectionSnapshot?(): Promise clearSessionlessConnectionSnapshot?(): Promise @@ -94,6 +99,7 @@ const STORE_NAME = 'userKeys' const IMPLICIT_SESSIONS_IDB_KEY = 'SequenceImplicitSession' const EXPLICIT_SESSIONS_IDB_KEY = 'SequenceExplicitSession' const SESSIONLESS_CONNECTION_IDB_KEY = 'SequenceSessionlessConnection' +const ETH_AUTH_PROOF_IDB_KEY = 'SequenceEthAuthProof' const SESSIONLESS_CONNECTION_SNAPSHOT_IDB_KEY = 'SequenceSessionlessConnectionSnapshot' const PENDING_REDIRECT_REQUEST_KEY = 'SequencePendingRedirect' @@ -305,6 +311,15 @@ export class WebStorage implements SequenceStorage { } } + async saveEthAuthProof(proof: ETHAuthProof): Promise { + try { + await this.setIDBItem(ETH_AUTH_PROOF_IDB_KEY, proof) + } catch (error) { + console.error('Failed to save ETHAuth proof:', error) + throw error + } + } + async getSessionlessConnection(): Promise { try { return (await this.getIDBItem(SESSIONLESS_CONNECTION_IDB_KEY)) ?? null @@ -314,6 +329,15 @@ export class WebStorage implements SequenceStorage { } } + async getEthAuthProof(): Promise { + try { + return (await this.getIDBItem(ETH_AUTH_PROOF_IDB_KEY)) ?? null + } catch (error) { + console.error('Failed to retrieve ETHAuth proof:', error) + return null + } + } + async clearSessionlessConnection(): Promise { try { await this.deleteIDBItem(SESSIONLESS_CONNECTION_IDB_KEY) @@ -323,6 +347,15 @@ export class WebStorage implements SequenceStorage { } } + async clearEthAuthProof(): Promise { + try { + await this.deleteIDBItem(ETH_AUTH_PROOF_IDB_KEY) + } catch (error) { + console.error('Failed to clear ETHAuth proof:', error) + throw error + } + } + async saveSessionlessConnectionSnapshot(sessionData: SessionlessConnectionData): Promise { try { await this.setIDBItem(SESSIONLESS_CONNECTION_SNAPSHOT_IDB_KEY, sessionData) @@ -363,6 +396,7 @@ export class WebStorage implements SequenceStorage { await this.clearExplicitSessions() await this.clearImplicitSession() await this.clearSessionlessConnection() + await this.clearEthAuthProof() await this.clearSessionlessConnectionSnapshot() } catch (error) { console.error('Failed to clear all data:', error) diff --git a/packages/wallet/dapp-client/test/ethauth-proof.test.ts b/packages/wallet/dapp-client/test/ethauth-proof.test.ts new file mode 100644 index 0000000000..93273f0d6a --- /dev/null +++ b/packages/wallet/dapp-client/test/ethauth-proof.test.ts @@ -0,0 +1,207 @@ +import { afterEach, describe, expect, it, vi } from 'vitest' + +import { DappClient } from '../src/DappClient.js' +import { DappTransport } from '../src/DappTransport.js' +import { RequestActionType, TransportMode } from '../src/types/index.js' +import { WebStorage } from '../src/utils/storage.js' + +describe('ETHAuth proof persistence', () => { + afterEach(() => { + vi.restoreAllMocks() + vi.unstubAllGlobals() + }) + + const createSequenceStorageMock = () => ({ + setPendingRedirectRequest: vi.fn().mockResolvedValue(undefined), + isRedirectRequestPending: vi.fn().mockResolvedValue(false), + saveTempSessionPk: vi.fn().mockResolvedValue(undefined), + getAndClearTempSessionPk: vi.fn().mockResolvedValue(null), + savePendingRequest: vi.fn().mockResolvedValue(undefined), + getAndClearPendingRequest: vi.fn().mockResolvedValue(null), + peekPendingRequest: vi.fn().mockResolvedValue(null), + saveExplicitSession: vi.fn().mockResolvedValue(undefined), + getExplicitSessions: vi.fn().mockResolvedValue([]), + clearExplicitSessions: vi.fn().mockResolvedValue(undefined), + saveImplicitSession: vi.fn().mockResolvedValue(undefined), + getImplicitSession: vi.fn().mockResolvedValue(null), + clearImplicitSession: vi.fn().mockResolvedValue(undefined), + saveSessionlessConnection: vi.fn().mockResolvedValue(undefined), + getSessionlessConnection: vi.fn().mockResolvedValue(null), + clearSessionlessConnection: vi.fn().mockResolvedValue(undefined), + saveEthAuthProof: vi.fn().mockResolvedValue(undefined), + getEthAuthProof: vi.fn().mockResolvedValue(null), + clearEthAuthProof: vi.fn().mockResolvedValue(undefined), + clearAllData: vi.fn().mockResolvedValue(undefined), + }) + + it('persists ETHAuth proof when connect requests ethAuth in redirect mode', async () => { + const fetchMock = vi.fn() + vi.stubGlobal('fetch', fetchMock) + vi.stubGlobal('window', { fetch: fetchMock }) + + const ethAuthProof = { + typedData: { + domain: {}, + types: {}, + message: {}, + }, + ewtString: 'proof-string', + } + + const sequenceStorage = createSequenceStorageMock() + const sendRequestMock = vi.spyOn(DappTransport.prototype, 'sendRequest').mockResolvedValue({ + walletAddress: '0x1111111111111111111111111111111111111111', + ethAuthProof, + }) + + const client = new DappClient('https://wallet.example', 'https://dapp.example', 'test-project-access-key', { + sequenceStorage, + transportMode: TransportMode.REDIRECT, + canUseIndexedDb: false, + redirectActionHandler: vi.fn(), + }) + + await client.connect(1, undefined, { + ethAuth: { + app: 'app-name', + }, + }) + + expect(sendRequestMock).toHaveBeenCalledWith( + RequestActionType.CREATE_NEW_SESSION, + 'https://dapp.example', + expect.objectContaining({ + ethAuth: { + app: 'app-name', + }, + }), + expect.any(Object), + ) + expect(sequenceStorage.saveEthAuthProof).toHaveBeenCalledWith(ethAuthProof) + }) + + it('persists ETHAuth proof when connect requests ethAuth in popup mode', async () => { + const fetchMock = vi.fn() + vi.stubGlobal('fetch', fetchMock) + vi.stubGlobal('window', { fetch: fetchMock }) + vi.stubGlobal('document', {}) + + const ethAuthProof = { + typedData: { + domain: {}, + types: {}, + message: {}, + }, + ewtString: 'proof-string', + } + + const sequenceStorage = createSequenceStorageMock() + const sendRequestMock = vi.spyOn(DappTransport.prototype, 'sendRequest').mockResolvedValue({ + walletAddress: '0x1111111111111111111111111111111111111111', + ethAuthProof, + }) + + const client = new DappClient('https://wallet.example', 'https://dapp.example', 'test-project-access-key', { + sequenceStorage, + transportMode: TransportMode.POPUP, + canUseIndexedDb: false, + }) + + await client.connect(1, undefined, { + ethAuth: { + app: 'app-name', + }, + }) + + expect(sendRequestMock).toHaveBeenCalledWith( + RequestActionType.CREATE_NEW_SESSION, + 'https://dapp.example', + expect.objectContaining({ + ethAuth: { + app: 'app-name', + }, + }), + expect.any(Object), + ) + expect(sequenceStorage.saveEthAuthProof).toHaveBeenCalledWith(ethAuthProof) + }) + + it('does not persist ETHAuth proof when connect does not request ethAuth', async () => { + const fetchMock = vi.fn() + vi.stubGlobal('fetch', fetchMock) + vi.stubGlobal('window', { fetch: fetchMock }) + + const ethAuthProof = { + typedData: { + domain: {}, + types: {}, + message: {}, + }, + ewtString: 'proof-string', + } + + const sequenceStorage = createSequenceStorageMock() + const sendRequestMock = vi.spyOn(DappTransport.prototype, 'sendRequest').mockResolvedValue({ + walletAddress: '0x1111111111111111111111111111111111111111', + ethAuthProof, + }) + + const client = new DappClient('https://wallet.example', 'https://dapp.example', 'test-project-access-key', { + sequenceStorage, + transportMode: TransportMode.REDIRECT, + canUseIndexedDb: false, + redirectActionHandler: vi.fn(), + }) + + await client.connect(1) + + expect(sendRequestMock).toHaveBeenCalledWith( + RequestActionType.CREATE_NEW_SESSION, + 'https://dapp.example', + expect.not.objectContaining({ + ethAuth: expect.anything(), + }), + expect.any(Object), + ) + expect(sequenceStorage.saveEthAuthProof).not.toHaveBeenCalled() + }) + + it('clears ETHAuth proof on disconnect', async () => { + const fetchMock = vi.fn() + vi.stubGlobal('fetch', fetchMock) + vi.stubGlobal('window', { fetch: fetchMock }) + + const ethAuthProof = { + typedData: { + domain: {}, + types: {}, + message: {}, + }, + ewtString: 'proof-string', + } + + vi.spyOn(DappTransport.prototype, 'sendRequest').mockResolvedValue({ + walletAddress: '0x1111111111111111111111111111111111111111', + ethAuthProof, + }) + + const client = new DappClient('https://wallet.example', 'https://dapp.example', 'test-project-access-key', { + sequenceStorage: new WebStorage(), + transportMode: TransportMode.REDIRECT, + canUseIndexedDb: false, + redirectActionHandler: vi.fn(), + }) + + await client.connect(1, undefined, { + ethAuth: { + app: 'app-name', + }, + }) + + expect(await client.getEthAuthProof()).toEqual(ethAuthProof) + + await client.disconnect() + + expect(await client.getEthAuthProof()).toBeNull() + }) +}) diff --git a/packages/wallet/primitives-cli/eslint.config.js b/packages/wallet/primitives-cli/eslint.config.js new file mode 100644 index 0000000000..cecf89b031 --- /dev/null +++ b/packages/wallet/primitives-cli/eslint.config.js @@ -0,0 +1,4 @@ +import { config as baseConfig } from "@repo/eslint-config/base" + +/** @type {import("eslint").Linter.Config} */ +export default baseConfig diff --git a/packages/wallet/primitives-cli/package.json b/packages/wallet/primitives-cli/package.json index 0a8c978d41..ec35fc66e7 100644 --- a/packages/wallet/primitives-cli/package.json +++ b/packages/wallet/primitives-cli/package.json @@ -23,11 +23,11 @@ "devDependencies": { "@repo/eslint-config": "workspace:^", "@repo/typescript-config": "workspace:^", - "@types/node": "^25.0.2", + "@types/node": "^25.3.0", "@types/yargs": "^17.0.35", "concurrently": "^9.2.1", - "esbuild": "^0.27.1", - "nodemon": "^3.1.11", + "esbuild": "^0.27.3", + "nodemon": "^3.1.14", "typescript": "^5.9.3" }, "dependencies": { diff --git a/packages/wallet/primitives/CHANGELOG.md b/packages/wallet/primitives/CHANGELOG.md index c0880a0d77..200be51020 100644 --- a/packages/wallet/primitives/CHANGELOG.md +++ b/packages/wallet/primitives/CHANGELOG.md @@ -1,5 +1,90 @@ # @0xsequence/wallet-primitives +## 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 diff --git a/packages/wallet/primitives/eslint.config.js b/packages/wallet/primitives/eslint.config.js new file mode 100644 index 0000000000..d10bbd1e97 --- /dev/null +++ b/packages/wallet/primitives/eslint.config.js @@ -0,0 +1,12 @@ +import { config as baseConfig } from '@repo/eslint-config/base' + +/** @type {import("eslint").Linter.Config} */ +export default [ + ...baseConfig, + { + // files: ['**/*.{test,spec}.ts'], + rules: { + '@typescript-eslint/no-explicit-any': 'off', + }, + }, +] diff --git a/packages/wallet/primitives/package.json b/packages/wallet/primitives/package.json index b964899e2f..df6e52100b 100644 --- a/packages/wallet/primitives/package.json +++ b/packages/wallet/primitives/package.json @@ -1,6 +1,6 @@ { "name": "@0xsequence/wallet-primitives", - "version": "3.0.0-beta.9", + "version": "3.0.0", "license": "Apache-2.0", "type": "module", "publishConfig": { @@ -13,7 +13,8 @@ "test": "vitest run", "test:coverage": "vitest run --coverage", "typecheck": "tsc --noEmit", - "clean": "rimraf dist" + "clean": "rimraf dist", + "lint": "eslint . --max-warnings 0" }, "exports": { ".": { @@ -22,10 +23,11 @@ } }, "devDependencies": { + "@repo/eslint-config": "workspace:^", "@repo/typescript-config": "workspace:^", - "@vitest/coverage-v8": "^4.0.15", + "@vitest/coverage-v8": "^4.0.18", "typescript": "^5.9.3", - "vitest": "^4.0.15" + "vitest": "^4.0.18" }, "dependencies": { "ox": "^0.9.17" diff --git a/packages/wallet/primitives/src/attestation.ts b/packages/wallet/primitives/src/attestation.ts index 78795862ed..4f576f7a0b 100644 --- a/packages/wallet/primitives/src/attestation.ts +++ b/packages/wallet/primitives/src/attestation.ts @@ -1,4 +1,4 @@ -import { Address, Bytes, Hash } from 'ox' +import { Address, Bytes, Hash, Hex } from 'ox' export type Attestation = { approvedSigner: Address.Address @@ -14,6 +14,18 @@ export type AuthData = { issuedAt: bigint // uint64 } +type EncodedAttestation = { + approvedSigner: Address.Address + identityType: Hex.Hex + issuerHash: Hex.Hex + audienceHash: Hex.Hex + applicationData: Hex.Hex + authData: { + redirectUrl: string + issuedAt: string + } +} + // Encoding and decoding export function encode(attestation: Attestation): Bytes.Bytes { @@ -76,9 +88,9 @@ export function toJson(attestation: Attestation, indent?: number): string { return JSON.stringify(encodeForJson(attestation), null, indent) } -export function encodeForJson(attestation: Attestation): any { +export function encodeForJson(attestation: Attestation): EncodedAttestation { return { - approvedSigner: attestation.approvedSigner.toString(), + approvedSigner: attestation.approvedSigner, identityType: Bytes.toHex(attestation.identityType), issuerHash: Bytes.toHex(attestation.issuerHash), audienceHash: Bytes.toHex(attestation.audienceHash), @@ -94,7 +106,7 @@ export function fromJson(json: string): Attestation { return fromParsed(JSON.parse(json)) } -export function fromParsed(parsed: any): Attestation { +export function fromParsed(parsed: EncodedAttestation): Attestation { return { approvedSigner: Address.from(parsed.approvedSigner), identityType: Bytes.fromHex(parsed.identityType), diff --git a/packages/wallet/primitives/src/config.ts b/packages/wallet/primitives/src/config.ts index 27bb7f0324..20c54dc494 100644 --- a/packages/wallet/primitives/src/config.ts +++ b/packages/wallet/primitives/src/config.ts @@ -2,7 +2,6 @@ import { Address, Bytes, Hash, Hex } from 'ox' import { isRawConfig, isRawNestedLeaf, - isRawNode, isRawSignerLeaf, isSignedSapientSignerLeaf, isSignedSignerLeaf, @@ -55,6 +54,49 @@ export type Leaf = SignerLeaf | SapientSignerLeaf | SubdigestLeaf | AnyAddressSu export type Topology = Node | Leaf +/** Encoded topology types for JSON serialization */ +type EncodedSignerLeaf = { + type: 'signer' + address: Address.Address + weight: string +} + +type EncodedSapientSignerLeaf = { + type: 'sapient-signer' + address: Address.Address + weight: string + imageHash: Hex.Hex +} + +type EncodedSubdigestLeaf = { + type: 'subdigest' + digest: Hex.Hex +} + +type EncodedAnyAddressSubdigestLeaf = { + type: 'any-address-subdigest' + digest: Hex.Hex +} + +type EncodedNestedLeaf = { + type: 'nested' + tree: EncodedTopology + weight: string + threshold: string +} + +type EncodedNodeLeaf = Hex.Hex + +export type EncodedLeaf = + | EncodedSignerLeaf + | EncodedSapientSignerLeaf + | EncodedSubdigestLeaf + | EncodedAnyAddressSubdigestLeaf + | EncodedNestedLeaf + | EncodedNodeLeaf +export type EncodedNode = [EncodedTopology, EncodedTopology] +export type EncodedTopology = EncodedNode | EncodedLeaf + export type Config = { threshold: bigint checkpoint: bigint @@ -62,39 +104,39 @@ export type Config = { checkpointer?: Address.Address } -export function isSignerLeaf(cand: any): cand is SignerLeaf { - return typeof cand === 'object' && cand !== null && cand.type === 'signer' +export function isSignerLeaf(cand: unknown): cand is SignerLeaf { + return typeof cand === 'object' && cand !== null && 'type' in cand && cand.type === 'signer' } -export function isSapientSignerLeaf(cand: any): cand is SapientSignerLeaf { - return typeof cand === 'object' && cand !== null && cand.type === 'sapient-signer' +export function isSapientSignerLeaf(cand: unknown): cand is SapientSignerLeaf { + return typeof cand === 'object' && cand !== null && 'type' in cand && cand.type === 'sapient-signer' } -export function isSubdigestLeaf(cand: any): cand is SubdigestLeaf { - return typeof cand === 'object' && cand !== null && cand.type === 'subdigest' +export function isSubdigestLeaf(cand: unknown): cand is SubdigestLeaf { + return typeof cand === 'object' && cand !== null && 'type' in cand && cand.type === 'subdigest' } -export function isAnyAddressSubdigestLeaf(cand: any): cand is AnyAddressSubdigestLeaf { - return typeof cand === 'object' && cand !== null && cand.type === 'any-address-subdigest' +export function isAnyAddressSubdigestLeaf(cand: unknown): cand is AnyAddressSubdigestLeaf { + return typeof cand === 'object' && cand !== null && 'type' in cand && cand.type === 'any-address-subdigest' } -export function isNodeLeaf(cand: any): cand is NodeLeaf { - return Hex.validate(cand) && cand.length === 66 +export function isNodeLeaf(cand: unknown): cand is NodeLeaf { + return typeof cand === 'string' && Hex.validate(cand) && cand.length === 66 } -export function isNestedLeaf(cand: any): cand is NestedLeaf { - return typeof cand === 'object' && cand !== null && cand.type === 'nested' +export function isNestedLeaf(cand: unknown): cand is NestedLeaf { + return typeof cand === 'object' && cand !== null && 'type' in cand && cand.type === 'nested' } -export function isNode(cand: any): cand is Node { +export function isNode(cand: unknown): cand is Node { return Array.isArray(cand) && cand.length === 2 && isTopology(cand[0]) && isTopology(cand[1]) } -export function isConfig(cand: any): cand is Config { - return typeof cand === 'object' && 'threshold' in cand && 'checkpoint' in cand && 'topology' in cand +export function isConfig(cand: unknown): cand is Config { + return typeof cand === 'object' && cand !== null && 'threshold' in cand && 'checkpoint' in cand && 'topology' in cand } -export function isLeaf(cand: Topology): cand is Leaf { +export function isLeaf(cand: unknown): cand is Leaf { return ( isSignerLeaf(cand) || isSapientSignerLeaf(cand) || @@ -105,7 +147,7 @@ export function isLeaf(cand: Topology): cand is Leaf { ) } -export function isTopology(cand: any): cand is Topology { +export function isTopology(cand: unknown): cand is Topology { return isNode(cand) || isLeaf(cand) } @@ -310,7 +352,7 @@ export function configFromJson(json: string): Config { } } -function encodeTopology(top: Topology): any { +function encodeTopology(top: Topology): EncodedTopology { if (isNode(top)) { return [encodeTopology(top[0]), encodeTopology(top[1])] } else if (isSignerLeaf(top)) { @@ -350,7 +392,7 @@ function encodeTopology(top: Topology): any { throw new Error('Invalid topology') } -function decodeTopology(obj: any): Topology { +function decodeTopology(obj: EncodedTopology): Topology { if (Array.isArray(obj)) { if (obj.length !== 2) { throw new Error('Invalid node structure in JSON') diff --git a/packages/wallet/primitives/src/extensions/recovery.ts b/packages/wallet/primitives/src/extensions/recovery.ts index 7073272e5e..43cd05b9c3 100644 --- a/packages/wallet/primitives/src/extensions/recovery.ts +++ b/packages/wallet/primitives/src/extensions/recovery.ts @@ -1,7 +1,6 @@ import { Abi, AbiFunction, Address, Bytes, Hex, Provider } from 'ox' import * as GenericTree from '../generic-tree.js' import { Signature } from '../index.js' -import * as Network from '../network.js' import * as Payload from '../payload.js' import { packRSY } from '../utils.js' @@ -56,21 +55,21 @@ export type Tree = Branch | GenericTree.Node | RecoveryLeaf /** * Type guard to check if a value is a RecoveryLeaf */ -export function isRecoveryLeaf(cand: any): cand is RecoveryLeaf { - return typeof cand === 'object' && cand !== null && cand.type === 'leaf' +export function isRecoveryLeaf(cand: unknown): cand is RecoveryLeaf { + return typeof cand === 'object' && cand !== null && 'type' in cand && cand.type === 'leaf' } /** * Type guard to check if a value is a Node (pair of subtrees) */ -export function isBranch(cand: any): cand is Branch { +export function isBranch(cand: unknown): cand is Branch { return Array.isArray(cand) && cand.length === 2 && isTree(cand[0]) && isTree(cand[1]) } /** * Type guard to check if a value is a Topology */ -export function isTree(cand: any): cand is Tree { +export function isTree(cand: unknown): cand is Tree { return isRecoveryLeaf(cand) || GenericTree.isNode(cand) || isBranch(cand) } @@ -203,7 +202,7 @@ export function parseBranch(encoded: Bytes.Bytes): { nodes: Tree[]; leftover: By */ export function trimTopology(topology: Tree, signer: Address.Address): Tree { if (isRecoveryLeaf(topology)) { - if (topology.signer === signer) { + if (Address.isEqual(topology.signer, signer)) { return topology } else { return hashConfiguration(topology) @@ -437,10 +436,10 @@ export function fromGenericTree(tree: GenericTree.Tree): Tree { */ export function encodeCalldata( wallet: Address.Address, - payload: Payload.Recovery, + payload: Payload.Recovery, signer: Address.Address, signature: Signature.SignatureOfSignerLeaf, -) { +): Hex.Hex { let signatureBytes: Hex.Hex if (signature.type === 'erc1271') { diff --git a/packages/wallet/primitives/src/network.ts b/packages/wallet/primitives/src/network.ts index b0ef2bbde1..4f1e8a8de3 100644 --- a/packages/wallet/primitives/src/network.ts +++ b/packages/wallet/primitives/src/network.ts @@ -1,3 +1,8 @@ +import { Address } from 'ox' + +const DEFAULT_MULTICALL3_ADDRESS: Address.Address = '0xcA11bde05977b3631167028862bE2a173976CA11' +const SEQUENCE_MULTICALL3_ADDRESS: Address.Address = '0xae96419a81516f063744206d4b5E36f3168280f8' + export enum NetworkType { MAINNET = 'mainnet', TESTNET = 'testnet', @@ -21,8 +26,11 @@ export interface Network { name: string decimals: number } - ensAddress?: string deprecated?: true + contracts?: { + multicall3?: Address.Address + ensUniversalResolver?: Address.Address + } } export const ChainId = { @@ -105,6 +113,7 @@ export const ChainId = { // ETHERLINK ETHERLINK: 42793, ETHERLINK_TESTNET: 128123, + ETHERLINK_SHADOWNET_TESTNET: 127823, // MOONBEAM MOONBEAM: 1284, @@ -129,6 +138,15 @@ export const ChainId = { // ARC ARC_TESTNET: 5042002, + + // HYPEREVM + HYPEREVM: 999, + + // SONIC + SONIC: 146, + + // BERACHAIN + BERACHAIN: 80094, } as const export type ChainId = (typeof ChainId)[keyof typeof ChainId] @@ -150,7 +168,10 @@ export const ALL: Network[] = [ name: 'Ether', decimals: 18, }, - ensAddress: '0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e', + contracts: { + multicall3: DEFAULT_MULTICALL3_ADDRESS, + ensUniversalResolver: '0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e', + }, }, { chainId: ChainId.SEPOLIA, @@ -168,6 +189,9 @@ export const ALL: Network[] = [ name: 'Sepolia Ether', decimals: 18, }, + contracts: { + multicall3: DEFAULT_MULTICALL3_ADDRESS, + }, }, { chainId: ChainId.POLYGON, @@ -185,6 +209,9 @@ export const ALL: Network[] = [ name: 'POL', decimals: 18, }, + contracts: { + multicall3: DEFAULT_MULTICALL3_ADDRESS, + }, }, { chainId: ChainId.POLYGON_AMOY, @@ -202,6 +229,9 @@ export const ALL: Network[] = [ name: 'Amoy POL', decimals: 18, }, + contracts: { + multicall3: DEFAULT_MULTICALL3_ADDRESS, + }, }, { chainId: ChainId.POLYGON_ZKEVM, @@ -219,6 +249,9 @@ export const ALL: Network[] = [ name: 'Ether', decimals: 18, }, + contracts: { + multicall3: DEFAULT_MULTICALL3_ADDRESS, + }, }, { chainId: ChainId.BSC, @@ -236,6 +269,9 @@ export const ALL: Network[] = [ name: 'BNB', decimals: 18, }, + contracts: { + multicall3: DEFAULT_MULTICALL3_ADDRESS, + }, }, { chainId: ChainId.BSC_TESTNET, @@ -253,6 +289,9 @@ export const ALL: Network[] = [ name: 'Testnet BNB', decimals: 18, }, + contracts: { + multicall3: DEFAULT_MULTICALL3_ADDRESS, + }, }, { chainId: ChainId.OPTIMISM, @@ -270,6 +309,9 @@ export const ALL: Network[] = [ name: 'Ether', decimals: 18, }, + contracts: { + multicall3: DEFAULT_MULTICALL3_ADDRESS, + }, }, { chainId: ChainId.OPTIMISM_SEPOLIA, @@ -287,6 +329,9 @@ export const ALL: Network[] = [ name: 'Sepolia Ether', decimals: 18, }, + contracts: { + multicall3: DEFAULT_MULTICALL3_ADDRESS, + }, }, { chainId: ChainId.ARBITRUM, @@ -304,6 +349,9 @@ export const ALL: Network[] = [ name: 'Ether', decimals: 18, }, + contracts: { + multicall3: DEFAULT_MULTICALL3_ADDRESS, + }, }, { chainId: ChainId.ARBITRUM_SEPOLIA, @@ -321,6 +369,9 @@ export const ALL: Network[] = [ name: 'Sepolia Ether', decimals: 18, }, + contracts: { + multicall3: DEFAULT_MULTICALL3_ADDRESS, + }, }, { chainId: ChainId.ARBITRUM_NOVA, @@ -338,6 +389,9 @@ export const ALL: Network[] = [ name: 'Ether', decimals: 18, }, + contracts: { + multicall3: DEFAULT_MULTICALL3_ADDRESS, + }, }, { chainId: ChainId.AVALANCHE, @@ -355,6 +409,9 @@ export const ALL: Network[] = [ name: 'AVAX', decimals: 18, }, + contracts: { + multicall3: DEFAULT_MULTICALL3_ADDRESS, + }, }, { chainId: ChainId.AVALANCHE_TESTNET, @@ -372,6 +429,9 @@ export const ALL: Network[] = [ name: 'Testnet AVAX', decimals: 18, }, + contracts: { + multicall3: DEFAULT_MULTICALL3_ADDRESS, + }, }, { chainId: ChainId.GNOSIS, @@ -389,12 +449,15 @@ export const ALL: Network[] = [ name: 'XDAI', decimals: 18, }, + contracts: { + multicall3: DEFAULT_MULTICALL3_ADDRESS, + }, }, { chainId: ChainId.BASE, type: NetworkType.MAINNET, name: 'base', - title: 'Base (Coinbase)', + title: 'Base', rpcUrl: getRpcUrl('base'), logoUrl: getLogoUrl(ChainId.BASE), blockExplorer: { @@ -406,6 +469,9 @@ export const ALL: Network[] = [ name: 'Ether', decimals: 18, }, + contracts: { + multicall3: DEFAULT_MULTICALL3_ADDRESS, + }, }, { chainId: ChainId.BASE_SEPOLIA, @@ -423,6 +489,9 @@ export const ALL: Network[] = [ name: 'Sepolia Ether', decimals: 18, }, + contracts: { + multicall3: DEFAULT_MULTICALL3_ADDRESS, + }, }, { chainId: ChainId.HOMEVERSE, @@ -440,6 +509,9 @@ export const ALL: Network[] = [ name: 'OAS', decimals: 18, }, + contracts: { + multicall3: DEFAULT_MULTICALL3_ADDRESS, + }, }, { chainId: ChainId.HOMEVERSE_TESTNET, @@ -457,6 +529,9 @@ export const ALL: Network[] = [ name: 'Testnet OAS', decimals: 18, }, + contracts: { + multicall3: SEQUENCE_MULTICALL3_ADDRESS, + }, }, { chainId: ChainId.XAI, @@ -474,6 +549,9 @@ export const ALL: Network[] = [ name: 'XAI', decimals: 18, }, + contracts: { + multicall3: DEFAULT_MULTICALL3_ADDRESS, + }, }, { chainId: ChainId.XAI_SEPOLIA, @@ -491,6 +569,9 @@ export const ALL: Network[] = [ name: 'Sepolia XAI', decimals: 18, }, + contracts: { + multicall3: SEQUENCE_MULTICALL3_ADDRESS, + }, }, { chainId: ChainId.B3, @@ -508,6 +589,9 @@ export const ALL: Network[] = [ name: 'Ether', decimals: 18, }, + contracts: { + multicall3: DEFAULT_MULTICALL3_ADDRESS, + }, }, { chainId: ChainId.B3_SEPOLIA, @@ -525,6 +609,9 @@ export const ALL: Network[] = [ name: 'Ether', decimals: 18, }, + contracts: { + multicall3: DEFAULT_MULTICALL3_ADDRESS, + }, }, { chainId: ChainId.APECHAIN, @@ -542,6 +629,9 @@ export const ALL: Network[] = [ name: 'ApeCoin', decimals: 18, }, + contracts: { + multicall3: DEFAULT_MULTICALL3_ADDRESS, + }, }, { chainId: ChainId.APECHAIN_TESTNET, @@ -559,6 +649,9 @@ export const ALL: Network[] = [ name: 'ApeCoin', decimals: 18, }, + contracts: { + multicall3: DEFAULT_MULTICALL3_ADDRESS, + }, }, { chainId: ChainId.BLAST, @@ -576,6 +669,9 @@ export const ALL: Network[] = [ name: 'Ether', decimals: 18, }, + contracts: { + multicall3: DEFAULT_MULTICALL3_ADDRESS, + }, }, { chainId: ChainId.BLAST_SEPOLIA, @@ -593,6 +689,9 @@ export const ALL: Network[] = [ name: 'Ether', decimals: 18, }, + contracts: { + multicall3: DEFAULT_MULTICALL3_ADDRESS, + }, }, { chainId: ChainId.TELOS, @@ -610,6 +709,9 @@ export const ALL: Network[] = [ name: 'TLOS', decimals: 18, }, + contracts: { + multicall3: DEFAULT_MULTICALL3_ADDRESS, + }, }, { chainId: ChainId.TELOS_TESTNET, @@ -627,6 +729,9 @@ export const ALL: Network[] = [ name: 'TLOS', decimals: 18, }, + contracts: { + multicall3: SEQUENCE_MULTICALL3_ADDRESS, + }, }, { chainId: ChainId.SKALE_NEBULA, @@ -644,6 +749,9 @@ export const ALL: Network[] = [ name: 'SKALE Fuel', decimals: 18, }, + contracts: { + multicall3: DEFAULT_MULTICALL3_ADDRESS, + }, }, { chainId: ChainId.SKALE_NEBULA_TESTNET, @@ -661,6 +769,9 @@ export const ALL: Network[] = [ name: 'SKALE Fuel', decimals: 18, }, + contracts: { + multicall3: DEFAULT_MULTICALL3_ADDRESS, + }, }, { chainId: ChainId.SONEIUM, @@ -678,6 +789,9 @@ export const ALL: Network[] = [ name: 'Ether', decimals: 18, }, + contracts: { + multicall3: DEFAULT_MULTICALL3_ADDRESS, + }, }, { chainId: ChainId.SONEIUM_MINATO, @@ -695,6 +809,9 @@ export const ALL: Network[] = [ name: 'Ether', decimals: 18, }, + contracts: { + multicall3: DEFAULT_MULTICALL3_ADDRESS, + }, }, { chainId: ChainId.TOY_TESTNET, @@ -712,6 +829,9 @@ export const ALL: Network[] = [ name: 'TOY', decimals: 18, }, + contracts: { + multicall3: DEFAULT_MULTICALL3_ADDRESS, + }, }, { chainId: ChainId.IMMUTABLE_ZKEVM, @@ -729,6 +849,9 @@ export const ALL: Network[] = [ name: 'IMX', decimals: 18, }, + contracts: { + multicall3: DEFAULT_MULTICALL3_ADDRESS, + }, }, { chainId: ChainId.IMMUTABLE_ZKEVM_TESTNET, @@ -746,6 +869,9 @@ export const ALL: Network[] = [ name: 'IMX', decimals: 18, }, + contracts: { + multicall3: DEFAULT_MULTICALL3_ADDRESS, + }, }, { chainId: ChainId.MOONBEAM, @@ -763,6 +889,9 @@ export const ALL: Network[] = [ name: 'GLMR', decimals: 18, }, + contracts: { + multicall3: DEFAULT_MULTICALL3_ADDRESS, + }, }, { chainId: ChainId.MOONBASE_ALPHA, @@ -780,6 +909,9 @@ export const ALL: Network[] = [ name: 'GLMR', decimals: 18, }, + contracts: { + multicall3: DEFAULT_MULTICALL3_ADDRESS, + }, }, { chainId: ChainId.ETHERLINK, @@ -797,23 +929,29 @@ export const ALL: Network[] = [ name: 'Tez', decimals: 18, }, + contracts: { + multicall3: DEFAULT_MULTICALL3_ADDRESS, + }, }, { - chainId: ChainId.ETHERLINK_TESTNET, + chainId: ChainId.ETHERLINK_SHADOWNET_TESTNET, type: NetworkType.TESTNET, - name: 'etherlink-testnet', - title: 'Etherlink Testnet', - rpcUrl: getRpcUrl('etherlink-testnet'), - logoUrl: getLogoUrl(ChainId.ETHERLINK_TESTNET), + name: 'etherlink-shadownet-testnet', + title: 'Etherlink Shadownet Testnet', + rpcUrl: getRpcUrl('etherlink-shadownet-testnet'), + logoUrl: getLogoUrl(ChainId.ETHERLINK_SHADOWNET_TESTNET), blockExplorer: { - name: 'Etherlink Testnet Explorer', - url: 'https://testnet.explorer.etherlink.com/', + name: 'Etherlink Shadownet Testnet Explorer', + url: 'https://shadownet.explorer.etherlink.com/', }, nativeCurrency: { symbol: 'XTZ', name: 'Tez', decimals: 18, }, + contracts: { + multicall3: DEFAULT_MULTICALL3_ADDRESS, + }, }, { chainId: ChainId.MONAD, @@ -831,6 +969,9 @@ export const ALL: Network[] = [ name: 'MON', decimals: 18, }, + contracts: { + multicall3: DEFAULT_MULTICALL3_ADDRESS, + }, }, { chainId: ChainId.MONAD_TESTNET, @@ -848,6 +989,9 @@ export const ALL: Network[] = [ name: 'MON', decimals: 18, }, + contracts: { + multicall3: DEFAULT_MULTICALL3_ADDRESS, + }, }, { @@ -866,6 +1010,9 @@ export const ALL: Network[] = [ name: 'SOMI', decimals: 18, }, + contracts: { + multicall3: SEQUENCE_MULTICALL3_ADDRESS, + }, }, { @@ -884,6 +1031,9 @@ export const ALL: Network[] = [ name: 'STT', decimals: 18, }, + contracts: { + multicall3: SEQUENCE_MULTICALL3_ADDRESS, + }, }, { @@ -902,6 +1052,9 @@ export const ALL: Network[] = [ name: 'TCENT', decimals: 18, }, + contracts: { + multicall3: DEFAULT_MULTICALL3_ADDRESS, + }, }, { @@ -920,6 +1073,9 @@ export const ALL: Network[] = [ name: 'ETH', decimals: 18, }, + contracts: { + multicall3: DEFAULT_MULTICALL3_ADDRESS, + }, }, { @@ -938,6 +1094,9 @@ export const ALL: Network[] = [ name: 'SAND', decimals: 18, }, + contracts: { + multicall3: DEFAULT_MULTICALL3_ADDRESS, + }, }, { @@ -956,6 +1115,63 @@ export const ALL: Network[] = [ name: 'USDC', decimals: 6, }, + contracts: { + multicall3: DEFAULT_MULTICALL3_ADDRESS, + }, + }, + + { + chainId: ChainId.HYPEREVM, + type: NetworkType.MAINNET, + name: 'hyperevm', + title: 'HyperEVM', + rpcUrl: getRpcUrl('hyperevm'), + logoUrl: getLogoUrl(ChainId.HYPEREVM), + blockExplorer: { + name: 'HyperEVM Explorer', + url: 'https://www.hyperscan.com/', + }, + nativeCurrency: { + symbol: 'HYPE', + name: 'HYPE', + decimals: 18, + }, + }, + + { + chainId: ChainId.BERACHAIN, + type: NetworkType.MAINNET, + name: 'berachain', + title: 'Berachain', + rpcUrl: getRpcUrl('berachain'), + logoUrl: getLogoUrl(ChainId.BERACHAIN), + blockExplorer: { + name: 'Berachain Explorer', + url: 'https://berascan.com/', + }, + nativeCurrency: { + symbol: 'BEAR', + name: 'BEAR', + decimals: 18, + }, + }, + + { + chainId: ChainId.SONIC, + type: NetworkType.MAINNET, + name: 'sonic', + title: 'Sonic', + rpcUrl: getRpcUrl('sonic'), + logoUrl: getLogoUrl(ChainId.SONIC), + blockExplorer: { + name: 'Sonic Explorer', + url: 'https://sonicscan.com/', + }, + nativeCurrency: { + symbol: 'S', + name: 'Sonic', + decimals: 18, + }, }, ] diff --git a/packages/wallet/primitives/src/payload.ts b/packages/wallet/primitives/src/payload.ts index 1359abdbe9..c933a6118e 100644 --- a/packages/wallet/primitives/src/payload.ts +++ b/packages/wallet/primitives/src/payload.ts @@ -1,7 +1,7 @@ import { AbiFunction, AbiParameters, Address, Bytes, Hash, Hex } from 'ox' import { getSignPayload } from 'ox/TypedData' import { EXECUTE_USER_OP, RECOVER_SAPIENT_SIGNATURE } from './constants.js' -import { Attestation, Network } from './index.js' +import { Attestation } from './index.js' import { minBytesFor } from './utils.js' import { UserOperation } from 'ox/erc4337' diff --git a/packages/wallet/primitives/src/signature.ts b/packages/wallet/primitives/src/signature.ts index 2e5d3212c0..6ba93f9c1b 100644 --- a/packages/wallet/primitives/src/signature.ts +++ b/packages/wallet/primitives/src/signature.ts @@ -1,4 +1,4 @@ -import { AbiFunction, AbiParameters, Address, Bytes, Hash, Hex, Provider, Secp256k1, Signature } from 'ox' +import { AbiFunction, AbiParameters, Address, Bytes, Hash, Hex, Provider, Secp256k1 } from 'ox' import { Config, Leaf, @@ -22,7 +22,7 @@ import { RECOVER_SAPIENT_SIGNATURE, RECOVER_SAPIENT_SIGNATURE_COMPACT, IS_VALID_ import { wrap, decode } from './erc-6492.js' import { fromConfigUpdate, hash, Parented } from './payload.js' import { minBytesFor, packRSY, unpackRSY } from './utils.js' -import { Constants, Network } from './index.js' +import { Constants } from './index.js' export const FLAG_SIGNATURE_HASH = 0 export const FLAG_ADDRESS = 1 @@ -618,7 +618,7 @@ export function fillLeaves( export function encodeChainedSignature(signatures: RawSignature[]): Uint8Array { let flag = 0x01 - let sigForCheckpointer = signatures[signatures.length - 1] + const sigForCheckpointer = signatures[signatures.length - 1] if (sigForCheckpointer?.configuration.checkpointer) { flag |= 0x40 @@ -723,7 +723,7 @@ export function encodeTopology( const isBranching = isNode(topology[1]!) || isRawNode(topology[1]!) if (isBranching) { - let encoded1Size = minBytesFor(BigInt(encoded1.length)) + const encoded1Size = minBytesFor(BigInt(encoded1.length)) if (encoded1Size > 15) { throw new Error('Branch too large') } @@ -799,7 +799,7 @@ export function encodeTopology( } else if (topology.signature.type === 'erc1271') { let flag = FLAG_SIGNATURE_ERC1271 << 4 - let bytesForSignatureSize = minBytesFor(BigInt(topology.signature.data.length)) + const bytesForSignatureSize = minBytesFor(BigInt(topology.signature.data.length)) if (bytesForSignatureSize > 3) { throw new Error('Signature too large') } @@ -826,7 +826,7 @@ export function encodeTopology( let flag = (topology.signature.type === 'sapient' ? FLAG_SIGNATURE_SAPIENT : FLAG_SIGNATURE_SAPIENT_COMPACT) << 4 const signatureBytes = Bytes.fromHex(topology.signature.data) - let bytesForSignatureSize = minBytesFor(BigInt(signatureBytes.length)) + const bytesForSignatureSize = minBytesFor(BigInt(signatureBytes.length)) if (bytesForSignatureSize > 3) { throw new Error('Signature too large') } @@ -1218,7 +1218,7 @@ async function recoverTopology( weight: topology.weight, } - default: + default: { const provider = 'provider' in options!.provider ? options!.provider.provider : options!.provider const block = 'block' in options!.provider ? options!.provider.block : undefined @@ -1254,6 +1254,7 @@ async function recoverTopology( } } } + } } case 'sapient': @@ -1264,7 +1265,7 @@ async function recoverTopology( case 'assume-valid': throw new Error(`unable to validate sapient signer ${topology.signature.address} signature`) - default: + default: { const provider = 'provider' in options!.provider ? options!.provider.provider : options!.provider const block = 'block' in options!.provider ? options!.provider.block : undefined @@ -1298,6 +1299,7 @@ async function recoverTopology( }, weight: topology.weight, } + } } } } else if (isRawNestedLeaf(topology)) { diff --git a/packages/wallet/primitives/src/utils.ts b/packages/wallet/primitives/src/utils.ts index 7a70fb0879..3a2b28d468 100644 --- a/packages/wallet/primitives/src/utils.ts +++ b/packages/wallet/primitives/src/utils.ts @@ -1,4 +1,4 @@ -import { AbiParameters, Bytes, Hash, Hex } from 'ox' +import { Bytes } from 'ox' export function minBytesFor(val: bigint): number { return Math.ceil(val.toString(16).length / 2) @@ -7,7 +7,7 @@ export function minBytesFor(val: bigint): number { // ERC-2098 export function packRSY({ r, s, yParity }: { r: bigint; s: bigint; yParity: number }): Bytes.Bytes { const rBytes = Bytes.padLeft(Bytes.fromNumber(r), 32) - let sBytes = Bytes.padLeft(Bytes.fromNumber(s), 32) + const sBytes = Bytes.padLeft(Bytes.fromNumber(s), 32) if (yParity % 2 === 1) { sBytes[0]! |= 0x80 } diff --git a/packages/wallet/primitives/test/address.test.ts b/packages/wallet/primitives/test/address.test.ts index 38ac16ccc4..b004dc96d4 100644 --- a/packages/wallet/primitives/test/address.test.ts +++ b/packages/wallet/primitives/test/address.test.ts @@ -88,7 +88,7 @@ describe('Address', () => { }) it('should work with Dev1 context', () => { - const { stage2, ...dev1Context } = Dev1 + const { stage2: _, ...dev1Context } = Dev1 const address = from(sampleConfig, dev1Context) expect(() => Address.assert(address)).not.toThrow() @@ -96,53 +96,53 @@ describe('Address', () => { }) it('should work with Dev2 context', () => { - const { stage2, ...dev2Context } = Dev2 + const { stage2: _stage2_1, ...dev2Context } = Dev2 const address = from(sampleConfig, dev2Context) expect(() => Address.assert(address)).not.toThrow() expect(address).toMatch(/^0x[a-fA-F0-9]{40}$/) // Should be different from Dev1 - const { stage2: _, ...dev1Context } = Dev1 + const { stage2: _stage2_2, ...dev1Context } = Dev1 const dev1Address = from(sampleConfig, dev1Context) expect(address).not.toBe(dev1Address) }) it('should work with Rc3 context', () => { - const { stage2, ...rc3Context } = Rc3 + const { stage2: _stage2_1, ...rc3Context } = Rc3 const address = from(sampleConfig, rc3Context) expect(() => Address.assert(address)).not.toThrow() expect(address).toMatch(/^0x[a-fA-F0-9]{40}$/) // Should be different from Dev2 - const { stage2: _, ...dev2Context } = Dev2 + const { stage2: _stage2_2, ...dev2Context } = Dev2 const dev2Address = from(sampleConfig, dev2Context) expect(address).not.toBe(dev2Address) }) it('should work with Rc4 context', () => { - const { stage2, ...rc4Context } = Rc4 + const { stage2: _stage2_1, ...rc4Context } = Rc4 const address = from(sampleConfig, rc4Context) expect(() => Address.assert(address)).not.toThrow() expect(address).toMatch(/^0x[a-fA-F0-9]{40}$/) // Should be different from Dev2 - const { stage2: _, ...dev2Context } = Dev2 + const { stage2: _stage2_2, ...dev2Context } = Dev2 const dev2Address = from(sampleConfig, dev2Context) expect(address).not.toBe(dev2Address) }) it('should work with Rc5 context', () => { - const { stage2, ...rc5Context } = Rc5 + const { stage2: _stage2_1, ...rc5Context } = Rc5 const address = from(sampleConfig, rc5Context) expect(() => Address.assert(address)).not.toThrow() expect(address).toMatch(/^0x[a-fA-F0-9]{40}$/) // Should be different from Dev2 - const { stage2: _, ...dev2Context } = Dev2 + const { stage2: _stage2_2, ...dev2Context } = Dev2 const dev2Address = from(sampleConfig, dev2Context) expect(address).not.toBe(dev2Address) }) diff --git a/packages/wallet/primitives/test/attestation.test.ts b/packages/wallet/primitives/test/attestation.test.ts index 41a75da07d..3708132a73 100644 --- a/packages/wallet/primitives/test/attestation.test.ts +++ b/packages/wallet/primitives/test/attestation.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { Address, Bytes, Hash, Hex } from 'ox' +import { Bytes, Hash } from 'ox' import { Attestation, diff --git a/packages/wallet/primitives/test/config.test.ts b/packages/wallet/primitives/test/config.test.ts index 4dbaa0f843..b4ff8e6d91 100644 --- a/packages/wallet/primitives/test/config.test.ts +++ b/packages/wallet/primitives/test/config.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { Address, Bytes, Hash, Hex } from 'ox' +import { Bytes } from 'ox' import { Config, diff --git a/packages/wallet/primitives/test/passkeys.test.ts b/packages/wallet/primitives/test/passkeys.test.ts index b6aa0990fb..ddfd59b9ea 100644 --- a/packages/wallet/primitives/test/passkeys.test.ts +++ b/packages/wallet/primitives/test/passkeys.test.ts @@ -104,13 +104,6 @@ describe('Passkeys', () => { y: testPublicKeyY, } - const samplePublicKeyWithHashMetadata: PublicKey = { - requireUserVerification: true, - x: testPublicKeyX, - y: testPublicKeyY, - metadata: testMetadataHash, - } - // Realistic authenticator data based on WebAuthn spec and ox patterns // This represents actual WebAuthn authenticator data structure const sampleAuthenticatorData = Bytes.fromHex( @@ -196,7 +189,7 @@ describe('Passkeys', () => { { name: 'special chars', credentialId: '!@#$%^&*()_+{}|:"<>?[]\\;\',./' }, ] - testCases.forEach(({ name, credentialId }) => { + testCases.forEach(({ credentialId }) => { const metadata: PasskeyMetadata = { credentialId } const tree = metadataTree(metadata) expect(GenericTree.isLeaf(tree)).toBe(true) @@ -709,7 +702,7 @@ describe('Passkeys', () => { }, ] - specialCharTests.forEach(({ name, credentialId, clientData }) => { + specialCharTests.forEach(({ credentialId, clientData }) => { if (credentialId) { const unicodeMetadata: PasskeyMetadata = { credentialId } const tree = metadataTree(unicodeMetadata) @@ -787,7 +780,7 @@ describe('Passkeys', () => { { userVerification: true, metadata: true, description: 'User verification with metadata' }, ] - testCombinations.forEach(({ userVerification, metadata, description }) => { + testCombinations.forEach(({ userVerification, metadata }) => { const pubKey = createValidPublicKey({ requireUserVerification: userVerification, ...(metadata && { metadata: samplePasskeyMetadata }), diff --git a/packages/wallet/primitives/test/payload.test.ts b/packages/wallet/primitives/test/payload.test.ts index 72b831d22a..33884dbdb1 100644 --- a/packages/wallet/primitives/test/payload.test.ts +++ b/packages/wallet/primitives/test/payload.test.ts @@ -1,6 +1,5 @@ -import { describe, expect, it, vi } from 'vitest' -import { Address, Bytes, Hash, Hex } from 'ox' -import { UserOperation } from 'ox/erc4337' +import { describe, expect, it } from 'vitest' +import { Address, Bytes, Hex } from 'ox' import { KIND_TRANSACTIONS, @@ -17,11 +16,7 @@ import { Digest, SessionImplicitAuthorize, Calls4337_07, - Recovery, - MayRecoveryPayload, - Payload, Parented, - TypedDataToSign, SolidityDecoded, fromMessage, fromConfigUpdate, diff --git a/packages/wallet/primitives/test/precondition.test.ts b/packages/wallet/primitives/test/precondition.test.ts index c994e8a52c..84f919d620 100644 --- a/packages/wallet/primitives/test/precondition.test.ts +++ b/packages/wallet/primitives/test/precondition.test.ts @@ -1,7 +1,6 @@ import { describe, expect, it } from 'vitest' import { - Precondition, NativeBalancePrecondition, Erc20BalancePrecondition, Erc20ApprovalPrecondition, @@ -10,7 +9,6 @@ import { Erc1155BalancePrecondition, Erc1155ApprovalPrecondition, AnyPrecondition, - IntentPrecondition, isValidPreconditionType, createPrecondition, createIntentPrecondition, @@ -225,13 +223,13 @@ describe('Precondition', () => { }) it('should throw for null precondition', () => { - expect(() => createPrecondition(null as any)).toThrow( + expect(() => createPrecondition(null as unknown as AnyPrecondition)).toThrow( "Invalid precondition object: missing or invalid 'type' property.", ) }) it('should throw for undefined precondition', () => { - expect(() => createPrecondition(undefined as any)).toThrow( + expect(() => createPrecondition(undefined as unknown as AnyPrecondition)).toThrow( "Invalid precondition object: missing or invalid 'type' property.", ) }) @@ -240,7 +238,7 @@ describe('Precondition', () => { const invalidPrecondition = { address: testAddress, min: testMinAmount, - } as any + } as unknown as AnyPrecondition expect(() => createPrecondition(invalidPrecondition)).toThrow( "Invalid precondition object: missing or invalid 'type' property.", ) @@ -250,7 +248,7 @@ describe('Precondition', () => { const invalidPrecondition = { type: 'invalid-type', address: testAddress, - } as any + } as unknown as AnyPrecondition expect(() => createPrecondition(invalidPrecondition)).toThrow( "Invalid precondition object: missing or invalid 'type' property.", ) @@ -260,7 +258,7 @@ describe('Precondition', () => { const invalidPrecondition = { type: 123, address: testAddress, - } as any + } as unknown as AnyPrecondition expect(() => createPrecondition(invalidPrecondition)).toThrow( "Invalid precondition object: missing or invalid 'type' property.", ) @@ -386,7 +384,7 @@ describe('Precondition', () => { const invalidPrecondition = { type: 'invalid-type', address: testAddress, - } as any + } as unknown as AnyPrecondition expect(() => createIntentPrecondition(invalidPrecondition)).toThrow('Invalid precondition type: invalid-type') }) diff --git a/packages/wallet/primitives/test/signature.test.ts b/packages/wallet/primitives/test/signature.test.ts index 8738b9bcf3..e3261948ac 100644 --- a/packages/wallet/primitives/test/signature.test.ts +++ b/packages/wallet/primitives/test/signature.test.ts @@ -14,7 +14,6 @@ import { FLAG_SIGNATURE_SAPIENT, FLAG_SIGNATURE_SAPIENT_COMPACT, RSY, - SignatureOfSignerLeafEthSign, SignatureOfSignerLeafHash, SignatureOfSignerLeafErc1271, SignatureOfSapientSignerLeaf, @@ -42,7 +41,7 @@ import { recover, } from '../src/signature.js' import { packRSY } from '../src/utils.js' -import { Config, SignerLeaf, SapientSignerLeaf } from '../src/config.js' +import { SignerLeaf, SapientSignerLeaf, SubdigestLeaf, Topology, NestedLeaf } from '../src/config.js' import * as Payload from '../src/payload.js' import { ChainId } from '../src/network.js' @@ -63,11 +62,6 @@ describe('Signature', () => { ...sampleRSY, } - const sampleEthSignSignature: SignatureOfSignerLeafEthSign = { - type: 'eth_sign', - ...sampleRSY, - } - const sampleErc1271Signature: SignatureOfSignerLeafErc1271 = { type: 'erc1271', address: testAddress, @@ -377,7 +371,7 @@ describe('Signature', () => { expect(result.nodes).toHaveLength(1) expect(result.leftover).toHaveLength(0) - const node = result.nodes[0] as any + const node = result.nodes[0] as SubdigestLeaf expect(node.type).toBe('subdigest') expect(node.digest).toBe(digest) }) @@ -517,7 +511,7 @@ describe('Signature', () => { }) it('should throw for invalid topology', () => { - expect(() => encodeTopology({} as any)).toThrow('Invalid topology') + expect(() => encodeTopology({} as Topology)).toThrow('Invalid topology') }) }) @@ -696,9 +690,9 @@ describe('Signature', () => { const signatureProvider = () => sampleHashSignature - const result = fillLeaves(nestedTopology, signatureProvider) - expect((result as any).type).toBe('nested') - expect((result as any).tree).toHaveProperty('signature') + const result = fillLeaves(nestedTopology, signatureProvider) as NestedLeaf + expect(result.type).toBe('nested') + expect(result.tree).toHaveProperty('signature') }) it('should handle topology without signatures', () => { @@ -751,12 +745,12 @@ describe('Signature', () => { const result = fillLeaves(binaryTree, signatureProvider) expect(Array.isArray(result)).toBe(true) - expect((result as any)[0]).toHaveProperty('signature') - expect((result as any)[1]).toHaveProperty('signature') + expect(result[0]).toHaveProperty('signature') + expect(result[1]).toHaveProperty('signature') }) it('should throw for invalid topology', () => { - expect(() => fillLeaves({} as any, () => undefined)).toThrow('Invalid topology') + expect(() => fillLeaves({} as Topology, () => undefined)).toThrow('Invalid topology') }) }) }) @@ -917,7 +911,7 @@ describe('Signature', () => { }, ] - signatures.forEach(({ topology, name }) => { + signatures.forEach(({ topology }) => { const signature = { noChainId: false, configuration: { @@ -1760,7 +1754,7 @@ describe('Signature', () => { }, ] - for (const { name, payload } of payloadTypes) { + for (const { payload } of payloadTypes) { const sapientSignature: RawSignature = { noChainId: false, configuration: { diff --git a/packages/wallet/primitives/test/utils.test.ts b/packages/wallet/primitives/test/utils.test.ts index 76ba462f0d..dc8392c328 100644 --- a/packages/wallet/primitives/test/utils.test.ts +++ b/packages/wallet/primitives/test/utils.test.ts @@ -248,7 +248,7 @@ describe('Utils', () => { it('should revive Uint8Array values', () => { const reviver = createJSONReviver() - const result = reviver('test', { __uint8array: [1, 2, 3, 255] }) + const result = reviver('test', { __uint8array: [1, 2, 3, 255] }) as Uint8Array expect(result).toBeInstanceOf(Uint8Array) expect(Array.from(result)).toEqual([1, 2, 3, 255]) @@ -314,7 +314,7 @@ describe('Utils', () => { it('should handle empty Uint8Array', () => { const reviver = createJSONReviver() - const result = reviver('test', { __uint8array: [] }) + const result = reviver('test', { __uint8array: [] }) as Uint8Array expect(result).toBeInstanceOf(Uint8Array) expect(result.length).toBe(0) @@ -401,7 +401,7 @@ describe('Utils', () => { it('should deserialize objects with BigInt', () => { const json = '{"value":{"__bigint":"0x75bcd15"},"name":"test"}' - const result = fromJSON(json) + const result = fromJSON(json) as { value: bigint; name: string } expect(result.value).toBe(123456789n) expect(result.name).toBe('test') @@ -409,7 +409,7 @@ describe('Utils', () => { it('should deserialize objects with Uint8Array', () => { const json = '{"data":{"__uint8array":[1,2,3]},"name":"test"}' - const result = fromJSON(json) + const result = fromJSON(json) as { data: Uint8Array; name: string } expect(result.data).toBeInstanceOf(Uint8Array) expect(Array.from(result.data)).toEqual([1, 2, 3]) diff --git a/packages/wallet/wdk/CHANGELOG.md b/packages/wallet/wdk/CHANGELOG.md index 37fc483bb3..81522e3a47 100644 --- a/packages/wallet/wdk/CHANGELOG.md +++ b/packages/wallet/wdk/CHANGELOG.md @@ -1,5 +1,175 @@ # @0xsequence/wallet-wdk +## 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 diff --git a/packages/wallet/wdk/eslint.config.js b/packages/wallet/wdk/eslint.config.js new file mode 100644 index 0000000000..d10bbd1e97 --- /dev/null +++ b/packages/wallet/wdk/eslint.config.js @@ -0,0 +1,12 @@ +import { config as baseConfig } from '@repo/eslint-config/base' + +/** @type {import("eslint").Linter.Config} */ +export default [ + ...baseConfig, + { + // files: ['**/*.{test,spec}.ts'], + rules: { + '@typescript-eslint/no-explicit-any': 'off', + }, + }, +] diff --git a/packages/wallet/wdk/package.json b/packages/wallet/wdk/package.json index 103d9cb7c3..15a8a75cc2 100644 --- a/packages/wallet/wdk/package.json +++ b/packages/wallet/wdk/package.json @@ -1,6 +1,6 @@ { "name": "@0xsequence/wallet-wdk", - "version": "3.0.0-beta.9", + "version": "3.0.0", "license": "Apache-2.0", "type": "module", "publishConfig": { @@ -12,9 +12,10 @@ "dev": "tsc --watch", "test": "vitest run && npm run test:ssr", "test:coverage": "vitest run --coverage", - "test:ssr": "node test/test-ssr-safety.mjs", + "test:ssr": "node test/test-ssr-safety.js", "typecheck": "tsc --noEmit", - "clean": "rimraf dist" + "clean": "rimraf dist", + "lint": "eslint . --max-warnings 0" }, "exports": { ".": { @@ -23,14 +24,15 @@ } }, "devDependencies": { + "@repo/eslint-config": "workspace:^", "@repo/typescript-config": "workspace:^", - "@types/node": "^25.0.2", - "@vitest/coverage-v8": "^4.0.15", - "dotenv": "^17.2.3", + "@types/node": "^25.3.0", + "@vitest/coverage-v8": "^4.0.18", + "dotenv": "^17.3.1", "fake-indexeddb": "^6.2.5", - "happy-dom": "^20.0.11", + "happy-dom": "^20.7.0", "typescript": "^5.9.3", - "vitest": "^4.0.15" + "vitest": "^4.0.18" }, "dependencies": { "@0xsequence/guard": "workspace:^", diff --git a/packages/wallet/wdk/src/dbs/auth-commitments.ts b/packages/wallet/wdk/src/dbs/auth-commitments.ts index a3f360639a..721d73619c 100644 --- a/packages/wallet/wdk/src/dbs/auth-commitments.ts +++ b/packages/wallet/wdk/src/dbs/auth-commitments.ts @@ -1,4 +1,4 @@ -import { Generic, Migration } from './generic.js' +import { Generic } from './generic.js' import { IDBPDatabase, IDBPTransaction } from 'idb' const TABLE_NAME = 'auth-commitments' diff --git a/packages/wallet/wdk/src/dbs/auth-keys.ts b/packages/wallet/wdk/src/dbs/auth-keys.ts index 56cf1ddf9f..690d18cd99 100644 --- a/packages/wallet/wdk/src/dbs/auth-keys.ts +++ b/packages/wallet/wdk/src/dbs/auth-keys.ts @@ -1,5 +1,6 @@ -import { Generic, Migration } from './generic.js' +import { Generic } from './generic.js' import { IDBPDatabase, IDBPTransaction } from 'idb' +import type { WdkEnv } from '../env.js' const TABLE_NAME = 'auth-keys' @@ -11,9 +12,12 @@ export type AuthKey = { } export class AuthKeys extends Generic { - private expirationTimers = new Map() + private expirationTimers = new Map>() - constructor(dbName: string = 'sequence-auth-keys') { + constructor( + dbName: string = 'sequence-auth-keys', + private readonly env?: WdkEnv, + ) { super(dbName, TABLE_NAME, 'address', [ ( db: IDBPDatabase, @@ -64,7 +68,10 @@ export class AuthKeys extends Generic { if (result !== undefined) { return result } else if (attempt < 2) { - await new Promise((resolve) => setTimeout(resolve, 50)) + const setTimeoutFn = this.env?.timers?.setTimeout ?? (globalThis as any).setTimeout + if (setTimeoutFn) { + await new Promise((resolve) => setTimeoutFn(resolve, 50)) + } return this.getBySigner(signer, attempt + 1) } else { try { @@ -108,7 +115,11 @@ export class AuthKeys extends Generic { await this.del(authKey.address.toLowerCase()) return } - const timer = window.setTimeout(() => { + const setTimeoutFn = this.env?.timers?.setTimeout ?? (globalThis as any).setTimeout + if (!setTimeoutFn) { + return + } + const timer = setTimeoutFn(() => { console.log('removing expired auth key', authKey) this.del(authKey.address.toLowerCase()) }, delay) @@ -118,7 +129,10 @@ export class AuthKeys extends Generic { private clearExpiration(address: string): void { const timer = this.expirationTimers.get(address.toLowerCase()) if (timer) { - window.clearTimeout(timer) + const clearTimeoutFn = this.env?.timers?.clearTimeout ?? (globalThis as any).clearTimeout + if (clearTimeoutFn) { + clearTimeoutFn(timer) + } this.expirationTimers.delete(address.toLowerCase()) } } diff --git a/packages/wallet/wdk/src/dbs/messages.ts b/packages/wallet/wdk/src/dbs/messages.ts index 8a076ea05a..54459f06fd 100644 --- a/packages/wallet/wdk/src/dbs/messages.ts +++ b/packages/wallet/wdk/src/dbs/messages.ts @@ -1,5 +1,5 @@ import { Message } from '../sequence/types/message-request.js' -import { Generic, Migration } from './generic.js' +import { Generic } from './generic.js' import { IDBPDatabase, IDBPTransaction } from 'idb' const TABLE_NAME = 'messages' diff --git a/packages/wallet/wdk/src/dbs/passkey-credentials.ts b/packages/wallet/wdk/src/dbs/passkey-credentials.ts index 9fdb2abc4e..5e9e6bc318 100644 --- a/packages/wallet/wdk/src/dbs/passkey-credentials.ts +++ b/packages/wallet/wdk/src/dbs/passkey-credentials.ts @@ -1,4 +1,4 @@ -import { Generic, Migration } from './generic.js' +import { Generic } from './generic.js' import { IDBPDatabase, IDBPTransaction } from 'idb' import { Address } from 'ox' import { Extensions } from '@0xsequence/wallet-primitives' diff --git a/packages/wallet/wdk/src/dbs/recovery.ts b/packages/wallet/wdk/src/dbs/recovery.ts index 164c7082bc..e035825f3a 100644 --- a/packages/wallet/wdk/src/dbs/recovery.ts +++ b/packages/wallet/wdk/src/dbs/recovery.ts @@ -1,4 +1,4 @@ -import { Generic, Migration } from './generic.js' +import { Generic } from './generic.js' import { QueuedRecoveryPayload } from '../sequence/types/recovery.js' import { IDBPDatabase, IDBPTransaction } from 'idb' diff --git a/packages/wallet/wdk/src/dbs/signatures.ts b/packages/wallet/wdk/src/dbs/signatures.ts index a108d113c3..3f7328187d 100644 --- a/packages/wallet/wdk/src/dbs/signatures.ts +++ b/packages/wallet/wdk/src/dbs/signatures.ts @@ -1,5 +1,5 @@ import { BaseSignatureRequest } from '../sequence/index.js' -import { Generic, Migration } from './generic.js' +import { Generic } from './generic.js' import { IDBPDatabase, IDBPTransaction } from 'idb' const TABLE_NAME = 'envelopes' diff --git a/packages/wallet/wdk/src/dbs/transactions.ts b/packages/wallet/wdk/src/dbs/transactions.ts index d9019702d7..48f7680c87 100644 --- a/packages/wallet/wdk/src/dbs/transactions.ts +++ b/packages/wallet/wdk/src/dbs/transactions.ts @@ -1,5 +1,5 @@ import { Transaction } from '../sequence/types/transaction-request.js' -import { Generic, Migration } from './generic.js' +import { Generic } from './generic.js' import { IDBPDatabase, IDBPTransaction } from 'idb' const TABLE_NAME = 'transactions' diff --git a/packages/wallet/wdk/src/dbs/wallets.ts b/packages/wallet/wdk/src/dbs/wallets.ts index bd9829eb5d..4b17776103 100644 --- a/packages/wallet/wdk/src/dbs/wallets.ts +++ b/packages/wallet/wdk/src/dbs/wallets.ts @@ -1,4 +1,4 @@ -import { Generic, Migration } from './generic.js' +import { Generic } from './generic.js' import { Wallet } from '../sequence/types/wallet.js' import { IDBPDatabase, IDBPTransaction } from 'idb' diff --git a/packages/wallet/wdk/src/env.ts b/packages/wallet/wdk/src/env.ts new file mode 100644 index 0000000000..4e3cecb1a5 --- /dev/null +++ b/packages/wallet/wdk/src/env.ts @@ -0,0 +1,58 @@ +import type { CoreEnv } from '@0xsequence/wallet-core' +import { resolveCoreEnv } from '@0xsequence/wallet-core' + +export type TimersLike = { + setTimeout: typeof setTimeout + clearTimeout: typeof clearTimeout + setInterval: typeof setInterval + clearInterval: typeof clearInterval +} + +export type LockManagerLike = { + request: (name: string, callback: (lock: Lock | null) => Promise | void) => Promise +} + +export type NavigationLike = { + getPathname: () => string + redirect: (url: string) => void +} + +export type WdkEnv = CoreEnv & { + timers?: TimersLike + locks?: LockManagerLike + navigation?: NavigationLike + urlSearchParams?: typeof URLSearchParams +} + +export function resolveWdkEnv(env?: WdkEnv): WdkEnv { + const core = resolveCoreEnv(env) + const globalObj = globalThis as any + const windowObj = typeof window !== 'undefined' ? window : (globalObj.window ?? {}) + const location = windowObj.location ?? globalObj.location + + return { + ...core, + timers: + env?.timers ?? + (typeof globalObj.setTimeout === 'function' + ? { + setTimeout: globalObj.setTimeout.bind(globalObj), + clearTimeout: globalObj.clearTimeout.bind(globalObj), + setInterval: globalObj.setInterval.bind(globalObj), + clearInterval: globalObj.clearInterval.bind(globalObj), + } + : undefined), + locks: env?.locks ?? globalObj.navigator?.locks ?? windowObj.navigator?.locks, + navigation: + env?.navigation ?? + (location + ? { + getPathname: () => location.pathname, + redirect: (url: string) => { + location.href = url + }, + } + : undefined), + urlSearchParams: env?.urlSearchParams ?? globalObj.URLSearchParams ?? windowObj.URLSearchParams, + } +} diff --git a/packages/wallet/wdk/src/identity/signer.ts b/packages/wallet/wdk/src/identity/signer.ts index fdc53ca417..0cb74bbbd6 100644 --- a/packages/wallet/wdk/src/identity/signer.ts +++ b/packages/wallet/wdk/src/identity/signer.ts @@ -1,17 +1,22 @@ -import { Address, Signature, Hex, Bytes, PersonalMessage } from 'ox' -import { Signers, State } from '@0xsequence/wallet-core' -import { IdentityInstrument, KeyType } from '@0xsequence/identity-instrument' +import { Address, Signature, Hex, Bytes } from 'ox' +import { Signers, State, type CryptoLike } from '@0xsequence/wallet-core' +import { IdentityInstrument } from '@0xsequence/identity-instrument' import { AuthKey } from '../dbs/auth-keys.js' import { Payload, Signature as SequenceSignature } from '@0xsequence/wallet-primitives' import * as Identity from '@0xsequence/identity-instrument' -export function toIdentityAuthKey(authKey: AuthKey): Identity.AuthKey { +export function toIdentityAuthKey(authKey: AuthKey, crypto?: CryptoLike): Identity.AuthKey { + const globalObj = globalThis as any + const resolvedCrypto = crypto ?? globalObj.window?.crypto ?? globalObj.crypto + if (!resolvedCrypto?.subtle) { + throw new Error('crypto.subtle is not available') + } return { address: authKey.address, keyType: Identity.KeyType.WebCrypto_Secp256r1, signer: authKey.identitySigner, async sign(digest: Bytes.Bytes) { - const authKeySignature = await window.crypto.subtle.sign( + const authKeySignature = await resolvedCrypto.subtle.sign( { name: 'ECDSA', hash: 'SHA-256', @@ -28,6 +33,7 @@ export class IdentitySigner implements Signers.Signer { constructor( readonly identityInstrument: IdentityInstrument, readonly authKey: AuthKey, + private readonly crypto?: CryptoLike, ) {} get address(): Address.Address { @@ -47,7 +53,7 @@ export class IdentitySigner implements Signers.Signer { } async signDigest(digest: Bytes.Bytes): Promise { - const sigHex = await this.identityInstrument.sign(toIdentityAuthKey(this.authKey), digest) + const sigHex = await this.identityInstrument.sign(toIdentityAuthKey(this.authKey, this.crypto), digest) const sig = Signature.fromHex(sigHex) return { type: 'hash', @@ -55,7 +61,7 @@ export class IdentitySigner implements Signers.Signer { } } - async witness(stateWriter: State.Writer, wallet: Address.Address, extra?: Object): Promise { + async witness(stateWriter: State.Writer, wallet: Address.Address, extra?: object): Promise { const payload = Payload.fromMessage( Hex.fromString( JSON.stringify({ diff --git a/packages/wallet/wdk/src/index.ts b/packages/wallet/wdk/src/index.ts index 973ec785aa..003abdd722 100644 --- a/packages/wallet/wdk/src/index.ts +++ b/packages/wallet/wdk/src/index.ts @@ -1,2 +1,3 @@ export * as Identity from './identity/signer.js' export * as Sequence from './sequence/index.js' +export * from './env.js' diff --git a/packages/wallet/wdk/src/sequence/cron.ts b/packages/wallet/wdk/src/sequence/cron.ts index a1640a7cfa..f95117109a 100644 --- a/packages/wallet/wdk/src/sequence/cron.ts +++ b/packages/wallet/wdk/src/sequence/cron.ts @@ -17,12 +17,14 @@ export class Cron { private readonly STORAGE_KEY = 'sequence-cron-jobs' private isStopping: boolean = false private currentCheckJobsPromise: Promise = Promise.resolve() + private readonly env: Shared['env'] /** * Initializes the Cron scheduler and starts the periodic job checker. * @param shared Shared context for modules and logging. */ constructor(private readonly shared: Shared) { + this.env = shared.env this.start() } @@ -33,7 +35,11 @@ export class Cron { private start() { if (this.isStopping) return this.executeCheckJobsChain() - this.checkInterval = setInterval(() => this.executeCheckJobsChain(), 60 * 1000) + const setIntervalFn = this.env.timers?.setInterval ?? (globalThis as any).setInterval + if (!setIntervalFn) { + return + } + this.checkInterval = setIntervalFn(() => this.executeCheckJobsChain(), 60 * 1000) } /** @@ -58,7 +64,10 @@ export class Cron { this.isStopping = true if (this.checkInterval) { - clearInterval(this.checkInterval) + const clearIntervalFn = this.env.timers?.clearInterval ?? (globalThis as any).clearInterval + if (clearIntervalFn) { + clearIntervalFn(this.checkInterval) + } this.checkInterval = undefined this.shared.modules.logger.log('Cron: Interval cleared.') } @@ -104,48 +113,22 @@ export class Cron { } try { - await navigator.locks.request('sequence-cron-jobs', async (lock: Lock | null) => { - if (this.isStopping) { - return - } - if (!lock) { - return - } - - const now = Date.now() - const storage = await this.getStorageState() - - for (const [id, job] of this.jobs) { + const locks = this.env.locks ?? (globalThis as any).navigator?.locks + if (locks?.request) { + await locks.request('sequence-cron-jobs', async (lock: Lock | null) => { if (this.isStopping) { - break + return } - - const lastRun = storage.get(id)?.lastRun ?? job.lastRun - const timeSinceLastRun = now - lastRun - - if (timeSinceLastRun >= job.interval) { - try { - await job.handler() - if (!this.isStopping) { - job.lastRun = now - storage.set(id, { lastRun: now }) - } - } catch (error) { - if (error instanceof DOMException && error.name === 'AbortError') { - this.shared.modules.logger.log(`Cron: Job ${id} was aborted.`) - } else { - console.error(`Cron job ${id} failed:`, error) - } - } + if (!lock) { + return } - } - - if (!this.isStopping) { - await this.syncWithStorage() - } - }) + await this.runJobs() + }) + } else { + await this.runJobs() + } } catch (error) { - if (error instanceof DOMException && error.name === 'AbortError') { + if (this.isAbortError(error)) { this.shared.modules.logger.log('Cron: navigator.locks.request was aborted.') } else { console.error('Cron: Error in navigator.locks.request:', error) @@ -153,13 +136,51 @@ export class Cron { } } + private async runJobs(): Promise { + const now = Date.now() + const storage = await this.getStorageState() + + for (const [id, job] of this.jobs) { + if (this.isStopping) { + break + } + + const lastRun = storage.get(id)?.lastRun ?? job.lastRun + const timeSinceLastRun = now - lastRun + + if (timeSinceLastRun >= job.interval) { + try { + await job.handler() + if (!this.isStopping) { + job.lastRun = now + storage.set(id, { lastRun: now }) + } + } catch (error) { + if (this.isAbortError(error)) { + this.shared.modules.logger.log(`Cron: Job ${id} was aborted.`) + } else { + console.error(`Cron job ${id} failed:`, error) + } + } + } + } + + if (!this.isStopping) { + await this.syncWithStorage() + } + } + /** * Loads the persisted last run times for jobs from localStorage. * @returns Map of job IDs to their last run times. */ private async getStorageState(): Promise> { if (this.isStopping) return new Map() - const state = localStorage.getItem(this.STORAGE_KEY) + const storage = this.env.storage + if (!storage) { + return new Map() + } + const state = storage.getItem(this.STORAGE_KEY) return new Map(state ? JSON.parse(state) : []) } @@ -168,7 +189,19 @@ export class Cron { */ private async syncWithStorage() { if (this.isStopping) return + const storage = this.env.storage + if (!storage) { + return + } const state = Array.from(this.jobs.entries()).map(([id, job]) => [id, { lastRun: job.lastRun }]) - localStorage.setItem(this.STORAGE_KEY, JSON.stringify(state)) + storage.setItem(this.STORAGE_KEY, JSON.stringify(state)) + } + + private isAbortError(error: unknown): boolean { + const domException = (globalThis as any).DOMException + if (domException && error instanceof domException) { + return (error as DOMException).name === 'AbortError' + } + return (error as any)?.name === 'AbortError' } } diff --git a/packages/wallet/wdk/src/sequence/handlers/authcode-pkce.ts b/packages/wallet/wdk/src/sequence/handlers/authcode-pkce.ts index 0b4706c0e9..f8f86d5afc 100644 --- a/packages/wallet/wdk/src/sequence/handlers/authcode-pkce.ts +++ b/packages/wallet/wdk/src/sequence/handlers/authcode-pkce.ts @@ -1,10 +1,11 @@ -import { Hex, Address, Bytes } from 'ox' +import { Hex, Bytes } from 'ox' import { Handler } from './handler.js' import * as Db from '../../dbs/index.js' import { Signatures } from '../signatures.js' import * as Identity from '@0xsequence/identity-instrument' import { IdentitySigner } from '../../identity/signer.js' import { AuthCodeHandler } from './authcode.js' +import type { WdkEnv } from '../../env.js' export class AuthCodePkceHandler extends AuthCodeHandler implements Handler { constructor( @@ -16,8 +17,9 @@ export class AuthCodePkceHandler extends AuthCodeHandler implements Handler { signatures: Signatures, commitments: Db.AuthCommitments, authKeys: Db.AuthKeys, + env?: WdkEnv, ) { - super(signupKind, issuer, oauthUrl, audience, nitro, signatures, commitments, authKeys) + super(signupKind, issuer, oauthUrl, audience, nitro, signatures, commitments, authKeys, env) } public async commitAuth(target: string, isSignUp: boolean, state?: string, signer?: string) { @@ -40,7 +42,7 @@ export class AuthCodePkceHandler extends AuthCodeHandler implements Handler { isSignUp, }) - const searchParams = new URLSearchParams({ + const searchParams = this.serializeQuery({ code_challenge: codeChallenge, code_challenge_method: 'S256', client_id: this.audience, @@ -51,7 +53,7 @@ export class AuthCodePkceHandler extends AuthCodeHandler implements Handler { state, }) - return `${this.oauthUrl}?${searchParams.toString()}` + return `${this.oauthUrl}?${searchParams}` } public async completeAuth( diff --git a/packages/wallet/wdk/src/sequence/handlers/authcode.ts b/packages/wallet/wdk/src/sequence/handlers/authcode.ts index 74ad9ee935..8e98745e87 100644 --- a/packages/wallet/wdk/src/sequence/handlers/authcode.ts +++ b/packages/wallet/wdk/src/sequence/handlers/authcode.ts @@ -6,6 +6,7 @@ import * as Identity from '@0xsequence/identity-instrument' import { SignerUnavailable, SignerReady, SignerActionable, BaseSignatureRequest } from '../types/signature-request.js' import { IdentitySigner } from '../../identity/signer.js' import { IdentityHandler } from './identity.js' +import type { NavigationLike, WdkEnv } from '../../env.js' export class AuthCodeHandler extends IdentityHandler implements Handler { protected redirectUri: string = '' @@ -19,8 +20,9 @@ export class AuthCodeHandler extends IdentityHandler implements Handler { signatures: Signatures, protected readonly commitments: Db.AuthCommitments, authKeys: Db.AuthKeys, + env?: WdkEnv, ) { - super(nitro, authKeys, signatures, Identity.IdentityType.OIDC) + super(nitro, authKeys, signatures, Identity.IdentityType.OIDC, env) } public get kind() { @@ -45,7 +47,7 @@ export class AuthCodeHandler extends IdentityHandler implements Handler { isSignUp, }) - const searchParams = new URLSearchParams({ + const searchParams = this.serializeQuery({ client_id: this.audience, redirect_uri: this.redirectUri, response_type: 'code', @@ -53,7 +55,7 @@ export class AuthCodeHandler extends IdentityHandler implements Handler { ...(this.signupKind === 'apple' ? {} : { scope: 'openid profile email' }), }) - return `${this.oauthUrl}?${searchParams.toString()}` + return `${this.oauthUrl}?${searchParams}` } public async completeAuth( @@ -94,10 +96,29 @@ export class AuthCodeHandler extends IdentityHandler implements Handler { status: 'actionable', message: 'request-redirect', handle: async () => { - const url = await this.commitAuth(window.location.pathname, false, request.id, address) - window.location.href = url + const navigation = this.getNavigation() + const url = await this.commitAuth(navigation.getPathname(), false, request.id, address) + navigation.redirect(url) return true }, } } + + protected serializeQuery(params: Record): string { + const searchParamsCtor = this.env.urlSearchParams ?? (globalThis as any).URLSearchParams + if (searchParamsCtor) { + return new searchParamsCtor(params).toString() + } + return Object.entries(params) + .map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`) + .join('&') + } + + private getNavigation(): NavigationLike { + const navigation = this.env.navigation + if (!navigation) { + throw new Error('navigation is not available') + } + return navigation + } } diff --git a/packages/wallet/wdk/src/sequence/handlers/devices.ts b/packages/wallet/wdk/src/sequence/handlers/devices.ts index 9da0f89711..4d525d37e1 100644 --- a/packages/wallet/wdk/src/sequence/handlers/devices.ts +++ b/packages/wallet/wdk/src/sequence/handlers/devices.ts @@ -13,7 +13,7 @@ export class DevicesHandler implements Handler { private readonly devices: Devices, ) {} - onStatusChange(cb: () => void): () => void { + onStatusChange(_cb: () => void): () => void { return () => {} } diff --git a/packages/wallet/wdk/src/sequence/handlers/guard.ts b/packages/wallet/wdk/src/sequence/handlers/guard.ts index bbe8c26989..b495c95d8b 100644 --- a/packages/wallet/wdk/src/sequence/handlers/guard.ts +++ b/packages/wallet/wdk/src/sequence/handlers/guard.ts @@ -35,7 +35,7 @@ export class GuardHandler implements Handler { this.onPromptCode = undefined } - onStatusChange(cb: () => void): () => void { + onStatusChange(_cb: () => void): () => void { return () => {} } @@ -87,8 +87,9 @@ export class GuardHandler implements Handler { address, handler: this, status: 'ready', - handle: () => - new Promise(async (resolve, reject) => { + handle: () => { + // eslint-disable-next-line no-async-promise-executor + return new Promise(async (resolve, reject) => { try { const signature = await guard.signEnvelope(request.envelope) await this.signatures.addSignature(request.id, signature) @@ -106,7 +107,8 @@ export class GuardHandler implements Handler { reject(e) } } - }), + }) + }, } } } diff --git a/packages/wallet/wdk/src/sequence/handlers/identity.ts b/packages/wallet/wdk/src/sequence/handlers/identity.ts index f182452220..f03876a5be 100644 --- a/packages/wallet/wdk/src/sequence/handlers/identity.ts +++ b/packages/wallet/wdk/src/sequence/handlers/identity.ts @@ -1,9 +1,10 @@ -import { Hex, Bytes } from 'ox' +import { Hex } from 'ox' import * as Db from '../../dbs/index.js' import * as Identity from '@0xsequence/identity-instrument' import { Signatures } from '../signatures.js' import { BaseSignatureRequest } from '../types/signature-request.js' import { IdentitySigner, toIdentityAuthKey } from '../../identity/signer.js' +import { resolveWdkEnv, type WdkEnv } from '../../env.js' export const identityTypeToHex = (identityType?: Identity.IdentityType): Hex.Hex => { // Bytes4 @@ -19,12 +20,17 @@ export const identityTypeToHex = (identityType?: Identity.IdentityType): Hex.Hex } export class IdentityHandler { + protected readonly env: WdkEnv + constructor( private readonly nitro: Identity.IdentityInstrument, private readonly authKeys: Db.AuthKeys, private readonly signatures: Signatures, public readonly identityType: Identity.IdentityType, - ) {} + env?: WdkEnv, + ) { + this.env = resolveWdkEnv(env) + } public onStatusChange(cb: () => void): () => void { return this.authKeys.addListener(cb) @@ -37,7 +43,7 @@ export class IdentityHandler { throw new Error('no-auth-key') } - const res = await this.nitro.commitVerifier(toIdentityAuthKey(authKey), challenge) + const res = await this.nitro.commitVerifier(toIdentityAuthKey(authKey, this.env.crypto), challenge) return res } @@ -47,7 +53,7 @@ export class IdentityHandler { throw new Error('no-auth-key') } - const res = await this.nitro.completeAuth(toIdentityAuthKey(authKey), challenge) + const res = await this.nitro.completeAuth(toIdentityAuthKey(authKey, this.env.crypto), challenge) authKey.identitySigner = res.signer.address authKey.expiresAt = new Date(Date.now() + 1000 * 60 * 3) // 3 minutes @@ -55,7 +61,7 @@ export class IdentityHandler { await this.authKeys.delBySigner(authKey.identitySigner) await this.authKeys.set(authKey) - const signer = new IdentitySigner(this.nitro, authKey) + const signer = new IdentitySigner(this.nitro, authKey, this.env.crypto) return { signer, email: res.identity.email } } @@ -72,13 +78,17 @@ export class IdentityHandler { if (!authKey) { return undefined } - return new IdentitySigner(this.nitro, authKey) + return new IdentitySigner(this.nitro, authKey, this.env.crypto) } private async getAuthKey(signer: string): Promise { let authKey = await this.authKeys.getBySigner(signer) if (!signer && !authKey) { - const keyPair = await window.crypto.subtle.generateKey( + const crypto = this.env.crypto ?? (globalThis as any).crypto + if (!crypto?.subtle) { + throw new Error('crypto.subtle is not available') + } + const keyPair = await crypto.subtle.generateKey( { name: 'ECDSA', namedCurve: 'P-256', @@ -86,7 +96,7 @@ export class IdentityHandler { false, ['sign', 'verify'], ) - const publicKey = await window.crypto.subtle.exportKey('raw', keyPair.publicKey) + const publicKey = await crypto.subtle.exportKey('raw', keyPair.publicKey) authKey = { address: Hex.fromBytes(new Uint8Array(publicKey)), identitySigner: '', diff --git a/packages/wallet/wdk/src/sequence/handlers/mnemonic.ts b/packages/wallet/wdk/src/sequence/handlers/mnemonic.ts index 143edc0cdd..3d932a5331 100644 --- a/packages/wallet/wdk/src/sequence/handlers/mnemonic.ts +++ b/packages/wallet/wdk/src/sequence/handlers/mnemonic.ts @@ -93,8 +93,9 @@ export class MnemonicHandler implements Handler { handler: this, status: 'actionable', message: 'enter-mnemonic', - handle: () => - new Promise(async (resolve, reject) => { + handle: () => { + // eslint-disable-next-line no-async-promise-executor + return new Promise(async (resolve, reject) => { const respond: RespondFn = async (mnemonic) => { const signer = MnemonicHandler.toSigner(mnemonic) if (!signer) { @@ -117,7 +118,8 @@ export class MnemonicHandler implements Handler { resolve(true) } await onPromptMnemonic(respond) - }), + }) + }, } } } diff --git a/packages/wallet/wdk/src/sequence/handlers/otp.ts b/packages/wallet/wdk/src/sequence/handlers/otp.ts index f037189cbf..42bf85c9e4 100644 --- a/packages/wallet/wdk/src/sequence/handlers/otp.ts +++ b/packages/wallet/wdk/src/sequence/handlers/otp.ts @@ -8,6 +8,7 @@ import { SignerUnavailable, SignerReady, SignerActionable, BaseSignatureRequest import { Kinds } from '../types/signer.js' import { IdentityHandler } from './identity.js' import { AnswerIncorrectError, ChallengeExpiredError, TooManyAttemptsError } from '../errors.js' +import type { WdkEnv } from '../../env.js' type RespondFn = (otp: string) => Promise @@ -18,8 +19,8 @@ export class OtpHandler extends IdentityHandler implements Handler { private onPromptOtp: undefined | PromptOtpHandler - constructor(nitro: Identity.IdentityInstrument, signatures: Signatures, authKeys: Db.AuthKeys) { - super(nitro, authKeys, signatures, Identity.IdentityType.Email) + constructor(nitro: Identity.IdentityInstrument, signatures: Signatures, authKeys: Db.AuthKeys, env?: WdkEnv) { + super(nitro, authKeys, signatures, Identity.IdentityType.Email, env) } public registerUI(onPromptOtp: PromptOtpHandler) { @@ -84,7 +85,7 @@ export class OtpHandler extends IdentityHandler implements Handler { try { await this.handleAuth(challenge, onPromptOtp) return true - } catch (e) { + } catch { return false } }, @@ -95,6 +96,7 @@ export class OtpHandler extends IdentityHandler implements Handler { challenge: Identity.OtpChallenge, onPromptOtp: PromptOtpHandler, ): 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) diff --git a/packages/wallet/wdk/src/sequence/handlers/passkeys.ts b/packages/wallet/wdk/src/sequence/handlers/passkeys.ts index da3db7ff32..17c3196ca2 100644 --- a/packages/wallet/wdk/src/sequence/handlers/passkeys.ts +++ b/packages/wallet/wdk/src/sequence/handlers/passkeys.ts @@ -1,33 +1,35 @@ -import { Signers, State } from '@0xsequence/wallet-core' +import { State } from '@0xsequence/wallet-core' import { Address, Hex } from 'ox' import { Kinds } from '../types/signer.js' import { Signatures } from '../signatures.js' -import { Extensions } from '@0xsequence/wallet-primitives' +import { Config, Extensions } from '@0xsequence/wallet-primitives' import { Handler } from './handler.js' import { SignerActionable, SignerUnavailable, BaseSignatureRequest } from '../types/index.js' +import type { PasskeyProvider, PasskeySigner } from '../passkeys-provider.js' export class PasskeysHandler implements Handler { kind = Kinds.LoginPasskey - private readySigners = new Map() + private readySigners = new Map() constructor( private readonly signatures: Signatures, private readonly extensions: Pick, private readonly stateReader: State.Reader, + private readonly passkeyProvider: PasskeyProvider, ) {} - onStatusChange(cb: () => void): () => void { + onStatusChange(_cb: () => void): () => void { return () => {} } - public addReadySigner(signer: Signers.Passkey.Passkey) { + public addReadySigner(signer: PasskeySigner) { // Use credentialId as key to match specific passkey instances this.readySigners.set(signer.credentialId, signer) } - private async loadPasskey(wallet: Address.Address, imageHash: Hex.Hex): Promise { + private async loadPasskey(wallet: Address.Address, imageHash: Hex.Hex): Promise { try { - return await Signers.Passkey.Passkey.loadFromWitness(this.stateReader, this.extensions, wallet, imageHash) + return await this.passkeyProvider.loadFromWitness(this.stateReader, this.extensions, wallet, imageHash) } catch (e) { console.warn('Failed to load passkey:', e) return undefined @@ -55,7 +57,7 @@ export class PasskeysHandler implements Handler { } // First check if we have a ready signer that matches the imageHash - let passkey: Signers.Passkey.Passkey | undefined + let passkey: PasskeySigner | undefined // Look for a ready signer with matching imageHash for (const readySigner of this.readySigners.values()) { @@ -91,12 +93,10 @@ export class PasskeysHandler implements Handler { message: 'request-interaction-with-passkey', imageHash: imageHash, handle: async () => { - const signature = await passkey.signSapient( - request.envelope.wallet, - request.envelope.chainId, - request.envelope.payload, - imageHash, + const normalized = Config.normalizeSignerSignature( + passkey.signSapient(request.envelope.wallet, request.envelope.chainId, request.envelope.payload, imageHash), ) + const signature = await normalized.signature await this.signatures.addSignature(request.id, { address, imageHash, diff --git a/packages/wallet/wdk/src/sequence/handlers/recovery.ts b/packages/wallet/wdk/src/sequence/handlers/recovery.ts index 57921de720..9c0ca654d8 100644 --- a/packages/wallet/wdk/src/sequence/handlers/recovery.ts +++ b/packages/wallet/wdk/src/sequence/handlers/recovery.ts @@ -76,7 +76,7 @@ export class RecoveryHandler implements Handler { return true }, } - } catch (e) { + } catch { return { address, handler: this, diff --git a/packages/wallet/wdk/src/sequence/index.ts b/packages/wallet/wdk/src/sequence/index.ts index 37729a4775..ed2f9e440a 100644 --- a/packages/wallet/wdk/src/sequence/index.ts +++ b/packages/wallet/wdk/src/sequence/index.ts @@ -3,6 +3,8 @@ export { Network as Networks } export type { ManagerOptions, Databases, Sequence, Modules, Shared } from './manager.js' export { ManagerOptionsDefaults, CreateWalletOptionsDefaults, applyManagerOptionsDefaults, Manager } from './manager.js' +export { defaultPasskeyProvider } from './passkeys-provider.js' +export type { PasskeyProvider, PasskeySigner } from './passkeys-provider.js' export { Sessions } from './sessions.js' export { Signatures } from './signatures.js' export type { diff --git a/packages/wallet/wdk/src/sequence/manager.ts b/packages/wallet/wdk/src/sequence/manager.ts index ba27116cf3..5418dd65bb 100644 --- a/packages/wallet/wdk/src/sequence/manager.ts +++ b/packages/wallet/wdk/src/sequence/manager.ts @@ -5,6 +5,7 @@ import { createAttestationVerifyingFetch } from '@0xsequence/tee-verifier' import { Config, Constants, Context, Extensions, Network } from '@0xsequence/wallet-primitives' import { Address } from 'ox' import * as Db from '../dbs/index.js' +import { resolveWdkEnv, type WdkEnv } from '../env.js' import { Cron } from './cron.js' import { Devices } from './devices.js' import { Guards, GuardRole } from './guards.js' @@ -31,6 +32,7 @@ import { GuardHandler, PromptCodeHandler } from './handlers/guard.js' import { PasskeyCredential } from '../dbs/index.js' import { PromptMnemonicHandler } from './handlers/mnemonic.js' import { PromptOtpHandler } from './handlers/otp.js' +import { defaultPasskeyProvider, type PasskeyProvider } from './passkeys-provider.js' export type ManagerOptions = { verbose?: boolean @@ -52,6 +54,9 @@ export type ManagerOptions = { dbPruningInterval?: number + env?: WdkEnv + passkeyProvider?: PasskeyProvider + stateProvider?: State.Provider networks?: Network.Network[] relayers?: Relayer.Relayer[] | (() => Relayer.Relayer[]) @@ -70,7 +75,7 @@ export type ManagerOptions = { identity?: { url?: string - fetch?: typeof window.fetch + fetch?: typeof fetch verifyAttestation?: boolean expectedPcr0?: string[] scope?: string @@ -95,6 +100,72 @@ export type ManagerOptions = { } } +export type ResolvedIdentityOptions = { + url: string + fetch?: typeof fetch + verifyAttestation: boolean + expectedPcr0?: string[] + scope?: string + email: { + enabled: boolean + } + google: { + enabled: boolean + clientId: string + } + apple: { + enabled: boolean + clientId: string + } + customProviders?: { + kind: `custom-${string}` + authMethod: 'id-token' | 'authcode' | 'authcode-pkce' + issuer: string + oauthUrl: string + clientId: string + }[] +} + +export type ResolvedManagerOptions = { + verbose: boolean + + extensions: Extensions.Extensions + context: Context.Context + context4337: Context.Context + guest: Address.Address + + encryptedPksDb: CoreSigners.Pk.Encrypted.EncryptedPksDb + managerDb: Db.Wallets + transactionsDb: Db.Transactions + signaturesDb: Db.Signatures + messagesDb: Db.Messages + authCommitmentsDb: Db.AuthCommitments + authKeysDb: Db.AuthKeys + recoveryDb: Db.Recovery + passkeyCredentialsDb: Db.PasskeyCredentials + + dbPruningInterval: number + + env: WdkEnv + passkeyProvider: PasskeyProvider + + stateProvider: State.Provider + networks: Network.Network[] + relayers: Relayer.Relayer[] | (() => Relayer.Relayer[]) + bundlers: Bundler.Bundler[] + guardUrl: string + guardAddresses: Record + + nonWitnessableSigners: Address.Address[] + + defaultGuardTopology: Config.Topology + defaultRecoverySettings: RecoverySettings + + multiInjectedProviderDiscovery: boolean + + identity: ResolvedIdentityOptions +} + export const ManagerOptionsDefaults = { verbose: false, @@ -115,7 +186,9 @@ export const ManagerOptionsDefaults = { dbPruningInterval: 1000 * 60 * 60 * 24, // 24 hours - stateProvider: new State.Sequence.Provider(), + passkeyProvider: defaultPasskeyProvider, + + stateProvider: typeof fetch !== 'undefined' ? new State.Sequence.Provider(undefined, fetch) : undefined, networks: Network.ALL, relayers: () => { if (typeof window !== 'undefined') { @@ -160,6 +233,7 @@ export const ManagerOptionsDefaults = { defaultRecoverySettings: { requiredDeltaTime: 2592000n, // 30 days (in seconds) minTimestamp: 0n, + includeTestnets: false, }, multiInjectedProviderDiscovery: true, @@ -186,13 +260,45 @@ export const CreateWalletOptionsDefaults = { useGuard: false, } -export function applyManagerOptionsDefaults(options?: ManagerOptions) { - const merged = { - ...ManagerOptionsDefaults, - ...options, - identity: { ...ManagerOptionsDefaults.identity, ...options?.identity }, +export function applyManagerOptionsDefaults(options?: ManagerOptions): ResolvedManagerOptions { + const env = resolveWdkEnv(options?.env) + + const identity: ResolvedIdentityOptions = { + ...ManagerOptionsDefaults.identity, + ...options?.identity, + email: { ...ManagerOptionsDefaults.identity.email, ...options?.identity?.email }, + google: { ...ManagerOptionsDefaults.identity.google, ...options?.identity?.google }, + apple: { ...ManagerOptionsDefaults.identity.apple, ...options?.identity?.apple }, + } + + if (!identity.fetch && env.fetch) { + identity.fetch = env.fetch + } + + let encryptedPksDb = options?.encryptedPksDb ?? ManagerOptionsDefaults.encryptedPksDb + if (!options?.encryptedPksDb && options?.env) { + encryptedPksDb = new CoreSigners.Pk.Encrypted.EncryptedPksDb(undefined, undefined, env) + } + + let authKeysDb = options?.authKeysDb ?? ManagerOptionsDefaults.authKeysDb + if (!options?.authKeysDb && options?.env) { + authKeysDb = new Db.AuthKeys(undefined, env) } + let stateProvider = options?.stateProvider ?? ManagerOptionsDefaults.stateProvider + if (!options?.stateProvider && options?.env?.fetch) { + stateProvider = new State.Sequence.Provider(undefined, options.env.fetch) + } else if (!stateProvider && env.fetch) { + stateProvider = new State.Sequence.Provider(undefined, env.fetch) + } + + if (!stateProvider) { + throw new Error('stateProvider is required. Provide ManagerOptions.stateProvider or env.fetch') + } + + const extensions = options?.extensions ?? ManagerOptionsDefaults.extensions + const defaultGuardTopology = options?.defaultGuardTopology ?? ManagerOptionsDefaults.defaultGuardTopology + // Merge and normalize non-witnessable signers. // We always include the sessions extension address for the active extensions set. const nonWitnessable = new Set() @@ -202,12 +308,12 @@ export function applyManagerOptionsDefaults(options?: ManagerOptions) { for (const address of options?.nonWitnessableSigners ?? []) { nonWitnessable.add(address.toLowerCase()) } - nonWitnessable.add(merged.extensions.sessions.toLowerCase()) + nonWitnessable.add(extensions.sessions.toLowerCase()) // Include static signer leaves from the guard topology (e.g. recovery guard signer), // but ignore the placeholder address that is later replaced per-role. - if (merged.defaultGuardTopology) { - const guardTopologySigners = Config.getSigners(merged.defaultGuardTopology) + if (defaultGuardTopology) { + const guardTopologySigners = Config.getSigners(defaultGuardTopology) for (const signer of guardTopologySigners.signers) { if (Address.isEqual(signer, Constants.PlaceholderAddress)) { continue @@ -219,14 +325,52 @@ export function applyManagerOptionsDefaults(options?: ManagerOptions) { } } - merged.nonWitnessableSigners = Array.from(nonWitnessable) as Address.Address[] + return { + verbose: options?.verbose ?? ManagerOptionsDefaults.verbose, - return merged + extensions, + context: options?.context ?? ManagerOptionsDefaults.context, + context4337: options?.context4337 ?? ManagerOptionsDefaults.context4337, + guest: options?.guest ?? ManagerOptionsDefaults.guest, + + encryptedPksDb, + managerDb: options?.managerDb ?? ManagerOptionsDefaults.managerDb, + transactionsDb: options?.transactionsDb ?? ManagerOptionsDefaults.transactionsDb, + signaturesDb: options?.signaturesDb ?? ManagerOptionsDefaults.signaturesDb, + messagesDb: options?.messagesDb ?? ManagerOptionsDefaults.messagesDb, + authCommitmentsDb: options?.authCommitmentsDb ?? ManagerOptionsDefaults.authCommitmentsDb, + recoveryDb: options?.recoveryDb ?? ManagerOptionsDefaults.recoveryDb, + authKeysDb, + passkeyCredentialsDb: options?.passkeyCredentialsDb ?? ManagerOptionsDefaults.passkeyCredentialsDb, + + dbPruningInterval: options?.dbPruningInterval ?? ManagerOptionsDefaults.dbPruningInterval, + + env, + passkeyProvider: options?.passkeyProvider ?? ManagerOptionsDefaults.passkeyProvider, + + stateProvider, + networks: options?.networks ?? ManagerOptionsDefaults.networks, + relayers: options?.relayers ?? ManagerOptionsDefaults.relayers, + bundlers: options?.bundlers ?? ManagerOptionsDefaults.bundlers, + guardUrl: options?.guardUrl ?? ManagerOptionsDefaults.guardUrl, + guardAddresses: options?.guardAddresses ?? ManagerOptionsDefaults.guardAddresses, + + nonWitnessableSigners: Array.from(nonWitnessable) as Address.Address[], + + defaultGuardTopology, + defaultRecoverySettings: options?.defaultRecoverySettings ?? ManagerOptionsDefaults.defaultRecoverySettings, + + multiInjectedProviderDiscovery: + options?.multiInjectedProviderDiscovery ?? ManagerOptionsDefaults.multiInjectedProviderDiscovery, + + identity, + } } export type RecoverySettings = { requiredDeltaTime: bigint minTimestamp: bigint + includeTestnets?: boolean } export type Databases = { @@ -283,6 +427,8 @@ export type Shared = { readonly sequence: Sequence readonly databases: Databases + readonly env: WdkEnv + readonly passkeyProvider: PasskeyProvider readonly handlers: Map @@ -415,7 +561,7 @@ export class Manager { const ops = applyManagerOptionsDefaults(options) // Build relayers list - let relayers: Relayer.Relayer[] = [] + const relayers: Relayer.Relayer[] = [] // Add EIP-6963 relayers if enabled if (ops.multiInjectedProviderDiscovery) { @@ -469,6 +615,9 @@ export class Manager { pruningInterval: ops.dbPruningInterval, }, + env: ops.env, + passkeyProvider: ops.passkeyProvider, + modules: {} as any, handlers: new Map(), } @@ -501,6 +650,7 @@ export class Manager { modules.signatures, shared.sequence.extensions, shared.sequence.stateProvider, + shared.passkeyProvider, ) shared.handlers.set(Kinds.LoginPasskey, this.passkeysHandler) @@ -523,7 +673,7 @@ export class Manager { const identityInstrument = new IdentityInstrument(ops.identity.url, ops.identity.scope, verifyingFetch) if (ops.identity.email?.enabled) { - this.otpHandler = new OtpHandler(identityInstrument, modules.signatures, shared.databases.authKeys) + this.otpHandler = new OtpHandler(identityInstrument, modules.signatures, shared.databases.authKeys, shared.env) shared.handlers.set(Kinds.LoginEmailOtp, this.otpHandler) } if (ops.identity.google?.enabled) { @@ -538,6 +688,7 @@ export class Manager { modules.signatures, shared.databases.authCommitments, shared.databases.authKeys, + shared.env, ), ) } @@ -553,6 +704,7 @@ export class Manager { modules.signatures, shared.databases.authCommitments, shared.databases.authKeys, + shared.env, ), ) } @@ -573,6 +725,7 @@ export class Manager { modules.signatures, shared.databases.authCommitments, shared.databases.authKeys, + shared.env, ), ) break @@ -588,6 +741,7 @@ export class Manager { modules.signatures, shared.databases.authCommitments, shared.databases.authKeys, + shared.env, ), ) break diff --git a/packages/wallet/wdk/src/sequence/messages.ts b/packages/wallet/wdk/src/sequence/messages.ts index 131aae3b1d..d8fe480c23 100644 --- a/packages/wallet/wdk/src/sequence/messages.ts +++ b/packages/wallet/wdk/src/sequence/messages.ts @@ -242,7 +242,7 @@ export class Messages implements MessagesInterface { const message = await this.getByMessageOrSignatureId(messageOrSignatureId) await this.shared.databases.signatures.del(message.signatureId) await this.shared.databases.messages.del(message.id) - } catch (error) { + } catch { // Ignore } } diff --git a/packages/wallet/wdk/src/sequence/passkeys-provider.ts b/packages/wallet/wdk/src/sequence/passkeys-provider.ts new file mode 100644 index 0000000000..3ed2068fe3 --- /dev/null +++ b/packages/wallet/wdk/src/sequence/passkeys-provider.ts @@ -0,0 +1,55 @@ +import { Signers, State } from '@0xsequence/wallet-core' +import type { Extensions } from '@0xsequence/wallet-primitives' +import type { Address, Hex } from 'ox' + +export type PasskeySigner = Signers.SapientSigner & + Signers.Witnessable & { + credentialId: string + publicKey: Extensions.Passkeys.PublicKey + imageHash: Hex.Hex + } + +export type PasskeyProvider = { + create: ( + extensions: Pick, + options?: Signers.Passkey.CreatePasskeyOptions, + ) => Promise + find: ( + stateReader: State.Reader, + extensions: Pick, + options?: Signers.Passkey.FindPasskeyOptions, + ) => Promise + loadFromWitness: ( + stateReader: State.Reader, + extensions: Pick, + wallet: Address.Address, + imageHash: Hex.Hex, + options?: Signers.Passkey.FindPasskeyOptions, + ) => Promise + fromCredential: (args: { + credentialId: string + publicKey: Extensions.Passkeys.PublicKey + extensions: Pick + embedMetadata?: boolean + metadata?: Extensions.Passkeys.PasskeyMetadata + webauthn?: Signers.Passkey.WebAuthnLike + }) => PasskeySigner + isSigner?: (signer: unknown) => signer is PasskeySigner +} + +export const defaultPasskeyProvider: PasskeyProvider = { + create: (extensions, options) => Signers.Passkey.Passkey.create(extensions, options), + find: (stateReader, extensions, options) => Signers.Passkey.Passkey.find(stateReader, extensions, options), + loadFromWitness: (stateReader, extensions, wallet, imageHash, options) => + Signers.Passkey.Passkey.loadFromWitness(stateReader, extensions, wallet, imageHash, options), + fromCredential: ({ credentialId, publicKey, extensions, embedMetadata, metadata, webauthn }) => + new Signers.Passkey.Passkey({ + credentialId, + publicKey, + extensions, + embedMetadata, + metadata, + webauthn, + }), + isSigner: (signer: unknown): signer is PasskeySigner => signer instanceof Signers.Passkey.Passkey, +} diff --git a/packages/wallet/wdk/src/sequence/recovery.ts b/packages/wallet/wdk/src/sequence/recovery.ts index 600fb76749..2e60743646 100644 --- a/packages/wallet/wdk/src/sequence/recovery.ts +++ b/packages/wallet/wdk/src/sequence/recovery.ts @@ -1,12 +1,16 @@ import { Envelope } from '@0xsequence/wallet-core' import { Config, Constants, Extensions, GenericTree, Payload } from '@0xsequence/wallet-primitives' -import { Address, Hex, Provider, RpcTransport } from 'ox' +import { Abi, AbiFunction, Address, Hex, Provider, RpcTransport } from 'ox' import { MnemonicHandler } from './handlers/mnemonic.js' import { Shared } from './manager.js' import { Actions, Module } from './types/index.js' import { QueuedRecoveryPayload } from './types/recovery.js' import { Kinds, RecoverySigner } from './types/signer.js' +const AGGREGATE3 = Abi.from([ + 'function aggregate3((address target, bool allowFailure, bytes callData)[] calls) external payable returns ((bool success, bytes returnData)[])', +])[0]! + export interface RecoveryInterface { /** * Retrieves the list of configured recovery signers for a given wallet. @@ -284,7 +288,7 @@ export class Recovery implements RecoveryInterface { } await this.updateRecoveryModule(modules, (leaves) => { - const next = leaves.filter((l) => l.signer !== address) + const next = leaves.filter((l) => !Address.isEqual(l.signer, address)) if (next.length === 0) { return [ { @@ -514,9 +518,16 @@ export class Recovery implements RecoveryInterface { async fetchQueuedPayloads(wallet: Address.Address, chainId?: number): Promise { // Create providers for each network const providers = this.shared.sequence.networks - .filter((network) => (chainId ? network.chainId === chainId : true)) + .filter((network) => + chainId + ? network.chainId === chainId + : !this.shared.sequence.defaultRecoverySettings.includeTestnets + ? network.type !== 'testnet' + : true, + ) .map((network) => ({ chainId: network.chainId, + multicall3Address: network.contracts?.multicall3, provider: Provider.from(RpcTransport.fromHttp(network.rpcUrl)), })) @@ -526,69 +537,167 @@ export class Recovery implements RecoveryInterface { return [] } + const recoveryExtension = this.shared.sequence.extensions.recovery const payloads: QueuedRecoveryPayload[] = [] - for (const signer of signers) { - for (const { chainId, provider } of providers) { - const totalPayloads = await Extensions.Recovery.totalQueuedPayloads( - provider, - this.shared.sequence.extensions.recovery, - wallet, - signer.address, - ) - - for (let i = 0n; i < totalPayloads; i++) { - const payloadHash = await Extensions.Recovery.queuedPayloadHashOf( - provider, - this.shared.sequence.extensions.recovery, - wallet, - signer.address, - i, - ) - - const timestamp = await Extensions.Recovery.timestampForQueuedPayload( - provider, - this.shared.sequence.extensions.recovery, - wallet, - signer.address, - payloadHash, - ) - - const payload = await this.shared.sequence.stateProvider.getPayload(payloadHash) - - // If ready, we need to check if it was executed already - // for this, we check if the wallet nonce for the given space - // is greater than the nonce in the payload - if (timestamp < Date.now() / 1000 && payload && Payload.isCalls(payload.payload)) { - const nonce = await this.shared.modules.wallets.getNonce(chainId, wallet, payload.payload.space) - if (nonce > i) { - continue + await Promise.all( + providers.map(async ({ chainId, provider, multicall3Address }) => { + try { + let totalPayloadsBySigner: bigint[] + + if (multicall3Address) { + try { + // Batch all totalQueuedPayloads calls for every signer into a single Multicall3 request. + // This reduces N signer calls per network down to 1 call per network. + totalPayloadsBySigner = await this.fetchTotalQueuedPayloadsBatched( + provider, + recoveryExtension, + wallet, + signers, + multicall3Address, + ) + } catch (err) { + console.error( + `Recovery.fetchQueuedPayloads multicall3 failed for chainId ${chainId}, retrying with individual calls:`, + err, + ) + totalPayloadsBySigner = await this.fetchTotalQueuedPayloadsFallback( + provider, + recoveryExtension, + wallet, + signers, + ) } + } else { + totalPayloadsBySigner = await this.fetchTotalQueuedPayloadsFallback( + provider, + recoveryExtension, + wallet, + signers, + ) } - // The id is the index + signer address + chainId + wallet address - const id = `${i}-${signer.address}-${chainId}-${wallet}` - - // Create a new payload - const payloadEntry: QueuedRecoveryPayload = { - id, - index: i, - recoveryModule: this.shared.sequence.extensions.recovery, - wallet: wallet, - signer: signer.address, - chainId, - startTimestamp: timestamp, - endTimestamp: timestamp + signer.requiredDeltaTime, - payloadHash, - payload: payload?.payload, + for (let s = 0; s < signers.length; s++) { + const signer = signers[s]! + const totalPayloads = totalPayloadsBySigner[s]! + if (totalPayloads === 0n) continue + + // Only make individual calls for the rare case where payloads actually exist + for (let i = 0n; i < totalPayloads; i++) { + const payloadHash = await Extensions.Recovery.queuedPayloadHashOf( + provider, + recoveryExtension, + wallet, + signer.address, + i, + ) + + const timestamp = await Extensions.Recovery.timestampForQueuedPayload( + provider, + recoveryExtension, + wallet, + signer.address, + payloadHash, + ) + + const payload = await this.shared.sequence.stateProvider.getPayload(payloadHash) + + // If ready, we need to check if it was executed already + // for this, we check if the wallet nonce for the given space + // is greater than the nonce in the payload + if (timestamp < Date.now() / 1000 && payload && Payload.isCalls(payload.payload)) { + const nonce = await this.shared.modules.wallets.getNonce(chainId, wallet, payload.payload.space) + if (nonce > i) { + continue + } + } + + // The id is the index + signer address + chainId + wallet address + const id = `${i}-${signer.address}-${chainId}-${wallet}` + + const payloadEntry: QueuedRecoveryPayload = { + id, + index: i, + recoveryModule: recoveryExtension, + wallet: wallet, + signer: signer.address, + chainId, + startTimestamp: timestamp, + endTimestamp: timestamp + signer.requiredDeltaTime, + payloadHash, + payload: payload?.payload, + } + + payloads.push(payloadEntry) + } } - - payloads.push(payloadEntry) + } catch (err) { + console.error(`Recovery.fetchQueuedPayloads error for chainId ${chainId}:`, err) } + }), + ) + + return payloads + } + + private async fetchTotalQueuedPayloadsBatched( + provider: Provider.Provider, + recoveryExtension: Address.Address, + wallet: Address.Address, + signers: RecoverySigner[], + multicall3Address: Address.Address, + ): Promise { + const calls = signers.map((signer) => ({ + target: recoveryExtension, + allowFailure: true, + callData: AbiFunction.encodeData(Extensions.Recovery.TOTAL_QUEUED_PAYLOADS, [wallet, signer.address]), + })) + + const response = await provider.request({ + method: 'eth_call', + params: [ + { + to: multicall3Address, + data: AbiFunction.encodeData(AGGREGATE3, [calls]), + }, + 'latest', + ], + }) + + const results = AbiFunction.decodeResult(AGGREGATE3, response) as readonly { + success: boolean + returnData: Hex.Hex + }[] + + return results.map((result) => { + if (!result.success || result.returnData === '0x') { + return 0n } + return Hex.toBigInt(result.returnData) + }) + } + + private fetchTotalQueuedPayloadsFallback = async ( + provider: Provider.Provider, + recoveryExtension: Address.Address, + wallet: Address.Address, + signers: RecoverySigner[], + ): Promise => { + const result: bigint[] = signers.map(() => 0n) + + // Fallback to individual calls if the multicall3 call fails + for (let s = 0; s < signers.length; s++) { + const signer = signers[s]! + const totalPayloads = await Extensions.Recovery.totalQueuedPayloads( + provider, + recoveryExtension, + wallet, + signer.address, + ) + result[s] = totalPayloads } - return payloads + return result } async encodeRecoverySignature(imageHash: Hex.Hex, signer: Address.Address) { diff --git a/packages/wallet/wdk/src/sequence/signers.ts b/packages/wallet/wdk/src/sequence/signers.ts index c2002d2d9a..64f9ff6690 100644 --- a/packages/wallet/wdk/src/sequence/signers.ts +++ b/packages/wallet/wdk/src/sequence/signers.ts @@ -81,7 +81,9 @@ export class Signers { if (isWitnessExtraSignerKind(message)) { return toKnownKind(message.signerKind) } - } catch {} + } catch { + // ignore + } return undefined } diff --git a/packages/wallet/wdk/src/sequence/transactions.ts b/packages/wallet/wdk/src/sequence/transactions.ts index 824cb00f69..26bf21d34c 100644 --- a/packages/wallet/wdk/src/sequence/transactions.ts +++ b/packages/wallet/wdk/src/sequence/transactions.ts @@ -347,7 +347,11 @@ export class Transactions implements TransactionsInterface { return [] } - const feeOptions = await relayer.feeOptions(tx.wallet, tx.envelope.chainId, tx.envelope.payload.calls) + // Determine the to address for the built transaction + const walletStatus = await wallet.getStatus(provider) + const to = walletStatus.isDeployed ? wallet.address : wallet.guest + + 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 : {} @@ -492,7 +496,7 @@ export class Transactions implements TransactionsInterface { let tx: Transaction | undefined try { tx = await this.get(transactionOrSignatureId) - } catch (e) { + } catch { // If not found, it might be a signature ID const signature = await this.shared.modules.signatures.get(transactionOrSignatureId) if (!signature) { diff --git a/packages/wallet/wdk/src/sequence/wallets.ts b/packages/wallet/wdk/src/sequence/wallets.ts index fd0320cc43..6cc4f94923 100644 --- a/packages/wallet/wdk/src/sequence/wallets.ts +++ b/packages/wallet/wdk/src/sequence/wallets.ts @@ -1,17 +1,17 @@ import { Wallet as CoreWallet, Envelope, Signers, State } from '@0xsequence/wallet-core' -import { Config, Constants, GenericTree, Payload, SessionConfig } from '@0xsequence/wallet-primitives' +import { Config, Constants, Payload } from '@0xsequence/wallet-primitives' import { Address, Hex, Provider, RpcTransport } from 'ox' import { AuthCommitment } from '../dbs/auth-commitments.js' import { AuthCodeHandler } from './handlers/authcode.js' import { MnemonicHandler } from './handlers/mnemonic.js' import { OtpHandler } from './handlers/otp.js' -import { ManagerOptionsDefaults, Shared } from './manager.js' +import { Shared } from './manager.js' import { Device } from './types/device.js' import { Action, Module } from './types/index.js' import { Kinds, SignerWithKind, WitnessExtraSignerKind } from './types/signer.js' import { Wallet, WalletSelectionUiHandler } from './types/wallet.js' import { PasskeysHandler } from './handlers/passkeys.js' -import { GuardRole } from './guards.js' +import type { PasskeySigner } from './passkeys-provider.js' export type StartSignUpWithRedirectArgs = { kind: 'google-pkce' | 'apple' | `custom-${string}` @@ -417,17 +417,17 @@ function buildCappedTree(members: { address: Address.Address; imageHash?: Hex.He } as Config.NestedLeaf } -function buildCappedTreeFromTopology(weight: bigint, topology: Config.Topology): Config.Topology { - // We may optimize this for some topology types - // but it is not worth it, because the topology - // that we will use for prod won't be optimizable - return { - type: 'nested', - weight: weight, - threshold: weight, - tree: topology, - } -} +// function buildCappedTreeFromTopology(weight: bigint, topology: Config.Topology): Config.Topology { +// // We may optimize this for some topology types +// // but it is not worth it, because the topology +// // that we will use for prod won't be optimizable +// return { +// type: 'nested', +// weight: weight, +// threshold: weight, +// tree: topology, +// } +// } function toConfig( checkpoint: bigint, @@ -625,8 +625,8 @@ export class Wallets implements WalletsInterface { loginEmail?: string }> { switch (args.kind) { - case 'passkey': - const passkeySigner = await Signers.Passkey.Passkey.create(this.shared.sequence.extensions, { + case 'passkey': { + const passkeySigner = await this.shared.passkeyProvider.create(this.shared.sequence.extensions, { stateProvider: this.shared.sequence.stateProvider, credentialName: args.name, }) @@ -638,8 +638,9 @@ export class Wallets implements WalletsInterface { signerKind: Kinds.LoginPasskey, }, } + } - case 'mnemonic': + case 'mnemonic': { const mnemonicSigner = MnemonicHandler.toSigner(args.mnemonic) if (!mnemonicSigner) { throw new Error('invalid-mnemonic') @@ -653,6 +654,7 @@ export class Wallets implements WalletsInterface { signerKind: Kinds.LoginMnemonic, }, } + } case 'email-otp': { const handler = this.shared.handlers.get(Kinds.LoginEmailOtp) as OtpHandler @@ -834,7 +836,7 @@ export class Wallets implements WalletsInterface { const sessionsGuardTopology = args.noGuard ? undefined : this.shared.modules.guards.topology('sessions') // Add modules - let modules: Module[] = [] + const modules: Module[] = [] if (!args.noSessionManager) { const identitySigners = [device.address] @@ -891,7 +893,7 @@ export class Wallets implements WalletsInterface { } // Store passkey credential ID mapping if this is a passkey signup - if (args.kind === 'passkey' && loginSigner.signer instanceof Signers.Passkey.Passkey) { + if (args.kind === 'passkey' && this.isPasskeySigner(loginSigner.signer)) { try { await this.shared.databases.passkeyCredentials.saveCredential( loginSigner.signer.credentialId, @@ -1043,8 +1045,6 @@ export class Wallets implements WalletsInterface { }) return requestId - } catch (error) { - throw error } finally { this.pendingMnemonicOrPasskeyLogin = undefined } @@ -1075,7 +1075,7 @@ export class Wallets implements WalletsInterface { } if (isLoginToPasskeyArgs(args)) { - let passkeySigner: Signers.Passkey.Passkey + let passkeySigner: PasskeySigner if (args.credentialId) { // Application-controlled login: use the provided credentialId @@ -1087,7 +1087,7 @@ export class Wallets implements WalletsInterface { } // Create passkey signer from stored credential - passkeySigner = new Signers.Passkey.Passkey({ + passkeySigner = this.shared.passkeyProvider.fromCredential({ credentialId: credential.credentialId, publicKey: credential.publicKey, extensions: this.shared.sequence.extensions, @@ -1098,7 +1098,7 @@ export class Wallets implements WalletsInterface { // Default discovery behavior: use WebAuthn discovery this.shared.modules.logger.log('No credentialId provided, using discovery method') - const foundPasskeySigner = await Signers.Passkey.Passkey.find( + const foundPasskeySigner = await this.shared.passkeyProvider.find( this.shared.sequence.stateProvider, this.shared.sequence.extensions, ) @@ -1153,6 +1153,20 @@ export class Wallets implements WalletsInterface { throw new Error('invalid-login-args') } + private isPasskeySigner(signer: unknown): signer is PasskeySigner { + const guard = this.shared.passkeyProvider.isSigner + if (guard) { + return guard(signer) + } + return ( + typeof signer === 'object' && + signer !== null && + 'credentialId' in signer && + 'publicKey' in signer && + 'imageHash' in signer + ) + } + async completeLogin(requestId: string) { const request = await this.shared.modules.signatures.get(requestId) @@ -1220,7 +1234,7 @@ export class Wallets implements WalletsInterface { return requestId } - async completeLogout(requestId: string, options?: { skipValidateSave?: boolean }) { + async completeLogout(requestId: string, _options?: { skipValidateSave?: boolean }) { const request = await this.shared.modules.signatures.get(requestId) const walletEntry = await this.shared.databases.manager.get(request.wallet) if (!walletEntry) { diff --git a/packages/wallet/wdk/test/authcode-pkce.test.ts b/packages/wallet/wdk/test/authcode-pkce.test.ts index c69e66d710..99e197c7ff 100644 --- a/packages/wallet/wdk/test/authcode-pkce.test.ts +++ b/packages/wallet/wdk/test/authcode-pkce.test.ts @@ -1,5 +1,4 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' -import { Address, Hex, Bytes } from 'ox' import * as Identity from '@0xsequence/identity-instrument' import { AuthCodePkceHandler } from '../src/sequence/handlers/authcode-pkce.js' import { Signatures } from '../src/sequence/signatures.js' @@ -68,7 +67,7 @@ describe('AuthCodePkceHandler', () => { handler.setRedirectUri('https://example.com/auth/callback') // Mock inherited methods - vi.spyOn(handler as any, 'nitroCommitVerifier').mockImplementation(async (challenge) => { + vi.spyOn(handler as any, 'nitroCommitVerifier').mockImplementation(async () => { return { verifier: 'mock-verifier-code', loginHint: 'user@example.com', @@ -76,7 +75,7 @@ describe('AuthCodePkceHandler', () => { } }) - vi.spyOn(handler as any, 'nitroCompleteAuth').mockImplementation(async (challenge) => { + vi.spyOn(handler as any, 'nitroCompleteAuth').mockImplementation(async () => { return { signer: mockIdentitySigner, email: 'user@example.com', diff --git a/packages/wallet/wdk/test/authcode.test.ts b/packages/wallet/wdk/test/authcode.test.ts index f5930894dd..a1c3be0e8e 100644 --- a/packages/wallet/wdk/test/authcode.test.ts +++ b/packages/wallet/wdk/test/authcode.test.ts @@ -1,5 +1,5 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' -import { Address, Hex, Bytes } from 'ox' +import { Address, Hex } from 'ox' import { Network, Payload } from '@0xsequence/wallet-primitives' import { IdentityInstrument, IdentityType, KeyType, AuthCodeChallenge } from '@0xsequence/identity-instrument' import { AuthCodeHandler } from '../src/sequence/handlers/authcode.js' @@ -45,8 +45,8 @@ class MockURLSearchParams { } } -// @ts-ignore - Override global URLSearchParams for testing -global.URLSearchParams = MockURLSearchParams as any +// Override global URLSearchParams for testing +globalThis.URLSearchParams = MockURLSearchParams as any // Mock dependencies with proper vi.fn() types const mockCommitVerifier = vi.fn() @@ -285,8 +285,7 @@ describe('AuthCodeHandler', () => { }) it('Should generate random state when not provided', async () => { - const result = await authCodeHandler.commitAuth('/target', false) - + await authCodeHandler.commitAuth('/target', false) const commitmentCall = mockAuthCommitmentsSet.mock.calls[0]![0]! expect(commitmentCall.id).toBeDefined() expect(typeof commitmentCall.id).toBe('string') @@ -316,8 +315,7 @@ describe('AuthCodeHandler', () => { }) it('Should create commitment without signer', async () => { - const result = await authCodeHandler.commitAuth('/target', true) - + await authCodeHandler.commitAuth('/target', true) const commitmentCall = mockAuthCommitmentsSet.mock.calls[0]![0]! expect(commitmentCall.signer).toBeUndefined() expect(commitmentCall.isSignUp).toBe(true) @@ -329,7 +327,7 @@ describe('AuthCodeHandler', () => { describe('completeAuth()', () => { it('Should complete auth flow with code and return signer', async () => { const authCode = 'test-auth-code-123' - const mockSigner = {} as IdentitySigner + // const mockSigner = {} as IdentitySigner const mockEmail = 'test@example.com' mockCommitVerifier.mockResolvedValueOnce(undefined) diff --git a/packages/wallet/wdk/test/constants.ts b/packages/wallet/wdk/test/constants.ts index 01dff3b508..855884c8b2 100644 --- a/packages/wallet/wdk/test/constants.ts +++ b/packages/wallet/wdk/test/constants.ts @@ -7,6 +7,7 @@ import { Relayer } from '@0xsequence/relayer' import * as Db from '../src/dbs/index.js' import { Network } from '@0xsequence/wallet-primitives' +// eslint-disable-next-line turbo/no-undeclared-env-vars const envFile = process.env.CI ? '.env.test' : '.env.test.local' dotenvConfig({ path: envFile }) @@ -14,6 +15,7 @@ export const EMITTER_ADDRESS: Address.Address = '0xb7bE532959236170064cf099e1a33 export const EMITTER_ABI = Abi.from(['function explicitEmit()', 'function implicitEmit()']) // Environment variables +// eslint-disable-next-line turbo/no-undeclared-env-vars export const LOCAL_RPC_URL = process.env.LOCAL_RPC_URL || 'http://localhost:8545' let testIdCounter = 0 @@ -81,8 +83,8 @@ export function newRemoteManager( ? `_${remoteManagerOptions.tag}_testrun_${testIdCounter}` : `_testrun_${testIdCounter}` - let relayers: Relayer.Relayer[] = [] - let bundlers: Bundler.Bundler[] = [] + const relayers: Relayer.Relayer[] = [] + const bundlers: Bundler.Bundler[] = [] if (remoteManagerOptions.network.relayerPk) { const provider = Provider.from(RpcTransport.fromHttp(remoteManagerOptions.network.rpcUrl)) diff --git a/packages/wallet/wdk/test/guard.test.ts b/packages/wallet/wdk/test/guard.test.ts index 8614de6c2c..ffb117c3fc 100644 --- a/packages/wallet/wdk/test/guard.test.ts +++ b/packages/wallet/wdk/test/guard.test.ts @@ -5,7 +5,7 @@ import { Address, Bytes, Hex, TypedData } from 'ox' import { Config, Constants, Network, Payload } from '@0xsequence/wallet-primitives' import { Kinds } from '../src/sequence/types/signer.js' import { newManager } from './constants.js' -import { GuardRole, Guards } from '../src/sequence/guards.js' +import { Guards } from '../src/sequence/guards.js' // Mock fetch globally for guard API calls const mockFetch = vi.fn() @@ -16,8 +16,8 @@ describe('GuardHandler', () => { let guards: Guards let testWallet: Address.Address let testPayload: Payload.Payload - let testMessageDigest: Bytes.Bytes - let testMessage: Hex.Hex + let _testMessageDigest: Bytes.Bytes + let _testMessage: Hex.Hex beforeEach(async () => { vi.clearAllMocks() @@ -28,8 +28,8 @@ describe('GuardHandler', () => { testWallet = '0x1234567890123456789012345678901234567890' as Address.Address testPayload = Payload.fromMessage(Hex.fromString('Test message')) - testMessage = TypedData.encode(Payload.toTyped(testWallet, Network.ChainId.ARBITRUM, testPayload)) - testMessageDigest = Payload.hash(testWallet, Network.ChainId.ARBITRUM, testPayload) + _testMessage = TypedData.encode(Payload.toTyped(testWallet, Network.ChainId.ARBITRUM, testPayload)) + _testMessageDigest = Payload.hash(testWallet, Network.ChainId.ARBITRUM, testPayload) }) afterEach(async () => { diff --git a/packages/wallet/wdk/test/identity-signer.test.ts b/packages/wallet/wdk/test/identity-signer.test.ts index 9d62f5719a..29403b028c 100644 --- a/packages/wallet/wdk/test/identity-signer.test.ts +++ b/packages/wallet/wdk/test/identity-signer.test.ts @@ -1,5 +1,5 @@ import { afterEach, beforeEach, describe, expect, it, Mock, vi } from 'vitest' -import { Address, Bytes, Hex } from 'ox' +import { Address, Hex } from 'ox' import { Network, Payload } from '@0xsequence/wallet-primitives' import { IdentityInstrument, KeyType } from '@0xsequence/identity-instrument' import { State } from '@0xsequence/wallet-core' diff --git a/packages/wallet/wdk/test/otp.test.ts b/packages/wallet/wdk/test/otp.test.ts index f3ae452094..8229dd7610 100644 --- a/packages/wallet/wdk/test/otp.test.ts +++ b/packages/wallet/wdk/test/otp.test.ts @@ -1,7 +1,7 @@ import { afterEach, beforeEach, describe, expect, it, Mock, vi } from 'vitest' import { Address, Hex } from 'ox' import { Network, Payload } from '@0xsequence/wallet-primitives' -import { IdentityInstrument, IdentityType, KeyType, OtpChallenge } from '@0xsequence/identity-instrument' +import { IdentityInstrument, IdentityType, KeyType } from '@0xsequence/identity-instrument' import { OtpHandler, PromptOtpHandler } from '../src/sequence/handlers/otp.js' import { Signatures } from '../src/sequence/signatures.js' import * as Db from '../src/dbs/index.js' diff --git a/packages/wallet/wdk/test/passkeys.test.ts b/packages/wallet/wdk/test/passkeys.test.ts index 199265822b..e73d0f4e3a 100644 --- a/packages/wallet/wdk/test/passkeys.test.ts +++ b/packages/wallet/wdk/test/passkeys.test.ts @@ -1,7 +1,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' import { Address, Hex } from 'ox' import { Network, Payload } from '@0xsequence/wallet-primitives' -import { Signers, State } from '@0xsequence/wallet-core' +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' diff --git a/packages/wallet/wdk/test/recovery.test.ts b/packages/wallet/wdk/test/recovery.test.ts index 3ca6da0752..ebaab9d3a5 100644 --- a/packages/wallet/wdk/test/recovery.test.ts +++ b/packages/wallet/wdk/test/recovery.test.ts @@ -174,7 +174,7 @@ describe('Recovery', () => { const recoverySigner = request4.signers.find((s) => s.handler?.kind === 'recovery-extension') expect(recoverySigner).toBeDefined() expect(recoverySigner!.status).toBe('ready') - 1 + // Handle the recovery signer const result4 = await (recoverySigner as SignerReady).handle() expect(result4).toBeDefined() @@ -303,9 +303,9 @@ describe('Recovery', () => { }) // Set up mnemonic handler and sign the payload - let handledMnemonic2 = 0 + let _handledMnemonic2 = 0 const unregisterHandler = manager.registerMnemonicUI(async (respond) => { - handledMnemonic2++ + _handledMnemonic2++ await respond(mnemonic2) }) diff --git a/packages/wallet/wdk/test/sessions.test.ts b/packages/wallet/wdk/test/sessions.test.ts index 98a762d3e3..aa6ad05b8f 100644 --- a/packages/wallet/wdk/test/sessions.test.ts +++ b/packages/wallet/wdk/test/sessions.test.ts @@ -358,7 +358,7 @@ for (const extension of ALL_EXTENSIONS) { throw new Error('Failed to create pk store') } // Create the initial permissions - let explicitSession: ExplicitSession = { + const explicitSession: ExplicitSession = { type: 'explicit', sessionAddress: e.address, chainId, diff --git a/packages/wallet/wdk/test/test-ssr-safety.mjs b/packages/wallet/wdk/test/test-ssr-safety.js similarity index 50% rename from packages/wallet/wdk/test/test-ssr-safety.mjs rename to packages/wallet/wdk/test/test-ssr-safety.js index 55ef7723db..71eb361702 100644 --- a/packages/wallet/wdk/test/test-ssr-safety.mjs +++ b/packages/wallet/wdk/test/test-ssr-safety.js @@ -1,12 +1,13 @@ #!/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 */ @@ -52,24 +53,25 @@ 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')) { + 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:') @@ -81,7 +83,7 @@ try { 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 @@ -98,83 +100,84 @@ 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)) { + 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 propValue = accessed[prop] - if (typeof propValue === 'object' && propValue !== null && depth < 2) { - await testExports(propValue, `${currentPath}.${prop}`, depth + 1) + 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}.${prop}: ${err.message}`) + errors.push(`${currentPath}[${i}]: ${err.message}`) } } } - } - } catch (err) { - if (err.message.includes('window') || err.message.includes('document')) { - errors.push(`${currentPath}: ${err.message}`) + } else { + // Test object properties recursively + await testExports(accessed, currentPath, depth + 1) } } - } 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') || + } 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}`) + 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...') @@ -191,43 +194,46 @@ if (!wdk) { } 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}`) + 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}`) + }) + } + } 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) { + // 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}`) } @@ -244,37 +250,37 @@ if (!wdk) { } 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}`) + 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}`) } @@ -290,7 +296,7 @@ if (errors.length === 0) { 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}`)) + warnings.slice(0, 5).forEach((warn) => console.log(` - ${warn}`)) if (warnings.length > 5) { console.log(` ... and ${warnings.length - 5} more`) } @@ -298,11 +304,11 @@ if (errors.length === 0) { process.exit(0) } else { console.log('\n❌ ERRORS FOUND:') - errors.forEach(err => console.log(` - ${err}`)) + 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}`)) + warnings.slice(0, 5).forEach((warn) => console.log(` - ${warn}`)) } process.exit(1) } diff --git a/packages/wallet/wdk/test/transactions.test.ts b/packages/wallet/wdk/test/transactions.test.ts index 910511e7a9..cf31c973c4 100644 --- a/packages/wallet/wdk/test/transactions.test.ts +++ b/packages/wallet/wdk/test/transactions.test.ts @@ -1,4 +1,4 @@ -import { afterEach, describe, expect, it, vi } from 'vitest' +import { afterEach, describe, expect, it } from 'vitest' import { Manager, SignerActionable, @@ -522,12 +522,12 @@ describe('Transactions', () => { }) let transactionsList: Transaction[] = [] - let updateCount = 0 + let _updateCount = 0 // Use onTransactionsUpdate to verify list functionality const unsubscribe = manager.transactions.onTransactionsUpdate((txs) => { transactionsList = txs - updateCount++ + _updateCount++ }) // Initially should be empty diff --git a/packages/wallet/wdk/test/wallets.test.ts b/packages/wallet/wdk/test/wallets.test.ts index 99e71d73d6..a5b26843c0 100644 --- a/packages/wallet/wdk/test/wallets.test.ts +++ b/packages/wallet/wdk/test/wallets.test.ts @@ -73,9 +73,9 @@ describe('Wallets', () => { it('Should register and unregister wallet selector', async () => { manager = newManager() - let selectorCalls = 0 + let _selectorCalls = 0 const mockSelector = async () => { - selectorCalls++ + _selectorCalls++ return 'create-new' as const } @@ -160,7 +160,7 @@ describe('Wallets', () => { const mnemonic = Mnemonic.random(Mnemonic.english) // Create initial wallet - const firstWallet = await manager!.wallets.signUp({ + const _firstWallet = await manager!.wallets.signUp({ mnemonic, kind: 'mnemonic', noGuard: true, @@ -705,8 +705,8 @@ describe('Wallets', () => { it('Should trigger an update when a wallet is logged in', async () => { const manager = newManager() - - let wallet: any | undefined + // eslint-disable-next-line + let wallet: Address.Address | undefined let callbackCalls = 0 let unregisterCallback: (() => void) | undefined diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index fdbb822b82..f3a0e98430 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -13,22 +13,22 @@ importers: devDependencies: '@changesets/cli': specifier: ^2.29.8 - version: 2.29.8(@types/node@25.0.2) + version: 2.29.8(@types/node@25.3.0) lefthook: - specifier: ^2.0.12 - version: 2.0.12 + specifier: ^2.1.1 + version: 2.1.1 prettier: - specifier: ^3.7.4 - version: 3.7.4 + specifier: ^3.8.1 + version: 3.8.1 rimraf: - specifier: ^6.1.2 - version: 6.1.2 + specifier: ^6.1.3 + version: 6.1.3 syncpack: - specifier: ^13.0.4 - version: 13.0.4(typescript@5.9.3) + specifier: ^14.0.0 + version: 14.0.0 turbo: - specifier: ^2.6.3 - version: 2.6.3 + specifier: ^2.8.10 + version: 2.8.10 typescript: specifier: ^5.9.3 version: 5.9.3 @@ -39,8 +39,8 @@ importers: specifier: workspace:^ version: link:../../repo/ui next: - specifier: ^15.5.9 - version: 15.5.9(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + specifier: ^15.5.10 + version: 15.5.10(react-dom@19.2.3(react@19.2.3))(react@19.2.3) react: specifier: ^19.2.3 version: 19.2.3 @@ -55,8 +55,8 @@ importers: specifier: workspace:^ version: link:../../repo/typescript-config '@types/node': - specifier: ^25.0.2 - version: 25.0.2 + specifier: ^25.3.0 + version: 25.3.0 '@types/react': specifier: ^19.2.7 version: 19.2.7 @@ -76,8 +76,8 @@ importers: specifier: workspace:^ version: link:../../repo/ui next: - specifier: ^15.5.9 - version: 15.5.9(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + specifier: ^15.5.10 + version: 15.5.10(react-dom@19.2.3(react@19.2.3))(react@19.2.3) react: specifier: ^19.2.3 version: 19.2.3 @@ -92,8 +92,8 @@ importers: specifier: workspace:^ version: link:../../repo/typescript-config '@types/node': - specifier: ^25.0.2 - version: 25.0.2 + specifier: ^25.3.0 + version: 25.3.0 '@types/react': specifier: ^19.2.7 version: 19.2.7 @@ -109,24 +109,30 @@ importers: packages/services/api: devDependencies: + '@repo/eslint-config': + specifier: workspace:^ + version: link:../../../repo/eslint-config '@repo/typescript-config': specifier: workspace:^ version: link:../../../repo/typescript-config '@types/node': - specifier: ^25.0.2 - version: 25.0.2 + specifier: ^25.3.0 + version: 25.3.0 typescript: specifier: ^5.9.3 version: 5.9.3 packages/services/builder: devDependencies: + '@repo/eslint-config': + specifier: workspace:^ + version: link:../../../repo/eslint-config '@repo/typescript-config': specifier: workspace:^ version: link:../../../repo/typescript-config '@types/node': - specifier: ^25.0.2 - version: 25.0.2 + specifier: ^25.3.0 + version: 25.3.0 typescript: specifier: ^5.9.3 version: 5.9.3 @@ -137,18 +143,21 @@ importers: specifier: ^0.9.17 version: 0.9.17(typescript@5.9.3)(zod@4.2.0) devDependencies: + '@repo/eslint-config': + specifier: workspace:^ + version: link:../../../repo/eslint-config '@repo/typescript-config': specifier: workspace:^ version: link:../../../repo/typescript-config '@types/node': - specifier: ^25.0.2 - version: 25.0.2 + specifier: ^25.3.0 + version: 25.3.0 typescript: specifier: ^5.9.3 version: 5.9.3 vitest: - specifier: ^4.0.15 - version: 4.0.15(@types/node@25.0.2)(happy-dom@20.0.11) + specifier: ^4.0.18 + version: 4.0.18(@types/node@25.3.0)(happy-dom@20.7.0) packages/services/identity-instrument: dependencies: @@ -162,51 +171,63 @@ importers: specifier: ^0.9.17 version: 0.9.17(typescript@5.9.3)(zod@4.2.0) devDependencies: + '@repo/eslint-config': + specifier: workspace:^ + version: link:../../../repo/eslint-config '@repo/typescript-config': specifier: workspace:^ version: link:../../../repo/typescript-config '@types/node': - specifier: ^25.0.2 - version: 25.0.2 + specifier: ^25.3.0 + version: 25.3.0 typescript: specifier: ^5.9.3 version: 5.9.3 vitest: - specifier: ^4.0.15 - version: 4.0.15(@types/node@25.0.2)(happy-dom@20.0.11) + specifier: ^4.0.18 + version: 4.0.18(@types/node@25.3.0)(happy-dom@20.7.0) packages/services/indexer: devDependencies: + '@repo/eslint-config': + specifier: workspace:^ + version: link:../../../repo/eslint-config '@repo/typescript-config': specifier: workspace:^ version: link:../../../repo/typescript-config '@types/node': - specifier: ^25.0.2 - version: 25.0.2 + specifier: ^25.3.0 + version: 25.3.0 typescript: specifier: ^5.9.3 version: 5.9.3 packages/services/marketplace: devDependencies: + '@repo/eslint-config': + specifier: workspace:^ + version: link:../../../repo/eslint-config '@repo/typescript-config': specifier: workspace:^ version: link:../../../repo/typescript-config '@types/node': - specifier: ^25.0.2 - version: 25.0.2 + specifier: ^25.3.0 + version: 25.3.0 typescript: specifier: ^5.9.3 version: 5.9.3 packages/services/metadata: devDependencies: + '@repo/eslint-config': + specifier: workspace:^ + version: link:../../../repo/eslint-config '@repo/typescript-config': specifier: workspace:^ version: link:../../../repo/typescript-config '@types/node': - specifier: ^25.0.2 - version: 25.0.2 + specifier: ^25.3.0 + version: 25.3.0 typescript: specifier: ^5.9.3 version: 5.9.3 @@ -226,39 +247,48 @@ importers: specifier: ^2.40.3 version: 2.42.1(typescript@5.9.3)(zod@4.2.0) devDependencies: + '@repo/eslint-config': + specifier: workspace:^ + version: link:../../../repo/eslint-config '@repo/typescript-config': specifier: workspace:^ version: link:../../../repo/typescript-config '@types/node': - specifier: ^25.0.2 - version: 25.0.2 + specifier: ^25.3.0 + version: 25.3.0 typescript: specifier: ^5.9.3 version: 5.9.3 vitest: - specifier: ^4.0.15 - version: 4.0.15(@types/node@25.0.2)(happy-dom@20.0.11) + specifier: ^4.0.18 + version: 4.0.18(@types/node@25.3.0)(happy-dom@20.7.0) packages/services/userdata: devDependencies: + '@repo/eslint-config': + specifier: workspace:^ + version: link:../../../repo/eslint-config '@repo/typescript-config': specifier: workspace:^ version: link:../../../repo/typescript-config '@types/node': - specifier: ^25.0.2 - version: 25.0.2 + specifier: ^25.3.0 + version: 25.3.0 typescript: specifier: ^5.9.3 version: 5.9.3 packages/utils/abi: devDependencies: + '@repo/eslint-config': + specifier: workspace:^ + version: link:../../../repo/eslint-config '@repo/typescript-config': specifier: workspace:^ version: link:../../../repo/typescript-config '@types/node': - specifier: ^25.0.2 - version: 25.0.2 + specifier: ^25.3.0 + version: 25.3.0 typescript: specifier: ^5.9.3 version: 5.9.3 @@ -284,18 +314,21 @@ importers: specifier: ^2.40.3 version: 2.42.1(typescript@5.9.3)(zod@4.2.0) devDependencies: + '@repo/eslint-config': + specifier: workspace:^ + version: link:../../../repo/eslint-config '@repo/typescript-config': specifier: workspace:^ version: link:../../../repo/typescript-config '@types/node': - specifier: ^25.0.2 - version: 25.0.2 + specifier: ^25.3.0 + version: 25.3.0 '@vitest/coverage-v8': - specifier: ^4.0.15 - version: 4.0.15(vitest@4.0.15(@types/node@25.0.2)(happy-dom@20.0.11)) + specifier: ^4.0.18 + version: 4.0.18(vitest@4.0.18(@types/node@25.3.0)(happy-dom@20.7.0)) dotenv: - specifier: ^17.2.3 - version: 17.2.3 + specifier: ^17.3.1 + version: 17.3.1 fake-indexeddb: specifier: ^6.2.5 version: 6.2.5 @@ -303,8 +336,8 @@ importers: specifier: ^5.9.3 version: 5.9.3 vitest: - specifier: ^4.0.15 - version: 4.0.15(@types/node@25.0.2)(happy-dom@20.0.11) + specifier: ^4.0.18 + version: 4.0.18(@types/node@25.3.0)(happy-dom@20.7.0) packages/wallet/dapp-client: dependencies: @@ -324,30 +357,33 @@ importers: specifier: ^0.9.17 version: 0.9.17(typescript@5.9.3)(zod@4.2.0) devDependencies: + '@repo/eslint-config': + specifier: workspace:^ + version: link:../../../repo/eslint-config '@repo/typescript-config': specifier: workspace:^ version: link:../../../repo/typescript-config '@types/node': - specifier: ^25.0.2 - version: 25.0.2 + specifier: ^25.3.0 + version: 25.3.0 '@vitest/coverage-v8': - specifier: ^4.0.15 - version: 4.0.15(vitest@4.0.15(@types/node@25.0.2)(happy-dom@20.0.11)) + specifier: ^4.0.18 + version: 4.0.18(vitest@4.0.18(@types/node@25.3.0)(happy-dom@20.7.0)) dotenv: - specifier: ^17.2.3 - version: 17.2.3 + specifier: ^17.3.1 + version: 17.3.1 fake-indexeddb: specifier: ^6.2.5 version: 6.2.5 happy-dom: - specifier: ^20.0.11 - version: 20.0.11 + specifier: ^20.7.0 + version: 20.7.0 typescript: specifier: ^5.9.3 version: 5.9.3 vitest: - specifier: ^4.0.15 - version: 4.0.15(@types/node@25.0.2)(happy-dom@20.0.11) + specifier: ^4.0.18 + version: 4.0.18(@types/node@25.3.0)(happy-dom@20.7.0) packages/wallet/primitives: dependencies: @@ -355,18 +391,21 @@ importers: specifier: ^0.9.17 version: 0.9.17(typescript@5.9.3)(zod@4.2.0) devDependencies: + '@repo/eslint-config': + specifier: workspace:^ + version: link:../../../repo/eslint-config '@repo/typescript-config': specifier: workspace:^ version: link:../../../repo/typescript-config '@vitest/coverage-v8': - specifier: ^4.0.15 - version: 4.0.15(vitest@4.0.15(@types/node@25.0.2)(happy-dom@20.0.11)) + specifier: ^4.0.18 + version: 4.0.18(vitest@4.0.18(@types/node@25.3.0)(happy-dom@20.7.0)) typescript: specifier: ^5.9.3 version: 5.9.3 vitest: - specifier: ^4.0.15 - version: 4.0.15(@types/node@25.0.2)(happy-dom@20.0.11) + specifier: ^4.0.18 + version: 4.0.18(@types/node@25.3.0)(happy-dom@20.7.0) packages/wallet/primitives-cli: dependencies: @@ -387,8 +426,8 @@ importers: specifier: workspace:^ version: link:../../../repo/typescript-config '@types/node': - specifier: ^25.0.2 - version: 25.0.2 + specifier: ^25.3.0 + version: 25.3.0 '@types/yargs': specifier: ^17.0.35 version: 17.0.35 @@ -396,11 +435,11 @@ importers: specifier: ^9.2.1 version: 9.2.1 esbuild: - specifier: ^0.27.1 - version: 0.27.1 + specifier: ^0.27.3 + version: 0.27.3 nodemon: - specifier: ^3.1.11 - version: 3.1.11 + specifier: ^3.1.14 + version: 3.1.14 typescript: specifier: ^5.9.3 version: 5.9.3 @@ -438,30 +477,33 @@ importers: specifier: ^13.0.0 version: 13.0.0 devDependencies: + '@repo/eslint-config': + specifier: workspace:^ + version: link:../../../repo/eslint-config '@repo/typescript-config': specifier: workspace:^ version: link:../../../repo/typescript-config '@types/node': - specifier: ^25.0.2 - version: 25.0.2 + specifier: ^25.3.0 + version: 25.3.0 '@vitest/coverage-v8': - specifier: ^4.0.15 - version: 4.0.15(vitest@4.0.15(@types/node@25.0.2)(happy-dom@20.0.11)) + specifier: ^4.0.18 + version: 4.0.18(vitest@4.0.18(@types/node@25.3.0)(happy-dom@20.7.0)) dotenv: - specifier: ^17.2.3 - version: 17.2.3 + specifier: ^17.3.1 + version: 17.3.1 fake-indexeddb: specifier: ^6.2.5 version: 6.2.5 happy-dom: - specifier: ^20.0.11 - version: 20.0.11 + specifier: ^20.7.0 + version: 20.7.0 typescript: specifier: ^5.9.3 version: 5.9.3 vitest: - specifier: ^4.0.15 - version: 4.0.15(@types/node@25.0.2)(happy-dom@20.0.11) + specifier: ^4.0.18 + version: 4.0.18(@types/node@25.3.0)(happy-dom@20.7.0) repo/eslint-config: devDependencies: @@ -488,7 +530,7 @@ importers: version: 7.0.1(eslint@9.39.2) eslint-plugin-turbo: specifier: ^2.6.3 - version: 2.6.3(eslint@9.39.2)(turbo@2.6.3) + version: 2.6.3(eslint@9.39.2)(turbo@2.8.10) globals: specifier: ^16.5.0 version: 16.5.0 @@ -518,10 +560,10 @@ importers: version: link:../typescript-config '@turbo/gen': specifier: ^1.13.4 - version: 1.13.4(@types/node@25.0.2)(typescript@5.9.3) + version: 1.13.4(@types/node@25.3.0)(typescript@5.9.3) '@types/node': - specifier: ^25.0.2 - version: 25.0.2 + specifier: ^25.3.0 + version: 25.3.0 '@types/react': specifier: ^19.2.7 version: 19.2.7 @@ -678,161 +720,161 @@ packages: resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} engines: {node: '>=12'} - '@emnapi/runtime@1.7.1': - resolution: {integrity: sha512-PVtJr5CmLwYAU9PZDMITZoR5iAOShYREoR45EyyLrbntV50mdePTgUn4AmOw90Ifcj+x2kRjdzr1HP3RrNiHGA==} + '@emnapi/runtime@1.8.1': + resolution: {integrity: sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg==} - '@esbuild/aix-ppc64@0.27.1': - resolution: {integrity: sha512-HHB50pdsBX6k47S4u5g/CaLjqS3qwaOVE5ILsq64jyzgMhLuCuZ8rGzM9yhsAjfjkbgUPMzZEPa7DAp7yz6vuA==} + '@esbuild/aix-ppc64@0.27.3': + resolution: {integrity: sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg==} engines: {node: '>=18'} cpu: [ppc64] os: [aix] - '@esbuild/android-arm64@0.27.1': - resolution: {integrity: sha512-45fuKmAJpxnQWixOGCrS+ro4Uvb4Re9+UTieUY2f8AEc+t7d4AaZ6eUJ3Hva7dtrxAAWHtlEFsXFMAgNnGU9uQ==} + '@esbuild/android-arm64@0.27.3': + resolution: {integrity: sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg==} engines: {node: '>=18'} cpu: [arm64] os: [android] - '@esbuild/android-arm@0.27.1': - resolution: {integrity: sha512-kFqa6/UcaTbGm/NncN9kzVOODjhZW8e+FRdSeypWe6j33gzclHtwlANs26JrupOntlcWmB0u8+8HZo8s7thHvg==} + '@esbuild/android-arm@0.27.3': + resolution: {integrity: sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA==} engines: {node: '>=18'} cpu: [arm] os: [android] - '@esbuild/android-x64@0.27.1': - resolution: {integrity: sha512-LBEpOz0BsgMEeHgenf5aqmn/lLNTFXVfoWMUox8CtWWYK9X4jmQzWjoGoNb8lmAYml/tQ/Ysvm8q7szu7BoxRQ==} + '@esbuild/android-x64@0.27.3': + resolution: {integrity: sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ==} engines: {node: '>=18'} cpu: [x64] os: [android] - '@esbuild/darwin-arm64@0.27.1': - resolution: {integrity: sha512-veg7fL8eMSCVKL7IW4pxb54QERtedFDfY/ASrumK/SbFsXnRazxY4YykN/THYqFnFwJ0aVjiUrVG2PwcdAEqQQ==} + '@esbuild/darwin-arm64@0.27.3': + resolution: {integrity: sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg==} engines: {node: '>=18'} cpu: [arm64] os: [darwin] - '@esbuild/darwin-x64@0.27.1': - resolution: {integrity: sha512-+3ELd+nTzhfWb07Vol7EZ+5PTbJ/u74nC6iv4/lwIU99Ip5uuY6QoIf0Hn4m2HoV0qcnRivN3KSqc+FyCHjoVQ==} + '@esbuild/darwin-x64@0.27.3': + resolution: {integrity: sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg==} engines: {node: '>=18'} cpu: [x64] os: [darwin] - '@esbuild/freebsd-arm64@0.27.1': - resolution: {integrity: sha512-/8Rfgns4XD9XOSXlzUDepG8PX+AVWHliYlUkFI3K3GB6tqbdjYqdhcb4BKRd7C0BhZSoaCxhv8kTcBrcZWP+xg==} + '@esbuild/freebsd-arm64@0.27.3': + resolution: {integrity: sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w==} engines: {node: '>=18'} cpu: [arm64] os: [freebsd] - '@esbuild/freebsd-x64@0.27.1': - resolution: {integrity: sha512-GITpD8dK9C+r+5yRT/UKVT36h/DQLOHdwGVwwoHidlnA168oD3uxA878XloXebK4Ul3gDBBIvEdL7go9gCUFzQ==} + '@esbuild/freebsd-x64@0.27.3': + resolution: {integrity: sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA==} engines: {node: '>=18'} cpu: [x64] os: [freebsd] - '@esbuild/linux-arm64@0.27.1': - resolution: {integrity: sha512-W9//kCrh/6in9rWIBdKaMtuTTzNj6jSeG/haWBADqLLa9P8O5YSRDzgD5y9QBok4AYlzS6ARHifAb75V6G670Q==} + '@esbuild/linux-arm64@0.27.3': + resolution: {integrity: sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg==} engines: {node: '>=18'} cpu: [arm64] os: [linux] - '@esbuild/linux-arm@0.27.1': - resolution: {integrity: sha512-ieMID0JRZY/ZeCrsFQ3Y3NlHNCqIhTprJfDgSB3/lv5jJZ8FX3hqPyXWhe+gvS5ARMBJ242PM+VNz/ctNj//eA==} + '@esbuild/linux-arm@0.27.3': + resolution: {integrity: sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw==} engines: {node: '>=18'} cpu: [arm] os: [linux] - '@esbuild/linux-ia32@0.27.1': - resolution: {integrity: sha512-VIUV4z8GD8rtSVMfAj1aXFahsi/+tcoXXNYmXgzISL+KB381vbSTNdeZHHHIYqFyXcoEhu9n5cT+05tRv13rlw==} + '@esbuild/linux-ia32@0.27.3': + resolution: {integrity: sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg==} engines: {node: '>=18'} cpu: [ia32] os: [linux] - '@esbuild/linux-loong64@0.27.1': - resolution: {integrity: sha512-l4rfiiJRN7sTNI//ff65zJ9z8U+k6zcCg0LALU5iEWzY+a1mVZ8iWC1k5EsNKThZ7XCQ6YWtsZ8EWYm7r1UEsg==} + '@esbuild/linux-loong64@0.27.3': + resolution: {integrity: sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA==} engines: {node: '>=18'} cpu: [loong64] os: [linux] - '@esbuild/linux-mips64el@0.27.1': - resolution: {integrity: sha512-U0bEuAOLvO/DWFdygTHWY8C067FXz+UbzKgxYhXC0fDieFa0kDIra1FAhsAARRJbvEyso8aAqvPdNxzWuStBnA==} + '@esbuild/linux-mips64el@0.27.3': + resolution: {integrity: sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw==} engines: {node: '>=18'} cpu: [mips64el] os: [linux] - '@esbuild/linux-ppc64@0.27.1': - resolution: {integrity: sha512-NzdQ/Xwu6vPSf/GkdmRNsOfIeSGnh7muundsWItmBsVpMoNPVpM61qNzAVY3pZ1glzzAxLR40UyYM23eaDDbYQ==} + '@esbuild/linux-ppc64@0.27.3': + resolution: {integrity: sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA==} engines: {node: '>=18'} cpu: [ppc64] os: [linux] - '@esbuild/linux-riscv64@0.27.1': - resolution: {integrity: sha512-7zlw8p3IApcsN7mFw0O1Z1PyEk6PlKMu18roImfl3iQHTnr/yAfYv6s4hXPidbDoI2Q0pW+5xeoM4eTCC0UdrQ==} + '@esbuild/linux-riscv64@0.27.3': + resolution: {integrity: sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ==} engines: {node: '>=18'} cpu: [riscv64] os: [linux] - '@esbuild/linux-s390x@0.27.1': - resolution: {integrity: sha512-cGj5wli+G+nkVQdZo3+7FDKC25Uh4ZVwOAK6A06Hsvgr8WqBBuOy/1s+PUEd/6Je+vjfm6stX0kmib5b/O2Ykw==} + '@esbuild/linux-s390x@0.27.3': + resolution: {integrity: sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw==} engines: {node: '>=18'} cpu: [s390x] os: [linux] - '@esbuild/linux-x64@0.27.1': - resolution: {integrity: sha512-z3H/HYI9MM0HTv3hQZ81f+AKb+yEoCRlUby1F80vbQ5XdzEMyY/9iNlAmhqiBKw4MJXwfgsh7ERGEOhrM1niMA==} + '@esbuild/linux-x64@0.27.3': + resolution: {integrity: sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA==} engines: {node: '>=18'} cpu: [x64] os: [linux] - '@esbuild/netbsd-arm64@0.27.1': - resolution: {integrity: sha512-wzC24DxAvk8Em01YmVXyjl96Mr+ecTPyOuADAvjGg+fyBpGmxmcr2E5ttf7Im8D0sXZihpxzO1isus8MdjMCXQ==} + '@esbuild/netbsd-arm64@0.27.3': + resolution: {integrity: sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA==} engines: {node: '>=18'} cpu: [arm64] os: [netbsd] - '@esbuild/netbsd-x64@0.27.1': - resolution: {integrity: sha512-1YQ8ybGi2yIXswu6eNzJsrYIGFpnlzEWRl6iR5gMgmsrR0FcNoV1m9k9sc3PuP5rUBLshOZylc9nqSgymI+TYg==} + '@esbuild/netbsd-x64@0.27.3': + resolution: {integrity: sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA==} engines: {node: '>=18'} cpu: [x64] os: [netbsd] - '@esbuild/openbsd-arm64@0.27.1': - resolution: {integrity: sha512-5Z+DzLCrq5wmU7RDaMDe2DVXMRm2tTDvX2KU14JJVBN2CT/qov7XVix85QoJqHltpvAOZUAc3ndU56HSMWrv8g==} + '@esbuild/openbsd-arm64@0.27.3': + resolution: {integrity: sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw==} engines: {node: '>=18'} cpu: [arm64] os: [openbsd] - '@esbuild/openbsd-x64@0.27.1': - resolution: {integrity: sha512-Q73ENzIdPF5jap4wqLtsfh8YbYSZ8Q0wnxplOlZUOyZy7B4ZKW8DXGWgTCZmF8VWD7Tciwv5F4NsRf6vYlZtqg==} + '@esbuild/openbsd-x64@0.27.3': + resolution: {integrity: sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ==} engines: {node: '>=18'} cpu: [x64] os: [openbsd] - '@esbuild/openharmony-arm64@0.27.1': - resolution: {integrity: sha512-ajbHrGM/XiK+sXM0JzEbJAen+0E+JMQZ2l4RR4VFwvV9JEERx+oxtgkpoKv1SevhjavK2z2ReHk32pjzktWbGg==} + '@esbuild/openharmony-arm64@0.27.3': + resolution: {integrity: sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g==} engines: {node: '>=18'} cpu: [arm64] os: [openharmony] - '@esbuild/sunos-x64@0.27.1': - resolution: {integrity: sha512-IPUW+y4VIjuDVn+OMzHc5FV4GubIwPnsz6ubkvN8cuhEqH81NovB53IUlrlBkPMEPxvNnf79MGBoz8rZ2iW8HA==} + '@esbuild/sunos-x64@0.27.3': + resolution: {integrity: sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA==} engines: {node: '>=18'} cpu: [x64] os: [sunos] - '@esbuild/win32-arm64@0.27.1': - resolution: {integrity: sha512-RIVRWiljWA6CdVu8zkWcRmGP7iRRIIwvhDKem8UMBjPql2TXM5PkDVvvrzMtj1V+WFPB4K7zkIGM7VzRtFkjdg==} + '@esbuild/win32-arm64@0.27.3': + resolution: {integrity: sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA==} engines: {node: '>=18'} cpu: [arm64] os: [win32] - '@esbuild/win32-ia32@0.27.1': - resolution: {integrity: sha512-2BR5M8CPbptC1AK5JbJT1fWrHLvejwZidKx3UMSF0ecHMa+smhi16drIrCEggkgviBwLYd5nwrFLSl5Kho96RQ==} + '@esbuild/win32-ia32@0.27.3': + resolution: {integrity: sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q==} engines: {node: '>=18'} cpu: [ia32] os: [win32] - '@esbuild/win32-x64@0.27.1': - resolution: {integrity: sha512-d5X6RMYv6taIymSk8JBP+nxv8DQAMY6A51GPgusqLdK9wBz5wWIXy1KjTck6HnjE9hqJzJRdk+1p/t5soSbCtw==} + '@esbuild/win32-x64@0.27.3': + resolution: {integrity: sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA==} engines: {node: '>=18'} cpu: [x64] os: [win32] @@ -1037,14 +1079,6 @@ packages: '@types/node': optional: true - '@isaacs/balanced-match@4.0.1': - resolution: {integrity: sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==} - engines: {node: 20 || >=22} - - '@isaacs/brace-expansion@5.0.0': - resolution: {integrity: sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==} - engines: {node: 20 || >=22} - '@jridgewell/gen-mapping@0.3.13': resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} @@ -1070,8 +1104,8 @@ packages: '@manypkg/get-packages@1.1.3': resolution: {integrity: sha512-fo+QhuU3qE/2TQMQmbVMqaQ6EWbMhi4ABWP+O4AM1NqPBuy0OrApV5LO6BrrgnhtAHS2NH6RrVk9OL181tTi8A==} - '@next/env@15.5.9': - resolution: {integrity: sha512-4GlTZ+EJM7WaW2HEZcyU317tIQDjkQIyENDLxYJfSWlfqguN+dHkZgyQTV/7ykvobU7yEH5gKvreNrH4B6QgIg==} + '@next/env@15.5.10': + resolution: {integrity: sha512-plg+9A/KoZcTS26fe15LHg+QxReTazrIOoKKUC3Uz4leGGeNPgLHdevVraAAOX0snnUs3WkRx3eUQpj9mreG6A==} '@next/eslint-plugin-next@15.5.9': resolution: {integrity: sha512-kUzXx0iFiXw27cQAViE1yKWnz/nF8JzRmwgMRTMh8qMY90crNsdXJRh2e+R0vBpFR3kk1yvAR7wev7+fCCb79Q==} @@ -1271,10 +1305,6 @@ packages: '@scure/bip39@1.6.0': resolution: {integrity: sha512-+lF0BbLiJNwVlev4eKelw1WWLaiKXw7sSl8T6FvBlWkdX+94aGJ4o8XjUdlyhTCjd8c+B3KT3JfS8P0bLRNU6A==} - '@sindresorhus/merge-streams@2.3.0': - resolution: {integrity: sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==} - engines: {node: '>=18'} - '@standard-schema/spec@1.0.0': resolution: {integrity: sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==} @@ -1329,11 +1359,8 @@ packages: '@types/node@12.20.55': resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} - '@types/node@20.19.27': - resolution: {integrity: sha512-N2clP5pJhB2YnZJ3PIHFk5RkygRX5WO/5f0WC08tp0wd+sv0rsJk3MqWn3CbNmT2J505a5336jaQj4ph1AdMug==} - - '@types/node@25.0.2': - resolution: {integrity: sha512-gWEkeiyYE4vqjON/+Obqcoeffmk0NF15WSBwSs7zwVA2bAbTaE0SJ7P0WNGoJn8uE7fiaV5a7dKYIJriEqOrmA==} + '@types/node@25.3.0': + resolution: {integrity: sha512-4K3bqJpXpqfg2XKGK9bpDTc6xO/xoUP/RBWS7AtRMug6zZFaRekiLzjVtAoZMquxoAbzBvy5nxQ7veS5eYzf8A==} '@types/react-dom@19.2.3': resolution: {integrity: sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==} @@ -1352,6 +1379,9 @@ packages: '@types/whatwg-mimetype@3.0.2': resolution: {integrity: sha512-c2AKvDT8ToxLIOUlN51gTiHXflsfIFisS4pO7pDPoKouJCESkhZnEy623gwP9laCy5lnLDAw1vAzu2vM2YLOrA==} + '@types/ws@8.18.1': + resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==} + '@types/yargs-parser@21.0.3': resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==} @@ -1417,20 +1447,20 @@ packages: resolution: {integrity: sha512-Xzmnb58+Db78gT/CCj/PVCvK+zxbnsw6F+O1oheYszJbBSdEjVhQi3C/Xttzxgi/GLmpvOggRs1RFpiJ8+c34Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@vitest/coverage-v8@4.0.15': - resolution: {integrity: sha512-FUJ+1RkpTFW7rQITdgTi93qOCWJobWhBirEPCeXh2SW2wsTlFxy51apDz5gzG+ZEYt/THvWeNmhdAoS9DTwpCw==} + '@vitest/coverage-v8@4.0.18': + resolution: {integrity: sha512-7i+N2i0+ME+2JFZhfuz7Tg/FqKtilHjGyGvoHYQ6iLV0zahbsJ9sljC9OcFcPDbhYKCet+sG8SsVqlyGvPflZg==} peerDependencies: - '@vitest/browser': 4.0.15 - vitest: 4.0.15 + '@vitest/browser': 4.0.18 + vitest: 4.0.18 peerDependenciesMeta: '@vitest/browser': optional: true - '@vitest/expect@4.0.15': - resolution: {integrity: sha512-Gfyva9/GxPAWXIWjyGDli9O+waHDC0Q0jaLdFP1qPAUUfo1FEXPXUfUkp3eZA0sSq340vPycSyOlYUeM15Ft1w==} + '@vitest/expect@4.0.18': + resolution: {integrity: sha512-8sCWUyckXXYvx4opfzVY03EOiYVxyNrHS5QxX3DAIi5dpJAAkyJezHCP77VMX4HKA2LDT/Jpfo8i2r5BE3GnQQ==} - '@vitest/mocker@4.0.15': - resolution: {integrity: sha512-CZ28GLfOEIFkvCFngN8Sfx5h+Se0zN+h4B7yOsPVCcgtiO7t5jt9xQh2E1UkFep+eb9fjyMfuC5gBypwb07fvQ==} + '@vitest/mocker@4.0.18': + resolution: {integrity: sha512-HhVd0MDnzzsgevnOWCBj5Otnzobjy5wLBe4EdeeFGv8luMsGcYqDuFRMcttKWZA5vVO8RFjexVovXvAM4JoJDQ==} peerDependencies: msw: ^2.4.9 vite: ^6.0.0 || ^7.0.0-0 @@ -1440,20 +1470,20 @@ packages: vite: optional: true - '@vitest/pretty-format@4.0.15': - resolution: {integrity: sha512-SWdqR8vEv83WtZcrfLNqlqeQXlQLh2iilO1Wk1gv4eiHKjEzvgHb2OVc3mIPyhZE6F+CtfYjNlDJwP5MN6Km7A==} + '@vitest/pretty-format@4.0.18': + resolution: {integrity: sha512-P24GK3GulZWC5tz87ux0m8OADrQIUVDPIjjj65vBXYG17ZeU3qD7r+MNZ1RNv4l8CGU2vtTRqixrOi9fYk/yKw==} - '@vitest/runner@4.0.15': - resolution: {integrity: sha512-+A+yMY8dGixUhHmNdPUxOh0la6uVzun86vAbuMT3hIDxMrAOmn5ILBHm8ajrqHE0t8R9T1dGnde1A5DTnmi3qw==} + '@vitest/runner@4.0.18': + resolution: {integrity: sha512-rpk9y12PGa22Jg6g5M3UVVnTS7+zycIGk9ZNGN+m6tZHKQb7jrP7/77WfZy13Y/EUDd52NDsLRQhYKtv7XfPQw==} - '@vitest/snapshot@4.0.15': - resolution: {integrity: sha512-A7Ob8EdFZJIBjLjeO0DZF4lqR6U7Ydi5/5LIZ0xcI+23lYlsYJAfGn8PrIWTYdZQRNnSRlzhg0zyGu37mVdy5g==} + '@vitest/snapshot@4.0.18': + resolution: {integrity: sha512-PCiV0rcl7jKQjbgYqjtakly6T1uwv/5BQ9SwBLekVg/EaYeQFPiXcgrC2Y7vDMA8dM1SUEAEV82kgSQIlXNMvA==} - '@vitest/spy@4.0.15': - resolution: {integrity: sha512-+EIjOJmnY6mIfdXtE/bnozKEvTC4Uczg19yeZ2vtCz5Yyb0QQ31QWVQ8hswJ3Ysx/K2EqaNsVanjr//2+P3FHw==} + '@vitest/spy@4.0.18': + resolution: {integrity: sha512-cbQt3PTSD7P2OARdVW3qWER5EGq7PHlvE+QfzSC0lbwO+xnt7+XH06ZzFjFRgzUX//JmpxrCu92VdwvEPlWSNw==} - '@vitest/utils@4.0.15': - resolution: {integrity: sha512-HXjPW2w5dxhTD0dLwtYHDnelK3j8sR8cWIaLxr22evTyY6q8pRCjZSmhRWVjBaOVXChQd6AwMzi9pucorXCPZA==} + '@vitest/utils@4.0.18': + resolution: {integrity: sha512-msMRKLMVLWygpK3u2Hybgi4MNjcYJvwTb0Ru09+fOyCXIgT5raYP041DRRdiJiI3k/2U6SEbAETB3YtBrUkCFA==} abitype@1.1.0: resolution: {integrity: sha512-6Vh4HcRxNMLA0puzPjM5GBgT4aAcFGKZzSgAXvuZ27shJP6NEpielTuqbBmZILR5/xd0PizkBGy5hReKz9jl5A==} @@ -1587,8 +1617,8 @@ packages: resolution: {integrity: sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==} engines: {node: '>=4'} - ast-v8-to-istanbul@0.3.8: - resolution: {integrity: sha512-szgSZqUxI5T8mLKvS7WTjF9is+MVbOeLADU73IseOcrqhxr/VAvy6wfoVE39KnKzA7JRhjF5eUagNlHwvZPlKQ==} + ast-v8-to-istanbul@0.3.11: + resolution: {integrity: sha512-Qya9fkoofMjCBNVdWINMjB5KZvkYfaO9/anwkWnjxibpWUxo5iHl2sOdP7/uAqaRuUYuoo8rDwnbaaKVFxoUvw==} async-function@1.0.0: resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==} @@ -1601,6 +1631,10 @@ packages: balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + balanced-match@4.0.4: + resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} + engines: {node: 18 || 20 || >=22} + base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} @@ -1629,6 +1663,10 @@ packages: brace-expansion@2.0.2: resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==} + brace-expansion@5.0.3: + resolution: {integrity: sha512-fy6KJm2RawA5RcHkLa1z/ScpBeA762UF9KmZQxwIbDtRJrgLzM10depAiEQ+CXYcoiqW1/m96OAAoke2nE9EeA==} + engines: {node: 18 || 20 || >=22} + braces@3.0.3: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} @@ -1664,8 +1702,8 @@ packages: camel-case@3.0.0: resolution: {integrity: sha512-+MbKztAYHXPr1jNTSKQF52VpcFjwY5RkR7fxksV8Doo4KAYc5Fl4UJRgthBbTmEx8C54DqahhbLJkDwjI3PI/w==} - caniuse-lite@1.0.30001760: - resolution: {integrity: sha512-7AAMPcueWELt1p3mi13HR/LHH0TJLT11cnwDJEs3xA4+CK/PLKeO9Kl1oru24htkyUKtkGCvAx4ohB0Ttry8Dw==} + caniuse-lite@1.0.30001769: + resolution: {integrity: sha512-BCfFL1sHijQlBGWBMuJyhZUhzo7wer5sVj9hqekB/7xn0Ypy+pER/edCYQm4exbXj4WiySGp40P8UuTh6w1srg==} cbor2@1.12.0: resolution: {integrity: sha512-3Cco8XQhi27DogSp9Ri6LYNZLi/TBY/JVnDe+mj06NkBjW/ZYOtekaEU4wZ4xcRMNrFkDv8KNtOAqHyDfz3lYg==} @@ -1675,10 +1713,6 @@ packages: resolution: {integrity: sha512-p4Z49OGG5W/WBCPSS/dH3jQ73kD6tiMmUM+bckNK6Jr5JHMG3k9bg/BvKR8lKmtVBKmOiuVaV2ws8s9oSbwysg==} engines: {node: '>=18'} - chalk-template@1.1.2: - resolution: {integrity: sha512-2bxTP2yUH7AJj/VAXfcA+4IcWGdQ87HwBANLt5XxGTeomo8yG0y95N1um9i5StvhT/Bl0/2cARA5v1PpPXUxUA==} - engines: {node: '>=14.16'} - chalk@2.4.2: resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} engines: {node: '>=4'} @@ -1691,10 +1725,6 @@ packages: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} - chalk@5.6.2: - resolution: {integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==} - engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} - change-case@3.1.0: resolution: {integrity: sha512-2AZp7uJZbYEzRPsFoa+ijKdvp9zsrnnt6+yFokfwEpeJm0xuJDVoxiRCAaTzyJND8GJkofo2IcKWaUZ/OECVzw==} @@ -1720,10 +1750,6 @@ packages: resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} engines: {node: '>=8'} - cli-cursor@5.0.0: - resolution: {integrity: sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==} - engines: {node: '>=18'} - cli-spinners@2.9.2: resolution: {integrity: sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==} engines: {node: '>=6'} @@ -1764,10 +1790,6 @@ packages: resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==} engines: {node: '>=14'} - commander@13.1.0: - resolution: {integrity: sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==} - engines: {node: '>=18'} - concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} @@ -1785,15 +1807,6 @@ packages: core-js-pure@3.47.0: resolution: {integrity: sha512-BcxeDbzUrRnXGYIVAGFtcGQVNpFcUhVjr6W7F8XktvQW2iJP9e66GP6xdKotCRFlrxBvNIBrhwKteRXqMV86Nw==} - cosmiconfig@9.0.0: - resolution: {integrity: sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==} - engines: {node: '>=14'} - peerDependencies: - typescript: '>=4.9.5' - peerDependenciesMeta: - typescript: - optional: true - create-require@1.1.1: resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} @@ -1882,17 +1895,14 @@ packages: resolution: {integrity: sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==} engines: {node: '>=12'} - dotenv@17.2.3: - resolution: {integrity: sha512-JVUnt+DUIzu87TABbhPmNfVdBDt18BLOWjMUFJMSi/Qqg7NTYtabbvSNJGOJ7afbRuv9D/lngizHtP7QyLQ+9w==} + dotenv@17.3.1: + resolution: {integrity: sha512-IO8C/dzEb6O3F9/twg6ZLXz164a2fhTnEWb95H23Dm4OuN+92NmEAlTrupP9VW6Jm3sO26tQlqyvyi4CsnY9GA==} engines: {node: '>=12'} dunder-proto@1.0.1: resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} engines: {node: '>= 0.4'} - effect@3.19.12: - resolution: {integrity: sha512-7F9RGTrCTC3D7nh9Zw+3VlJWwZgo5k33KA+476BAaD0rKIXKZsY/jQ+ipyhR/Avo239Fi6GqAVFs1mqM1IJ7yg==} - electron-to-chromium@1.5.267: resolution: {integrity: sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==} @@ -1906,12 +1916,9 @@ packages: resolution: {integrity: sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==} engines: {node: '>=8.6'} - env-paths@2.2.1: - resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} - engines: {node: '>=6'} - - error-ex@1.3.4: - resolution: {integrity: sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==} + entities@7.0.1: + resolution: {integrity: sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==} + engines: {node: '>=0.12'} es-abstract@1.24.1: resolution: {integrity: sha512-zHXBLhP+QehSSbsS9Pt23Gg964240DPd6QCf8WpkqEXxQ7fhdZzYsocOr5u7apWonsS5EjZDmTF+/slGMyasvw==} @@ -1948,8 +1955,8 @@ packages: resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==} engines: {node: '>= 0.4'} - esbuild@0.27.1: - resolution: {integrity: sha512-yY35KZckJJuVVPXpvjgxiCuVEJT67F6zDeVTv4rizyPrfGBUpZQsvmxnN+C371c2esD/hNMjj4tpBhuueLN7aA==} + esbuild@0.27.3: + resolution: {integrity: sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg==} engines: {node: '>=18'} hasBin: true @@ -2070,10 +2077,6 @@ packages: resolution: {integrity: sha512-CGnyrvbhPlWYMngksqrSSUT1BAVP49dZocrHuK0SvtR0D5TMs5wP0o3j7jexDJW01KSadjBp1M/71o/KR3nD1w==} engines: {node: '>=18'} - fast-check@3.23.2: - resolution: {integrity: sha512-h5+1OzzfCC3Ef7VbtKdcv7zsstUQwUDlYpUTvjeUsJAssPgLn7QzbboPtL5ro04Mq0rPOsMzl7q5hIbRs2wD1A==} - engines: {node: '>=8.0.0'} - fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} @@ -2208,13 +2211,13 @@ packages: resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} engines: {node: '>=10.13.0'} - glob@13.0.0: - resolution: {integrity: sha512-tvZgpqk6fz4BaNZ66ZsRaZnbHvP/jG3uKJvAZOwEVUL4RTA5nJeeLYfyN9/VA8NX/V3IBG+hkeuGpKjvELkVhA==} - engines: {node: 20 || >=22} + glob@13.0.6: + resolution: {integrity: sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==} + engines: {node: 18 || 20 || >=22} glob@7.2.3: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} - deprecated: Glob versions prior to v9 are no longer supported + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me globals@14.0.0: resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} @@ -2236,10 +2239,6 @@ packages: resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} engines: {node: '>=10'} - globby@14.1.0: - resolution: {integrity: sha512-0Ia46fDOaT7k4og1PDW4YbodWWr3scS2vAr2lTbsplOt2WkKp0vQbkI9wKis/T5LV/dqPjO3bpS/z6GTJB82LA==} - engines: {node: '>=18'} - gopd@1.2.0: resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} engines: {node: '>= 0.4'} @@ -2256,8 +2255,8 @@ packages: engines: {node: '>=0.4.7'} hasBin: true - happy-dom@20.0.11: - resolution: {integrity: sha512-QsCdAUHAmiDeKeaNojb1OHOPF7NjcWPBR7obdu3NwH2a/oyQaLg5d0aaCy/9My6CdPChYF07dvz5chaXBGaD4g==} + happy-dom@20.7.0: + resolution: {integrity: sha512-hR/uLYQdngTyEfxnOoa+e6KTcfBFyc1hgFj/Cc144A5JJUuHFYqIEBDcD4FeGqUeKLRZqJ9eN9u7/GDjYEgS1g==} engines: {node: '>=20.0.0'} has-bigints@1.1.0: @@ -2300,10 +2299,6 @@ packages: hermes-parser@0.25.1: resolution: {integrity: sha512-6pEjquH3rqaI6cYAXYPcz9MS4rY6R4ngRgrgfDshRptUZIc3lw0MCIJIGDj9++mfySOuPTHB4nrSW99BCvOPIA==} - hosted-git-info@8.1.0: - resolution: {integrity: sha512-Rw/B2DNQaPBICNXEm8balFz9a6WpZrkCGpcWFpy7nCj+NyhSdqXipmfvtmWt9xGfp0wZnBxB+iVpLmQMYt47Tw==} - engines: {node: ^18.17.0 || >=20.5.0} - html-escaper@2.0.2: resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} @@ -2390,9 +2385,6 @@ packages: resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==} engines: {node: '>= 0.4'} - is-arrayish@0.2.1: - resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} - is-async-function@2.1.1: resolution: {integrity: sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==} engines: {node: '>= 0.4'} @@ -2449,10 +2441,6 @@ packages: resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==} engines: {node: '>=8'} - is-interactive@2.0.0: - resolution: {integrity: sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==} - engines: {node: '>=12'} - is-lower-case@1.1.3: resolution: {integrity: sha512-+5A1e/WJpLLXZEDlgz4G//WYSHyQBD32qa4Jd3Lw06qQlv3fJHnp3YIHjTQSGzHMgzmVKz2ZP3rBxTHkPw/lxA==} @@ -2516,14 +2504,6 @@ packages: resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} engines: {node: '>=10'} - is-unicode-supported@1.3.0: - resolution: {integrity: sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==} - engines: {node: '>=12'} - - is-unicode-supported@2.1.0: - resolution: {integrity: sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==} - engines: {node: '>=18'} - is-upper-case@1.1.2: resolution: {integrity: sha512-GQYSJMgfeAmVwh9ixyk888l7OIhNAGKtY6QA+IrWlu9MDTCaXmeozOZ2S9Knj7bQwBO/H6J2kb+pbyTUiMNbsw==} @@ -2566,10 +2546,6 @@ packages: resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} engines: {node: '>=10'} - istanbul-lib-source-maps@5.0.6: - resolution: {integrity: sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==} - engines: {node: '>=10'} - istanbul-reports@3.2.0: resolution: {integrity: sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==} engines: {node: '>=8'} @@ -2578,12 +2554,12 @@ packages: resolution: {integrity: sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==} engines: {node: '>= 0.4'} + js-tokens@10.0.0: + resolution: {integrity: sha512-lM/UBzQmfJRo9ABXbPWemivdCW8V2G8FHaHdypQaIy523snUjog0W71ayWXTjiR+ixeMyVHN2XcpnTd/liPg/Q==} + js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} - js-tokens@9.0.1: - resolution: {integrity: sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==} - js-yaml@3.14.2: resolution: {integrity: sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==} hasBin: true @@ -2603,9 +2579,6 @@ packages: json-canonicalize@2.0.0: resolution: {integrity: sha512-yyrnK/mEm6Na3ChbJUWueXdapueW0p380RUyTW87XGb1ww8l8hU0pRrGC3vSWHe9CxrbPHX2fGUOZpNiHR0IIg==} - json-parse-even-better-errors@2.3.1: - resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} - json-schema-traverse@0.4.1: resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} @@ -2617,9 +2590,6 @@ packages: engines: {node: '>=6'} hasBin: true - jsonc-parser@3.3.1: - resolution: {integrity: sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==} - jsonfile@4.0.0: resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} @@ -2637,71 +2607,64 @@ packages: keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} - kleur@3.0.3: - resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} - engines: {node: '>=6'} - - lefthook-darwin-arm64@2.0.12: - resolution: {integrity: sha512-tuBz1sNLien+nKKb8BDopKjS6EnbXU8rQzhMVBY+bnVfsTiYDfbBr4wo/IzA5TcwoTL/b5somCJhljEw6DvSyg==} + lefthook-darwin-arm64@2.1.1: + resolution: {integrity: sha512-O/RS1j03/Fnq5zCzEb2r7UOBsqPeBuf1C5pMkIJcO4TSE6hf3rhLUkcorKc2M5ni/n5zLGtzQUXHV08/fSAT3Q==} cpu: [arm64] os: [darwin] - lefthook-darwin-x64@2.0.12: - resolution: {integrity: sha512-FnuUMPPRMJyTEPXg6PotSrFJ8qf8FDLhhD1zLh74D+9Cye5j9n3lcrCQEjXubPT8du/GZLxMBjjffRbcZ8eYDA==} + lefthook-darwin-x64@2.1.1: + resolution: {integrity: sha512-mm/kdKl81ROPoYnj9XYk5JDqj+/6Al8w/SSPDfhItkLJyl4pqS+hWUOP6gDGrnuRk8S0DvJ2+hzhnDsQnZohWQ==} cpu: [x64] os: [darwin] - lefthook-freebsd-arm64@2.0.12: - resolution: {integrity: sha512-DXElB0qR5e6a8cXkFNYakhwCieypbfh6Y4QG39pzMnLsG03g/nhe093o6owfiUZ4mUFyDM6+0xmy0steOooF2g==} + lefthook-freebsd-arm64@2.1.1: + resolution: {integrity: sha512-F7JXlKmjxGqGbCWPLND0bVB4DMQezIe48pEwTlUQZbxh450c2gP5Q8FdttMZKOT163kBGGTqJAJSEC6zW+QSxA==} cpu: [arm64] os: [freebsd] - lefthook-freebsd-x64@2.0.12: - resolution: {integrity: sha512-iJN1ZxFeaDi4Fi3b9jcW9wgyNl19LOv2NaVOaAi/tG6mlIn196cmSdXkOA3+943ZbqbdfV9I+bBcIKwneXDA3Q==} + lefthook-freebsd-x64@2.1.1: + resolution: {integrity: sha512-Po8/lJMqNzKSZPuEI46dLuWoBoXtAxCuRpeOh6DAV/M4RhBynaCu8rLMZ9BqF7cVbZEWoplOmYo6HdOuiYpCkQ==} cpu: [x64] os: [freebsd] - lefthook-linux-arm64@2.0.12: - resolution: {integrity: sha512-byvmO4Iri6P0COwM8c3lGgeCV3Q0hh1XJpRfrcZDr4Wslq9O63t6J3T6i87oOtY+UjC9pXLl6xGk6hlUcHZ3BQ==} + lefthook-linux-arm64@2.1.1: + resolution: {integrity: sha512-mI2ljFgPEqHxI8vrN9nKgnVu63Rz1KisDbPwlvs7BTYNwq3sncdK5ukpGR4zzWdh6saNJ5tCtHEtep5GQI11nw==} cpu: [arm64] os: [linux] - lefthook-linux-x64@2.0.12: - resolution: {integrity: sha512-KBaiinmf336rA+/dmYs7H7TTeAOByB0CyLA7k8IecTCuaiuKr6ez7ktSjht19poa5G+V0mts4GgEGcx6HViR0w==} + lefthook-linux-x64@2.1.1: + resolution: {integrity: sha512-m3G/FaxC+crxeg9XeaUuHfEoL+i9gbkg2Hp2KD2IcVVIxprqlyqf0Hb8zbLV2NMXuo5RSGokJu44oAoTO3Ou2g==} cpu: [x64] os: [linux] - lefthook-openbsd-arm64@2.0.12: - resolution: {integrity: sha512-1QBMXX1UW5rtgC4TB52OKWB7Rz/kCBRB+bKKLT/gDD79aPzLgJANTitQQzgFNIWoa7aM9UvzvIAJzOo6FcFIbg==} + lefthook-openbsd-arm64@2.1.1: + resolution: {integrity: sha512-gz/8FJPvhjOdOFt1GmFvuvDOe+W+BBRjoeAT1/mTgkN7HCXMXgqNjjvakQKQeGz1I1v08wXG1ZNf5y+T9XBCDQ==} cpu: [arm64] os: [openbsd] - lefthook-openbsd-x64@2.0.12: - resolution: {integrity: sha512-zPcvUzs65GexRA37UHmaZqWuEGSU/zpBaPIY98MybXzzcJfCIf+O0oUQe2riMllwYGvNW0B1y3NOYRziDNe/vA==} + lefthook-openbsd-x64@2.1.1: + resolution: {integrity: sha512-ch3lyMUtbmtWUufaQVn4IoEs/2hjK51XqaCdY1mh5ca//VctR1peknIwQ5feHu+vATCDviWQ7HsdNDewm3HMPg==} cpu: [x64] os: [openbsd] - lefthook-windows-arm64@2.0.12: - resolution: {integrity: sha512-kgwxguS2GssoHM4SMTp+ArD/Gjg9q5MinD6iI5vSFpuJygD13ZWiXQQfESMHq9y/v1XkD0BdHTJej49dx8P+Vw==} + lefthook-windows-arm64@2.1.1: + resolution: {integrity: sha512-mm3PZhKDs9FE/jQDimkfWxtoj9xQ2k8uw2MdhtC825bhvIh+MEi0WFj/MOW+ug0RBg0I55tGYzZ5aVuozAWpTQ==} cpu: [arm64] os: [win32] - lefthook-windows-x64@2.0.12: - resolution: {integrity: sha512-Tf/VtSOtF3rBTc9dzRWROa+HuhqaiIV+Xp+1gzlx5+uCueLM0m87Rz6yd4IN5mL7TrDaNkiRXI3FvjCp0dUE4Q==} + lefthook-windows-x64@2.1.1: + resolution: {integrity: sha512-1L2oGIzmhfOTxfwbe5mpSQ+m3ilpvGNymwIhn4UHq6hwHsUL6HEhODqx02GfBn6OXpVIr56bvdBAusjL/SVYGQ==} cpu: [x64] os: [win32] - lefthook@2.0.12: - resolution: {integrity: sha512-I2FdA9cdnq1icwlNz4RADs7exuqe47q1N9+p2LmcP/WfchWh16mvTB82OAD7w7zK9GxblS9GpF7pASaOSl4c7A==} + lefthook@2.1.1: + resolution: {integrity: sha512-Tl9h9c+sG3ShzTHKuR3LAIblnnh+Mgxnm2Ul7yu9cu260Z27LEbO3V6Zw4YZFP59/2rlD42pt/llYsQCkkCFzw==} hasBin: true levn@0.4.1: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} - lines-and-columns@1.2.4: - resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} - locate-path@5.0.0: resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} engines: {node: '>=8'} @@ -2731,10 +2694,6 @@ packages: resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} engines: {node: '>=10'} - log-symbols@6.0.0: - resolution: {integrity: sha512-i24m8rpwhmPIS4zscNzK6MSEhk0DUWa/8iYQWxhffV8jkI4Phvs3F+quL5xvS0gdQR0FyTCMMH33Y78dDTzzIw==} - engines: {node: '>=18'} - loose-envify@1.4.0: resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} hasBin: true @@ -2745,9 +2704,6 @@ packages: lower-case@1.1.4: resolution: {integrity: sha512-2Fgx1Ycm599x+WGpIYwJOvsjmXFzTSc34IwDWALRA/8AopUKAVPwfJ+h5+f85BCp0PWmmJcWzEpxOpoXycMpdA==} - lru-cache@10.4.3: - resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} - lru-cache@11.2.4: resolution: {integrity: sha512-B5Y16Jr9LB9dHVkh6ZevG+vAbOsNOYCX+sXvFWFu7B3Iz5mijW3zdbMyhsh8ANd2mSWBYdJgnqi+mL7/LrOPYg==} engines: {node: 20 || >=22} @@ -2791,13 +2747,9 @@ packages: resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} engines: {node: '>=6'} - mimic-function@5.0.1: - resolution: {integrity: sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==} - engines: {node: '>=18'} - - minimatch@10.1.1: - resolution: {integrity: sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==} - engines: {node: 20 || >=22} + minimatch@10.2.2: + resolution: {integrity: sha512-+G4CpNBxa5MprY+04MbgOw1v7So6n5JY166pFi9KfYwT78fxScCeSNQSNzp6dpPSW2rONOps6Ocam1wFhCgoVw==} + engines: {node: 18 || 20 || >=22} minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} @@ -2809,8 +2761,8 @@ packages: minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} - minipass@7.1.2: - resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} + minipass@7.1.3: + resolution: {integrity: sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==} engines: {node: '>=16 || 14 >=14.17'} mipd@0.0.7: @@ -2850,8 +2802,8 @@ packages: resolution: {integrity: sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==} engines: {node: '>= 0.4.0'} - next@15.5.9: - resolution: {integrity: sha512-agNLK89seZEtC5zUHwtut0+tNrc0Xw4FT/Dg+B/VLEo9pAcS9rtTKpek3V6kVcVwsB2YlqMaHdfZL4eLEVYuCg==} + next@15.5.10: + resolution: {integrity: sha512-r0X65PNwyDDyOrWNKpQoZvOatw7BcsTPRKdwEqtc9cj3wv7mbBIk9tKed4klRaFXJdX0rugpuMTHslDrAU1bBg==} engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0} hasBin: true peerDependencies: @@ -2881,8 +2833,8 @@ packages: node-releases@2.0.27: resolution: {integrity: sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==} - nodemon@3.1.11: - resolution: {integrity: sha512-is96t8F/1//UHAjNPHpbsNY46ELPpftGUoSVNXwUfMk/qdjSylYrWSu1XavVTBOn526kFiOR733ATgNBCQyH0g==} + nodemon@3.1.14: + resolution: {integrity: sha512-jakjZi93UtB3jHMWsXL68FXSAosbLfY0In5gtKq3niLSkrWznrVBzXFNOEMJUfc9+Ke7SHWoAZsiMkNP3vq6Jw==} engines: {node: '>=10'} hasBin: true @@ -2890,10 +2842,6 @@ packages: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} - npm-package-arg@12.0.2: - resolution: {integrity: sha512-f1NpFjNI9O4VbKMOlA5QoBq/vSQPORHcTZ2feJpFkTHJ9eQkdlmZEKSjcAhxTGInC7RlEyScT9ui67NaOsjFWA==} - engines: {node: ^18.17.0 || >=20.5.0} - npm-run-path@4.0.1: resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} engines: {node: '>=8'} @@ -2936,10 +2884,6 @@ packages: resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} engines: {node: '>=6'} - onetime@7.0.0: - resolution: {integrity: sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==} - engines: {node: '>=18'} - optionator@0.9.4: resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} engines: {node: '>= 0.8.0'} @@ -2952,10 +2896,6 @@ packages: resolution: {integrity: sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==} engines: {node: '>=10'} - ora@8.2.0: - resolution: {integrity: sha512-weP+BZ8MVNnlCm8c0Qdc1WSWq4Qn7I+9CJGm7Qali6g44e/PUzbjNqJX5NJ9ljlNMosfJvg1fKEGILklK9cwnw==} - engines: {node: '>=18'} - os-tmpdir@1.0.2: resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} engines: {node: '>=0.10.0'} @@ -3028,10 +2968,6 @@ packages: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} - parse-json@5.2.0: - resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} - engines: {node: '>=8'} - pascal-case@2.0.1: resolution: {integrity: sha512-qjS4s8rBOJa2Xm0jmxXiyh1+OFf6ekCWOvUaRgAQSktzlTbMotS0nmG9gyYAybCWBcuP4fsBeRCKNwGBnMe2OQ==} @@ -3053,18 +2989,14 @@ packages: path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} - path-scurry@2.0.1: - resolution: {integrity: sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==} - engines: {node: 20 || >=22} + path-scurry@2.0.2: + resolution: {integrity: sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==} + engines: {node: 18 || 20 || >=22} path-type@4.0.0: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} - path-type@6.0.0: - resolution: {integrity: sha512-Vj7sf++t5pBD637NSfkxpHSMfWaeig5+DKWLhcqIYx6mWQz5hdJTGDVMQiJcw1ZYkhs7AazKDGpRVji1LJCZUQ==} - engines: {node: '>=18'} - pathe@2.0.3: resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} @@ -3108,19 +3040,11 @@ packages: engines: {node: '>=10.13.0'} hasBin: true - prettier@3.7.4: - resolution: {integrity: sha512-v6UNi1+3hSlVvv8fSaoUbggEM5VErKmmpGA7Pl3HF8V6uKY7rvClBOJlH6yNwQtfTueNkGVpOv/mtWL9L4bgRA==} + prettier@3.8.1: + resolution: {integrity: sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==} engines: {node: '>=14'} hasBin: true - proc-log@5.0.0: - resolution: {integrity: sha512-Azwzvl90HaF0aCz1JrDdXQykFakSSNPaPoiZ9fm5qJIMHioDZEi7OAdRwSm6rSoPtY3Qutnm3L7ogmg3dc+wbQ==} - engines: {node: ^18.17.0 || >=20.5.0} - - prompts@2.4.2: - resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} - engines: {node: '>= 6'} - prop-types@15.8.1: resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} @@ -3138,9 +3062,6 @@ packages: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} - pure-rand@6.1.0: - resolution: {integrity: sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==} - pvtsutils@1.3.6: resolution: {integrity: sha512-PLgQXQ6H2FWCaeRak8vvk1GW462lMxB5s3Jm673N82zI4vqtVUPuZdffdZbPDFRoU8kAhItWFtPCWiPpp4/EDg==} @@ -3174,10 +3095,6 @@ packages: resolution: {integrity: sha512-VIMnQi/Z4HT2Fxuwg5KrY174U1VdUIASQVWXXyqtNRtxSr9IYkn1rsI6Tb6HsrHCmB7gVpNwX6JxPTHcH6IoTA==} engines: {node: '>=6'} - read-yaml-file@2.1.0: - resolution: {integrity: sha512-UkRNRIwnhG+y7hpqnycCL/xbTk7+ia9VuVTC0S+zVbwd65DI9eUpRMfsWIGrCWxTU/mi+JW8cHQCrv+zfCbEPQ==} - engines: {node: '>=10.13'} - readable-stream@3.6.2: resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} engines: {node: '>= 6'} @@ -3226,10 +3143,6 @@ packages: resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} engines: {node: '>=8'} - restore-cursor@5.1.0: - resolution: {integrity: sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==} - engines: {node: '>=18'} - reusify@1.1.0: resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} @@ -3239,8 +3152,8 @@ packages: deprecated: Rimraf versions prior to v4 are no longer supported hasBin: true - rimraf@6.1.2: - resolution: {integrity: sha512-cFCkPslJv7BAXJsYlK1dZsbP8/ZNLkCAQ0bi1hf5EKX2QHegmDFEFA6QhuYJlk7UDdc+02JjO80YSOrWPpw06g==} + rimraf@6.1.3: + resolution: {integrity: sha512-LKg+Cr2ZF61fkcaK1UdkH2yEBBKnYjTyWzTJT6KNPcSPaiT7HSdhtMXQuN5wkTX0Xu72KQ1l8S42rlmexS2hSA==} engines: {node: 20 || >=22} hasBin: true @@ -3293,6 +3206,11 @@ packages: engines: {node: '>=10'} hasBin: true + semver@7.7.4: + resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==} + engines: {node: '>=10'} + hasBin: true + sentence-case@2.1.1: resolution: {integrity: sha512-ENl7cYHaK/Ktwk5OTD+aDbQ3uC8IByu/6Bkg+HDv8Mm+XnBnppVNalcfJTNsp1ibstKh030/JKQQWglDvtKwEQ==} @@ -3354,17 +3272,10 @@ packages: resolution: {integrity: sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==} engines: {node: '>=10'} - sisteransi@1.0.5: - resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} - slash@3.0.0: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} engines: {node: '>=8'} - slash@5.1.0: - resolution: {integrity: sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==} - engines: {node: '>=14.16'} - smart-buffer@4.2.0: resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==} engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} @@ -3400,10 +3311,6 @@ packages: std-env@3.10.0: resolution: {integrity: sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==} - stdin-discarder@0.2.2: - resolution: {integrity: sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ==} - engines: {node: '>=18'} - stop-iteration-iterator@1.1.0: resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==} engines: {node: '>= 0.4'} @@ -3450,10 +3357,6 @@ packages: resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} engines: {node: '>=4'} - strip-bom@4.0.0: - resolution: {integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==} - engines: {node: '>=8'} - strip-final-newline@2.0.0: resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} engines: {node: '>=6'} @@ -3498,9 +3401,49 @@ packages: swap-case@1.1.2: resolution: {integrity: sha512-BAmWG6/bx8syfc6qXPprof3Mn5vQgf5dwdUNJhsNqU9WdPt5P+ES/wQ5bxfijy8zwZgZZHslC3iAsxsuQMCzJQ==} - syncpack@13.0.4: - resolution: {integrity: sha512-kJ9VlRxNCsBD5pJAE29oXeBYbPLhEySQmK4HdpsLv81I6fcDDW17xeJqMwiU3H7/woAVsbgq25DJNS8BeiN5+w==} - engines: {node: '>=18.18.0'} + syncpack-darwin-arm64@14.0.0: + resolution: {integrity: sha512-mEcku9YkOHfM6JOxhq9McgeLvd4djsJvRwNONZXHeoJ6+yqC96DdxZwFjkw3e8Vn95wsxsrwY5ZjMExs5Gbacw==} + cpu: [arm64] + os: [darwin] + + syncpack-darwin-x64@14.0.0: + resolution: {integrity: sha512-qSj3bT3SIZA5NLM5PNVeExapyOrdmptlGSMu0SLVHj9hata/Vqh3xWgwq7wB9uajmlrHljeJ84R/NKAHyzFewA==} + cpu: [x64] + os: [darwin] + + syncpack-linux-arm64-musl@14.0.0: + resolution: {integrity: sha512-i57Chz0tHP7ybKElPLhoygl6Cab1fxyUKS9xRgezX5NDrNxKUgrvqBfYd7288/QKB4C8+IcYHugFPjZjoFlAIA==} + cpu: [arm64] + os: [linux] + + syncpack-linux-arm64@14.0.0: + resolution: {integrity: sha512-votlkb4P/0Bxd9yhBWCSUOjZwaii+LfFn1tZZVN5dfs8qcjcLeqfdG5zbnlJSzZhS3T+BfzejFW+Z95OxZag0A==} + cpu: [arm64] + os: [linux] + + syncpack-linux-x64-musl@14.0.0: + resolution: {integrity: sha512-RKyp+29UlLGE8oYkd3UfwgjWUHN4dLHDyarv0dS6gWVpWM6qHtHS339KBc9JcIS7FD1vNGnQ3GmSaAodxDlkMA==} + cpu: [x64] + os: [linux] + + syncpack-linux-x64@14.0.0: + resolution: {integrity: sha512-sZGy4+uL+P/+nI0yc9jwW/R22u9lw0+NXDYC/9ts9eYiWFyO4+luOeosvVKbED1OavUp/GQJqNV+9KHjMwq0Fw==} + cpu: [x64] + os: [linux] + + syncpack-windows-arm64@14.0.0: + resolution: {integrity: sha512-aNtr0F6HkA7M0azDuDkt//DlPWlplFa4kmvHXirwDmJQ9u3SAvN3ZItW4ZYS96ZbiV1DgO15jIKBI7rDkzcwrQ==} + cpu: [arm64] + os: [win32] + + syncpack-windows-x64@14.0.0: + resolution: {integrity: sha512-usMH61wlonssfh2Q8SJDiiAcsXVzuPzRl8XdHqdavR3XeCSGBIW9ieJpPfiKvDPWslekufWD+GhLNoH+8vV0Cg==} + cpu: [x64] + os: [win32] + + syncpack@14.0.0: + resolution: {integrity: sha512-OfAa3Oip5YC9Ad1jEs92Hw08Wy4JfdpdeequIwaJGsQG0tJtb8gpQfCdLuBefsk6n8WiUdt/5qmzcW+BDXtzbQ==} + engines: {node: '>=14.17.0'} hasBin: true term-size@2.2.1: @@ -3510,10 +3453,6 @@ packages: through@2.3.8: resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} - tightrope@0.2.0: - resolution: {integrity: sha512-Kw36UHxJEELq2VUqdaSGR2/8cAsPgMtvX8uGVU6Jk26O66PhXec0A5ZnRYs47btbtwPDpXXF66+Fo3vimCM9aQ==} - engines: {node: '>=16'} - tinybench@2.9.0: resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} @@ -3574,47 +3513,44 @@ packages: '@swc/wasm': optional: true - ts-toolbelt@9.6.0: - resolution: {integrity: sha512-nsZd8ZeNUzukXPlJmTBwUAuABDe/9qtVDelJeT/qW0ow3ZS3BsQJtNkan1802aM9Uf68/Y8ljw86Hu0h5IUW3w==} - tslib@1.14.1: resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} - turbo-darwin-64@2.6.3: - resolution: {integrity: sha512-BlJJDc1CQ7SK5Y5qnl7AzpkvKSnpkfPmnA+HeU/sgny3oHZckPV2776ebO2M33CYDSor7+8HQwaodY++IINhYg==} + turbo-darwin-64@2.8.10: + resolution: {integrity: sha512-A03fXh+B7S8mL3PbdhTd+0UsaGrhfyPkODvzBDpKRY7bbeac4MDFpJ7I+Slf2oSkCEeSvHKR7Z4U71uKRUfX7g==} cpu: [x64] os: [darwin] - turbo-darwin-arm64@2.6.3: - resolution: {integrity: sha512-MwVt7rBKiOK7zdYerenfCRTypefw4kZCue35IJga9CH1+S50+KTiCkT6LBqo0hHeoH2iKuI0ldTF2a0aB72z3w==} + turbo-darwin-arm64@2.8.10: + resolution: {integrity: sha512-sidzowgWL3s5xCHLeqwC9M3s9M0i16W1nuQF3Mc7fPHpZ+YPohvcbVFBB2uoRRHYZg6yBnwD4gyUHKTeXfwtXA==} cpu: [arm64] os: [darwin] - turbo-linux-64@2.6.3: - resolution: {integrity: sha512-cqpcw+dXxbnPtNnzeeSyWprjmuFVpHJqKcs7Jym5oXlu/ZcovEASUIUZVN3OGEM6Y/OTyyw0z09tOHNt5yBAVg==} + turbo-linux-64@2.8.10: + resolution: {integrity: sha512-YK9vcpL3TVtqonB021XwgaQhY9hJJbKKUhLv16osxV0HkcQASQWUqR56yMge7puh6nxU67rQlTq1b7ksR1T3KA==} cpu: [x64] os: [linux] - turbo-linux-arm64@2.6.3: - resolution: {integrity: sha512-MterpZQmjXyr4uM7zOgFSFL3oRdNKeflY7nsjxJb2TklsYqiu3Z9pQ4zRVFFH8n0mLGna7MbQMZuKoWqqHb45w==} + turbo-linux-arm64@2.8.10: + resolution: {integrity: sha512-3+j2tL0sG95iBJTm+6J8/45JsETQABPqtFyYjVjBbi6eVGdtNTiBmHNKrbvXRlQ3ZbUG75bKLaSSDHSEEN+btQ==} cpu: [arm64] os: [linux] - turbo-windows-64@2.6.3: - resolution: {integrity: sha512-biDU70v9dLwnBdLf+daoDlNJVvqOOP8YEjqNipBHzgclbQlXbsi6Gqqelp5er81Qo3BiRgmTNx79oaZQTPb07Q==} + turbo-windows-64@2.8.10: + resolution: {integrity: sha512-hdeF5qmVY/NFgiucf8FW0CWJWtyT2QPm5mIsX0W1DXAVzqKVXGq+Zf+dg4EUngAFKjDzoBeN6ec2Fhajwfztkw==} cpu: [x64] os: [win32] - turbo-windows-arm64@2.6.3: - resolution: {integrity: sha512-dDHVKpSeukah3VsI/xMEKeTnV9V9cjlpFSUs4bmsUiLu3Yv2ENlgVEZv65wxbeE0bh0jjpmElDT+P1KaCxArQQ==} + turbo-windows-arm64@2.8.10: + resolution: {integrity: sha512-QGdr/Q8LWmj+ITMkSvfiz2glf0d7JG0oXVzGL3jxkGqiBI1zXFj20oqVY0qWi+112LO9SVrYdpHS0E/oGFrMbQ==} cpu: [arm64] os: [win32] - turbo@2.6.3: - resolution: {integrity: sha512-bf6YKUv11l5Xfcmg76PyWoy/e2vbkkxFNBGJSnfdSXQC33ZiUfutYh6IXidc5MhsnrFkWfdNNLyaRk+kHMLlwA==} + turbo@2.8.10: + resolution: {integrity: sha512-OxbzDES66+x7nnKGg2MwBA1ypVsZoDTLHpeaP4giyiHSixbsiTaMyeJqbEyvBdp5Cm28fc+8GG6RdQtic0ijwQ==} hasBin: true type-check@0.4.0: @@ -3665,15 +3601,8 @@ packages: undefsafe@2.0.5: resolution: {integrity: sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==} - undici-types@6.21.0: - resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} - - undici-types@7.16.0: - resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} - - unicorn-magic@0.3.0: - resolution: {integrity: sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==} - engines: {node: '>=18'} + undici-types@7.18.2: + resolution: {integrity: sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==} universalify@0.1.2: resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} @@ -3715,10 +3644,6 @@ packages: resolution: {integrity: sha512-OljLrQ9SQdOUqTaQxqL5dEfZWrXExyyWsozYlAWFawPVNuD83igl7uJD2RTkNMbniIYgt8l81eCJGIdQF7avLQ==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - validate-npm-package-name@6.0.2: - resolution: {integrity: sha512-IUoow1YUtvoBBC06dXs8bR8B9vuA3aJfmQNKMoaPG/OFsPmoQvw8xh+6Ye25Gx9DQhoEom3Pcu9MKHerm/NpUQ==} - engines: {node: ^18.17.0 || >=20.5.0} - viem@2.42.1: resolution: {integrity: sha512-NzT/f54jT+b0Um6pYzN/uAGMLg+3twhricAzXS+XH8pVIREzPEh7P25rlhPQnLYiPWzQd9mrFcvnm73Sc8bx+A==} peerDependencies: @@ -3767,18 +3692,18 @@ packages: yaml: optional: true - vitest@4.0.15: - resolution: {integrity: sha512-n1RxDp8UJm6N0IbJLQo+yzLZ2sQCDyl1o0LeugbPWf8+8Fttp29GghsQBjYJVmWq3gBFfe9Hs1spR44vovn2wA==} + vitest@4.0.18: + resolution: {integrity: sha512-hOQuK7h0FGKgBAas7v0mSAsnvrIgAvWmRFjmzpJ7SwFHH3g1k2u37JtYwOwmEKhK6ZO3v9ggDBBm0La1LCK4uQ==} engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} hasBin: true peerDependencies: '@edge-runtime/vm': '*' '@opentelemetry/api': ^1.9.0 '@types/node': ^20.0.0 || ^22.0.0 || >=24.0.0 - '@vitest/browser-playwright': 4.0.15 - '@vitest/browser-preview': 4.0.15 - '@vitest/browser-webdriverio': 4.0.15 - '@vitest/ui': 4.0.15 + '@vitest/browser-playwright': 4.0.18 + '@vitest/browser-preview': 4.0.18 + '@vitest/browser-webdriverio': 4.0.18 + '@vitest/ui': 4.0.18 happy-dom: '*' jsdom: '*' peerDependenciesMeta: @@ -4054,7 +3979,7 @@ snapshots: dependencies: '@changesets/types': 6.1.0 - '@changesets/cli@2.29.8(@types/node@25.0.2)': + '@changesets/cli@2.29.8(@types/node@25.3.0)': dependencies: '@changesets/apply-release-plan': 7.0.14 '@changesets/assemble-release-plan': 6.0.9 @@ -4070,7 +3995,7 @@ snapshots: '@changesets/should-skip-package': 0.1.2 '@changesets/types': 6.1.0 '@changesets/write': 0.4.0 - '@inquirer/external-editor': 1.0.3(@types/node@25.0.2) + '@inquirer/external-editor': 1.0.3(@types/node@25.3.0) '@manypkg/get-packages': 1.1.3 ansi-colors: 4.1.3 ci-info: 3.9.0 @@ -4173,87 +4098,87 @@ snapshots: dependencies: '@jridgewell/trace-mapping': 0.3.9 - '@emnapi/runtime@1.7.1': + '@emnapi/runtime@1.8.1': dependencies: tslib: 2.8.1 optional: true - '@esbuild/aix-ppc64@0.27.1': + '@esbuild/aix-ppc64@0.27.3': optional: true - '@esbuild/android-arm64@0.27.1': + '@esbuild/android-arm64@0.27.3': optional: true - '@esbuild/android-arm@0.27.1': + '@esbuild/android-arm@0.27.3': optional: true - '@esbuild/android-x64@0.27.1': + '@esbuild/android-x64@0.27.3': optional: true - '@esbuild/darwin-arm64@0.27.1': + '@esbuild/darwin-arm64@0.27.3': optional: true - '@esbuild/darwin-x64@0.27.1': + '@esbuild/darwin-x64@0.27.3': optional: true - '@esbuild/freebsd-arm64@0.27.1': + '@esbuild/freebsd-arm64@0.27.3': optional: true - '@esbuild/freebsd-x64@0.27.1': + '@esbuild/freebsd-x64@0.27.3': optional: true - '@esbuild/linux-arm64@0.27.1': + '@esbuild/linux-arm64@0.27.3': optional: true - '@esbuild/linux-arm@0.27.1': + '@esbuild/linux-arm@0.27.3': optional: true - '@esbuild/linux-ia32@0.27.1': + '@esbuild/linux-ia32@0.27.3': optional: true - '@esbuild/linux-loong64@0.27.1': + '@esbuild/linux-loong64@0.27.3': optional: true - '@esbuild/linux-mips64el@0.27.1': + '@esbuild/linux-mips64el@0.27.3': optional: true - '@esbuild/linux-ppc64@0.27.1': + '@esbuild/linux-ppc64@0.27.3': optional: true - '@esbuild/linux-riscv64@0.27.1': + '@esbuild/linux-riscv64@0.27.3': optional: true - '@esbuild/linux-s390x@0.27.1': + '@esbuild/linux-s390x@0.27.3': optional: true - '@esbuild/linux-x64@0.27.1': + '@esbuild/linux-x64@0.27.3': optional: true - '@esbuild/netbsd-arm64@0.27.1': + '@esbuild/netbsd-arm64@0.27.3': optional: true - '@esbuild/netbsd-x64@0.27.1': + '@esbuild/netbsd-x64@0.27.3': optional: true - '@esbuild/openbsd-arm64@0.27.1': + '@esbuild/openbsd-arm64@0.27.3': optional: true - '@esbuild/openbsd-x64@0.27.1': + '@esbuild/openbsd-x64@0.27.3': optional: true - '@esbuild/openharmony-arm64@0.27.1': + '@esbuild/openharmony-arm64@0.27.3': optional: true - '@esbuild/sunos-x64@0.27.1': + '@esbuild/sunos-x64@0.27.3': optional: true - '@esbuild/win32-arm64@0.27.1': + '@esbuild/win32-arm64@0.27.3': optional: true - '@esbuild/win32-ia32@0.27.1': + '@esbuild/win32-ia32@0.27.3': optional: true - '@esbuild/win32-x64@0.27.1': + '@esbuild/win32-x64@0.27.3': optional: true '@eslint-community/eslint-utils@4.9.0(eslint@9.39.2)': @@ -4398,7 +4323,7 @@ snapshots: '@img/sharp-wasm32@0.34.5': dependencies: - '@emnapi/runtime': 1.7.1 + '@emnapi/runtime': 1.8.1 optional: true '@img/sharp-win32-arm64@0.34.5': @@ -4410,18 +4335,12 @@ snapshots: '@img/sharp-win32-x64@0.34.5': optional: true - '@inquirer/external-editor@1.0.3(@types/node@25.0.2)': + '@inquirer/external-editor@1.0.3(@types/node@25.3.0)': dependencies: chardet: 2.1.1 iconv-lite: 0.7.1 optionalDependencies: - '@types/node': 25.0.2 - - '@isaacs/balanced-match@4.0.1': {} - - '@isaacs/brace-expansion@5.0.0': - dependencies: - '@isaacs/balanced-match': 4.0.1 + '@types/node': 25.3.0 '@jridgewell/gen-mapping@0.3.13': dependencies: @@ -4463,7 +4382,7 @@ snapshots: globby: 11.1.0 read-yaml-file: 1.1.0 - '@next/env@15.5.9': {} + '@next/env@15.5.10': {} '@next/eslint-plugin-next@15.5.9': dependencies: @@ -4594,8 +4513,6 @@ snapshots: '@noble/hashes': 1.8.0 '@scure/base': 1.2.6 - '@sindresorhus/merge-streams@2.3.0': {} - '@standard-schema/spec@1.0.0': {} '@swc/helpers@0.5.15': @@ -4612,17 +4529,17 @@ snapshots: '@tsconfig/node16@1.0.4': {} - '@turbo/gen@1.13.4(@types/node@25.0.2)(typescript@5.9.3)': + '@turbo/gen@1.13.4(@types/node@25.3.0)(typescript@5.9.3)': dependencies: - '@turbo/workspaces': 1.13.4(@types/node@25.0.2) + '@turbo/workspaces': 1.13.4(@types/node@25.3.0) chalk: 2.4.2 commander: 10.0.1 fs-extra: 10.1.0 - inquirer: 8.2.7(@types/node@25.0.2) + inquirer: 8.2.7(@types/node@25.3.0) minimatch: 9.0.5 node-plop: 0.26.3 proxy-agent: 6.5.0 - ts-node: 10.9.2(@types/node@25.0.2)(typescript@5.9.3) + ts-node: 10.9.2(@types/node@25.3.0)(typescript@5.9.3) update-check: 1.5.4 validate-npm-package-name: 5.0.1 transitivePeerDependencies: @@ -4632,7 +4549,7 @@ snapshots: - supports-color - typescript - '@turbo/workspaces@1.13.4(@types/node@25.0.2)': + '@turbo/workspaces@1.13.4(@types/node@25.3.0)': dependencies: chalk: 2.4.2 commander: 10.0.1 @@ -4640,7 +4557,7 @@ snapshots: fast-glob: 3.3.3 fs-extra: 10.1.0 gradient-string: 2.0.2 - inquirer: 8.2.7(@types/node@25.0.2) + inquirer: 8.2.7(@types/node@25.3.0) js-yaml: 4.1.1 ora: 4.1.1 rimraf: 3.0.2 @@ -4661,7 +4578,7 @@ snapshots: '@types/glob@7.2.0': dependencies: '@types/minimatch': 6.0.0 - '@types/node': 25.0.2 + '@types/node': 25.3.0 '@types/inquirer@6.5.0': dependencies: @@ -4676,13 +4593,9 @@ snapshots: '@types/node@12.20.55': {} - '@types/node@20.19.27': - dependencies: - undici-types: 6.21.0 - - '@types/node@25.0.2': + '@types/node@25.3.0': dependencies: - undici-types: 7.16.0 + undici-types: 7.18.2 '@types/react-dom@19.2.3(@types/react@19.2.7)': dependencies: @@ -4694,12 +4607,16 @@ snapshots: '@types/through@0.0.33': dependencies: - '@types/node': 25.0.2 + '@types/node': 25.3.0 '@types/tinycolor2@1.4.6': {} '@types/whatwg-mimetype@3.0.2': {} + '@types/ws@8.18.1': + dependencies: + '@types/node': 25.3.0 + '@types/yargs-parser@21.0.3': {} '@types/yargs@17.0.35': @@ -4797,60 +4714,57 @@ snapshots: '@typescript-eslint/types': 8.50.0 eslint-visitor-keys: 4.2.1 - '@vitest/coverage-v8@4.0.15(vitest@4.0.15(@types/node@25.0.2)(happy-dom@20.0.11))': + '@vitest/coverage-v8@4.0.18(vitest@4.0.18(@types/node@25.3.0)(happy-dom@20.7.0))': dependencies: '@bcoe/v8-coverage': 1.0.2 - '@vitest/utils': 4.0.15 - ast-v8-to-istanbul: 0.3.8 + '@vitest/utils': 4.0.18 + ast-v8-to-istanbul: 0.3.11 istanbul-lib-coverage: 3.2.2 istanbul-lib-report: 3.0.1 - istanbul-lib-source-maps: 5.0.6 istanbul-reports: 3.2.0 magicast: 0.5.1 obug: 2.1.1 std-env: 3.10.0 tinyrainbow: 3.0.3 - vitest: 4.0.15(@types/node@25.0.2)(happy-dom@20.0.11) - transitivePeerDependencies: - - supports-color + vitest: 4.0.18(@types/node@25.3.0)(happy-dom@20.7.0) - '@vitest/expect@4.0.15': + '@vitest/expect@4.0.18': dependencies: '@standard-schema/spec': 1.0.0 '@types/chai': 5.2.3 - '@vitest/spy': 4.0.15 - '@vitest/utils': 4.0.15 + '@vitest/spy': 4.0.18 + '@vitest/utils': 4.0.18 chai: 6.2.1 tinyrainbow: 3.0.3 - '@vitest/mocker@4.0.15(vite@7.3.0(@types/node@25.0.2))': + '@vitest/mocker@4.0.18(vite@7.3.0(@types/node@25.3.0))': dependencies: - '@vitest/spy': 4.0.15 + '@vitest/spy': 4.0.18 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 7.3.0(@types/node@25.0.2) + vite: 7.3.0(@types/node@25.3.0) - '@vitest/pretty-format@4.0.15': + '@vitest/pretty-format@4.0.18': dependencies: tinyrainbow: 3.0.3 - '@vitest/runner@4.0.15': + '@vitest/runner@4.0.18': dependencies: - '@vitest/utils': 4.0.15 + '@vitest/utils': 4.0.18 pathe: 2.0.3 - '@vitest/snapshot@4.0.15': + '@vitest/snapshot@4.0.18': dependencies: - '@vitest/pretty-format': 4.0.15 + '@vitest/pretty-format': 4.0.18 magic-string: 0.30.21 pathe: 2.0.3 - '@vitest/spy@4.0.15': {} + '@vitest/spy@4.0.18': {} - '@vitest/utils@4.0.15': + '@vitest/utils@4.0.18': dependencies: - '@vitest/pretty-format': 4.0.15 + '@vitest/pretty-format': 4.0.18 tinyrainbow: 3.0.3 abitype@1.1.0(typescript@5.9.3)(zod@4.2.0): @@ -4991,11 +4905,11 @@ snapshots: dependencies: tslib: 2.8.1 - ast-v8-to-istanbul@0.3.8: + ast-v8-to-istanbul@0.3.11: dependencies: '@jridgewell/trace-mapping': 0.3.31 estree-walker: 3.0.3 - js-tokens: 9.0.1 + js-tokens: 10.0.0 async-function@1.0.0: {} @@ -5005,6 +4919,8 @@ snapshots: balanced-match@1.0.2: {} + balanced-match@4.0.4: {} + base64-js@1.5.1: {} baseline-browser-mapping@2.9.7: {} @@ -5032,6 +4948,10 @@ snapshots: dependencies: balanced-match: 1.0.2 + brace-expansion@5.0.3: + dependencies: + balanced-match: 4.0.4 + braces@3.0.3: dependencies: fill-range: 7.1.1 @@ -5039,7 +4959,7 @@ snapshots: browserslist@4.28.1: dependencies: baseline-browser-mapping: 2.9.7 - caniuse-lite: 1.0.30001760 + caniuse-lite: 1.0.30001769 electron-to-chromium: 1.5.267 node-releases: 2.0.27 update-browserslist-db: 1.2.2(browserslist@4.28.1) @@ -5075,16 +4995,12 @@ snapshots: no-case: 2.3.2 upper-case: 1.1.3 - caniuse-lite@1.0.30001760: {} + caniuse-lite@1.0.30001769: {} cbor2@1.12.0: {} chai@6.2.1: {} - chalk-template@1.1.2: - dependencies: - chalk: 5.6.2 - chalk@2.4.2: dependencies: ansi-styles: 3.2.1 @@ -5101,8 +5017,6 @@ snapshots: ansi-styles: 4.3.0 supports-color: 7.2.0 - chalk@5.6.2: {} - change-case@3.1.0: dependencies: camel-case: 3.0.0 @@ -5148,10 +5062,6 @@ snapshots: dependencies: restore-cursor: 3.1.0 - cli-cursor@5.0.0: - dependencies: - restore-cursor: 5.1.0 - cli-spinners@2.9.2: {} cli-width@3.0.0: {} @@ -5186,8 +5096,6 @@ snapshots: commander@10.0.1: {} - commander@13.1.0: {} - concat-map@0.0.1: {} concurrently@9.2.1: @@ -5208,15 +5116,6 @@ snapshots: core-js-pure@3.47.0: {} - cosmiconfig@9.0.0(typescript@5.9.3): - dependencies: - env-paths: 2.2.1 - import-fresh: 3.3.1 - js-yaml: 4.1.1 - parse-json: 5.2.0 - optionalDependencies: - typescript: 5.9.3 - create-require@1.1.1: {} cross-spawn@7.0.6: @@ -5311,7 +5210,7 @@ snapshots: dotenv@16.0.3: {} - dotenv@17.2.3: {} + dotenv@17.3.1: {} dunder-proto@1.0.1: dependencies: @@ -5319,11 +5218,6 @@ snapshots: es-errors: 1.3.0 gopd: 1.2.0 - effect@3.19.12: - dependencies: - '@standard-schema/spec': 1.0.0 - fast-check: 3.23.2 - electron-to-chromium@1.5.267: {} emoji-regex@10.6.0: {} @@ -5335,11 +5229,7 @@ snapshots: ansi-colors: 4.1.3 strip-ansi: 6.0.1 - env-paths@2.2.1: {} - - error-ex@1.3.4: - dependencies: - is-arrayish: 0.2.1 + entities@7.0.1: {} es-abstract@1.24.1: dependencies: @@ -5444,34 +5334,34 @@ snapshots: is-date-object: 1.1.0 is-symbol: 1.1.1 - esbuild@0.27.1: + esbuild@0.27.3: optionalDependencies: - '@esbuild/aix-ppc64': 0.27.1 - '@esbuild/android-arm': 0.27.1 - '@esbuild/android-arm64': 0.27.1 - '@esbuild/android-x64': 0.27.1 - '@esbuild/darwin-arm64': 0.27.1 - '@esbuild/darwin-x64': 0.27.1 - '@esbuild/freebsd-arm64': 0.27.1 - '@esbuild/freebsd-x64': 0.27.1 - '@esbuild/linux-arm': 0.27.1 - '@esbuild/linux-arm64': 0.27.1 - '@esbuild/linux-ia32': 0.27.1 - '@esbuild/linux-loong64': 0.27.1 - '@esbuild/linux-mips64el': 0.27.1 - '@esbuild/linux-ppc64': 0.27.1 - '@esbuild/linux-riscv64': 0.27.1 - '@esbuild/linux-s390x': 0.27.1 - '@esbuild/linux-x64': 0.27.1 - '@esbuild/netbsd-arm64': 0.27.1 - '@esbuild/netbsd-x64': 0.27.1 - '@esbuild/openbsd-arm64': 0.27.1 - '@esbuild/openbsd-x64': 0.27.1 - '@esbuild/openharmony-arm64': 0.27.1 - '@esbuild/sunos-x64': 0.27.1 - '@esbuild/win32-arm64': 0.27.1 - '@esbuild/win32-ia32': 0.27.1 - '@esbuild/win32-x64': 0.27.1 + '@esbuild/aix-ppc64': 0.27.3 + '@esbuild/android-arm': 0.27.3 + '@esbuild/android-arm64': 0.27.3 + '@esbuild/android-x64': 0.27.3 + '@esbuild/darwin-arm64': 0.27.3 + '@esbuild/darwin-x64': 0.27.3 + '@esbuild/freebsd-arm64': 0.27.3 + '@esbuild/freebsd-x64': 0.27.3 + '@esbuild/linux-arm': 0.27.3 + '@esbuild/linux-arm64': 0.27.3 + '@esbuild/linux-ia32': 0.27.3 + '@esbuild/linux-loong64': 0.27.3 + '@esbuild/linux-mips64el': 0.27.3 + '@esbuild/linux-ppc64': 0.27.3 + '@esbuild/linux-riscv64': 0.27.3 + '@esbuild/linux-s390x': 0.27.3 + '@esbuild/linux-x64': 0.27.3 + '@esbuild/netbsd-arm64': 0.27.3 + '@esbuild/netbsd-x64': 0.27.3 + '@esbuild/openbsd-arm64': 0.27.3 + '@esbuild/openbsd-x64': 0.27.3 + '@esbuild/openharmony-arm64': 0.27.3 + '@esbuild/sunos-x64': 0.27.3 + '@esbuild/win32-arm64': 0.27.3 + '@esbuild/win32-ia32': 0.27.3 + '@esbuild/win32-x64': 0.27.3 escalade@3.2.0: {} @@ -5526,11 +5416,11 @@ snapshots: string.prototype.matchall: 4.0.12 string.prototype.repeat: 1.0.0 - eslint-plugin-turbo@2.6.3(eslint@9.39.2)(turbo@2.6.3): + eslint-plugin-turbo@2.6.3(eslint@9.39.2)(turbo@2.8.10): dependencies: dotenv: 16.0.3 eslint: 9.39.2 - turbo: 2.6.3 + turbo: 2.8.10 eslint-scope@8.4.0: dependencies: @@ -5630,10 +5520,6 @@ snapshots: fake-indexeddb@6.2.5: {} - fast-check@3.23.2: - dependencies: - pure-rand: 6.1.0 - fast-deep-equal@3.1.3: {} fast-glob@3.3.1: @@ -5783,11 +5669,11 @@ snapshots: dependencies: is-glob: 4.0.3 - glob@13.0.0: + glob@13.0.6: dependencies: - minimatch: 10.1.1 - minipass: 7.1.2 - path-scurry: 2.0.1 + minimatch: 10.2.2 + minipass: 7.1.3 + path-scurry: 2.0.2 glob@7.2.3: dependencies: @@ -5827,15 +5713,6 @@ snapshots: merge2: 1.4.1 slash: 3.0.0 - globby@14.1.0: - dependencies: - '@sindresorhus/merge-streams': 2.3.0 - fast-glob: 3.3.3 - ignore: 7.0.5 - path-type: 6.0.0 - slash: 5.1.0 - unicorn-magic: 0.3.0 - gopd@1.2.0: {} graceful-fs@4.2.11: {} @@ -5854,11 +5731,17 @@ snapshots: optionalDependencies: uglify-js: 3.19.3 - happy-dom@20.0.11: + happy-dom@20.7.0: dependencies: - '@types/node': 20.19.27 + '@types/node': 25.3.0 '@types/whatwg-mimetype': 3.0.2 + '@types/ws': 8.18.1 + entities: 7.0.1 whatwg-mimetype: 3.0.0 + ws: 8.18.3 + transitivePeerDependencies: + - bufferutil + - utf-8-validate has-bigints@1.1.0: {} @@ -5895,10 +5778,6 @@ snapshots: dependencies: hermes-estree: 0.25.1 - hosted-git-info@8.1.0: - dependencies: - lru-cache: 10.4.3 - html-escaper@2.0.2: {} http-proxy-agent@7.0.2: @@ -5971,9 +5850,9 @@ snapshots: strip-ansi: 6.0.1 through: 2.3.8 - inquirer@8.2.7(@types/node@25.0.2): + inquirer@8.2.7(@types/node@25.3.0): dependencies: - '@inquirer/external-editor': 1.0.3(@types/node@25.0.2) + '@inquirer/external-editor': 1.0.3(@types/node@25.3.0) ansi-escapes: 4.3.2 chalk: 4.1.2 cli-cursor: 3.1.0 @@ -6005,8 +5884,6 @@ snapshots: call-bound: 1.0.4 get-intrinsic: 1.3.0 - is-arrayish@0.2.1: {} - is-async-function@2.1.1: dependencies: async-function: 1.0.0 @@ -6067,8 +5944,6 @@ snapshots: is-interactive@1.0.0: {} - is-interactive@2.0.0: {} - is-lower-case@1.1.3: dependencies: lower-case: 1.1.4 @@ -6124,10 +5999,6 @@ snapshots: is-unicode-supported@0.1.0: {} - is-unicode-supported@1.3.0: {} - - is-unicode-supported@2.1.0: {} - is-upper-case@1.1.2: dependencies: upper-case: 1.1.3 @@ -6163,14 +6034,6 @@ snapshots: make-dir: 4.0.0 supports-color: 7.2.0 - istanbul-lib-source-maps@5.0.6: - dependencies: - '@jridgewell/trace-mapping': 0.3.31 - debug: 4.4.3(supports-color@5.5.0) - istanbul-lib-coverage: 3.2.2 - transitivePeerDependencies: - - supports-color - istanbul-reports@3.2.0: dependencies: html-escaper: 2.0.2 @@ -6185,9 +6048,9 @@ snapshots: has-symbols: 1.1.0 set-function-name: 2.0.2 - js-tokens@4.0.0: {} + js-tokens@10.0.0: {} - js-tokens@9.0.1: {} + js-tokens@4.0.0: {} js-yaml@3.14.2: dependencies: @@ -6204,16 +6067,12 @@ snapshots: json-canonicalize@2.0.0: {} - json-parse-even-better-errors@2.3.1: {} - json-schema-traverse@0.4.1: {} json-stable-stringify-without-jsonify@1.0.1: {} json5@2.2.3: {} - jsonc-parser@3.3.1: {} - jsonfile@4.0.0: optionalDependencies: graceful-fs: 4.2.11 @@ -6237,58 +6096,54 @@ snapshots: dependencies: json-buffer: 3.0.1 - kleur@3.0.3: {} - - lefthook-darwin-arm64@2.0.12: + lefthook-darwin-arm64@2.1.1: optional: true - lefthook-darwin-x64@2.0.12: + lefthook-darwin-x64@2.1.1: optional: true - lefthook-freebsd-arm64@2.0.12: + lefthook-freebsd-arm64@2.1.1: optional: true - lefthook-freebsd-x64@2.0.12: + lefthook-freebsd-x64@2.1.1: optional: true - lefthook-linux-arm64@2.0.12: + lefthook-linux-arm64@2.1.1: optional: true - lefthook-linux-x64@2.0.12: + lefthook-linux-x64@2.1.1: optional: true - lefthook-openbsd-arm64@2.0.12: + lefthook-openbsd-arm64@2.1.1: optional: true - lefthook-openbsd-x64@2.0.12: + lefthook-openbsd-x64@2.1.1: optional: true - lefthook-windows-arm64@2.0.12: + lefthook-windows-arm64@2.1.1: optional: true - lefthook-windows-x64@2.0.12: + lefthook-windows-x64@2.1.1: optional: true - lefthook@2.0.12: + lefthook@2.1.1: optionalDependencies: - lefthook-darwin-arm64: 2.0.12 - lefthook-darwin-x64: 2.0.12 - lefthook-freebsd-arm64: 2.0.12 - lefthook-freebsd-x64: 2.0.12 - lefthook-linux-arm64: 2.0.12 - lefthook-linux-x64: 2.0.12 - lefthook-openbsd-arm64: 2.0.12 - lefthook-openbsd-x64: 2.0.12 - lefthook-windows-arm64: 2.0.12 - lefthook-windows-x64: 2.0.12 + lefthook-darwin-arm64: 2.1.1 + lefthook-darwin-x64: 2.1.1 + lefthook-freebsd-arm64: 2.1.1 + lefthook-freebsd-x64: 2.1.1 + lefthook-linux-arm64: 2.1.1 + lefthook-linux-x64: 2.1.1 + lefthook-openbsd-arm64: 2.1.1 + lefthook-openbsd-x64: 2.1.1 + lefthook-windows-arm64: 2.1.1 + lefthook-windows-x64: 2.1.1 levn@0.4.1: dependencies: prelude-ls: 1.2.1 type-check: 0.4.0 - lines-and-columns@1.2.4: {} - locate-path@5.0.0: dependencies: p-locate: 4.1.0 @@ -6314,11 +6169,6 @@ snapshots: chalk: 4.1.2 is-unicode-supported: 0.1.0 - log-symbols@6.0.0: - dependencies: - chalk: 5.6.2 - is-unicode-supported: 1.3.0 - loose-envify@1.4.0: dependencies: js-tokens: 4.0.0 @@ -6329,8 +6179,6 @@ snapshots: lower-case@1.1.4: {} - lru-cache@10.4.3: {} - lru-cache@11.2.4: {} lru-cache@5.1.1: @@ -6351,7 +6199,7 @@ snapshots: make-dir@4.0.0: dependencies: - semver: 7.7.3 + semver: 7.7.4 make-error@1.3.6: {} @@ -6368,11 +6216,9 @@ snapshots: mimic-fn@2.1.0: {} - mimic-function@5.0.1: {} - - minimatch@10.1.1: + minimatch@10.2.2: dependencies: - '@isaacs/brace-expansion': 5.0.0 + brace-expansion: 5.0.3 minimatch@3.1.2: dependencies: @@ -6384,7 +6230,7 @@ snapshots: minimist@1.2.8: {} - minipass@7.1.2: {} + minipass@7.1.3: {} mipd@0.0.7(typescript@5.9.3): optionalDependencies: @@ -6408,11 +6254,11 @@ snapshots: netmask@2.0.2: {} - next@15.5.9(react-dom@19.2.3(react@19.2.3))(react@19.2.3): + next@15.5.10(react-dom@19.2.3(react@19.2.3))(react@19.2.3): dependencies: - '@next/env': 15.5.9 + '@next/env': 15.5.10 '@swc/helpers': 0.5.15 - caniuse-lite: 1.0.30001760 + caniuse-lite: 1.0.30001769 postcss: 8.4.31 react: 19.2.3 react-dom: 19.2.3(react@19.2.3) @@ -6451,14 +6297,14 @@ snapshots: node-releases@2.0.27: {} - nodemon@3.1.11: + nodemon@3.1.14: dependencies: chokidar: 3.6.0 debug: 4.4.3(supports-color@5.5.0) ignore-by-default: 1.0.1 - minimatch: 3.1.2 + minimatch: 10.2.2 pstree.remy: 1.1.8 - semver: 7.7.3 + semver: 7.7.4 simple-update-notifier: 2.0.0 supports-color: 5.5.0 touch: 3.1.1 @@ -6466,13 +6312,6 @@ snapshots: normalize-path@3.0.0: {} - npm-package-arg@12.0.2: - dependencies: - hosted-git-info: 8.1.0 - proc-log: 5.0.0 - semver: 7.7.3 - validate-npm-package-name: 6.0.2 - npm-run-path@4.0.1: dependencies: path-key: 3.1.1 @@ -6523,10 +6362,6 @@ snapshots: dependencies: mimic-fn: 2.1.0 - onetime@7.0.0: - dependencies: - mimic-function: 5.0.1 - optionator@0.9.4: dependencies: deep-is: 0.1.4 @@ -6559,18 +6394,6 @@ snapshots: strip-ansi: 6.0.1 wcwidth: 1.0.1 - ora@8.2.0: - dependencies: - chalk: 5.6.2 - cli-cursor: 5.0.0 - cli-spinners: 2.9.2 - is-interactive: 2.0.0 - is-unicode-supported: 2.1.0 - log-symbols: 6.0.0 - stdin-discarder: 0.2.2 - string-width: 7.2.0 - strip-ansi: 7.1.2 - os-tmpdir@1.0.2: {} outdent@0.5.0: {} @@ -6656,13 +6479,6 @@ snapshots: dependencies: callsites: 3.1.0 - parse-json@5.2.0: - dependencies: - '@babel/code-frame': 7.27.1 - error-ex: 1.3.4 - json-parse-even-better-errors: 2.3.1 - lines-and-columns: 1.2.4 - pascal-case@2.0.1: dependencies: camel-case: 3.0.0 @@ -6680,15 +6496,13 @@ snapshots: path-parse@1.0.7: {} - path-scurry@2.0.1: + path-scurry@2.0.2: dependencies: lru-cache: 11.2.4 - minipass: 7.1.2 + minipass: 7.1.3 path-type@4.0.0: {} - path-type@6.0.0: {} - pathe@2.0.3: {} picocolors@1.1.1: {} @@ -6726,14 +6540,7 @@ snapshots: prettier@2.8.8: {} - prettier@3.7.4: {} - - proc-log@5.0.0: {} - - prompts@2.4.2: - dependencies: - kleur: 3.0.3 - sisteransi: 1.0.5 + prettier@3.8.1: {} prop-types@15.8.1: dependencies: @@ -6760,8 +6567,6 @@ snapshots: punycode@2.3.1: {} - pure-rand@6.1.0: {} - pvtsutils@1.3.6: dependencies: tslib: 2.8.1 @@ -6795,11 +6600,6 @@ snapshots: pify: 4.0.1 strip-bom: 3.0.0 - read-yaml-file@2.1.0: - dependencies: - js-yaml: 4.1.1 - strip-bom: 4.0.0 - readable-stream@3.6.2: dependencies: inherits: 2.0.4 @@ -6862,20 +6662,15 @@ snapshots: onetime: 5.1.2 signal-exit: 3.0.7 - restore-cursor@5.1.0: - dependencies: - onetime: 7.0.0 - signal-exit: 4.1.0 - reusify@1.1.0: {} rimraf@3.0.2: dependencies: glob: 7.2.3 - rimraf@6.1.2: + rimraf@6.1.3: dependencies: - glob: 13.0.0 + glob: 13.0.6 package-json-from-dist: 1.0.1 rollup@4.53.4: @@ -6949,6 +6744,8 @@ snapshots: semver@7.7.3: {} + semver@7.7.4: {} + sentence-case@2.1.1: dependencies: no-case: 2.3.2 @@ -6980,7 +6777,7 @@ snapshots: dependencies: '@img/colour': 1.0.0 detect-libc: 2.1.2 - semver: 7.7.3 + semver: 7.7.4 optionalDependencies: '@img/sharp-darwin-arm64': 0.34.5 '@img/sharp-darwin-x64': 0.34.5 @@ -7052,14 +6849,10 @@ snapshots: simple-update-notifier@2.0.0: dependencies: - semver: 7.7.3 - - sisteransi@1.0.5: {} + semver: 7.7.4 slash@3.0.0: {} - slash@5.1.0: {} - smart-buffer@4.2.0: {} snake-case@2.1.0: @@ -7094,8 +6887,6 @@ snapshots: std-env@3.10.0: {} - stdin-discarder@0.2.2: {} - stop-iteration-iterator@1.1.0: dependencies: es-errors: 1.3.0 @@ -7171,8 +6962,6 @@ snapshots: strip-bom@3.0.0: {} - strip-bom@4.0.0: {} - strip-final-newline@2.0.0: {} strip-json-comments@2.0.1: {} @@ -7203,34 +6992,45 @@ snapshots: lower-case: 1.1.4 upper-case: 1.1.3 - syncpack@13.0.4(typescript@5.9.3): - dependencies: - chalk: 5.6.2 - chalk-template: 1.1.2 - commander: 13.1.0 - cosmiconfig: 9.0.0(typescript@5.9.3) - effect: 3.19.12 - enquirer: 2.4.1 - fast-check: 3.23.2 - globby: 14.1.0 - jsonc-parser: 3.3.1 - minimatch: 9.0.5 - npm-package-arg: 12.0.2 - ora: 8.2.0 - prompts: 2.4.2 - read-yaml-file: 2.1.0 - semver: 7.7.3 - tightrope: 0.2.0 - ts-toolbelt: 9.6.0 - transitivePeerDependencies: - - typescript + syncpack-darwin-arm64@14.0.0: + optional: true + + syncpack-darwin-x64@14.0.0: + optional: true + + syncpack-linux-arm64-musl@14.0.0: + optional: true + + syncpack-linux-arm64@14.0.0: + optional: true + + syncpack-linux-x64-musl@14.0.0: + optional: true + + syncpack-linux-x64@14.0.0: + optional: true + + syncpack-windows-arm64@14.0.0: + optional: true + + syncpack-windows-x64@14.0.0: + optional: true + + syncpack@14.0.0: + optionalDependencies: + syncpack-darwin-arm64: 14.0.0 + syncpack-darwin-x64: 14.0.0 + syncpack-linux-arm64: 14.0.0 + syncpack-linux-arm64-musl: 14.0.0 + syncpack-linux-x64: 14.0.0 + syncpack-linux-x64-musl: 14.0.0 + syncpack-windows-arm64: 14.0.0 + syncpack-windows-x64: 14.0.0 term-size@2.2.1: {} through@2.3.8: {} - tightrope@0.2.0: {} - tinybench@2.9.0: {} tinycolor2@1.6.0: {} @@ -7270,14 +7070,14 @@ snapshots: dependencies: typescript: 5.9.3 - ts-node@10.9.2(@types/node@25.0.2)(typescript@5.9.3): + ts-node@10.9.2(@types/node@25.3.0)(typescript@5.9.3): dependencies: '@cspotcode/source-map-support': 0.8.1 '@tsconfig/node10': 1.0.12 '@tsconfig/node12': 1.0.11 '@tsconfig/node14': 1.0.3 '@tsconfig/node16': 1.0.4 - '@types/node': 25.0.2 + '@types/node': 25.3.0 acorn: 8.15.0 acorn-walk: 8.3.4 arg: 4.1.3 @@ -7288,38 +7088,36 @@ snapshots: v8-compile-cache-lib: 3.0.1 yn: 3.1.1 - ts-toolbelt@9.6.0: {} - tslib@1.14.1: {} tslib@2.8.1: {} - turbo-darwin-64@2.6.3: + turbo-darwin-64@2.8.10: optional: true - turbo-darwin-arm64@2.6.3: + turbo-darwin-arm64@2.8.10: optional: true - turbo-linux-64@2.6.3: + turbo-linux-64@2.8.10: optional: true - turbo-linux-arm64@2.6.3: + turbo-linux-arm64@2.8.10: optional: true - turbo-windows-64@2.6.3: + turbo-windows-64@2.8.10: optional: true - turbo-windows-arm64@2.6.3: + turbo-windows-arm64@2.8.10: optional: true - turbo@2.6.3: + turbo@2.8.10: optionalDependencies: - turbo-darwin-64: 2.6.3 - turbo-darwin-arm64: 2.6.3 - turbo-linux-64: 2.6.3 - turbo-linux-arm64: 2.6.3 - turbo-windows-64: 2.6.3 - turbo-windows-arm64: 2.6.3 + turbo-darwin-64: 2.8.10 + turbo-darwin-arm64: 2.8.10 + turbo-linux-64: 2.8.10 + turbo-linux-arm64: 2.8.10 + turbo-windows-64: 2.8.10 + turbo-windows-arm64: 2.8.10 type-check@0.4.0: dependencies: @@ -7385,11 +7183,7 @@ snapshots: undefsafe@2.0.5: {} - undici-types@6.21.0: {} - - undici-types@7.16.0: {} - - unicorn-magic@0.3.0: {} + undici-types@7.18.2: {} universalify@0.1.2: {} @@ -7424,8 +7218,6 @@ snapshots: validate-npm-package-name@5.0.1: {} - validate-npm-package-name@6.0.2: {} - viem@2.42.1(typescript@5.9.3)(zod@4.2.0): dependencies: '@noble/curves': 1.9.1 @@ -7443,27 +7235,27 @@ snapshots: - utf-8-validate - zod - vite@7.3.0(@types/node@25.0.2): + vite@7.3.0(@types/node@25.3.0): dependencies: - esbuild: 0.27.1 + esbuild: 0.27.3 fdir: 6.5.0(picomatch@4.0.3) picomatch: 4.0.3 postcss: 8.5.6 rollup: 4.53.4 tinyglobby: 0.2.15 optionalDependencies: - '@types/node': 25.0.2 + '@types/node': 25.3.0 fsevents: 2.3.3 - vitest@4.0.15(@types/node@25.0.2)(happy-dom@20.0.11): + vitest@4.0.18(@types/node@25.3.0)(happy-dom@20.7.0): dependencies: - '@vitest/expect': 4.0.15 - '@vitest/mocker': 4.0.15(vite@7.3.0(@types/node@25.0.2)) - '@vitest/pretty-format': 4.0.15 - '@vitest/runner': 4.0.15 - '@vitest/snapshot': 4.0.15 - '@vitest/spy': 4.0.15 - '@vitest/utils': 4.0.15 + '@vitest/expect': 4.0.18 + '@vitest/mocker': 4.0.18(vite@7.3.0(@types/node@25.3.0)) + '@vitest/pretty-format': 4.0.18 + '@vitest/runner': 4.0.18 + '@vitest/snapshot': 4.0.18 + '@vitest/spy': 4.0.18 + '@vitest/utils': 4.0.18 es-module-lexer: 1.7.0 expect-type: 1.3.0 magic-string: 0.30.21 @@ -7475,11 +7267,11 @@ snapshots: tinyexec: 1.0.2 tinyglobby: 0.2.15 tinyrainbow: 3.0.3 - vite: 7.3.0(@types/node@25.0.2) + vite: 7.3.0(@types/node@25.3.0) why-is-node-running: 2.3.0 optionalDependencies: - '@types/node': 25.0.2 - happy-dom: 20.0.11 + '@types/node': 25.3.0 + happy-dom: 20.7.0 transitivePeerDependencies: - jiti - less diff --git a/repo/eslint-config/CHANGELOG.md b/repo/eslint-config/CHANGELOG.md index ddc6085a88..2df72f2e7a 100644 --- a/repo/eslint-config/CHANGELOG.md +++ b/repo/eslint-config/CHANGELOG.md @@ -1,5 +1,12 @@ # @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 diff --git a/repo/eslint-config/package.json b/repo/eslint-config/package.json index 5625bc6999..9c38b69880 100644 --- a/repo/eslint-config/package.json +++ b/repo/eslint-config/package.json @@ -1,6 +1,6 @@ { "name": "@repo/eslint-config", - "version": "0.0.1-beta.1", + "version": "0.0.1", "type": "module", "private": true, "exports": { diff --git a/repo/typescript-config/CHANGELOG.md b/repo/typescript-config/CHANGELOG.md index 611dc70b2d..3e5ecbabf4 100644 --- a/repo/typescript-config/CHANGELOG.md +++ b/repo/typescript-config/CHANGELOG.md @@ -1,5 +1,12 @@ # @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 diff --git a/repo/typescript-config/package.json b/repo/typescript-config/package.json index cb34e9260e..ed931bce61 100644 --- a/repo/typescript-config/package.json +++ b/repo/typescript-config/package.json @@ -1,6 +1,6 @@ { "name": "@repo/typescript-config", - "version": "0.0.1-beta.1", + "version": "0.0.1", "private": true, "license": "MIT", "publishConfig": { diff --git a/repo/ui/CHANGELOG.md b/repo/ui/CHANGELOG.md index 8994e02948..232f9accb7 100644 --- a/repo/ui/CHANGELOG.md +++ b/repo/ui/CHANGELOG.md @@ -1,5 +1,12 @@ # @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 diff --git a/repo/ui/eslint.config.mjs b/repo/ui/eslint.config.js similarity index 100% rename from repo/ui/eslint.config.mjs rename to repo/ui/eslint.config.js diff --git a/repo/ui/package.json b/repo/ui/package.json index 6b380862e7..f0045e54d0 100644 --- a/repo/ui/package.json +++ b/repo/ui/package.json @@ -1,7 +1,8 @@ { "name": "@repo/ui", - "version": "0.0.1-beta.1", + "version": "0.0.1", "private": true, + "type": "module", "exports": { "./button": "./src/button.tsx", "./card": "./src/card.tsx", @@ -16,7 +17,7 @@ "@repo/eslint-config": "workspace:^", "@repo/typescript-config": "workspace:^", "@turbo/gen": "^1.13.4", - "@types/node": "^25.0.2", + "@types/node": "^25.3.0", "@types/react": "^19.2.7", "@types/react-dom": "^19.2.3", "typescript": "^5.9.3" diff --git a/turbo.json b/turbo.json index fcf0462701..139d2ea571 100644 --- a/turbo.json +++ b/turbo.json @@ -1,5 +1,5 @@ { - "$schema": "https://turbo.build/schema.json", + "$schema": "https://v2-8-10.turborepo.dev/schema.json", "ui": "tui", "tasks": { "build": { @@ -26,6 +26,7 @@ "repo/**/*.tsx", "test/**/*.ts", "test/**/*.tsx", + "test/**/*.js", "test/**/*.mjs" ], "outputs": []