TIL: Attaching IPFS folder to a Stellar Account

A Stellar account can have arbitrary data associated with it through Data Entries. Don’t abuse it though. Each entry adds to the minimum balance needed on the account.

A lot of blockchains use IPFS to store documents in a verifiable way.

But I thought, wouldn’t it be great if people could see documents

associated with a Stellar account for visibility and verifiability?

Here’s how to do it:

// Here we are setting up our imports. We will need Stellar and IPFS.
// We will also use Axios to talk to Stellar's Friendbot to fund our test account
const StellarSDK = require('stellar-sdk')
const ipfsClient = require('ipfs-http-client')
const ipfs = ipfsClient()
const axios = require('axios')

// We are on the test network
const server = new StellarSDK.Server('https://horizon-testnet.stellar.org')
StellarSDK.Network.useTestNetwork()

/**
 * Creates a Stellar Account on the test network,
 * Funds it with friendbot,
 * Creates a folder in IPFS, and
 * Adds that folder the accounts data
 * Returns the created account's keypair
 */
async function createAccount() {
  // Create a public/secret keypair
  // This will be what we will use to create the Stellar account
  const pair = StellarSDK.Keypair.random()

  //Fund with friendbot to make it an actual account, passing it the public key
  await axios.get(`https://friendbot.stellar.org?addr=${pair.publicKey()}`)

  // Get the account from Stellar. Load it for use
  const account = await server.loadAccount(pair.publicKey())

  //Our directory in IPFS will begin with the public key name
  const docsDirectory = `/${pair.publicKey()}`

  //Using the IPFS Files API, we can create folders just as we would in a Unix environment
  await ipfs.files.mkdir(docsDirectory)

  //Add the directory to our created account's data
  const transaction = new StellarSDK.TransactionBuilder(account)
    .addOperation(
      StellarSDK.Operation.manageData({
        name: 'docs',
        value: docsDirectory,
      })
    )
    .build()

  //Sign and submit the transaction
  transaction.sign(pair)
  await server.submitTransaction(transaction)

  // Return the keypair
  return pair
}

Now, let’s show how to get the information back.

// We call our function above and return the keypair of the created account
const pair = await createAccount()

// We get the actual account from Stellar
const account = await server.loadAccount(pair.publicKey())

// We get the data we stored on the Stellar account using
// the key we stored it with
const keyValuePair = await account.data({key: 'docs'})

// our ipfs folder name. Value will be in base64 for we have to decode it
const docsFolder = Buffer.from(keyValuePair.value, 'base64').toString()

// If the folder had documents in it, we can use the IPFS Files API to list them
ipfs.files.ls(docsFolder, function (err, files) {
  files.forEach((file) => {
    console.log(file.name)
  })
})

Attaching the hash to the folder in IPFS makes it so you can add items to it without having to update the value in the data entry every time something is added to it.

We share what we’ve learned on the Revelry blog.

Scroll down this page and Subscribe to Revelry, and we’l let you know when the next post is published! Or, leave a comment and let’s chat more about Stellar accounts.

More Posts by Bryan Joseph: