agw-svelte Svelte Themes

Agw Svelte

svelte implementation of the abstract global wallet

@abashoverse/agw-svelte

Svelte bindings for Abstract Global Wallet (AGW)

Svelte-native SDK for integrating the Abstract Global Wallet into your Svelte applications. Built on top of @abstract-foundation/agw-client with reactive Svelte stores and components.

Features

  • Reactive Stores: First-class Svelte store support for wallet state
  • Svelte 5 Ready: Built with Svelte 5 runes while maintaining Svelte 4 compatibility
  • Type-Safe: Full TypeScript support with comprehensive type definitions
  • Gas Sponsorship: Built-in support for sponsored transactions via paymasters
  • Session Keys: Manage session keys for delegated transaction signing
  • SSR Compatible: Safe to use in SvelteKit applications
  • Lightweight: Minimal bundle size leveraging framework-agnostic agw-client

Installation

Choose your preferred package manager:

npm:

npm install @abashoverse/agw-svelte

pnpm:

pnpm add @abashoverse/agw-svelte

yarn:

yarn add @abashoverse/agw-svelte

bun:

bun add @abashoverse/agw-svelte

Peer Dependencies

The following peer dependencies are required:

npm:

npm install svelte viem @abstract-foundation/agw-client @wagmi/core

pnpm:

pnpm add svelte viem @abstract-foundation/agw-client @wagmi/core

yarn:

yarn add svelte viem @abstract-foundation/agw-client @wagmi/core

bun:

bun add svelte viem @abstract-foundation/agw-client @wagmi/core

Quick Start

1. Wrap Your App with AbstractProvider

<!-- +layout.svelte -->
<script>
  import { AbstractProvider } from '@abashoverse/agw-svelte';
</script>

<AbstractProvider config={{ testnet: true }}>
  <slot />
</AbstractProvider>

2. Use the ConnectButton Component

<!-- +page.svelte -->
<script>
  import { ConnectButton, isConnected, address } from '@abashoverse/agw-svelte';
</script>

<ConnectButton />

{#if $isConnected}
  <p>Connected: {$address}</p>
{/if}

3. Perform Sponsored Contract Writes

<script>
  import {
    createWriteContractSponsored,
    address,
    isConnected,
  } from '@abashoverse/agw-svelte';
  
  const { subscribe, writeContractSponsored } = createWriteContractSponsored();
  
  let writeState;
  subscribe((s) => (writeState = s));
  
  const NFT_CONTRACT = '0xC4822AbB9F05646A9Ce44EFa6dDcda0Bf45595AA';
  const NFT_ABI = [
    {
      inputs: [
        { name: 'to', type: 'address' },
        { name: 'amount', type: 'uint256' },
      ],
      name: 'mint',
      outputs: [],
      stateMutability: 'nonpayable',
      type: 'function',
    },
  ];
  
  async function mintNFT() {
    try {
      const hash = await writeContractSponsored({
        address: NFT_CONTRACT,
        abi: NFT_ABI,
        functionName: 'mint',
        args: [$address, BigInt(1)],
      });
      
      console.log('Transaction hash:', hash);
    } catch (error) {
      console.error('Mint failed:', error);
    }
  }
</script>

{#if $isConnected}
  <button onclick={mintNFT} disabled={writeState?.isPending}>
    {writeState?.isPending ? 'Minting...' : 'Mint NFT'}
  </button>
  
  {#if writeState?.isSuccess}
    <p>Success! Hash: {writeState.data.hash}</p>
  {/if}
  
  {#if writeState?.error}
    <p>Error: {writeState.error.message}</p>
  {/if}
{/if}

API Reference

Components

<AbstractProvider>

Context provider that initializes AGW configuration.

Props:

  • config: AGWSvelteConfig - Configuration object
<AbstractProvider config={{ testnet: true }}>
  <!-- Your app -->
</AbstractProvider>

Config Options:

interface AGWSvelteConfig {
  /** The blockchain chain to use (optional, defaults to abstract/abstractTestnet) */
  chain?: Chain;
  /** Transport to use (optional, defaults to http()) */
  transport?: Transport;
  /** Whether to use testnet (default: false) */
  testnet?: boolean;
}

<ConnectButton>

Pre-styled button component for connecting/disconnecting wallet.

<ConnectButton />

Stores

All stores follow the standard Svelte store contract and can be subscribed to with $.

Account Stores

// Connection state
$isConnected: boolean
$address: Address | undefined
$chainId: number | undefined
$isConnecting: boolean
$isDisconnected: boolean
$account: GetAccountReturnType

AbstractClient Stores

// AGW client instance and state
$abstractClient: AbstractClient | null
$isAbstractClientLoading: boolean
$abstractClientError: Error | null

Signer Stores

// Signer account and client
$signerAccount: Account | null
$signerClient: WalletClient | null

Session Stores

// Session key management
$sessions: SessionConfig[]
$isCreatingSession: boolean
$isRevokingSession: boolean
$sessionError: Error | null

Actions

createLoginWithAbstract(wagmiConfig)

Creates login/logout handlers.

const { login, logout, isLoggingIn } = createLoginWithAbstract(wagmiConfig);

await login();  // Connect wallet
await logout(); // Disconnect wallet

createWriteContractSponsored()

Creates a sponsored contract write handler.

const { subscribe, writeContractSponsored, reset } = createWriteContractSponsored();

const hash = await writeContractSponsored({
  address: '0x...',
  abi: [...],
  functionName: 'transfer',
  args: [recipient, amount],
  paymaster: '0x...', // Optional, defaults to Abstract paymaster
});

Parameters:

interface WriteContractSponsoredParams {
  address: Address;              // Contract address
  abi: Abi;                       // Contract ABI
  functionName: string;           // Function to call
  args?: unknown[];               // Function arguments
  paymaster?: Address;            // Paymaster address
  paymasterInput?: Hash;          // Paymaster input data
  value?: bigint;                 // ETH value to send
  gas?: bigint;                   // Gas limit
}

createSendTransaction()

Creates a transaction sender.

const { subscribe, sendTransaction, reset } = createSendTransaction();

const hash = await sendTransaction({
  to: '0x...',
  value: parseEther('0.1'),
  data: '0x...',
});

Session Management

import { sessionStore } from '@abashoverse/agw-svelte';

// Create a session
await sessionStore.create({
  sessionKeyAddress: '0x...',
  allowedContracts: ['0x...'],
  expiresAt: BigInt(Date.now() + 86400000), // 24 hours
});

// Revoke sessions
await sessionStore.revoke(['0xsessionhash...']);

TypeScript Support

All types are exported from the package:

import type {
  AGWSvelteConfig,
  WriteContractSponsoredParams,
  SessionConfig,
  // ... and more
} from '@abashoverse/agw-svelte';

Examples

Custom Login Button

<script>
  import { getAGWContext } from '@abashoverse/agw-svelte';
  import { createLoginWithAbstract } from '@abashoverse/agw-svelte';
  import { isConnected } from '@abashoverse/agw-svelte';
  
  const { wagmiConfig } = getAGWContext();
  const { login, logout } = createLoginWithAbstract(wagmiConfig);
</script>

<button onclick={$isConnected ? logout : login}>
  {$isConnected ? 'Disconnect' : 'Connect'}
</button>

Send Native Token Transfer

<script>
  import { createSendTransaction, address } from '@abashoverse/agw-svelte';
  import { parseEther } from 'viem';
  
  const { subscribe, sendTransaction } = createSendTransaction();
  let txState;
  subscribe((s) => (txState = s));
  
  async function sendETH() {
    await sendTransaction({
      to: '0xRecipientAddress',
      value: parseEther('0.01'),
    });
  }
</script>

Multiple Contract Interactions

<script>
  import { createWriteContractSponsored } from '@abashoverse/agw-svelte';
  
  const approve = createWriteContractSponsored();
  const swap = createWriteContractSponsored();
  
  async function performSwap() {
    // First approve
    await approve.writeContractSponsored({
      address: TOKEN_ADDRESS,
      abi: ERC20_ABI,
      functionName: 'approve',
      args: [ROUTER_ADDRESS, amount],
    });
    
    // Then swap
    await swap.writeContractSponsored({
      address: ROUTER_ADDRESS,
      abi: ROUTER_ABI,
      functionName: 'swap',
      args: [tokenIn, tokenOut, amount],
    });
  }
</script>

SSR Considerations

This library is safe to use in SvelteKit with SSR. All browser-specific code is properly guarded.

Development

# Install dependencies
npm install

# Build the library
npm run build

# Run tests
npm test

# Type check
npm run check

Architecture

This package is built on top of:

  • @abstract-foundation/agw-client - Framework-agnostic AGW core
  • @wagmi/core - VanillaJS wallet utilities
  • viem - TypeScript Ethereum interface

It provides:

  • Svelte Stores for reactive state management
  • Svelte Components for common UI patterns
  • Actions for wallet interactions and transactions

Documentation

Testing

This library includes comprehensive test coverage (168 tests):

  • Error handling (44 tests)
  • Input validation (66 tests)
  • Configuration utilities (39 tests)
  • General utilities (19 tests)
npm test           # Run all tests
npm run test:watch # Watch mode

License

MIT

Contributing

Contributions are welcome! Please open an issue or PR on GitHub.

Publishing (Maintainers Only)

To publish a new version to npm:

  1. Ensure you're authenticated with npm:

    npm whoami  # Verify you're logged in
    npm login   # If not logged in
    
  2. Update version in package.json:

    npm version patch  # or minor, or major
    
  3. Build and publish:

    npm run package    # Build the package
    npm publish        # Publish to npm (uses --access public from .npmrc)
    
  4. Push the version tag:

    git push && git push --tags
    

Support

For questions and support:

Top categories

Loading Svelte Themes