Extract Transaction Data from cbor raw (Eternl)

Hello,

I have a cardano submit API running along with my cardano node, I want to control who can use it by catching the Transaction going into it and checking the sender address if it’s in the allowlist or not.

My plan is to have a relay (using Node.js) which will be used as the custom submit API endpoint (in Eternl or Nami), once it gets the TX it decode it and find the sender address or stake key, and check if it’s allowed to decide if it send the TX to the real submit API endpoint or not.

I already have this relay working, but I’m having difficulties trying to decode the transactions that are coming to it.

const app = express();
const RealSubmitEndpoint = 'http://192.168.15.110:16456/api/submit/tx'; // Replace this URL with your own

app.post('/api/submit/tx', (req, res) => {
  // get the raw Transaction from req.body (Content-type:application/cbor)
  // decode the transaction cbor
  // check if the address is allowed
  if(!isAllowed(addr))
    return res.status(403).json({ type: 'error', message: 'Sender Address isn\'t allowed' });
    
  request.post(
    {
      url: RealSubmitEndpoint,
      json: req.body // Include the request body as the payload
    },
    (error, response, body) => {
      if (error || response.statusCode !== 200) {
        return res.status(500).json({ type: 'error', message: error ? error.message : 'Request failed' });
      }

      res.json(body);
    }
  );
  
});

const PORT = process.env.PORT || 5123;
app.listen(PORT, () => console.log(`Listening on port ${PORT}`));

npm has a few cbor library options for serialization cbor - npm but if you want a very user friendly way to deconstruct some CBOR pycardano has very easy to use interface for encoding/decoding cbor using from_cbor() and to_cbor() Serialization — PyCardano documentation

ps. Great idea! Very clever way to whitelist the service without needing IP addresses which are most likely behind NAT.

1 Like

Thank you @map84

I’ve found a similar solution but in node.js @emurgo/cardano-serialization-lib-nodejs - npm
I was able to decode the transaction, but when reviewing the transaction body, the Inputs have only a tx id (the utxo Id I assume) so there isn’t an address in the input.

I assume that you need to query that txin transaction from the blockchain to get the wanted address?

Can Anybody confirm this for me please, I still don’t get the UTXO approach entirely.

My need is to know from a given TX body, which address (addr or stake) sent it, or signed it.

Yes, you need to query db-sync or an API like Blockfrost or Koios to find out the address where the input UTxO comes from. I did something similar more than one year ago in Python, just to test the concept.

Thank you @georgem1976

That’s what I wanted to avoid, since this part of the code will be execute for each TX being sent to this relay Cardano Submit API, checking the dbsync will delay things a bit, and thus ruining the whole point of this which is having TXs going faster than the public nodes.

Can you guys give me any other solutions? that won’t take much time.

Maybe something like the the witness Vkey, I’m not sure if It’s something I can use to identify a TX sender.

Beside anything on the TX body itself, I have a Cardano node running on the same server, is there some cardano-cli commands that I can run and get me what I want quickly beside having to run a dbsync which need more resources?

My last resort (if I didn’t go the Dbsync way) is just to look for the address in the outputs, since the sender address will also be present in the output (UTXO remanings)

I think you will find that a short delay looking up the address wont be the biggest limiting factor - having a relay network that connects to a large number of high probability block-producers is one of the most important factors getting transactions on chain quickly. You will most likely want multiple interconnected relays with multiple submit api end-points… getting your tx to the mempool of the next node producing the block can take a while… Verifying vkeys sounds like a good approach for whitelisting but I haven’t tested anything like this myself… looking for a change-address is also a good approach… allow the tx if one of the outputs is in your whitelist… could further discriminate by making sure they always send a very specific amount to themselves. or perhaps even better make them send a specific token you mint to themselves… a token which you mint and control and only give to the whitelisted wallets…