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:
- The output types you submitted are the output types you find.
- A data output's
valueequals the value you submitted. - 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
Combine outputs
Carry several outputs, of the same or different types, in one transaction, and read them back without relying on their position.
Build your first machine
Wire an application class, a reader, a writer and a recorder into a running Machine, and watch its state rebuild itself from the records it wrote.