Skip to content

Support sidestr chains (gitmark, melchain) #51

Description

@melvincarvalho

Add the sidestr chains as --chain options, starting with gitmark (sidestr:gitmark, the chain made for trails, checkpointed into txbt4) and melchain (sidestr:melchain).

Signing: nothing new

A sidestr chain validates like the BLAKE2b chains: P2TR key-path spends signed with SIGHASH_ALL|SIGHASH_UNIFIED (0x21). So buildTransaction(..., { unified: true }) already produces what they accept, and the entries are close to xbt/txbt4:

gitmark:  { sidestr: 'sidestr:gitmark',  name: 'sidestr gitmark',  hrp: 'gm',  unified: true },
melchain: { sidestr: 'sidestr:melchain', name: 'sidestr melchain', hrp: 'mel', unified: true },

Addresses are the same raw x-only P2TR outputs (5120<x>), under the chain's own prefix.

Backend: the part that differs

gitmark talks to an explorer through two calls: GET {explorer}/tx/:txid (output values and scripts, confirmation) and POST {explorer}/tx (broadcast). A sidestr chain has no Esplora API. It has:

  • a mirror: static chain.json, blocks.json, blocks.dat. Readers validate every block themselves; the mirror is found from the signer's announcement on nostr relays, given chain;
  • relays to send on: a transaction goes out as a kind 23500 event, and producers pick it up. A local producer also takes POST /tx.

Two ways to bridge:

  1. Use the sidestr client (npm, optional dependency, loaded only for sidestr chains): openWallet({ chain }) validates the chain, coins(script) / ex.txs answer the lookups, publish(hex) sends, mined(txid) confirms. This works for anyone with just the chain id.
  2. Esplora-lite endpoints on the producer (GET /tx/:txid, GET /tx/:txid/status): then gitmark needs only a config entry. But only a producer's operator can reach one; the public mirror is static files.

Suggest 1, with a small backend switch around the two explorer calls, and 2 perhaps later as a sidestr feature.

Already tried

An experiment in blocktrails/git-mark (different key chaining, see blocktrails/git-mark#1) built exactly this backend with the sidestr client. Three agent repos made 5 marks across sidestr:melchain and sidestr:gitmark (melchain blocks 625–629, gitmark block 728), each a 1-in, 1-out payment, 112 sats, no data. Things learned:

  • Spend exactly the trail output. An agent's trail genesis address is also its wallet address, so letting a wallet pick coins could spend the wrong one.
  • Sign a fresh tx object once, and check the signature from the serialized bytes. The sidestr stack's interpreter caches sighash midstates per tx object (Sighash cache keyed by tx object returns stale hashes after the tx (or its prevouts) changes bitcoin-desktop/schema#96). gitmark's own unified-sighash.js doesn't need this, but checking from the bytes is still a good idea.
  • Marks land in about 10 s on these chains, so git mark can wait until mined before writing blocktrails.json.

Also

  • --voucher / funding: both chains have faucets (kind 23501 over the relays; the sidestr faucet CLI command). git mark init --chain gitmark could ask the faucet for trail dust instead of needing a voucher.
  • verify: reads through the same backend.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions