intrepidshape/elm-web3/1.4.4

NOTE: the latest version is 3.0.0

Web3.Transaction

Transaction lifecycle state machine.

Every transaction goes through explicit states. Pattern matching forces you to handle every case — no "transaction failed silently" bugs. The state machine follows the TLA+ spec in proofs/tla/TransactionSpec.tla: terminal states never transition out (except via TxReset), and confirmation counts only increase.

case tx.status of
    Idle ->
        viewBuyButton


    AwaitingSignature ->
        viewSigningSpinner


    Submitted hash ->
        viewPendingWithHash hash


    Confirming hash n ->
        viewConfirming n


    Confirmed receipt ->
        viewSuccess receipt


    Failed err ->
        viewError err


    Rejected ->
        viewRejected

To poll for a receipt after submission, encode a RequestReceipt command:

case tx.status of
    Submitted hash ->
        ( model
        , web3Cmd (Tx.encodeCmd (Tx.RequestReceipt hash "my-tx"))
        )
    _ ->
        ( model, Cmd.none )

To reset a terminal transaction back to Idle:

Tx.update Tx.TxReset tx.status

Related modules: Web3.Contract.Send to build and encode write calls; Web3.Contract.Call to simulate writes before broadcasting.

type Status
= Idle
| AwaitingSignature
| Submitted TxHash
| Confirming TxHash Int
| Confirmed Receipt
| Failed String
| Rejected

Transaction lifecycle status. Cannot be in an invalid state.

type Msg
= TxSubmitted String
| TxConfirmation String Int
| TxConfirmed ReceiptJson
| TxFailed String
| TxRejected
| TxReset
| TxReceiptNotFound String

Messages from the JS transaction port.

type TxCmd
= RequestReceipt TxHash String

Commands to send to the JS transaction port.

type alias Receipt =
{ txHash : TxHash
, blockNumber : Int
, gasUsed : String
, status : Bool
, logs : List EventLog
}

A confirmed transaction receipt, including emitted logs.

type alias EventLog =
{ address : Address
, topics : List String
, data : String
, blockNumber : Int
, logIndex : Int
}

A single log entry emitted during a transaction.

Update transaction status from a port message.

Transitions are guarded to match the TLA+ GuardedNext specification:

  • Terminal states (Confirmed, Failed, Rejected) never transition out, except via TxReset.
  • TxSubmitted is only accepted from AwaitingSignature.
  • TxConfirmation is only accepted from Submitted or Confirming.
  • TxFailed is accepted from any non-terminal state.
  • TxRejected from AwaitingSignature → Rejected; from Submitted/Confirming → Failed.
  • TxReset from any terminal state → Idle; from non-terminal states → no-op.
  • TxReceiptNotFound is a no-op; the app can schedule another RequestReceipt.
isTerminal : Status -> Bool

Is this status terminal (no more updates expected)?

isPending : Status -> Bool

Is this status still pending?

transactionConfirmations : Int -> Receipt -> Int

Number of confirmations for a confirmed transaction given the current block number.

encodeCmd : TxCmd -> Value

Encode a TxCmd for the JS port.

decoder : Decoder Msg

Decode transaction messages from JS port.

parseReceiptEvents : List (EventLog -> Maybe a) -> Receipt -> List a

Apply a list of event decoders to the logs in a receipt, collecting all successfully decoded events.

type MyEvent
    = Transfer { from : Address, to : Address, amount : BigInt }
    | Approval { owner : Address, spender : Address, amount : BigInt }


decodeTransfer : EventLog -> Maybe MyEvent
decodeTransfer log =
    -- match topic[0] to Transfer signature, then decode
    ...


events : List MyEvent
events =
    parseReceiptEvents [ decodeTransfer, decodeApproval ] receipt