@tuwaio/orbit-evm 0.2.22 → 1.0.0-feat-update-alpha.2.addd21d

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -61,6 +61,26 @@ async function switchNetwork(targetChainId: number) {
61
61
  }
62
62
  ```
63
63
 
64
+ ### ERC-4337 Pimlico Bundler Client
65
+
66
+ Instantiate and cache Viem Bundler clients with automated Pimlico URL resolution:
67
+
68
+ ```typescript
69
+ import { createBundlerRpcClient, createPimlicoRpcUrl } from '@tuwaio/orbit-evm';
70
+
71
+ // Generate or retrieve cached Pimlico RPC endpoint
72
+ const rpcUrl = createPimlicoRpcUrl({
73
+ chainId: 11155111,
74
+ apiKey: 'pim_test_key_123',
75
+ });
76
+
77
+ // Retrieve cached or new Viem Bundler Client (with in-memory cache)
78
+ const bundlerClient = createBundlerRpcClient({
79
+ chainId: 11155111,
80
+ apiKey: 'pim_test_key_123',
81
+ });
82
+ ```
83
+
64
84
  ---
65
85
 
66
86
  ## 🔧 API & Module Architecture
@@ -70,6 +90,7 @@ async function switchNetwork(targetChainId: number) {
70
90
  - **Chain Alignment:** `checkAndSwitchChain`.
71
91
  - **Client Factory:** `createViemClient`.
72
92
  - **ENS Resolvers:** `getAddress`, `getAvatar`, `getName`, `isEnsName`.
93
+ - **ERC-4337 Account Abstraction:** `createPimlicoRpcUrl`, `createBundlerRpcClient`, `clearBundlerCache`.
73
94
 
74
95
  ---
75
96
 
package/dist/index.d.mts CHANGED
@@ -1,6 +1,51 @@
1
+ import { HttpTransport, PublicClient, Address, Hex } from 'viem';
2
+ import { BundlerClientConfig, BundlerClient } from 'viem/account-abstraction';
1
3
  import { Chain } from 'viem/chains';
2
4
  import { Config } from '@wagmi/core';
3
- import { PublicClient, Address, Hex } from 'viem';
5
+
6
+ /**
7
+ * @file Utilities for Pimlico and ERC-4337 Bundler client instantiation with local in-memory caching.
8
+ */
9
+
10
+ /**
11
+ * Configuration options for generating Pimlico Bundler RPC URLs.
12
+ */
13
+ interface PimlicoUrlConfig {
14
+ /** Target EVM chain ID (e.g. 1 for Ethereum Mainnet, 11155111 for Sepolia). */
15
+ chainId: number;
16
+ /** Optional Pimlico API key. If omitted, falls back to public RPC or bundlerUrl. */
17
+ apiKey?: string;
18
+ /** Optional explicit custom bundler RPC URL that takes precedence. */
19
+ bundlerUrl?: string;
20
+ }
21
+ /**
22
+ * Optional additional configuration forwarded to Viem's createBundlerClient.
23
+ */
24
+ type BundlerRpcClientConfig = PimlicoUrlConfig & Partial<Omit<BundlerClientConfig<HttpTransport>, 'transport'>>;
25
+ /**
26
+ * Creates and caches a Pimlico RPC URL based on provided configuration.
27
+ *
28
+ * Priority order:
29
+ * 1. Explicit `bundlerUrl` (if provided, returned directly).
30
+ * 2. Dedicated Pimlico endpoint `https://api.pimlico.io/v2/${chainId}/rpc?apikey=${apiKey}` (if apiKey provided).
31
+ * 3. Public community endpoint `https://public.pimlico.io/v2/${chainId}/rpc` (fallback).
32
+ *
33
+ * @param config - The Pimlico URL configuration.
34
+ * @returns The resolved Bundler RPC URL string.
35
+ */
36
+ declare function createPimlicoRpcUrl(config: PimlicoUrlConfig): string;
37
+ /**
38
+ * Creates or retrieves a cached Viem Bundler Client configured for the resolved Pimlico endpoint.
39
+ *
40
+ * @param config - Bundler URL and optional client configuration parameters.
41
+ * @returns Cached or newly instantiated BundlerClient.
42
+ */
43
+ declare function createBundlerRpcClient(config: BundlerRpcClientConfig): BundlerClient<HttpTransport>;
44
+ /**
45
+ * Clears the in-memory cache of Pimlico URLs and Bundler clients.
46
+ * Useful for testing and resetting runtime state.
47
+ */
48
+ declare function clearBundlerCache(): void;
4
49
 
5
50
  /**
6
51
  * Get EVM chain IDs from app chains configuration
@@ -97,4 +142,4 @@ declare const getAddress: (name: string, chains: readonly [Chain, ...Chain[]]) =
97
142
  */
98
143
  declare const isEnsName: (nameOrAddress: string) => boolean;
99
144
 
100
- export { checkAndSwitchChain, createViemClient, getAddress, getAvatar, getEvmChains, getName, isEnsName, isEvmChainList };
145
+ export { type BundlerRpcClientConfig, type PimlicoUrlConfig, checkAndSwitchChain, clearBundlerCache, createBundlerRpcClient, createPimlicoRpcUrl, createViemClient, getAddress, getAvatar, getEvmChains, getName, isEnsName, isEvmChainList };
package/dist/index.d.ts CHANGED
@@ -1,6 +1,51 @@
1
+ import { HttpTransport, PublicClient, Address, Hex } from 'viem';
2
+ import { BundlerClientConfig, BundlerClient } from 'viem/account-abstraction';
1
3
  import { Chain } from 'viem/chains';
2
4
  import { Config } from '@wagmi/core';
3
- import { PublicClient, Address, Hex } from 'viem';
5
+
6
+ /**
7
+ * @file Utilities for Pimlico and ERC-4337 Bundler client instantiation with local in-memory caching.
8
+ */
9
+
10
+ /**
11
+ * Configuration options for generating Pimlico Bundler RPC URLs.
12
+ */
13
+ interface PimlicoUrlConfig {
14
+ /** Target EVM chain ID (e.g. 1 for Ethereum Mainnet, 11155111 for Sepolia). */
15
+ chainId: number;
16
+ /** Optional Pimlico API key. If omitted, falls back to public RPC or bundlerUrl. */
17
+ apiKey?: string;
18
+ /** Optional explicit custom bundler RPC URL that takes precedence. */
19
+ bundlerUrl?: string;
20
+ }
21
+ /**
22
+ * Optional additional configuration forwarded to Viem's createBundlerClient.
23
+ */
24
+ type BundlerRpcClientConfig = PimlicoUrlConfig & Partial<Omit<BundlerClientConfig<HttpTransport>, 'transport'>>;
25
+ /**
26
+ * Creates and caches a Pimlico RPC URL based on provided configuration.
27
+ *
28
+ * Priority order:
29
+ * 1. Explicit `bundlerUrl` (if provided, returned directly).
30
+ * 2. Dedicated Pimlico endpoint `https://api.pimlico.io/v2/${chainId}/rpc?apikey=${apiKey}` (if apiKey provided).
31
+ * 3. Public community endpoint `https://public.pimlico.io/v2/${chainId}/rpc` (fallback).
32
+ *
33
+ * @param config - The Pimlico URL configuration.
34
+ * @returns The resolved Bundler RPC URL string.
35
+ */
36
+ declare function createPimlicoRpcUrl(config: PimlicoUrlConfig): string;
37
+ /**
38
+ * Creates or retrieves a cached Viem Bundler Client configured for the resolved Pimlico endpoint.
39
+ *
40
+ * @param config - Bundler URL and optional client configuration parameters.
41
+ * @returns Cached or newly instantiated BundlerClient.
42
+ */
43
+ declare function createBundlerRpcClient(config: BundlerRpcClientConfig): BundlerClient<HttpTransport>;
44
+ /**
45
+ * Clears the in-memory cache of Pimlico URLs and Bundler clients.
46
+ * Useful for testing and resetting runtime state.
47
+ */
48
+ declare function clearBundlerCache(): void;
4
49
 
5
50
  /**
6
51
  * Get EVM chain IDs from app chains configuration
@@ -97,4 +142,4 @@ declare const getAddress: (name: string, chains: readonly [Chain, ...Chain[]]) =
97
142
  */
98
143
  declare const isEnsName: (nameOrAddress: string) => boolean;
99
144
 
100
- export { checkAndSwitchChain, createViemClient, getAddress, getAvatar, getEvmChains, getName, isEnsName, isEvmChainList };
145
+ export { type BundlerRpcClientConfig, type PimlicoUrlConfig, checkAndSwitchChain, clearBundlerCache, createBundlerRpcClient, createPimlicoRpcUrl, createViemClient, getAddress, getAvatar, getEvmChains, getName, isEnsName, isEvmChainList };
package/dist/index.js CHANGED
@@ -1 +1,2 @@
1
- 'use strict';var core=require('@wagmi/core'),viem=require('viem'),chains=require('viem/chains'),ens=require('viem/ens');function C(e){return e!=null&&typeof e=="number"&&e>0}function E(e){return !e||e.length===0?[]:e.map(r=>r.id).filter(C)}function N(e){return e.length>0&&e.every(r=>typeof r=="number")}async function U(e,r){let{connector:t,chainId:o}=core.getConnection(r);if(t&&o!==e)try{await core.switchChain(r,{chainId:e});}catch(n){throw n.cause?.name==="UserRejectedRequestError"?new Error("User rejected the request to switch network.",{cause:n}):(console.error("Failed to switch network:",n),new Error("An error occurred while switching the network.",{cause:n}))}}var u=new Map;function s(e,r){let t=r.find(n=>n.id===e),o=u.get(e);if(o&&o.chain?.rpcUrls.default.http[0]===t?.rpcUrls.default.http[0])return o;if(t){let n=viem.createPublicClient({chain:t,transport:viem.http()});return u.set(e,n),n}console.warn(`createViemClient: No chain configuration found for chainId ${e}. A client could not be created.`);}var d=new Map,m=new Map,f=new Map,c=e=>{let r=e.find(t=>t.id===chains.mainnet.id);return r?s(chains.mainnet.id,[r]):s(chains.mainnet.id,[chains.mainnet])},D=async(e,r)=>{let t=c(r);if(!t)return null;let o=d.get(e);if(o!==void 0)return o;try{let n=await ens.getEnsName(t,{address:e});return d.set(e,n),n}catch(n){return console.error(`ENS name lookup failed for address ${e}:`,n),null}},G=async(e,r)=>{let t=c(r);if(!t)return null;let o=ens.normalize(e),n=m.get(o);if(n!==void 0)return n;try{let i=await ens.getEnsAvatar(t,{name:o});return m.set(o,i),i}catch(i){return console.error(`ENS avatar lookup failed for name ${e}:`,i),null}},I=async(e,r)=>{let t=c(r);if(!t)return null;let o=ens.normalize(e),n=f.get(o);if(n!==void 0)return n;try{let i=await ens.getEnsAddress(t,{name:o}),l=i?i.toLowerCase():null;return f.set(o,l),l}catch(i){return console.error(`ENS address lookup failed for name ${e}:`,i),null}},J=e=>e.includes(".")&&!viem.isAddress(e);exports.checkAndSwitchChain=U;exports.createViemClient=s;exports.getAddress=I;exports.getAvatar=G;exports.getEvmChains=E;exports.getName=D;exports.isEnsName=J;exports.isEvmChainList=N;
1
+ 'use strict';var viem=require('viem'),accountAbstraction=require('viem/account-abstraction'),core=require('@wagmi/core'),chains=require('viem/chains'),ens=require('viem/ens');var l=new Map,c=new Map;function w(e){return e.bundlerUrl?`custom:${e.bundlerUrl.trim()}`:`${e.chainId}:${e.apiKey?.trim()??"public"}`}function b(e){let n=w(e),i=l.get(n);if(i)return i;let r;return e.bundlerUrl?r=e.bundlerUrl.trim():e.apiKey?r=`https://api.pimlico.io/v2/${e.chainId}/rpc?apikey=${e.apiKey.trim()}`:r=`https://public.pimlico.io/v2/${e.chainId}/rpc`,l.set(n,r),r}function K(e){let n=b(e),i=c.get(n);if(i)return i;let r={...e};delete r.bundlerUrl,delete r.apiKey;let t=accountAbstraction.createBundlerClient({...r,transport:viem.http(n)});return c.set(n,t),t}function M(){l.clear(),c.clear();}function x(e){return e!=null&&typeof e=="number"&&e>0}function S(e){return !e||e.length===0?[]:e.map(n=>n.id).filter(x)}function I(e){return e.length>0&&e.every(n=>typeof n=="number")}async function j(e,n){let{connector:i,chainId:r}=core.getConnection(n);if(i&&r!==e)try{await core.switchChain(n,{chainId:e});}catch(t){throw t?.cause?.name==="UserRejectedRequestError"?new Error("User rejected the request to switch network.",{cause:t}):(console.error("Failed to switch network:",t),new Error("An error occurred while switching the network.",{cause:t}))}}var m=new Map;function s(e,n){let i=n.find(t=>t.id===e),r=m.get(e);if(r&&r.chain?.rpcUrls.default.http[0]===i?.rpcUrls.default.http[0])return r;if(i){let t=viem.createPublicClient({chain:i,transport:viem.http()});return m.set(e,t),t}console.warn(`createViemClient: No chain configuration found for chainId ${e}. A client could not be created.`);}var p=new Map,h=new Map,C=new Map,u=e=>{let n=e.find(i=>i.id===chains.mainnet.id);return n?s(chains.mainnet.id,[n]):s(chains.mainnet.id,[chains.mainnet])},Z=async(e,n)=>{let i=u(n);if(!i)return null;let r=p.get(e);if(r!==void 0)return r;try{let t=await ens.getEnsName(i,{address:e});return p.set(e,t),t}catch(t){return console.error(`ENS name lookup failed for address ${e}:`,t),null}},_=async(e,n)=>{let i=u(n);if(!i)return null;let r=ens.normalize(e),t=h.get(r);if(t!==void 0)return t;try{let o=await ens.getEnsAvatar(i,{name:r});return h.set(r,o),o}catch(o){return console.error(`ENS avatar lookup failed for name ${e}:`,o),null}},ee=async(e,n)=>{let i=u(n);if(!i)return null;let r=ens.normalize(e),t=C.get(r);if(t!==void 0)return t;try{let o=await ens.getEnsAddress(i,{name:r}),d=o?o.toLowerCase():null;return C.set(r,d),d}catch(o){return console.error(`ENS address lookup failed for name ${e}:`,o),null}},re=e=>e.includes(".")&&!viem.isAddress(e);
2
+ exports.checkAndSwitchChain=j;exports.clearBundlerCache=M;exports.createBundlerRpcClient=K;exports.createPimlicoRpcUrl=b;exports.createViemClient=s;exports.getAddress=ee;exports.getAvatar=_;exports.getEvmChains=S;exports.getName=Z;exports.isEnsName=re;exports.isEvmChainList=I;
package/dist/index.mjs CHANGED
@@ -1 +1,2 @@
1
- import {getConnection,switchChain}from'@wagmi/core';import {createPublicClient,http,isAddress}from'viem';import {mainnet}from'viem/chains';import {getEnsName,normalize,getEnsAvatar,getEnsAddress}from'viem/ens';function C(e){return e!=null&&typeof e=="number"&&e>0}function E(e){return !e||e.length===0?[]:e.map(r=>r.id).filter(C)}function N(e){return e.length>0&&e.every(r=>typeof r=="number")}async function U(e,r){let{connector:t,chainId:o}=getConnection(r);if(t&&o!==e)try{await switchChain(r,{chainId:e});}catch(n){throw n.cause?.name==="UserRejectedRequestError"?new Error("User rejected the request to switch network.",{cause:n}):(console.error("Failed to switch network:",n),new Error("An error occurred while switching the network.",{cause:n}))}}var u=new Map;function s(e,r){let t=r.find(n=>n.id===e),o=u.get(e);if(o&&o.chain?.rpcUrls.default.http[0]===t?.rpcUrls.default.http[0])return o;if(t){let n=createPublicClient({chain:t,transport:http()});return u.set(e,n),n}console.warn(`createViemClient: No chain configuration found for chainId ${e}. A client could not be created.`);}var d=new Map,m=new Map,f=new Map,c=e=>{let r=e.find(t=>t.id===mainnet.id);return r?s(mainnet.id,[r]):s(mainnet.id,[mainnet])},D=async(e,r)=>{let t=c(r);if(!t)return null;let o=d.get(e);if(o!==void 0)return o;try{let n=await getEnsName(t,{address:e});return d.set(e,n),n}catch(n){return console.error(`ENS name lookup failed for address ${e}:`,n),null}},G=async(e,r)=>{let t=c(r);if(!t)return null;let o=normalize(e),n=m.get(o);if(n!==void 0)return n;try{let i=await getEnsAvatar(t,{name:o});return m.set(o,i),i}catch(i){return console.error(`ENS avatar lookup failed for name ${e}:`,i),null}},I=async(e,r)=>{let t=c(r);if(!t)return null;let o=normalize(e),n=f.get(o);if(n!==void 0)return n;try{let i=await getEnsAddress(t,{name:o}),l=i?i.toLowerCase():null;return f.set(o,l),l}catch(i){return console.error(`ENS address lookup failed for name ${e}:`,i),null}},J=e=>e.includes(".")&&!isAddress(e);export{U as checkAndSwitchChain,s as createViemClient,I as getAddress,G as getAvatar,E as getEvmChains,D as getName,J as isEnsName,N as isEvmChainList};
1
+ import {http,createPublicClient,isAddress}from'viem';import {createBundlerClient}from'viem/account-abstraction';import {getConnection,switchChain}from'@wagmi/core';import {mainnet}from'viem/chains';import {getEnsName,normalize,getEnsAvatar,getEnsAddress}from'viem/ens';var l=new Map,c=new Map;function w(e){return e.bundlerUrl?`custom:${e.bundlerUrl.trim()}`:`${e.chainId}:${e.apiKey?.trim()??"public"}`}function b(e){let n=w(e),i=l.get(n);if(i)return i;let r;return e.bundlerUrl?r=e.bundlerUrl.trim():e.apiKey?r=`https://api.pimlico.io/v2/${e.chainId}/rpc?apikey=${e.apiKey.trim()}`:r=`https://public.pimlico.io/v2/${e.chainId}/rpc`,l.set(n,r),r}function K(e){let n=b(e),i=c.get(n);if(i)return i;let r={...e};delete r.bundlerUrl,delete r.apiKey;let t=createBundlerClient({...r,transport:http(n)});return c.set(n,t),t}function M(){l.clear(),c.clear();}function x(e){return e!=null&&typeof e=="number"&&e>0}function S(e){return !e||e.length===0?[]:e.map(n=>n.id).filter(x)}function I(e){return e.length>0&&e.every(n=>typeof n=="number")}async function j(e,n){let{connector:i,chainId:r}=getConnection(n);if(i&&r!==e)try{await switchChain(n,{chainId:e});}catch(t){throw t?.cause?.name==="UserRejectedRequestError"?new Error("User rejected the request to switch network.",{cause:t}):(console.error("Failed to switch network:",t),new Error("An error occurred while switching the network.",{cause:t}))}}var m=new Map;function s(e,n){let i=n.find(t=>t.id===e),r=m.get(e);if(r&&r.chain?.rpcUrls.default.http[0]===i?.rpcUrls.default.http[0])return r;if(i){let t=createPublicClient({chain:i,transport:http()});return m.set(e,t),t}console.warn(`createViemClient: No chain configuration found for chainId ${e}. A client could not be created.`);}var p=new Map,h=new Map,C=new Map,u=e=>{let n=e.find(i=>i.id===mainnet.id);return n?s(mainnet.id,[n]):s(mainnet.id,[mainnet])},Z=async(e,n)=>{let i=u(n);if(!i)return null;let r=p.get(e);if(r!==void 0)return r;try{let t=await getEnsName(i,{address:e});return p.set(e,t),t}catch(t){return console.error(`ENS name lookup failed for address ${e}:`,t),null}},_=async(e,n)=>{let i=u(n);if(!i)return null;let r=normalize(e),t=h.get(r);if(t!==void 0)return t;try{let o=await getEnsAvatar(i,{name:r});return h.set(r,o),o}catch(o){return console.error(`ENS avatar lookup failed for name ${e}:`,o),null}},ee=async(e,n)=>{let i=u(n);if(!i)return null;let r=normalize(e),t=C.get(r);if(t!==void 0)return t;try{let o=await getEnsAddress(i,{name:r}),d=o?o.toLowerCase():null;return C.set(r,d),d}catch(o){return console.error(`ENS address lookup failed for name ${e}:`,o),null}},re=e=>e.includes(".")&&!isAddress(e);
2
+ export{j as checkAndSwitchChain,M as clearBundlerCache,K as createBundlerRpcClient,b as createPimlicoRpcUrl,s as createViemClient,ee as getAddress,_ as getAvatar,S as getEvmChains,Z as getName,re as isEnsName,I as isEvmChainList};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tuwaio/orbit-evm",
3
- "version": "0.2.22",
3
+ "version": "1.0.0-feat-update-alpha.2.addd21d",
4
4
  "private": false,
5
5
  "author": "Oleksandr Tkach",
6
6
  "license": "Apache-2.0",
@@ -41,13 +41,14 @@
41
41
  "viem": "2.x.x"
42
42
  },
43
43
  "devDependencies": {
44
- "@wagmi/core": "^3.6.4",
44
+ "@wagmi/core": "^3.6.5",
45
45
  "tsup": "^8.5.1",
46
46
  "typescript": "^6.0.3",
47
- "viem": "^2.55.11"
47
+ "viem": "^2.56.3"
48
48
  },
49
49
  "scripts": {
50
50
  "start": "tsup src/index.ts --watch",
51
- "build": "tsup"
51
+ "build": "tsup",
52
+ "test": "vitest run"
52
53
  }
53
54
  }