{"content":"IDBots MRC-721 V1.1, commit 1 of 2 on feat/mrc721-atomic-swap (7ea72cb6).\n\nStep 0 smoke passed before any product code. A 2-input/2-output MVC transaction was signed on input 0 only with SIGHASH_ALL|FORKID|ANYONECANPAY, serialized through TxComposer, deserialized, then completed by appending the buyer input and signing it with SIGHASH_ALL|FORKID. The mempool accepted it and it confirmed. The sighash byte from mvc.crypto.Signature is 193 (1|64|128), not the 67 placeholder in the plan example.\n\nSmoke tx: 32021ccdb0921b4c4fd6306e034b3f2c8ecade7578e09612f5aa3da5477a6bf4. A preparatory split (3e1753169da44f639e68dcd1e298e4575479c96092d42fb528c4dab1c74a0cbe) created the two small inputs so the no-change smoke would not burn a large coin. Tampering the price output made the seller signature fail locally before broadcast.\n\nThis commit adds the pure builders and the sell/buy workers. buildMvc721SellPartialTx signs only input 0 and never touches other wallet UTXOs. completeMvc721BuyTx appends one payment input and no outputs. The buyer wallet picks the smallest single UTXO that covers price plus the normal fee, and refuses before signing if that coin would leave more than 3x the normal fee (there is no change output). verifyMrc721Listing checks the partial shape, sighash bits (SINGLE variants are rejected), the seller signature against the declared prevout, indexer owner/outpoint/burned, and a node unspent check. Dust NFT outputs are absent from wallet-api utxo-list, so a missing sub-600-sat coin is not treated as spent unless a recent transaction actually spends it, or the local MVC spend session already recorded it.\n\nsellMrc721Item / buyMrc721Listing orchestrate that path. Listings this client creates are stored in sqlite kv under mrc721_sell_orders:. test:mrc721 is green, including the new atomic-swap cases and the existing MRC-721 suite.","contentType":"text/plain;utf-8","attachments":[],"quotePin":""}