mintBlue
GuidesTransactions

Read a record back

Fetch a transaction by its id, decrypt the outputs your account is entitled to read, recover a stored file, and walk a project's history.

Reading is the half of the job that proves the other half. A transaction id returned by createTransaction says the call succeeded. Fetching the record and getting your value back says the record is right.

Fetch one transaction

getTransaction takes a transaction id. With parse: true the client resolves the outputs and decrypts what your account holds keys for, so you get objects rather than bytes.

const { Mintblue } = require('@mintblue/sdk');

async function main() {
  const client = await Mintblue.create({
    token: process.env.MINTBLUE_SDK_TOKEN,
  });

  const transaction = await client.getTransaction({
    txid: process.env.TXID,
    parse: true,
  });

  for (const output of transaction.outputs) {
    console.log(output.type);
  }
}

main();

Decryption happens locally. The keys were unwrapped into memory when Mintblue.create ran, and no secret is passed into the call.

With parse: false you get the transaction and its raw form without any output resolution, which is what you want when you are storing the raw transaction somewhere yourself rather than reading its contents.

Take a data output apart

Select by type rather than by position, for the reason in Combine outputs: the array you read back is not guaranteed to be the array you submitted.

const record = transaction.outputs.find((output) => output.type === 'data');

console.log(record.value);

value comes back in the shape you submitted it. If you published a string you get a string; if you published an object you get an object.

Recover a stored file

A file output carries the file name, the content type and the bytes. Writing them out is the whole recovery step.

const fs = require('node:fs');

const file = transaction.outputs.find((output) => output.type === 'file');

fs.writeFileSync(file.value.fileName, file.value.content);
console.log('wrote', file.value.fileName, file.value.contentType);

To confirm the recovered file is the file that went in, compare digests rather than file sizes.

const { utils } = require('@mintblue/sdk');

const digest = await utils.sha256s(file.value.content);
console.log(digest);

Everything above is done by the SDK: the envelope is opened, the content is decrypted with your key and the file is handed back assembled. You do not have to parse the published record by hand to get your file out of it.

Walk a project's history

listTransactions returns the transactions in a project, most usefully with a date range or a limit. It returns the transaction records, not their outputs, so fetch the ones you want.

const transactions = await client.listTransactions({
  project_id: process.env.MINTBLUE_PROJECT_ID,
  order: 'desc',
  limit: 25,
});

for (const summary of transactions) {
  const full = await client.getTransaction({ txid: summary.txid, parse: true });
  const record = full.outputs.find((output) => output.type === 'data');
  if (record) console.log(summary.published_at, record.value);
}

For a process that has to keep up with a project rather than scan it, transactionsAfterTxid takes the last transaction id you handled and returns what has arrived since. That is the read pattern a Machine automates: it holds the position for you and dispatches each new record into your application.

Check it worked

You have read a record back correctly when three things hold:

  1. The output types you submitted are the output types you find.
  2. A data output's value equals the value you submitted.
  3. A recovered file's digest equals the digest of the original file.

The third is the strict one, and it is the only one that catches a file that came back the right size and the wrong bytes.

Next

On this page