SpankPay BOOTY Drop 2: Hub + Client APIs

DOCUMENT FOR HUB/WALLET API

Canonical links: +SpankPay BOOTY Drop 2: CANONICAL URLs 

Contract API spec:

Contract:

Design Patterns

Connext Client vs. Hub Responsibilities

  1. State Validation
  1. Connext client does state validation to determine whether a state is globally valid, in that it can be used to dispute / exit onchain. 
  1. The Hub will first use Connext to do the global validation, but then also run separate validation to determine if the hub wants to accept the state update.
  1. For example, for a proposed exchange update, the client will check that balances are conserved, but the hub will check that it has enough liquidity and like the exchange rate.

Shared code between Client and Hub

  1. Contract types (TypeChain)
  1. Generating state updates:
  const cs = new ChannelState(initialState, isPartyA)) 
  const stateUpdate = cs.chain()
    .deposit(Currency.ETH(1))
    .exchange(69Booty)
    .sign()
  ==> [
    { reason: "deposit", state: { ..., sigA: "..." },
    { reason: "exchange", state: { ..., sigA: "..." },
  ]
  
  // TODO - later, as an optimization, we can have the hub client only sign the *last*
  // state update and the hub would just verify that the chain of updates is legit 
  // instead of checking the signatures on each update
  1. Merkle root inclusion checks + prepping root

Contract uses a reserve fund (ie, hub never transfers ETH)

  • In the course of normal operations, the contract has an ETH and Token balance, tracked with the SpankPay.getHubReserveWei() and SpankPay.getHubReserveTokens() methods.
  • For example, when the hub makes a deposit into a channel, the logic is approximately:
this.totalChannelWei = this.totalChannelWei.sub(depositAmount)
channel.balancesWei[1] = channel.balances[1].add(depositAmount)
  • A separate process will monitor the ETH and Token balances, transferring to/from the smart contract as necessary

Transaction Batching

  1. If the client has to send multiple state updates, it should send them in a batch but as separately signed state updates to avoid roundtrips.
  1. For example, after a user deposit succeeds, the client will create and batch two state updates:
  1. approve deposit → moves the balance from pendingWeiDeposit → weiBalances
  1. offer exchange → transfer weiBalance from user to hub and tokeBalance from hub to user
  1. The success response from the hub should contain its signature on the last proposed state update

On-chain updates and resolving / removing pending fields

Chainsaw will be watching the blockchain for events signalling that an on-chain transaction has resolved any pending fields (for example, if the current state has a pendingDeposits: [0, 1 eth] field, it will be resolved and removed when the user makes an on-chain 1 ETH deposit).

On-chain transactions will trigger a ChannelUpdated event:
event ChannelUpdated(
  indexed address channelId,