Skip to content

1.3.0

Choose a tag to compare

@dovgopoly dovgopoly released this 09 Oct 19:51
· 6 commits to main since this release
  • Breaking: the wallet derives its keys from a seed of its own, so the same
    mnemonic gives a different user_id and different swap keys. Swaps made
    with an earlier SDK are not listed or restored; finish them with the SDK
    that made them.
  • Breaking: SwapWallet::pubkey and privkey are split into
    source_refund_pubkey/source_refund_privkey and
    dest_claim_pubkey/dest_claim_privkey.
  • Breaking: the driver's Config::trust_unsigned is removed, so restore
    refuses a swap the server holds no signed request for.
  • Breaking: the driver has one swap handle type, Handle, in place of
    Swap, SwapInHandle and SwapOutHandle. It keeps no copy of the swap,
    so record, status, address and claim_invoice read the store and are
    async, and a call meant for the other swap type fails with WrongSwapType.
  • Breaking: the server's status is kept in the swap record as
    server_status, so it survives a restart, and ServerStatus is now the
    status name alone. Updates now also fire when only the server's status
    changes.
  • Breaking: the Destinations methods are async and return a Result;
    an Err fails the call as DriverError::Destination.
  • Breaking: restore_all takes no query. It restores every swap the
    server lists for the wallet that the store lacks.
  • Breaking: ClientError::Header and ClientError::Json carry a message
    instead of the source error, so every error can be cloned.
  • Breaking: amounts in sats serialize as decimal strings, in the API
    types and in the driver's Quote, SwapRecord and Status. The Rust
    fields are unchanged, but a store written before this holds numbers and no
    longer loads; finish or drop those swaps first.
  • Breaking: SwapScript::spend_path reads from an input's witness how it
    spent the swap output: SpendPath::Keypath, Preimage with the verified
    preimage, or Csv. The driver's Spender carries it as path in place of
    preimage and pays_address, and Tx::preimage_at, Tx::pays and
    SwapScript::destination_script are gone.
  • Breaking: a SwapOut's claim is a spend of the opening through the
    keypath or the preimage leaf, which the server's key alone cannot open. It
    used to be any spend paying the claim address.
  • Breaking: the driver's opening, a SwapIn deposit or a SwapOut opening,
    is the oldest output paying exactly the swap's amount, and every other
    output is a stray. Two such outputs used to mean none. Observed::unique
    is Observed::split, which returns the opening and the strays.
  • Breaking: a SwapOut sends its preimage once, at the release gate, then
    claims every pass until a claim of the opening is in a block, rebuilt at the
    current fee rate: by keypath when the server answered with its key, by
    preimage once the opening is at min_confs when it did not. A spend still in
    the mempool is outbid, the server's CSV refund at max_fee_rate, where the
    driver used to wait on it and to resend its own claim unchanged. The
    preimage is marked tried and saved before the request, and any answer
    counts as tried. CoopKey and Spending are one Claiming, Lost is a
    Canceled with its opening, and Config::coop_timeout,
    SwapRecord::committed_at, Action::Commit, Spend::Rebroadcast and
    Spender::tx_hex are gone. A store holding a SwapOut in CoopKey,
    Spending or Lost no longer loads; finish those swaps first.
  • Breaking: a restored SwapOut no longer takes the server's Claimed as
    its preimage having left. It counts the preimage as out only when the
    server's key verifies or a claim of ours on chain shows it, and otherwise
    sends it through the release gate like any other. SwapRecord::preimage
    holds a SwapOut's own preimage once a claim shows it.
  • Breaking: a SwapIn's status is worked out from the chain and the
    server's key and preimage on every pass, and it ends Completed or
    Canceled. Status::Refund is gone, along with the early returns that
    kept a stored Completed or Refund forever. What under the script is the
    user's is the record's funds, read with Handle::funds: one Fund per
    output, Locked, Refundable, Dust, Refunding or Refunded. Every
    pass refunds whatever is Refundable in any status, where strays used to
    come back only in Refund or by hand. Whose a spend is reads its path, and
    a keypath refund is taken only while our refund key is home.
    Handle::refund is a pass with the given destination. Action::Close is
    gone, SwapRecord gains funds and ended_at, and refund_timeout
    counts from a SwapIn's end. Confirming no longer carries matures_at,
    which nothing read. A store holding a SwapIn in Refund no longer loads;
    finish those swaps first.
  • Breaking: ChainClient has a new required method, outspend(txid, vout): the transaction spending an output, mempool included, or None
    while it is unspent. Each pass asks it about the opening and, on a SwapIn,
    each output worth its refund fee, when the address history shows them
    unspent. Only a failure on the opening fails the pass. BitcoinEsplora and
    LiquidEsplora answer it from /tx/:txid/outspend/:vout.
  • Breaking: SwapRecord gains base_fee and service_fee, the server's
    split of send_amount - receive_amount as acceptance checked it. A store
    written before this no longer loads.
  • Breaking: Status::Canceled carries a reason: ServerCanceled with
    the server's error_type and cancel_message, CsvMatured for a SwapIn
    whose deposit's CSV matured with no word from the server, or
    ServerRefunded for a SwapOut the server's CSV refund took. The server's
    cancel is kept in the record as server_cancel from the first pass that
    reads it, so a SwapOut canceled before any opening stays Canceled through
    a pass the server does not answer, where it used to read Funding again.
  • Breaking: a restored swap is Status::Restoring until its first pass,
    the loop's or a step, where it used to read Funding whatever it stood
    at, so a page could show an ended SwapIn's deposit address as open.
    cancel takes it as open, and the server refuses what is past.
  • Breaking: the driver sends the protocol version built into core,
    PROTOCOL_VERSION, the release's major and minor version, where it used to
    send back whatever the server's /v1/info reported. A quote from a server
    on another version fails with Refusal::ProtocolVersion, so the SDK and
    the server have to share a minor version. Quote no longer carries
    protocol_version.
  • Breaking: both crates declare rust-version = "1.91", up from 1.85.
  • Breaking: SwapStore::list returns the stored swap ids instead of the
    records. The driver loads each record on its own, so one that fails to load
    stops only its own swap. It used to stop every pass of run and fail
    restore_all.

Minor

  • A pass whose message or spend fails still saves what it saw and refunds
    what is refundable, then returns the error. A cancel or refund key the
    server could not take used to end the pass before the refund, so with the
    server gone a SwapIn's stray deposit never came back, even past its CSV,
    and Handle::refund failed the same way. Funding's cancel_sent now
    turns true only once the cancel is delivered.
  • A pass whose refund fails after it saved a change still announces that
    change, where the next pass used to see nothing new and never did.
  • The driver's run loop ends on stop, and wait_stopped resolves once it
    has exited; state says where the loop is. Updates end once the driver
    is stopped and drained.
  • Creating or restoring a swap wakes the loop, and a second run is a no-op.
  • PROTOCOL_VERSION is re-exported, and the wasm crate returns it from
    protocolVersion(), for a request built by hand.