@tuwaio/nova-connect 0.10.6 → 0.10.7

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
@@ -11,7 +11,7 @@
11
11
 
12
12
  - **Provider:** `NovaConnectProvider` renders the connect and connected modals and the error toasts of Satellite Connect, gives its UI state to the components through `useNovaConnect`, and merges the `labels` prop with the English defaults. The modals are rendered only when `appChains` or `solanaRPCUrls` is set; a wallet connects to the first EVM chain or the first Solana cluster of these lists.
13
13
  - **Components** (`/components`): `ConnectButton` opens the connect modal, or shows the active wallet (avatar, name, balance and chain when `withBalance` and `withChain` are set) and opens the connected modal. The modal screens (wallet list grouped into installed, popular and custom groups, network selection, connecting state, "about wallets", "get a wallet", address impersonation when `withImpersonated` is set, legal disclaimer, and the "Remember this wallet" checkbox `RememberWallet`) and their parts are exported too. Most components take a `customization` prop with class name functions, handlers and replacement components for their parts.
14
- - **Chains:** EVM and Solana wallets are listed from the Satellite adapters of the store. The chain selector lists `appChains` for EVM wallets and the clusters of `solanaRPCUrls` for Solana wallets, and switches the network through the store. The root entry point imports no EVM or Solana package: importing `/evm` or `/solana` registers the chain helpers of that network and types `appChains` (viem chains) or `solanaRPCUrls` (cluster monikers), so an app installs only the packages of the networks it uses.
14
+ - **Chains:** EVM and Solana wallets are listed from the Satellite adapters of the store. The modals follow the wallet list of the store (`useWalletConnectors`), so a wallet found after a modal opened (an installed EIP-6963 wallet added when wagmi hydrates its config, a Wallet Standard wallet registered later) appears in it; the wallets of an adapter that reports no changes (an older `@tuwaio/satellite-solana`, a custom adapter, a `@tuwaio/satellite-core` without `watchConnectors`) appear at the next render of the modal. The chain selector lists `appChains` for EVM wallets and the clusters of `solanaRPCUrls` for Solana wallets, and switches the network through the store. The root entry point imports no EVM or Solana package: importing `/evm` or `/solana` registers the chain helpers of that network and types `appChains` (viem chains) or `solanaRPCUrls` (cluster monikers), so an app installs only the packages of the networks it uses.
15
15
  - **Transactions:** with the `transactionPool` and `pulsarAdapter` of a [Pulsar](https://pulsar.docs.tuwa.io) store, `NovaConnectProvider` shows the transaction history in the connected modal (rendered by `@tuwaio/nova-transactions`, loaded on demand). `ConnectButton` takes its own `transactionPool` prop to show the status of the latest transaction.
16
16
  - **SIWX:** with the `siwx` prop (a verifier, and optionally `getNonce`, `destroyer` and the message fields), the provider renders `NovaSiwxWatcher`, which asks the connected wallet to sign in with [`@tuwaio/siwx-react`](https://siwx.docs.tuwa.io/packages/siwx-react) once per address and disconnects the wallet when the sign-in is rejected or fails. When the wallet is disconnected, it clears the session and calls `destroyer`; after a page load it keeps the session restored by `@tuwaio/siwx-react` until Satellite Connect has finished reconnecting (`isAutoConnectFinished`). `useNovaSiwx` signs in and out on demand. Do not also pass `siwx` to the Satellite watchers: they would disconnect the wallet on an account change instead of asking the new account to sign in.
17
17
  - **Labels:** English (`defaultLabels`) and Ukrainian (`ukrainianLabels`) labels in `/i18n`; `useNovaConnectLabels` reads them in custom components.
@@ -27,7 +27,7 @@ The package has seven entry points:
27
27
  | --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
28
28
  | `@tuwaio/nova-connect` | `NovaConnectProvider`, `NovaSiwxWatcher`, the hooks, the chain configuration types |
29
29
  | `@tuwaio/nova-connect/components` | `ConnectButton`, the modals and their parts |
30
- | `@tuwaio/nova-connect/hooks` | `useNovaConnect`, `useNovaConnectLabels`, `useNovaSiwx`, balance, chain and name hooks |
30
+ | `@tuwaio/nova-connect/hooks` | `useNovaConnect`, `useNovaConnectLabels`, `useNovaSiwx`, `useWalletConnectors`, balance, chain and name hooks |
31
31
  | `@tuwaio/nova-connect/i18n` | `defaultLabels`, `ukrainianLabels`, `NovaConnectLabels` |
32
32
  | `@tuwaio/nova-connect/satellite` | `SatelliteConnectProvider`, `useSatelliteConnectStore` and the types of `@tuwaio/satellite-react` |
33
33
  | `@tuwaio/nova-connect/evm` | `EVMConnectorsWatcher`, `EVMConnection`, `ConnectorEVM`, `Chain`; registers the EVM chain helpers |
@@ -0,0 +1 @@
1
+ 'use strict';var chunkWAFPT2CO_cjs=require('./chunk-WAFPT2CO.cjs'),chunkEGATOYHY_cjs=require('./chunk-EGATOYHY.cjs'),chunkYJRNNNR6_cjs=require('./chunk-YJRNNNR6.cjs'),utils=require('@tuwaio/nova-core/utils'),orbitCore=require('@tuwaio/orbit-core'),react=require('react'),siwxReact=require('@tuwaio/siwx-react');function Te(e){let{abbreviateSymbols:t=12,maxNameLength:o=30,autoRetry:n=false,retryDelay:a=3e3}=e,r=chunkEGATOYHY_cjs.d(L=>L.activeConnection),c=chunkEGATOYHY_cjs.d(L=>L.getAdapter),i=r?.address,u=r?.connectorType,s=u?c(orbitCore.getAdapterFromConnectorType(u)):null,[d,C]=react.useState(null),[O,p]=react.useState(null),[v,m]=react.useState(false),[A,g]=react.useState(null),N=react.useRef(null),w=react.useRef(null),U=!!(s&&"getName"in s&&typeof s.getName=="function"),F=!!(s&&"getAvatar"in s&&typeof s.getAvatar=="function"),h=react.useCallback(()=>{N.current&&(N.current.abort(),N.current=null),w.current!==null&&(clearTimeout(w.current),w.current=null);},[]),T=react.useCallback(async function L(){if(h(),!i||!s||!U){C(null),p(null),m(false),g(null);return}N.current=new AbortController;let{signal:x}=N.current;m(true),g(null),C(null),p(null);try{if(x.aborted)return;let y=await s.getName?.(i);if(x.aborted)return;if(y&&(C(y),F))try{let S=await s.getAvatar?.(y);x.aborted||p(S??null);}catch(S){console.warn("Failed to fetch avatar:",S),x.aborted||p(null);}}catch(y){if(x.aborted)return;let S=y instanceof Error?y.message:"Failed to fetch name service data";console.error("Failed to fetch name service data:",y),g(S),C(null),p(null),n&&(w.current=setTimeout(()=>{L();},a));}finally{x.aborted||m(false);}},[i,s,U,F,n,a,h]),Z=react.useCallback(()=>{g(null),T();},[T]);react.useEffect(()=>(T(),h),[T,h]),react.useEffect(()=>h,[h]);let ee=d?d.length>o?utils.textCenterEllipsis(d,t,t):d:i?utils.textCenterEllipsis(i,t,t):void 0;return {ensName:d,ensAvatar:O,isLoading:v,ensNameAbbreviated:ee,error:A,retry:Z}}var B=class extends Error{constructor(t="useNovaConnect must be used within NovaConnectProvider"){super(t),this.name="NovaConnectProviderError";}},R=react.createContext(void 0),We=()=>{let e=react.useContext(R);if(!e)throw new B;return e},Ee=()=>react.useContext(R)!==void 0,Pe=()=>react.useContext(R)??null;var ae=react.createContext(chunkWAFPT2CO_cjs.a),j=()=>react.useContext(ae),Ge=e=>j()[e],Ue=e=>{let t=j(),o={};for(let n of e)o[n]=t[n];return o},Fe=(e,t)=>!!e[t]?.trim(),Ve=e=>{let t=j(),n={actions:["connectWallet","disconnect","connecting","connected","tryAgain","back","connect"],states:["success","error","replaced","loading"],accessibility:["chainSelector","closeModal","selectChain","walletControls","openWalletModal"],transactions:["transactionLoading","transactionSuccess","transactionError","transactionReplaced","recent"]}[e],a={};for(let r of n)a[r]=t[r];return a},De=e=>e===chunkWAFPT2CO_cjs.a,Ke=(e,t,o)=>{let n=e[t];return n&&n.trim()?n:o||chunkWAFPT2CO_cjs.a[t]||t.toString()},$e=(e,t)=>{let o={};for(let n of t)o[n]=e[n];return o};function ze(e){let t=chunkEGATOYHY_cjs.d(i=>i.activeConnection),{signIn:o,signOut:n}=siwxReact.useSiwx(),a=react.useCallback(async(i,u)=>{let s=i??t;if(!s?.address||!s?.chainId)throw new Error("[useNovaSiwx] No active connection available.");if(!s.signMessage)throw new Error("[useNovaSiwx] Connection missing signMessage capability.");let d=u??e?.verifier;if(!d)throw new Error("[useNovaSiwx] Verifier callback required to complete SIWX sign in.");let C={address:String(s.address),chainId:s.chainId,signMessage:s.signMessage,isConnected:s.isConnected},O=siwxReact.getSatelliteSiwxFields(C,e);return o({signer:s.signMessage,verifier:d,fields:O})},[t,o,e]),r=e?.destroyer,c=react.useCallback(async()=>{if(n(),r)try{await r();}catch(i){console.warn("[useNovaSiwx] Failed to execute session destroyer on signOut:",i);}},[n,r]);return {signIn:a,signOut:c}}function le(e,t){switch(e){case orbitCore.OrbitAdapter.EVM:return (t.appChains??[]).map(o=>o.id).filter(o=>typeof o=="number");case orbitCore.OrbitAdapter.SOLANA:return t.solanaRPCUrls?Object.keys(t.solanaRPCUrls):[];default:return []}}function _(e){let{connectorType:t,chains:o,...n}=e;if(!t)return console.warn("getChainsListByConnectorType: connectorType is required"),[];let a=orbitCore.getAdapterFromConnectorType(t),r=chunkYJRNNNR6_cjs.b(a);if(r)try{return r.getChains(n,o)}catch(c){console.warn(`getChainsListByConnectorType: the ${a} chain helpers failed:`,c);}return le(a,n)}function tt(e){let t=chunkYJRNNNR6_cjs.b(orbitCore.OrbitAdapter.EVM);return t?t.isChainList(e):e.length>0&&e.every(o=>typeof o=="number")}function nt(e){let t=chunkYJRNNNR6_cjs.b(orbitCore.OrbitAdapter.SOLANA);return t?t.isChainList(e):e.length>0&&e.every(o=>typeof o=="string")}function q(e){if(!e||typeof e!="object"||!("connectedWallet"in e))return;let{connectedWallet:t}=e;if(!t||typeof t!="object"||!("chains"in t))return;let{chains:o}=t;if(Array.isArray(o))return o.filter(n=>typeof n=="string"||typeof n=="number")}var b={[orbitCore.OrbitAdapter.EVM]:1,[orbitCore.OrbitAdapter.SOLANA]:"mainnet",[orbitCore.OrbitAdapter.Starknet]:"0x534e5f4d41494e"};function at({selectedAdapter:e,appChains:t,solanaRPCUrls:o}){switch(e){case orbitCore.OrbitAdapter.EVM:{let n=t?.[0];return n?.id&&typeof n.id=="number"?n.id:(process.env.NODE_ENV==="development"&&!t?.length&&console.warn("getConnectChainId: No EVM chains configured, using Ethereum Mainnet"),b[orbitCore.OrbitAdapter.EVM])}case orbitCore.OrbitAdapter.SOLANA:{if(o&&typeof o=="object"){let n=Object.keys(o);if(n.length>0)return n[0]}return process.env.NODE_ENV==="development"&&!o&&console.warn("getConnectChainId: No Solana RPC URLs configured, using mainnet"),b[orbitCore.OrbitAdapter.SOLANA]}case orbitCore.OrbitAdapter.Starknet:return process.env.NODE_ENV==="development"&&console.info("getConnectChainId: Using default Starknet chain ID"),b[orbitCore.OrbitAdapter.Starknet];default:return process.env.NODE_ENV==="development"&&console.error("getConnectChainId: Unknown adapter:",e),b[orbitCore.OrbitAdapter.EVM]}}function it({selectedAdapter:e,appChains:t,solanaRPCUrls:o}){switch(e){case orbitCore.OrbitAdapter.EVM:{let n=t?.map(a=>a.id).filter(Boolean);return n&&n.length>0?n:[b[orbitCore.OrbitAdapter.EVM]]}case orbitCore.OrbitAdapter.SOLANA:{let n=o?Object.keys(o):[];return n.length>0?n:[b[orbitCore.OrbitAdapter.SOLANA]]}case orbitCore.OrbitAdapter.Starknet:return [b[orbitCore.OrbitAdapter.Starknet]];default:return [b[orbitCore.OrbitAdapter.EVM]]}}function ue(e,t){if(!e||typeof e!="object")return null;let o=e;if(!o.name||typeof o.name!="string")return null;let n;if("icon"in o){let a=o.icon;if(typeof a=="string")n=a;else if(a&&typeof a=="object"&&"toString"in a&&typeof a.toString=="function")try{n=a.toString();}catch{}}return {name:o.name,icon:n,adapter:t,originalConnector:o}}function H({connectors:e,excludeConnectors:t=["injected"]}={connectors:{}}){if(!e||Object.keys(e).length===0)return [];let o=new Set(t.map(r=>orbitCore.formatConnectorName(r))),n=[];Object.entries(e).forEach(([r,c])=>{if(Array.isArray(c)){let i=r;c.forEach(u=>{let s=ue(u,i);if(s){let d=orbitCore.formatConnectorName(s.name);o.has(d)||n.push(s);}});}});let a=new Map;return n.forEach(r=>{let c=orbitCore.formatConnectorName(r.name);a.has(c)||a.set(c,{name:r.name,icon:r.icon,adapters:[],connectors:[]});let i=a.get(c);i.adapters.includes(r.adapter)||i.adapters.push(r.adapter);let u=Object.assign({},r.originalConnector,{adapter:r.adapter});i.connectors.push(u),!i.icon&&r.icon&&(i.icon=r.icon);}),Array.from(a.values()).sort((r,c)=>r.name.localeCompare(c.name,void 0,{sensitivity:"base"}))}function ut(e){return Object.values(e).some(t=>Array.isArray(t)&&t.length>0)}function de(e){try{if(e&&typeof e=="object"&&"adapter"in e)return e.adapter}catch{}}function X(e,t){return de(e)===t}function Ct({connectors:e,selectedAdapter:t}){if(!e||Object.keys(e).length===0)return [];let o=H({connectors:e});return t?o.filter(n=>n.adapters.includes(t)&&n.connectors.some(a=>X(a,t))).map(n=>{let a=n.connectors.filter(r=>X(r,t));return {...n,adapters:[t],connectors:a}}).filter(n=>n.connectors.length>0):o}function mt(e,t){let o=e[t];return Array.isArray(o)&&o.length>0}function Ot({activeConnection:e,appChains:t,solanaRPCUrls:o}){return {chainsList:react.useMemo(()=>_({connectorType:e?e.connectorType:`${orbitCore.OrbitAdapter.EVM}:not-connected`,appChains:t,solanaRPCUrls:o,chains:q(e)}),[e,t,o])}}var be=()=>{},z=new WeakMap,ge=0,ye=e=>{if(e===null||typeof e!="object"&&typeof e!="function")return `=${String(e)}`;let t=z.get(e);return t===void 0&&(t=++ge,z.set(e,t)),String(t)},ve=e=>Object.entries(e??{}).map(([t,o])=>`${t}:${Array.isArray(o)?o.map(ye).join(","):""}`).join(";");function he(e,t,o){let n=0,a=-1,r;return {render:()=>{n+=1;},subscribe:c=>!e||!o?be:(n+=1,o(()=>{n+=1,c();})),getSnapshot:()=>{if(!e)return;if(r&&a===n)return r.connectors;a=n;let c=t(),i=ve(c);return r?.signature!==i&&(r={signature:i,connectors:c}),r.connectors}}}var xe=()=>{};function It({enabled:e=true}={}){let t=chunkEGATOYHY_cjs.d(a=>a.getConnectors),o=chunkEGATOYHY_cjs.d(a=>a.watchConnectors),n=react.useMemo(()=>he(e,t,o),[e,t,o]);return n.render(),react.useSyncExternalStore(n.subscribe,n.getSnapshot,xe)}function Mt(){let[e,t]=react.useState({}),[o,n]=react.useState(false),a=react.useRef(null),r=chunkEGATOYHY_cjs.d(p=>p.activeConnection),c=chunkEGATOYHY_cjs.d(p=>p.getAdapter),i=r?.chainId&&r?.address?`${r.address}-${r.chainId}`:null,u=r?.connectorType?c(orbitCore.getAdapterFromConnectorType(r.connectorType)):null,s=u&&"getBalance"in u&&typeof u.getBalance=="function",d=react.useCallback(async(p=false)=>{if(!r?.address||!u||!r?.chainId||!i||!s){n(false);return}let v=`${i}-${Date.now()}`;if(a.current=v,!p&&e[i]){n(false);return}n(true);try{let m=await u.getBalance(r.address,r.chainId);a.current===v&&t(A=>({...A,[i]:m}));}catch(m){console.error(`Failed to fetch native balance for ${i}:`,m),p&&a.current===v&&t(A=>{let g={...A};return delete g[i],g});}finally{a.current===v&&n(false);}},[r,u,i,s,e]),C=react.useCallback(()=>{d(true);},[d]);return react.useEffect(()=>{i&&s&&!e[i]?d(false):(!i||!s)&&n(false);},[i,s,e,d]),react.useEffect(()=>()=>{a.current=null;},[]),{balance:i&&e[i]||null,isLoading:o,refetch:C}}exports.A=Ot;exports.B=It;exports.C=Mt;exports.a=Te;exports.b=B;exports.c=R;exports.d=We;exports.e=Ee;exports.f=Pe;exports.g=ae;exports.h=j;exports.i=Ge;exports.j=Ue;exports.k=Fe;exports.l=Ve;exports.m=De;exports.n=Ke;exports.o=$e;exports.p=ze;exports.q=_;exports.r=tt;exports.s=nt;exports.t=q;exports.u=at;exports.v=it;exports.w=H;exports.x=ut;exports.y=Ct;exports.z=mt;