customConnection, which creates a WalletConnectionStore backed by a vanilla Zustand store. The previous customHook and walletConnectionProvider fields are no longer part of the provider contract.
The chain factory still supplies its normal balance, gas, transfer, gasless, and other resolvers. customConnection replaces only its connection state.
Choose the integration shape
- You read your wallet SDK through React hooks: return a
WalletConnectionProvidersnapshot from a custom hook, bridge it withcreateReactHookConnectionAdapter, and render the adapter’sHydrator. - Your wallet SDK exposes an external store or event API: create the vanilla Zustand store directly and return a
WalletConnectionStore. No hydrator is needed.
Adapt a React hook
1. Install the eager chain package
Custom connections are configured on a chain’s eager provider factory. Import that factory from its chain package, not a lazy descriptor from@layerswap/wallets:
@layerswap/wallet-starknet with the package for the chain family you are adapting.
2. Return the current connection snapshot
The hook translates third-party wallet state intoWalletConnectionProvider. Both files below belong to the integrating application: the first adapts Dynamic’s React state, and the second turns a generic Dynamic wallet into the concrete Starknet account required by Layerswap.
- Wallet hook
- Account adapter
useCustomStarknet.ts
createReactHookConnectionAdapter creates one singleton store per adapter. Create the adapter once, outside a component. Two Widget instances that use the same adapter also share that connection store and its state.
Dynamic’s getWalletAccount() is asynchronous. Resolve it before assigning metadata.starknetAccount; do not assign the promise itself. The resulting account supplies the estimateInvokeFee and execute methods used by the default Starknet gas and transfer resolvers.
If your wallet SDK does not expose a compatible Starknet account, leave asSourceSupportedNetworks and withdrawalSupportedNetworks empty so the Widget does not offer a signing flow it cannot complete, or replace the default gas and transfer resolvers.
ready should stay false until the third-party SDK can service connection requests. Use connectedWallets: undefined while restoring an unknown session and connectedWallets: [] once initialization has finished with no connected wallet. The Widget shows a restoring state while the value is undefined; if the SDK’s account resolution never settles, the wallet UI remains blocked, so consider applying a timeout.
This sample marks only the first resolved wallet as isActive and does not implement switchAccount. The Widget therefore cannot switch between multiple Dynamic wallets. Implement switchAccount and keep isActive and activeWallet synchronized if your integration needs account switching.
3. Render the hydrator
The adapter’sHydrator runs the hook and mirrors each snapshot into the external store. It must be inside both the third-party SDK provider and LayerswapProvider, because it consumes both contexts. Its props also require a network adapter.
walletNetworkAdapter.ts
networkAdapter is required by the Hydrator contract, but the Widget does not currently export the adapter it uses internally. This host-side copy mirrors the Widget’s NetworkWithTokens adapter and derives its type through WalletConnectionProviderProps, so the host does not need a direct @layerswap/wallet-core dependency for the adapter type.CustomStarknetHydrator.tsx
useLayoutEffect internally; in the Next.js Pages Router, load it with next/dynamic and ssr: false to avoid the server-render warning.
4. Pass customConnection to the chain factory
Layerswap.tsx
walletProviders array stable. Recreating them during render tears down and recreates connection state.
createReactHookConnectionAdapter is exported from @layerswap/widget/internal. Keep @layerswap/widget and every @layerswap/wallet-* package on compatible releases when using this advanced integration.External-store wallet managers
If the third-party SDK already exposes subscribe/get-state primitives, create the Zustand store directly. The Widget callsupdateProps when settings networks change and destroy when the connection is removed or the provider unmounts.
./walletManager module below is illustrative and is not provided by Layerswap. Implement its wallets, activeWalletId, ready, connect, disconnect, and subscribe operations—and the mapWallet and supportedNetworkNames helpers—against your SDK. Its connect operation must resolve undefined when the user cancels.
createCustomConnection.ts
customConnection:
Hydrator.
Current contract
WalletConnectionStore
Required connection snapshot fields
Common optional fields include
disconnectWallets, switchAccount, switchChain, availableConnectors, asSourceSupportedNetworks, autofillSupportedNetworks, providerIcon, unsupportedPlatforms, and hideFromList.
Wallet
These are the fields most custom adapters need:
id. icon is now an image string; omit it to let the Widget render its address-based fallback.
Preserve signing support
The connection snapshot tells the Widget which accounts exist; it does not automatically teach the chain package how your third-party SDK signs.- The default Starknet gas and transfer resolvers read
wallet.metadata.starknetAccount. - Other chain packages can use package-owned SDK state or signer adapters. A custom connection must either populate compatible state or replace those resolvers.
balanceProviders,gasProviders, andtransferProviderscan be passed besidecustomConnection. Supplying one of these fields replaces that factory’s default list for the capability.- For EVM integrations backed by wagmi, pass the existing
wagmiConfigso the EVM transfer resolver uses the same signer. In most cases, the dedicated wagmi integration is simpler than a custom connection.
Migrating an older custom provider
Remove the old object-spreading pattern as well; provider constants such as
StarknetProvider are no longer the customization surface.
Related guides
Wallet management
Understand the self-bundled provider architecture.
Wallet providers
Choose the eager chain factory and configure its native credentials.
Sharing your wagmi config
Reuse an app-owned EVM connection without a custom store.
Self-bundled Widget
Install and render the package-based Widget.