by shoegazer

This is an outline of the design for the L2 tBTC SDK off-chain Relayer based on this specification provided by the tbtc team. That specification is required reading as the below design is just outlining how we’ll implement the relayer specification.

Unknown Gravity is contracted to do this work for Arbitrum based on this design. We aspire to have the relayer built so that it can be used for other L2 native minting without modification.

Top-Level Decisions

Implementation Details

Untitled

The off-chain relayer should model a funded (i.e. having a transaction on BTC) deposit as (pseudocode):

type Deposit = {
   id: string
   txHash: string
   outputIndex: number
   receipt: {
       depositor: string
       blindingFactor: string
       walletPublicKeyHash: string
       refundPublicKeyHash: string
       refundLocktime: string
       extraData: string
   }
   owner: string
   status: "QUEUED" | "INITIALIZED" | "FINALIZED" | "CANCELLED"
}
Specific fields are:

id : A unique identifier of the deposit, e.g. uuid4
txHash: Hash of the BTC transaction that funds the deposit
outputIndex: Index of the specific BTC transaction output that funds the deposit
receipt: Deposit receipt generated by Typescript SDK upon native minting start
owner: Address of the deposit owner on the L2/side chain. This is the address that will obtain minted TBTC token on L2/side chain.
status: Current status of the deposit. Specific statuses are:
QUEUED : A deposit was queued by the relayer for initialization
INITIALIZED : The deposit was initialized in the on-chain L1BitcoinDepositor contract
FINALIZED : The deposit was finalized in the on-chain L1BitcoinDepositor contract
CANCELLED : A deposit spent more than X hours in QUEUED state and was not initialized

The relayer will listen for the DepositInitialized event on L2BitcoinDepositor. Upon receiving the event, the relayer will:

  1. Validate the deposit data and make sure the deposit funding transaction (txHash and outputIndex) are present in the BTC mempool
  2. Store the deposit in persistent storage and set the appropriate status by checking L1BitcoinDepositor.deposits: • QUEUED if the deposit has not been initialized in L1BitcoinDepositor yet (i.e. is unknown) • INITIALIZED if the deposit has been already initialized in L1BitcoinDepositor (corner case when deposit was initialized outside the relayer or by another relayer)

Internal Tasks