# Tracking Transactions

Many Arc.js functions generate transactions that proceed asychronously through a "lifecycle" of state changes.  A user interface will require manual attention from the user to sign each transaction and configure the parameters for sending it to the network. Depending on the speed of the net, substantial delays may occur before the result of a transaction becomes available and reliable.  Some functions generate multiple transactions, with significant delays between each transaction until the operation has fully completed.

So you may wish to give the user a visual sense of progress and assistance during a multi-stage and potentially lengthy asynchronous process.

This is where the Arc.js [TransactionService](/arc.js/api/classes/TransactionService) comes in.  `TransactionService` can notify your application when transactions are about to be generated by a particular Arc.js function, how many transactions there will be, and when each transaction has completed each phase in its lifecycle.

For example, take [DAO.new](/arc.js/api/classes/DAO#new) which, out of all functions in Arc.js, generates the most transactions.  Suppose you want to feed back to the user how many transactions to expect and when each transaction has completed.  Here is how your application can be notified of changes throughout the transaction lifecycle:

```typescript
import { TransactionService } from "@daostack/arc.js";

const subscription = TransactionService.subscribe("TxTracking.DAO.new",
  /**
   * 'topic' is the name of the event,
   * `txEventInfo` is often referred-to as the "payload".
   */
  (topic: string, txEventInfo: TransactionReceiptsEventInfo) => {

    // the options you passed into the function (DAO.new in this case)
    const optionsWithDefaults = txEventInfo.options;

    // the expected number of transactions
    const expectedNumTransactions = txEventInfo.txCount;

    // a key that is unique to a single invocation of the function (DAO.new in this case)
    const uniqueInvocationKey = txEventInfo.invocationKey;

    // Transaction hash for `sent` transaction.
    // Will be null in the `kickoff` event.
    const txHash = txEventInfo.tx;

    // TransactionReceiptTruffle for mined and confirmed transactions.
    // Will be null in the `kickoff` and `sent` events.
    const txReceipt = txEventInfo.txReceipt;

    // Stage of the transaction.  See `TransactionStage`.
    const stage = txEventInfo.txStage;

    // Error, if this is a failed transaction.
    const error = txEventInfo.error;
});
```

Now you are ready to handle "TxTracking.DAO.new" events whenever you call `DAO.new`.

!!! warning "Important"
    You must unsubscribe to the subscription or you risk memory leaks and excessive CPU usage:
    ```javascript
    subscription.unsubscribe();
    ```

To let you know in advance the expected count of transactions, a single "kick-off" event is published at the beginning of each function invocation and before any transactions have begun.  In that event, `txEventInfo.tx` will be null.  The property `txEventInfo.uniqueInvocationKey` uniquely identifies the "thread" of events associated with a single function at the root of an invocation.

You can supply anything you want in the options passed to the invoked function.  The entire object will be passed back to you in the event callback (`txEventInfo.options`, above). For example, you may desire a tighter coupling between the events and a specific function invocation, so for you the invocationKey not given to you until the `kickoff` event may not suffice.  In that case you might want to add a property to the `options` object in advance of calling the wrapper function, and use this property as your unique invocation key.  You can create this key however you want, one way being to use the same function that `TransactionService` uses:

```javascript
options.myInvocationkey = TransactionService.generateInvocationKey();
```

!!! note
    `txEventInfo.options` will usually contain the options you passed in, with default values added.  But in the case of `DAO.new`, it will not contain the default values.  If you need to see the default values for `DAO.new` then instead of subscribing to "TxTracking.DAO.new" you can subscribe to "TxTracking.DaoCreator" and receive events published by  [DaoCreatorWrapper.forgeOrg](/arc.js/api/classes/DaoCreatorWrapper#forgeOrg) and [DaoCreatorWrapper.setSchemes](/arc.js/api/classes/DaoCreatorWrapper#setSchemes).  This would otherwise be the same as subscribing to "TxTracking.DAO.new".

!!! note
    In cases where a transaction-generating function invokes another transaction-generating function, Arc.js will insert into the `options` object that you passed into the root function a property called `txEventContext`.  This is meant only for internal use by Arc.js and may change without notice at any time.

!!! info "More about Pub/Sub events"
    See more about how to use the Pub/Sub event system, including how to scope your subscriptions to whole sets of events, [here](Events.md#pubsub-events).
  
## Transaction Lifecycle
All transactions proceed through three stages:  sent, mined and confirmed.  In the example above, when we subscribed to `TxTracking.DAO.new`, we are actually subscribing to four distinct events: 

1. TxTracking.DAO.new.kickoff
2. TxTracking.DAO.sent
3. TxTracking.DAO.mined
4. TxTracking.DAO.confirmed

You can identify the stage of the event using the `topic` parameter of the callback, or by the `txStage` property of the payload (`txEventInfo`) parameter of the callback (see the example code given in the previous section).

Errors may occur at any point in the lifecycle.  When they do you will receive an event with ".failed" appended to the `topic` parameter of the callback, and the `error` property of the payload will contain the `Error` that describes what happened.  `txStage` will represent the stage at which the error occurred, and you will receive no further events on the transaction.

<a name="gettingtxinfo"></a>
## Getting Information About Transactions

The `TransactionService` provides several static functions you can use to obtain information about a transaction:

Function | Description
---------|----------
 [getMinedTransaction](/arc.js/api/classes/TransactionService#getMinedTransaction) | Returns a promise of a `TransactionReceipt` if the given transaction has been mined according to the optional `requiredDepth` (default `requiredDepth` is 0)
 [watchForMinedTransaction](/arc.js/api/classes/TransactionService#watchForMinedTransaction) | Returns a promise of a `TransactionReceipt` once the given transaction has been mined according to the optional `requiredDepth` (default `requiredDepth` is 0)
 [getConfirmedTransaction](/arc.js/api/classes/TransactionService#getConfirmedTransaction) | Returns a promise of a `TransactionReceipt` if the given transaction has been confirmed according to the optional `requiredDepth` (default `requiredDepth` comes from the `ConfigService`)
 [watchForConfirmedTransaction](/arc.js/api/classes/TransactionService#watchForConfirmedTransaction) | Returns a promise of a `TransactionReceipt` once the given transaction has been confirmed according to the optional `requiredDepth` (default `requiredDepth` comes from the `ConfigService`)
 [getTransactionDepth](/arc.js/api/classes/TransactionService#getTransactionDepth) | Returns a promise of the number of blocks that have been added to the chain since the given transaction was mined.

## Wrapper Functions that Generate a Transaction

Contract wrapper functions that generate a promise of a transaction will return the promise of an [ArcTransactionResult](/arc.js/api/classes/ArcTransactionResult) that contains methods giving you access to the functions described in [Getting Information About Transactions](#gettingtxinfo) without having to supply the transaction hash.  For example:

```javascript
import { ArcTransactionResult } from "@daostack.arc.js";

  const txResult = await someWrapper.aTxGeneratingFunction();

  const confirmedTransactionReceipt = await txResult.watchForTxConfirmed();
```

<a name="transactiondepth"></a>
## Transaction Depth

As described in the previous sections, you can obtain information about a transaction on the condition that it has reached a desired depth in terms of the number of blocks that have been added to the chain since the given transaction was mined.

You can supply the required depth as a parameter to the function that returns the transaction information, or you can rely on the default depth that is defined by the global setting "[txDepthRequiredForConfirmation](Configuration.md#txDepthRequiredForConfirmation)".

The `txDepthRequiredForConfirmation` setting is defined individually for each network.  For example, if you want to set the value for the "live" network:

```javascript
ConfigService.set("txDepthRequiredForConfirmation.live", 6);
```

## Transaction Logs
You can obtain information from a `TransactionReceiptTruffle` or `TransactionReceipt` using [TransactionService.getValueFromLogs](/arc.js/api/classes/TransactionService#getValueFromLogs):

```javascript
const txResult = await someWrapper.aTxGeneratingFunction();

const minedTransactionReceipt = await txResult.watchForTxMined();

const avatarAddress = TransactionService.getValueFromLogs(minedTransactionReceipt, "_avatar", "eventName");
```
