{"id":19122975,"url":"https://github.com/digitalbazaar/bedrock-ledger-storage-mongodb","last_synced_at":"2025-10-28T17:49:00.961Z","repository":{"id":48992040,"uuid":"92447128","full_name":"digitalbazaar/bedrock-ledger-storage-mongodb","owner":"digitalbazaar","description":"A storage subsystem for Bedrock ledger.","archived":false,"fork":false,"pushed_at":"2021-07-16T21:20:06.000Z","size":480,"stargazers_count":5,"open_issues_count":7,"forks_count":3,"subscribers_count":11,"default_branch":"main","last_synced_at":"2024-10-12T00:38:52.193Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/digitalbazaar.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-05-25T21:47:02.000Z","updated_at":"2021-07-01T19:30:42.000Z","dependencies_parsed_at":"2022-09-16T07:02:23.314Z","dependency_job_id":null,"html_url":"https://github.com/digitalbazaar/bedrock-ledger-storage-mongodb","commit_stats":null,"previous_names":[],"tags_count":21,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/digitalbazaar%2Fbedrock-ledger-storage-mongodb","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/digitalbazaar%2Fbedrock-ledger-storage-mongodb/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/digitalbazaar%2Fbedrock-ledger-storage-mongodb/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/digitalbazaar%2Fbedrock-ledger-storage-mongodb/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/digitalbazaar","download_url":"https://codeload.github.com/digitalbazaar/bedrock-ledger-storage-mongodb/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223788272,"owners_count":17202944,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-09T05:23:48.773Z","updated_at":"2025-10-28T17:48:55.923Z","avatar_url":"https://github.com/digitalbazaar.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# bedrock-ledger-storage-mongodb\n\n[![Build Status](https://ci.digitalbazaar.com/buildStatus/icon?job=bedrock-ledger-storage-mongodb)](https://ci.digitalbazaar.com/job/bedrock-ledger-storage-mongodb)\n\nA MongoDB ledger storage subsystem for bedrock-ledger that enables the\nstorage and retrieval of ledgers, blocks, events, and operations. The\nrelationship of these objects are shown below:\n\n\u003cimg alt=\"Ledgers contain blocks, blocks contain events\"\n  src=\"https://w3c.github.io/web-ledger/diagrams/blocks.svg\"\n  width=\"450px\"\u003e\n\nThis API exposes the following methods:\n\n* Ledger Storage API\n  * api.add(configEvent, meta, options, callback(err, storage))\n  * api.get(storageId, options, callback(err, storage))\n  * api.remove(storageId, options, callback(err))\n  * api.getLedgerIterator(options, callback(err, iterator))\n* Block Storage API\n  * storage.blocks.add(block, meta, options, callback(err, result))\n  * storage.blocks.get(blockId, options, callback(err, result))\n  * storage.blocks.getAll(blockId, options, callback(err, result))\n  * storage.blocks.getGenesis(options, callback(err, result))\n  * storage.blocks.getLatest(options, callback(err, result))\n  * storage.blocks.update(blockHash, patch, options, callback(err))\n  * storage.blocks.remove(blockHash, options, callback(err))\n* Event Storage API\n  * storage.events.add(event, meta, options, callback(err, result))\n  * storage.events.get(eventHash, options, callback(err, result))\n  * storage.events.getLatestConfig(options, callback(err, result))\n  * storage.events.exists(eventHash, callback(err, result))\n  * storage.events.update(eventHash, patch, options, callback(err))\n  * storage.events.remove(eventHash, options, callback(err))\n* Database Driver API\n  * storage.driver\n\n##  Configuration\n\nConfiguration options and their defaults are documented\nin [lib/config.js](lib/config.js).\n\n## Using the API\n\nThe API in this module is designed to be used by the\n[bedrock-ledger](https://github.com/digitalbazaar/bedrock-ledger/)\nmodule. Do not use this API directly unless you are\ncreating a new ledger node API.\n\n## Ledger API\n\nThe MongoDB ledger storage API is capable of mapping ledger node\nstorage requests to a set of MongoDB collections.\n\n### Creating a Ledger\n\nAdd a new ledger given an initial configuration event,\nconfiguration event metadata, and a set of options.\n\n* configEvent - the initial configuration event for the ledger.\n* meta - the metadata associated with the configuration event.\n* options - a set of options used when creating the ledger.\n* callback(err, storage) - the callback to call when finished.\n  * err - An Error if an error occurred, null otherwise\n  * storage - The storage to use for the purposes of accessing\n    and modifying the ledger.\n\n```javascript\nconst blsMongodb = require('bedrock-ledger-storage-mongodb');\n\nconst configEvent = {\n  '@context': 'https://w3id.org/webledger/v1',\n  type: 'WebLedgerConfigurationEvent',\n  ledgerConfiguration: {\n    '@context': 'https://w3id.org/example-ledger/v1',\n    type: 'WebLedgerConfiguration',\n    ledger: 'urn:uuid:651544dc-c029-420d-9d85-3cecad6fc5c5',\n    consensusMethod: 'Continuity2017',\n    ledgerConfigurationValidator: [],\n    operationValidator: [{\n      type: 'ExampleValidator2017',\n      validatorFilter: [{\n        type: 'ValidatorFilterByType',\n        validatorFilterByType: [\n          'CreateWebLedgerRecord',\n          'UpdateWebLedgerRecord'\n    ]}]}],\n    proof: {\n      type: 'RsaSignature2018',\n      created: '2018-07-01T18:59:52Z',\n      creator: 'did:v1:nym:z2DzQmYumekrfMLh...zSjN5vN8W8g3#authn-key-1',\n      jws: 'eyJhbGciO...ltm5VrsXunx-A '\n    }\n  }\n};\nconst meta = {\n  eventHash: myBlockHasher(configEvent),\n};\nconst options = {};\n\nblsMongodb.add(configEvent, meta, options, (err, storage) =\u003e {\n  if(err) {\n    throw new Error('Failed to create ledger:', err);\n  }\n\n  // use the storage API to read and write to the ledger\n  storage.events.add( /* create new events */ );\n  storage.blocks.add( /* create new blocks */ );\n});\n```\n\n### Retrieving a Ledger\n\nRetrieves a storage API for performing operations on a ledger.\n\n* storageId - a URI identifying the ledger storage.\n* options - a set of options used when retrieving the storage API.\n* callback(err, storage) - the callback to call when finished.\n  * err - An Error if an error occurred, null otherwise\n  * storage - A ledger storage API.\n\n```javascript\nconst blsMongodb = require('bedrock-ledger-storage-mongodb');\n\nconst storageId = 'urn:uuid:eb8c22dc-bde6-4315-92e2-59bd3f3c7d59';\nconst options = {};\n\nblsMongodb.get(storageId, options, (err, storage) =\u003e {\n  storage.events.add( /* write new events to the ledger storage */ );\n  /* ... perform other operations on ledger storage ... */\n});\n```\n\n### Remove a Ledger\n\nRemoves a ledger given a set of options.\n\n* storageId - a URI identifying the ledger storage.\n* options - a set of options used when deleting the ledger.\n* callback(err) - the callback to call when finished.\n  * err - An Error if an error occurred, null otherwise.\n\n```javascript\nconst blsMongodb = require('bedrock-ledger-storage-mongodb');\n\nconst storageId = 'urn:uuid:eb8c22dc-bde6-4315-92e2-59bd3f3c7d59';\nconst options = {};\n\nblsMongodb.remove(storageId, options, err =\u003e {\n  if(err) {\n    throw new Error('Failed to delete ledger:', err);\n  }\n\n  console.log('Ledger deletion successful!');\n});\n```\n\n### Get an Iterator for All Ledgers\n\nGets an iterator that will iterate over all ledger storage\nAPIs in the system. The iterator will return a\nledger storage API that can then be used to operate directly on\nthe ledger storage.\n\n* options - a set of options to use when retrieving the list.\n* callback(err, iterator) - the callback to call when finished.\n  * err - An Error if an error occurred, null otherwise.\n  * iterator - An iterator that returns ledger storage APIs.\n\n```javascript\nconst options = {};\n\nbedrockLedger.getLedgerIterator(options, (err, iterator) =\u003e {\n  if(err) {\n    throw new Error('Failed to fetch iterator for ledgers:', err);\n  }\n\n  for(let storage of iterator) {\n    console.log('Ledger Storage ID:',  storage.id);\n  }\n});\n```\n\n## Blocks API\n\nThe blocks API is used to perform operations on blocks associated with a\nparticular ledger.\n\n### Add a Block\n\nAdds a block in the ledger given a block, metadata associated\nwith the block, and a set of options.\n\n* block - the block to create in the ledger.\n* meta - the metadata associated with the block.\n  * blockHash (required) - a unique identifier for the block that\n      the storage subsystem will use to index the block.\n* options - a set of options used when creating the block.\n* callback(err) - the callback to call when finished.\n  * err - An Error if an error occurred, null otherwise.\n  * result - the result of the operation.\n    * block - the block that was committed to storage.\n    * meta - the metadata that was committed to storage.\n\n```javascript\nconst block = {\n  '@context': 'https://w3id.org/webledger/v1',\n  id: 'urn:uuid:cb868833-14df-40a0-bdd3-544f77e0a612/blocks/2',\n  type: 'WebLedgerEventBlock',\n  event: [/* { ... JSON-LD-OBJECT ... }, ... */],\n  previousBlock: 'urn:uuid:cb868833-14df-40a0-bdd3-544f77e0a612/blocks/1',\n  previousBlockHash: 'zQmVc1MEd4J3X7UDMojVwU7XN2MRYwvA6zR5wYw1eyJgocv',\n  signature: {\n    type: 'RsaSignature2018',\n    created: '2018-05-10T19:47:15Z',\n    creator: 'http://example.com#keys-789',\n    jws: 'JoS27wqa...BFMgXIMw=='\n  }\n};\nconst meta = {\n  blockHash: myBlockHasher(block),\n  pending: true\n};\nconst options = {};\n\nstorage.blocks.add(block, options, (err, result) =\u003e {\n  if(err) {\n    throw new Error('Failed to create the block:', err);\n  }\n\n  console.log('Block creation successful:', result.block, result.meta);\n});\n```\n\n### Get a Consensus Block\n\nGets a block that has achieved consensus and its associated metadata\nfrom the ledger given a blockId.\n\n* blockId - the identifier of the consensus block to fetch from the ledger.\n* options - a set of options used when retrieving the block.\n* callback(err, records) - the callback to call when finished.\n  * err - An Error if an error occurred, null otherwise.\n  * result - the result of the retrieval.\n    * block - the block.\n    * meta - metadata about the block.\n\n```javascript\nconst blockId = 'urn:uuid:cb868833-14df-40a0-bdd3-544f77e0a612/blocks/1';\nconst options = {};\n\nstorage.blocks.get(blockId, options, (err, result) =\u003e {\n  if(err) {\n    throw new Error('Block query failed:', err);\n  }\n\n  console.log('Block:', result.block, result.meta);\n});\n```\n\n### Get all Blocks with ID\n\nGets all blocks matching a given blockId even if they have not\nachieved consensus.\n\n* blockId - the identifier of the block(s) to fetch from the ledger.\n* options - a set of options used when retrieving the block(s).\n   * callback(err, iterator) - the callback to call when finished.\n   *   err - An Error if an error occurred, null otherwise.\n   *   iterator - an iterator for all of the returned blocks.\n\n```javascript\nconst blockId = 'urn:uuid:cb868833-14df-40a0-bdd3-544f77e0a612/blocks/1';\nconst options = {};\n\n// get all blocks with given blockId\nledgerStorage.blocks.getAll(blockId, options, (err, iterator) =\u003e {\n  async.eachSeries(iterator, (promise, callback) =\u003e {\n    promise.then(result =\u003e {\n      console.log('Got block:', result.meta.blockHash);\n      callback();\n    });\n  });\n});\n```\n\n### Get Genesis Block\n\nRetrieves the genesis block from the ledger.\n\n* options - a set of options used when retrieving the genesis block.\n* callback(err, result) - the callback to call when finished.\n  * err - An Error if an error occurred, null otherwise.\n  * result - the genesis block.\n    * genesisBlock - the genesis block and meta.\n\n```javascript\nconst options = {};\n\nstorage.blocks.getGenesis(options, (err, result) =\u003e {\n  if(err) {\n    throw new Error('Failed to get genesis block:', err);\n  }\n\n  console.log('Genesis block:', result.genesisBlock);\n});\n```\n\n### Get Latest Blocks\n\nRetrieves the latest events block and the latest configuration\nblock from the ledger.\n\n* options - a set of options used when retrieving the latest blocks.\n* callback(err, result) - the callback to call when finished.\n  * err - An Error if an error occurred, null otherwise.\n  * result - the latest events and configuration blocks.\n    * configurationBlock - the latest configuration block and meta.\n    * eventBlock - the latest event block and meta.\n\n```javascript\nconst options = {};\n\nstorage.blocks.getLatest(options, (err, result) =\u003e {\n  if(err) {\n    throw new Error('Failed to get latest blocks:', err);\n  }\n\n  console.log('Latest config block:', result.configurationBlock);\n  console.log('Latest events block:', result.eventsBlock);\n});\n```\n\n### Update an Existing Block\n\nUpdate an existing block in the ledger given a blockHash,\nan array of patch instructions, and a set of options.\n\n* blockHash - the hash of the block to update.\n* patch - the patch instructions to execute on the block.\n* options - a set of options used when updating the block.\n* callback(err) - the callback to call when finished.\n  * err - An Error if an error occurred, null otherwise.\n\n```javascript\nconst blockHash = 'zQmVc1MEd4J3X7UDMojVwU7XN2MRYwvA6zR5wYw1eyJgocv';\nconst patch = [{\n  op: 'unset',\n  changes: {\n    meta: {\n      pending: 1\n    }\n  }\n}, {\n  op: 'set',\n  changes: {\n    meta: {\n      consensus: Date.now()\n    }\n  }\n}, {\n  op: 'add',\n  changes: {\n    meta: {\n      someArray: 'c'\n    }\n  }\n}, {\n  op: 'remove',\n  changes: {\n    meta: {\n      someOtherArray: 'z'\n    }\n  }\n}];\n\nconst options = {};\n\nstorage.blocks.update(blockHash, patch, options, (err) =\u003e {\n  if(err) {\n    throw new Error('Block update failed:', err);\n  }\n\n  console.log('Block update succeeded.');\n});\n```\n\n### Remove a Block\n\nRemove a block in the ledger given a block hash and a set of options.\n\n* blockHash - the block with the given hash to delete in the ledger.\n* options - a set of options used when deleting the block.\n* callback(err) - the callback to call when finished.\n  * err - An Error if an error occurred, null otherwise.\n\n```javascript\nconst blockHash = 'zQmVc1MEd4J3X7UDMojVwU7XN2MRYwvA6zR5wYw1eyJgocv';\nconst options = {};\n\nstorage.blocks.remove(blockHash, options, (err) =\u003e {\n  if(err) {\n    throw new Error('Block delete failed:', err);\n  }\n\n  console.log('Successfully deleted block.');\n});\n```\n\n## Events API\n\nThe events API is used to perform operations on events associated with a\nparticular ledger.\n\n### Add an Event\n\nAdds an event to associate with a ledger given an\nevent and a set of options.\n\n* event - the event to associate with a ledger.\n* meta - the metadata that is associated with the event.\n  * eventHash (required) - a unique identifier for the event that\n      the storage subsystem will use to index the event.\n* options - a set of options used when creating the event.\n* callback(err, result) - the callback to call when finished.\n  * err - An Error if an error occurred, null otherwise.\n  * result - the result of the operation.\n    * event - the event that was committed to storage.\n    * meta - the metadata that was committed to storage.\n\n```javascript\nconst event = {\n  '@context': 'https://w3id.org/webledger/v1',\n  type: 'ContinuityMergeEvent',\n  parentHash: [ 'zQmZ3QU3hitUmuZh2KgkKHZJ5Dh7hGvNfLRKJ6cusKCzuRF' ],\n  proof: {\n    type: 'Ed25519Signature2018',\n    created: '2018-08-16T13:25:14Z',\n    creator: 'https://example.com/.../voters/zQmQNQwo...hTvbWxUrGgh9GP',\n    jws: 'eyJhbGciO...RurJsUXZnyxBg'\n  }\n};\n\nconst meta = {\n  eventHash: myEventHasher(event),\n  pending: true\n};\nconst options = {};\n\nstorage.events.add(event, meta, options, (err, result) =\u003e {\n  if(err) {\n    throw new Error('Failed to create the event:', err);\n  }\n\n  console.log('Event creation successful:', result.event, result.meta);\n});\n```\n\n### Get an Event\n\nGets one or more events in the ledger given a query and a set of options.\n\n* eventHash - the identifier of the event to fetch from storage.\n* options - a set of options used when retrieving the event.\n* callback(err, result) - the callback to call when finished.\n  * err - An Error if an error occurred, null otherwise.\n  * result - the result of the retrieval\n    * event - the event.\n    * meta - metadata about the event.\n\n```javascript\nconst eventHash = 'zQmNVs8dM6sEmyQiFUkqRWXFUjhzp7mCfnPJKK6pWmgr4uJ';\nconst options = {};\n\nstorage.events.get(eventHash, options, (err, result) =\u003e {\n  if(err) {\n    throw new Error('Event retrieval failed:', err);\n  }\n\n  console.log('Event:', result.event, result.meta);\n});\n```\n\n### Determine If an Event Exists\n\nDetermine if one or more events exist given the event hash(es);\n\n* eventHash - a string or array of event hashes.\n* callback(err, result) - the callback to call when finished.\n  * err - An Error if an error occurred, null otherwise.\n  * result - the result of the check: true if all the events exist, false if\n      *any* of the events do not exist.\n\n```javascript\nconst eventHash = 'zQmNVs8dM6sEmyQiFUkqRWXFUjhzp7mCfnPJKK6pWmgr4uJ';\n\nstorage.events.exists(eventHash, (err, result) =\u003e {\n  if(err) {\n    throw new Error('Event retrieval failed:', err);\n  }\n  if(result) {\n    console.log('The event exists.');\n  } else {\n    console.log('The event does not exist.');\n  }\n});\n```\n\n### Get the Latest Config Event\n\nGets the latest configuration event that has consensus.\n\n* options - a set of options used when retrieving the event.\n* callback(err, result) - the callback to call when finished.\n  * err - An Error if an error occurred, null otherwise.\n  * result - the result of the retrieval\n    * event - the event.\n    * meta - metadata about the event.\n\n```javascript\nconst options = {};\n\nstorage.events.getLatestConfig(options, (err, result) =\u003e {\n  if(err) {\n    throw new Error('Config event retrieval failed:' + err);\n  }\n\n  console.log('Latest config event:', result.event, result.meta);\n});\n```\n\n### Update an Existing Event\n\nUpdate an existing event associated with the ledger given\nan eventHash, an array of patch instructions, and a set of options.\n\n* eventHash - the ID of the event to update\n* patch - a list of patch commands for the event\n* options - a set of options used when updating the event.\n* callback(err, result) - the callback to call when finished.\n  * err - An Error if an error occurred, null otherwise.\n  * result - the value of the updated event.\n\n```javascript\nconst eventHash = 'zQmTjnK9iQGrGeEWvv37L63JTmSBiLMpVWx6aD1e1YzDuc5';\nconst patch = [{\n  op: 'delete',\n  changes: {\n    meta: {\n      pending: true\n    }\n  }\n}, {\n  op: 'set',\n  changes: {\n    meta: {\n      block: 'urn:uuid:cb868833-14df-40a0-bdd3-544f77e0a612/blocks/2'\n    }\n  }\n}, {\n  op: 'add',\n  changes: {\n    event: {\n      signature: { /* signature goes here */ }\n    }\n  }\n}];\nconst options = {};\n\nstorage.events.update(eventHash, patch, options, (err) =\u003e {\n  if(err) {\n    throw new Error('Event update failed:', err);\n  }\n\n  console.log('Event update succeeded.');\n});\n```\n\n### Remove an Event\n\nRemove an event associated with the ledger given an event hash and a set\nof options.\n\n* eventHash - the hash of the event to delete.\n* options - a set of options used when deleting the event.\n* callback(err) - the callback to call when finished.\n  * err - An Error if an error occurred, null otherwise.\n\n```javascript\nconst eventHash = 'zQmNVs8dM6sEmyQiFUkqRWXFUjhzp7mCfnPJKK6pWmgr4uJ';\nconst options = {};\n\nstorage.events.remove(eventHash, options, (err) =\u003e {\n  if(err) {\n    throw new Error('Event delete failed:', err);\n  }\n\n  console.log('Successfully deleted event.');\n});\n```\n\n## Raw Driver API\n\nThe raw driver API enables access to the low level database driver.\nUsage of the raw driver to enact database changes is strongly\ndiscouraged as it breaks the storage layer abstraction.\n\n```javascript\nconst mongodbDriver = storage.driver\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdigitalbazaar%2Fbedrock-ledger-storage-mongodb","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdigitalbazaar%2Fbedrock-ledger-storage-mongodb","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdigitalbazaar%2Fbedrock-ledger-storage-mongodb/lists"}