bsp-network
Version:
SDK for writing node.js applications to interact with bsp network. This package encapsulates the APIs to connect to a bsp network, submit transactions and perform queries against the ledger.
498 lines (461 loc) • 21.1 kB
JavaScript
/**
* Copyright 2018 IBM All Rights Reserved.
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* <h3>Overview</h3>
*
* <p>This module provides a higher level API for interacting with smart contracts, and is the recommended API for
* client applications to interact with smart contracts deployed to a Hyperledger Fabric blockchain network.</p>
*
* <p>Note that administrative capabilities, such as installing and starting smart contracts, are not currently provided
* by this API. For only specific advanced usage, the lower level <em>fabric-common</em> API can be used. Access to
* related <em>fabric-common</em> objects is provided through the <em>fabric-network</em> API objects.</p>
*
* <p>If migrating a client application from an earlier version of the API, consult the
* [migration tutorial]{@tutorial migration} for details of potentially breaking changes and recommended actions.</p>
*
* <p>[TypeScript]{@link http://www.typescriptlang.org/} definitions are included in this module.</p>
*
* <h3>Getting started</h3>
*
* <p>The entry point used to interact with a Hyperledger Fabric blockchain network is the
* [Gateway]{@link module:fabric-network.Gateway} class. Once instantiated, this long-living object provides a
* reusable connection to a peer within the blockchain network, and enables access to any of the blockchain
* [Networks]{@link module:fabric-network.Network} (channels) for which that peer is a member. This in turn
* provides access to Smart [Contracts]{@link module:fabric-network.Contract} (chaincode) running within that
* blockchain network, and to which [Transactions]{@link module:fabric-network.Transaction} can be
* [submitted]{@link module:fabric-network.Contract#submitTransaction} or queries can be
* [evaluated]{@link module:fabric-network.Contract#evaluateTransaction}.</p>
*
* <p>Private data can be submitted to transactions as [transient]{@link module:fabric-network.Transaction#setTransient}
* data to prevent it from being recorded on the ledger.</p>
*
* Client applications can initiate actions or business processes in response to events emitted by smart contract
* transactions using [smart contract event listeners]{@link module:fabric-network.Contract}. All updates to the ledger
* can be observed using [block event listeners]{@link module:fabric-network.Network}.
*
* @example
* // Obtain the smart contract with which our application wants to interact
* const wallet = await Wallets.newFileSystemWallet(walletDirectoryPath);
* const gatewayOptions: GatewayOptions = {
* identity: 'user@example.org', // Previously imported identity
* wallet,
* };
* const gateway = new Gateway();
* await gateway.connect(commonConnectionProfile, gatewayOptions);
* const network = await gateway.getNetwork(channelName);
* const contract = network.getContract(chaincodeId);
*
* // Submit transactions for the smart contract
* const args = [arg1, arg2];
* const submitResult = await contract.submitTransaction("transactionName", ...args);
*
* // Evaluate queries for the smart contract
* const evalResult = await contract.evaluateTransaction("transactionName", ...args);
*
* // Create and submit transactions for the smart contract with transient data
* const transientResult = await contract.createTransaction(transactionName)
* .setTransient(privateData)
* .submit(arg1, arg2);
*
* @module fabric-network
*/
/**
* A base user identity. Actual identity objects will extend this basic structure with credentials applicable to their
* type. See [X509Identity]{@link module:fabric-network.X509Identity} and
* [HsmX509Identity]{@link module:fabric-network.HsmX509Identity}.
* @typedef {object} Identity
* @memberof module:fabric-network
* @property {string} type The type of the identity.
* @property {string} mspId The member services provider with which this identity is associated.
*/
/**
* Identity described by an X.509 certificate.
* @typedef {object} X509Identity
* @memberof module:fabric-network
* @implements module:fabric-network.Identity
* @property {'X.509'} type The type of the identity.
* @property {string} credentials.certificate Certificate in PEM format.
* @property {string} credentials.privateKey Private key in PEM format.
*/
/**
* Identity described by an X.509 certificate where the private key is stored in a hardware security module.
* To use identities of this type, a suitable [HsmX509Provider]{@link module:fabric-network.HsmX509Provider} must be
* created and added to the identity provider registry of the wallet containing the identity.
* @typedef {object} HsmX509Identity
* @memberof module:fabric-network
* @implements module:fabric-network.Identity
* @property {'HSM-X.509'} type The type of the identity.
* @property {string} credentials.certificate Certificate in PEM format.
*/
/**
* Understands the format of identities of a given type. Converts identity objects to/from the persistent format used
* within wallet stores, and configures the client with a given identity.
* @typedef IdentityProvider
* @memberof module:fabric-network
* @property {string} type The type identifier for identities that this provider understands.
*/
/**
* Options describing how to connect to a hardware security module. Options without default values are mandatory but
* may be be omitted from this object if they are specified through environment variables or external configuration.
* @typedef {object} HsmOptions
* @memberof module:fabric-network
* @property {string} [lib] Path to implementation-specific PKCS#11 library used to interact with the HSM.
* @property {string} [pin] PIN used to access the HSM.
* @property {number} [slot] The hardware slot number where data is stored in the HSM.
* @property {number} [usertype=1] Specify the user type for accessing the HSM.
* @property {boolean} [readwrite=true] True if the session should be read/write; false if read-only.
*/
/**
* Interface for store implementations that provide backing storage for identities in a [Wallet]{@link module:fabric-network.Wallet}.
* @interface WalletStore
* @memberof module:fabric-network
*/
/**
* Remove data associated with a given label.
* @function module:fabric-network.WalletStore#remove
* @async
* @param {string} label A label identifying stored data.
* @returns {Promise<void>}
*/
/**
* Get data associated with a given label.
* @function module:fabric-network.WalletStore#get
* @async
* @param {string} label A label identifying stored data.
* @returns {Promise<Buffer | undefined>} Stored data as a Buffer if it exists; otherwise undefined.
*/
/**
* List the labels for all stored data.
* @function module:fabric-network.WalletStore#list
* @async
* @returns {Promise<string[]>} A list of labels.
*/
/**
* Put data associated with a given label.
* @function module:fabric-network.WalletStore#put
* @async
* @param {string} label A label identifying stored data.
* @param {Buffer} data Data to store.
* @returns {Promise<void>}
*/
/**
* Factory function to obtain transaction event handler instances. Called on every transaction submit.
* @typedef {Function} TxEventHandlerFactory
* @memberof module:fabric-network
* @param {string} transactionId The ID of the transaction being submitted.
* @param {module:fabric-network.Network} network The network on which this transaction is being submitted.
* @returns {module:fabric-network.TxEventHandler} A transaction event handler.
*/
/**
* Handler used to wait for commit events when a transaction is submitted.
* @interface TxEventHandler
* @memberof module:fabric-network
*/
/**
* Resolves when the handler has started listening for transaction commit events. Called after the transaction proposal
* has been accepted and prior to submission of the transaction to the orderer.
* @function module:fabric-network.TxEventHandler#startListening
* @async
* @returns {Promise<void>}
*/
/**
* Resolves (or rejects) when suitable transaction commit events have been received. Called after submission of the
* transaction to the orderer.
* @function module:fabric-network.TxEventHandler#waitForEvents
* @async
* @returns {Promise<void>}
*/
/**
* Called if submission of the transaction to the orderer fails.
* @function module:fabric-network.TxEventHandler#cancelListening
* @returns {void}
*/
/**
* Factory function to obtain query handler instances. Called on every network creation.
* @typedef {Function} QueryHandlerFactory
* @memberof module:fabric-network
* @param {module:fabric-network.Network} network The network on which queries are being evaluated.
* @returns {module:fabric-network.QueryHandler} A query handler.
*/
/**
* Handler used to obtain query results from peers when a transaction is evaluated.
* @interface QueryHandler
* @memberof module:fabric-network
*/
/**
* Called when a transaction is evaluated to obtain query results from suitable network peers.
* @function module:fabric-network.QueryHandler#evaluate
* @async
* @param {module:fabric-network.Query} query Query object that can be used by the handler to send the query to
* specific peers.
* @returns {Promise<Buffer>}
*/
/**
* Used by query handler implementations to evaluate transactions on peers of their choosing.
* @interface Query
* @memberof module:fabric-network
*/
/**
* Get query results from specified peers.
* @function module:fabric-network.Query#evaluate
* @async
* @param {Endorser[]} peers
* @returns {Promise<Array<module:fabric-network.Query~QueryResponse | Error>>}
*/
/**
* @typedef {Object} Query~QueryResponse
* @memberof module:fabric-network
* @property {boolean} isEndorsed True if the proposal was endorsed by the peer.
* @property {number} status The status value from the endorsement. This attriibute will be set by the chaincode.
* @property {Buffer} payload The payload value from the endorsement. This attribute may be considered the query value
* if the proposal was endorsed by the peer.
* @property {string} message The message value from the endorsement. This property contains the error message from
* the peer if it did not endorse the proposal.
*/
/**
* A callback function that will be invoked when either a peer communication error occurs or a transaction commit event
* is received. Only one of the two arguments will have a value for any given invocation.
* @callback CommitListener
* @memberof module:fabric-network
* @param {module:fabric-network.CommitError} [error] Peer communication error.
* @param {module:fabric-network.CommitEvent} [event] Transaction commit event from a specific peer.
*/
/**
* @typedef {Error} CommitError
* @memberof module:fabric-network
* @property {Endorser} peer The peer that raised this error.
*/
/**
* @interface CommitEvent
* @implements {module:fabric-network.TransactionEvent}
* @memberof module:fabric-network
* @property {Endorser} peer The endorsing peer that produced this event.
*/
/**
* A callback function that will be invoked when a block event is received.
* @callback BlockListener
* @memberof module:fabric-network
* @async
* @param {module:fabric-network.BlockEvent} event A block event.
* @returns {Promise<void>}
*/
/**
* @typedef ListenerOptions
* @memberof module:fabric-network
* @property {(number | string | Long)} [startBlock] The block number from which events should be received. Leaving this
* value undefined starts listening from the current block.
* @property {module:fabric-network.EventType} [type] The type of events to be received.
* @property {module:fabric-network.Checkpointer} [checkpointer] A checkpointer instance. If the checkpointer has a
* current block number set, this takes precendence over the <code>startBlock</code> option. If no current block number
* is set, the <code>startBlock</code> option is used if present.
*/
/**
* The type of an event. The type is based on the type of the raw event data: filtered, full block or including
* private data. The presence of optional fields and the type of raw protobuf data associated with events is dictated
* by this value.
* @typedef {('filtered' | 'full' | 'private')} EventType
* @memberof module:fabric-network
*/
/**
* Persists the current block and transactions within that block to enable event listening to be resumed following an
* application outage. Default implementations can be obtained from
* [DefaultCheckpointers]{@link module:fabric-network.DefaultCheckpointers}. Application developers are encouraged to
* build their own implementations that use a persistent store suitable to their environment.
* @interface Checkpointer
* @memberof module:fabric-network
*/
/**
* Add a transaction ID for the current block. Typically called once a transaction has been processed.
* @method Checkpointer#addTransactionId
* @memberof module:fabric-network
* @async
* @param {string} transactionId A transaction ID.
* @returns {Promise<void>}
*/
/**
* Get the current block number, or <code>undefined</code> if there is no previously saved state.
* @method Checkpointer#getBlockNumber
* @memberof module:fabric-network
* @async
* @returns {Promise<Long | undefined>} A block number.
*/
/**
* Get the transaction IDs processed within the current block.
* @method Checkpointer#getTransactionIds
* @memberof module:fabric-network
* @async
* @returns {Promise<Set<string>>} Transaction IDs.
*/
/**
* Set the current block number. Also clears the stored transaction IDs. Typically set when the previous block has been
* processed.
* @method Checkpointer#setBlockNumber
* @memberof module:fabric-network
* @async
* @param {Long} blockNumber A block number.
* @returns {Promise<void>}
*/
/**
* Event representing a block on the ledger.
* @interface BlockEvent
* @memberof module:fabric-network
* @property {Long} blockNumber The number of the block this event represents.
* @property {(FilteredBlock | Block)} blockData The raw block event protobuf.
*/
/**
* Get the transactions included in this block.
* @method BlockEvent#getTransactionEvents
* @memberof module:fabric-network
* @returns {module:fabric-network.TransactionEvent[]} Transaction events.
*/
/**
* Event representing a transaction processed within a block.
* @interface TransactionEvent
* @memberof module:fabric-network
* @property {string} transactionId The ID of the transaction this event represents.
* @property {string} status The status of this transaction.
* @property {boolean} isValid Whether this transaction was successfully committed to the ledger. <code>true</code> if
* the transaction was commited; otherwise <code>false</code>. The status will provide a more specific reason why an
* invalid transaction was not committed.
* @property {(FilteredTransaction | any)} transactionData The raw transaction event protobuf.
* @property {any} [privateData] Private data read/write sets associated with this transaction. Only present if
* listening to <strong>private</strong> events and there is private data associated with the transaction.
*/
/**
* Get the parent block event for this event.
* @method TransactionEvent#getBlockEvent
* @memberof module:fabric-network
* @returns {module:fabric-network.BlockEvent} A block event.
*/
/**
* Get the contract events emitted by this transaction.
* @method TransactionEvent#getContractEvents
* @memberof module:fabric-network
* @returns {module:fabric-network.ContractEvent[]} Contract events.
*/
/**
* Event representing a contract event emitted by a smart contract.
* @interface ContractEvent
* @memberof module:fabric-network
* @property {string} chaincodeId The chaincode ID of the smart contract that emitted this event.
* @property {string} eventName The name of the emitted event.
* @property {Buffer} [payload] The data associated with this event by the smart contract. Note that
* <strong>filtered</strong> events do not include any payload data.
*/
/**
* Get the parent transaction event of this event.
* @method ContractEvent#getTransactionEvent
* @memberof module:fabric-network
* @returns {module:fabric-network.TransactionEvent} A transaction event.
*/
/**
* A callback function that will be invoked when a block event is received.
* @callback ContractListener
* @memberof module:fabric-network
* @async
* @param {module:fabric-network.ContractEvent} event Contract event.
* @returns {Promise<void>}
*/
/**
* <p>A Network represents the set of peers in a Fabric network.
* Applications should get a Network instance using the
* gateway's [getNetwork]{@link module:fabric-network.Gateway#getNetwork} method.</p>
*
* <p>The Network object provides the ability for applications to:</p>
* <ul>
* <li>Obtain a specific smart contract deployed to the network using [getContract]{@link module:fabric-network.Network#getContract},
* in order to submit and evaluate transactions for that smart contract.</li>
* <li>Listen to new block events and replay previous block events using
* [addBlockListener]{@link module:fabric-network.Network#addBlockListener}.</li>
* </ul>
* @interface Network
* @memberof module:fabric-network
*/
/**
* Get the owning Gateway connection.
* @method Network#getGateway
* @memberof module:fabric-network
* @returns {module:fabric-network.Gateway} A Gateway.
*/
/**
* Get an instance of a contract (chaincode) on the current network.
* @method Network#getContract
* @memberof module:fabric-network
* @param {string} chaincodeId - the chaincode identifier.
* @param {string} [name] - the name of the contract.
* @param {string[]} [collections] - the names of collections defined for this chaincode.
* @returns {module:fabric-network.Contract} the contract.
*/
/**
* Get the underlying channel object representation of this network.
* @method Network#getChannel
* @memberof module:fabric-network
* @returns {Channel} A channel.
*/
/**
* Add a listener to receive transaction commit and peer disconnect events for a set of peers. This is typically used
* only within the implementation of a custom [transaction commit event handler]{@tutorial transaction-commit-events}.
* @method Network#addCommitListener
* @memberof module:fabric-network
* @param {module:fabric-network.CommitListener} listener A transaction commit listener callback function.
* @param {Endorser[]} peers The peers from which to receive events.
* @param {string} transactionId A transaction ID.
* @returns {module:fabric-network.CommitListener} The added listener.
* @example
* const listener: CommitListener = (error, event) => {
* if (error) {
* // Handle peer communication error
* } else {
* // Handle transaction commit event
* }
* }
* const peers = network.channel.getEndorsers();
* await network.addCommitListener(listener, peers, transactionId);
*/
/**
* Remove a previously added transaction commit listener.
* @method Network#removeCommitListener
* @memberof module:fabric-network
* @param {module:fabric-network.CommitListener} listener A transaction commit listener callback function.
*/
/**
* Add a listener to receive block events for this network. Blocks will be received in order and without duplication.
* The default is to listen for full block events from the current block position.
* @method Network#addBlockListener
* @memberof module:fabric-network
* @async
* @param {module:fabric-network.BlockListener} listener A block listener callback function.
* @param {module:fabric-network.ListenerOptions} [options] Listener options.
* @returns {Promise<module:fabric-network.BlockListener>} The added listener.
* @example
* const listener: BlockListener = async (event) => {
* // Handle block event
*
* // Listener may remove itself if desired
* if (event.blockNumber.equals(endBlock)) {
* network.removeBlockListener(listener);
* }
* }
* const options: ListenerOptions = {
* startBlock: 1
* };
* await network.addBlockListener(listener, options);
*/
/**
* Remove a previously added block listener.
* @method Network#removeBlockListener
* @memberof module:fabric-network
* @param listener {module:fabric-network.BlockListener} A block listener callback function.
*/
module.exports.Gateway = require('./lib/gateway');
module.exports.Wallet = require('./lib/impl/wallet/wallet').Wallet;
module.exports.Wallets = require('./lib/impl/wallet/wallets').Wallets;
module.exports.IdentityProviderRegistry = require('./lib/impl/wallet/identityproviderregistry').IdentityProviderRegistry;
module.exports.HsmX509Provider = require('./lib/impl/wallet/hsmx509identity').HsmX509Provider;
module.exports.DefaultCheckpointers = require('./lib/defaultcheckpointers').DefaultCheckpointers;
module.exports.DefaultEventHandlerStrategies = require('./lib/impl/event/defaulteventhandlerstrategies');
module.exports.DefaultQueryHandlerStrategies = require('./lib/impl/query/defaultqueryhandlerstrategies');
module.exports.TimeoutError = require('./lib/errors/timeouterror').TimeoutError;