Nasty Pirate Macaw

    TypeScript icon, indicating that this package has built-in type declarations

    0.0.2 • Public • Published


    Library for syncing state from contracts.

    Originally designed for managing state in Svelte Kit Ethers Template, ether-state will query Ethereum contracts with the least amount of calls and event listeners.

    Basic Usage

    import { providers, utils } from 'ethers'
    import { Sync, Trigger } from 'ether-state'
    import type { StateSync } from 'ether-state'
    const IERC20 = new utils.Interface(['function totalSupply() external view returns (uint256)', 'function balanceOf(address) external view returns (uint256)', 'event Transfer(address indexed from, address indexed to, uint256 value)'])
    // Check totalSupply of DAI every block, check balance of every DAI recipient on Transfer event
    const syncs: StateSync[] = [
        trigger: Trigger.BLOCK,
        input: () => [],
        call: {
          target: () => '0x6B175474E89094C44Da98b954EedeAC495271d0F', // DAI contract
          interface: IERC20,
          selector: 'totalSupply'
        output: (totalSupply) => {
          console.log("DAI Total Supply:", utils.formatEther(totalSupply[0]))
        trigger: Trigger.EVENT,
        triggerValue: { // Event filter
          address: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
          topics: [
        input: (log) => {
          const event = IERC20.decodeEventLog("Transfer",, log.topics)
          console.log(`${event.from} sent ${utils.formatEther(event.value)} DAI to ${}`)
          return []
        call: {
          target: () => '0x6B175474E89094C44Da98b954EedeAC495271d0F', // DAI contract
          interface: IERC20,
          selector: 'balanceOf'
        output: (balance) => {
          console.log("Recipents balance is now: ", utils.formatEther(balance[0]), " DAI")
    const provider = providers.getDefaultProvider()
    const sync = new Sync(syncs, provider)



    Takes an array of StateSyncs and manages calling contracts based on their triggers.

    import { Sync, Trigger, StateSync } from 'ether-state'
    import { providers } from 'ethers'
    const provider = providers.getDefaultProvider()
    const stateSyncs: StateSync[] = []
    // Create Sync
    const mySync = new Sync(provider, stateSyncs)
    // Manually trigger contract calls to all StateSyncs with BLOCK trigger
    // Destory Sync, turn off all event listeners

    Create new Sync -Sync.constructor(ethers.providers.Provider, StateSync[])

    Manually Trigger Updates - Sync.pushUpdate(Trigger.TIME | Trigger.BLOCK) Triggers update calls to all StateSyncs with trigger types of either TIME or BLOCK.

    Stop Updates = Sync.destroy() Removes all event listeners and stops all updates


    Type for passing to Syncs.

    type StateSync = {
    	trigger: Trigger,
    	triggerValue?: any
    	input: Function,
    	call: ContractCall,
    	output: Function
    • *trigger - What type of Trigger to call contract
    • triggerValue (Optional) - Used for EVENT or TIME triggers, being an Ethers EventFilter object or interval in milliseconds.
    • input - Function that returns an array of function parameters. Eg ["0x6B175474E89094C44Da98b954EedeAC495271d0F", "5000"]
    • call - See ContractCall
    • output - Callback function that takes first argument as the call return value


    Enum type for specifiying what to trigger a contract call.

    enum Trigger {


    Type that contains interface, selector and target of a call.

    type ContractCall = {
    	target: () => string,
    	interface: Interface,
    	selector: string

    target - A function that returns the target contract address interface - An Ethers Interface type, can be created with new ethers.Interface(ABI) selector - Name of the function, just name like balanceOf or include full selector if needed like balanceOf(address)



      npm i ether-state

      DownloadsWeekly Downloads






      Unpacked Size

      9.07 kB

      Total Files


      Last publish


      • decentralisedtech