@sfpro/sdk

How to connect to a GDA pool

Join distribution pools and claim your tokens as a pool member

As a pool member, you need to connect to a GDA pool to start receiving distributions. This guide covers how to join pools and claim accumulated tokens.

Check Pool Membership

First, check if you're already a member and your current units:

import { useReadGdaPool } from "@sfpro/sdk/hook"
import { useAccount } from "wagmi"

const poolAddress = "0x..." // Pool address

function MembershipStatus() {
  const { address } = useAccount()
  const { data: units } = useReadGdaPool({ 
    address: poolAddress, 
    functionName: "getUnits", 
    args: [address!] 
  }) 
  
  return (
    <div>
      {units && units > 0n 
        ? `You have ${units} units in this pool`
        : "You are not a member of this pool"}
    </div>
  )
}
import { gdaPoolAbi } from "@sfpro/sdk/abi"
import { createPublicClient, http } from "viem"
import { mainnet } from "viem/chains"

const client = createPublicClient({
  chain: mainnet,
  transport: http()
})

const poolAddress = "0x..." // Pool address
const memberAddress = "0x..." // Your address

async function checkMembership() {
  const units = await client.readContract({ 
    address: poolAddress, 
    abi: gdaPoolAbi, 
    functionName: "getUnits", 
    args: [memberAddress] 
  }) 
  
  return units > 0n // You're a member if you have units
}
import { readGdaPool } from "@sfpro/sdk/action"
import { createConfig } from "@wagmi/core"
import { http } from "viem"
import { mainnet } from "viem/chains"

const wagmiConfig = createConfig({
  chains: [mainnet],
  transports: {
    [mainnet.id]: http()
  }
})

const poolAddress = "0x..." // Pool address
const memberAddress = "0x..." // Your address

async function checkMembership() {
  const units = await readGdaPool(wagmiConfig, { 
    chainId: mainnet.id, 
    address: poolAddress, 
    functionName: "getUnits", 
    args: [memberAddress] 
  }) 
  
  return units > 0n
}

Connect to Pool

Connect to the pool to enable automatic distribution claims:

import { useWriteGdaForwarder } from "@sfpro/sdk/hook"

const poolAddress = "0x..." // Pool address

function ConnectToPool() {
  const { writeContract: connect } = useWriteGdaForwarder({ 
    functionName: "connectPool", 
    args: [poolAddress, "0x"] 
  }) 
  
  return (
    <button onClick={() => connect?.()}>
      Connect to Pool
    </button>
  )
}
import { gdaForwarderAbi, gdaForwarderAddress } from "@sfpro/sdk/abi"
import { createWalletClient, http } from "viem"
import { mainnet } from "viem/chains"
import { privateKeyToAccount } from "viem/accounts"

const account = privateKeyToAccount(process.env.PRIVATE_KEY as `0x${string}`)
const walletClient = createWalletClient({
  account,
  chain: mainnet,
  transport: http()
})

const poolAddress = "0x..." // Pool address

async function connectToPool() {
  const hash = await walletClient.writeContract({ 
    address: gdaForwarderAddress[mainnet.id], 
    abi: gdaForwarderAbi, 
    functionName: "connectPool", 
    args: [poolAddress, "0x"] 
  }) 
  
  return hash
}
import { writeGdaForwarder } from "@sfpro/sdk/action"
import { createConfig } from "@wagmi/core"
import { createWalletClient, http } from "viem"
import { mainnet } from "viem/chains"
import { privateKeyToAccount } from "viem/accounts"

const account = privateKeyToAccount(process.env.PRIVATE_KEY as `0x${string}`)
const wagmiConfig = createConfig({
  chains: [mainnet],
  client({ chain }) {
    return createWalletClient({
      account,
      chain,
      transport: http(),
    })
  },
})

const poolAddress = "0x..." // Pool address

async function connectToPool() {
  const hash = await writeGdaForwarder(wagmiConfig, { 
    chainId: mainnet.id, 
    functionName: "connectPool", 
    args: [poolAddress, "0x"] 
  }) 
  
  return hash
}

Check Claimable Balance

Check how many tokens you can claim from the pool:

import { useReadGdaPool } from "@sfpro/sdk/hook"
import { useAccount } from "wagmi"
import { formatEther } from "viem"

const poolAddress = "0x..." // Pool address

function ClaimableBalance() {
  const { address } = useAccount()
  const { data: claimable } = useReadGdaPool({ 
    address: poolAddress, 
    functionName: "getClaimableNow", 
    args: [address!] 
  }) 
  
  return (
    <div>
      Claimable: {claimable ? formatEther(claimable) : "0"} tokens
    </div>
  )
}
import { gdaPoolAbi } from "@sfpro/sdk/abi"
import { createPublicClient, http } from "viem"
import { mainnet } from "viem/chains"

const client = createPublicClient({
  chain: mainnet,
  transport: http()
})

const poolAddress = "0x..." // Pool address
const memberAddress = "0x..." // Your address

async function getClaimableBalance() {
  const claimable = await client.readContract({ 
    address: poolAddress, 
    abi: gdaPoolAbi, 
    functionName: "getClaimableNow", 
    args: [memberAddress] 
  }) 
  
  return claimable
}
import { readGdaPool } from "@sfpro/sdk/action"
import { createConfig } from "@wagmi/core"
import { http } from "viem"
import { mainnet } from "viem/chains"

const wagmiConfig = createConfig({
  chains: [mainnet],
  transports: {
    [mainnet.id]: http()
  }
})

const poolAddress = "0x..." // Pool address
const memberAddress = "0x..." // Your address

async function getClaimableBalance() {
  const claimable = await readGdaPool(wagmiConfig, { 
    chainId: mainnet.id, 
    address: poolAddress, 
    functionName: "getClaimableNow", 
    args: [memberAddress] 
  }) 
  
  return claimable
}

Claim Tokens

Manually claim accumulated tokens from the pool:

import { useWriteGdaPool } from "@sfpro/sdk/hook"

const poolAddress = "0x..." // Pool address

function ClaimTokens() {
  const { writeContract: claim } = useWriteGdaPool({ 
    address: poolAddress, 
    functionName: "claimAll", 
  }) 
  
  return (
    <button onClick={() => claim?.()}>
      Claim All Tokens
    </button>
  )
}
import { gdaPoolAbi } from "@sfpro/sdk/abi"
import { createWalletClient, http } from "viem"
import { mainnet } from "viem/chains"
import { privateKeyToAccount } from "viem/accounts"

const account = privateKeyToAccount(process.env.PRIVATE_KEY as `0x${string}`)
const walletClient = createWalletClient({
  account,
  chain: mainnet,
  transport: http()
})

const poolAddress = "0x..." // Pool address

async function claimFromPool() {
  const hash = await walletClient.writeContract({ 
    address: poolAddress, 
    abi: gdaPoolAbi, 
    functionName: "claimAll", 
  }) 
  
  return hash
}
import { writeGdaPool } from "@sfpro/sdk/action"
import { createConfig } from "@wagmi/core"
import { createWalletClient, http } from "viem"
import { mainnet } from "viem/chains"
import { privateKeyToAccount } from "viem/accounts"

const account = privateKeyToAccount(process.env.PRIVATE_KEY as `0x${string}`)
const wagmiConfig = createConfig({
  chains: [mainnet],
  client({ chain }) {
    return createWalletClient({
      account,
      chain,
      transport: http(),
    })
  },
})

const poolAddress = "0x..." // Pool address

async function claimFromPool() {
  const hash = await writeGdaPool(wagmiConfig, { 
    chainId: mainnet.id, 
    address: poolAddress, 
    functionName: "claimAll", 
  }) 
  
  return hash
}

Disconnect from Pool

Stop receiving distributions from a pool:

import { useWriteGdaForwarder } from "@sfpro/sdk/hook"

const poolAddress = "0x..." // Pool address

function DisconnectFromPool() {
  const { writeContract: disconnect } = useWriteGdaForwarder({ 
    functionName: "disconnectPool", 
    args: [poolAddress, "0x"] 
  }) 
  
  return (
    <button onClick={() => disconnect?.()}>
      Disconnect from Pool
    </button>
  )
}
import { gdaForwarderAbi, gdaForwarderAddress } from "@sfpro/sdk/abi"
import { createWalletClient, http } from "viem"
import { mainnet } from "viem/chains"
import { privateKeyToAccount } from "viem/accounts"

const account = privateKeyToAccount(process.env.PRIVATE_KEY as `0x${string}`)
const walletClient = createWalletClient({
  account,
  chain: mainnet,
  transport: http()
})

const poolAddress = "0x..." // Pool address

async function disconnectFromPool() {
  const hash = await walletClient.writeContract({ 
    address: gdaForwarderAddress[mainnet.id], 
    abi: gdaForwarderAbi, 
    functionName: "disconnectPool", 
    args: [poolAddress, "0x"] 
  }) 
  
  return hash
}
import { writeGdaForwarder } from "@sfpro/sdk/action"
import { createConfig } from "@wagmi/core"
import { createWalletClient, http } from "viem"
import { mainnet } from "viem/chains"
import { privateKeyToAccount } from "viem/accounts"

const account = privateKeyToAccount(process.env.PRIVATE_KEY as `0x${string}`)
const wagmiConfig = createConfig({
  chains: [mainnet],
  client({ chain }) {
    return createWalletClient({
      account,
      chain,
      transport: http(),
    })
  },
})

const poolAddress = "0x..." // Pool address

async function disconnectFromPool() {
  const hash = await writeGdaForwarder(wagmiConfig, { 
    chainId: mainnet.id, 
    functionName: "disconnectPool", 
    args: [poolAddress, "0x"] 
  }) 
  
  return hash
}

Complete Member Flow

Here's a complete example of joining and interacting with a pool as a member:

import { 
  useReadGdaPool,
  useWriteGdaForwarder,
  useWriteGdaPool
} from "@sfpro/sdk/hook"
import { useAccount } from "wagmi"
import { formatEther } from "viem"
import { useState } from "react"

const poolAddress = "0x..." as const

function PoolMemberDashboard() {
  const { address } = useAccount()
  const [isConnected, setIsConnected] = useState(false)
  
  // Check membership
  const { data: units } = useReadGdaPool({
    address: poolAddress,
    functionName: "getUnits",
    args: [address!]
  })
  
  // Check claimable balance
  const { data: claimable } = useReadGdaPool({
    address: poolAddress,
    functionName: "getClaimableNow",
    args: [address!]
  })
  
  // Connect to pool
  const { writeContract: connect } = useWriteGdaForwarder({
    functionName: "connectPool",
    args: [poolAddress, "0x"]
  })
  
  // Claim tokens
  const { writeContract: claim } = useWriteGdaPool({
    address: poolAddress,
    functionName: "claimAll"
  })
  
  const handleConnect = async () => {
    await connect?.()
    setIsConnected(true)
  }
  
  const isMember = units && units > 0n
  
  return (
    <div>
      <h2>Pool Member Dashboard</h2>
      
      {isMember ? (
        <>
          <p>Your units: {units.toString()}</p>
          <p>Claimable: {claimable ? formatEther(claimable) : "0"} tokens</p>
          
          {!isConnected && (
            <button onClick={handleConnect}>
              Connect to Pool
            </button>
          )}
          
          {claimable && claimable > 0n && (
            <button onClick={() => claim?.()}>
              Claim {formatEther(claimable)} tokens
            </button>
          )}
        </>
      ) : (
        <p>You are not a member of this pool</p>
      )}
    </div>
  )
}

Key Concepts

  1. Connection: Connecting to a pool enables automatic claiming
  2. Units: Your share of distributions (set by pool admin)
  3. Claiming: Can be done manually or automatically when connected
  4. Disconnection: Stops receiving new distributions but doesn't affect units

Next Steps