@hashspan/core 0.7.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -12,7 +12,7 @@ Payments that another party settles on chain, such as x402 payments, become a **
12
12
  of a `send` span.
13
13
 
14
14
  The core is library-agnostic and read-only: it never signs, sends or fetches anything. Adapters such as
15
- [`@hashspan/viem`](https://github.com/selimaytac/hashspan/tree/@hashspan/core@0.7.0/packages/viem) call it for you. Use the core directly to instrument any other send path.
15
+ [`@hashspan/viem`](https://github.com/selimaytac/hashspan/tree/@hashspan/core@0.9.0/packages/viem) call it for you. Use the core directly to instrument any other send path.
16
16
 
17
17
  ## Install
18
18
 
@@ -68,15 +68,34 @@ stays the class name.
68
68
 
69
69
  `tracker.startPayment({ chainId, protocol, payer, recipient, asset, amount })` records a payment that another
70
70
  party settles on chain, such as an x402 facilitator, as a `payment {chainId}` span; end it with
71
- `end({ status, hash })` or `fail(error)`. A settlement with a hash links the transaction's confirm span to the payment
72
- span ([ADR 0013](https://github.com/selimaytac/hashspan/blob/@hashspan/core@0.7.0/docs/adr/0013-x402-payments.md)).
73
-
74
- All three calls accept an explicit parent `Context` as a second argument. An integration that learns about a call only
71
+ `end({ status, hash })`, `fail(error)` or `timeout()`, and call `link(hash)` to link a settling transaction's confirm
72
+ span before the payment ends. A settlement with a hash links the transaction's confirm span to the payment
73
+ span ([ADR 0013](https://github.com/selimaytac/hashspan/blob/@hashspan/core@0.9.0/docs/adr/0013-x402-payments.md)).
74
+
75
+ `tracker.startUserOperationSend({ chainId, sender, entryPoint, callCount })` records a user operation of an ERC-4337
76
+ smart account handed to a bundler as a `send {chainId}` span; end it with `end({ userOpHash })` or `fail(error)`.
77
+ `tracker.startUserOperationConfirm({ chainId, userOpHash })` joins its confirm span, as `startConfirm` does for a
78
+ transaction, and `end(receipt)` takes the operation's receipt: `success`, `actualGasCost`, `actualGasUsed`, `sender`,
79
+ `nonce`, `paymaster`, `entryPoint`, `revertReason`, and the bundle transaction's `transactionHash` and `blockNumber`.
80
+ A receipt with `success: false` ends the span with `error.type` `reverted`; the bundle transaction's status and fee
81
+ are not recorded, since they cover every operation in the bundle
82
+ ([ADR 0021](https://github.com/selimaytac/hashspan/blob/@hashspan/core@0.9.0/docs/adr/0021-user-operations.md)).
83
+
84
+ `tracker.startCallBatchSend({ chainId, sender, callCount })` records a batch of calls handed to a wallet with
85
+ EIP-5792 `wallet_sendCalls` as a `send {chainId}` span; end it with `end({ id })`, the batch id the wallet returned, or
86
+ `fail(error)`. `end({ id, transactionHashes })` also links the transactions an account sent itself for the batch.
87
+ `tracker.startCallBatchConfirm({ chainId, id })` joins its confirm span, and `end(status)` takes the batch status:
88
+ `statusCode`, `atomic`, and `receipts` with their `transactionHash` and `blockNumber`. The status code sets the
89
+ outcome, and no fee is recorded; see the call batch rows of the
90
+ [semantic conventions](https://github.com/selimaytac/hashspan/blob/@hashspan/core@0.9.0/docs/semconv.md) and
91
+ [ADR 0022](https://github.com/selimaytac/hashspan/blob/@hashspan/core@0.9.0/docs/adr/0022-call-batches.md).
92
+
93
+ All of these calls accept an explicit parent `Context` as a second argument. An integration that learns about a call only
75
94
  after it started can record it after the fact: pass `startTime` in the input and `endTime` in the options of the
76
- handle method, e.g. `send.end({ hash }, { endTime })` ([ADR 0009](https://github.com/selimaytac/hashspan/blob/@hashspan/core@0.7.0/docs/adr/0009-telemetry-off-the-call-path.md)). Every method is safe to call: failures inside
95
+ handle method, e.g. `send.end({ hash }, { endTime })` ([ADR 0009](https://github.com/selimaytac/hashspan/blob/@hashspan/core@0.9.0/docs/adr/0009-telemetry-off-the-call-path.md)). Every method is safe to call: failures inside
77
96
  the instrumentation are reported through `diag` and never thrown into your code. The positional forms of earlier
78
- releases, `send.end(hash, endTime)` and `send.fail(error, endTime, { errorType })`, still work and are deprecated
79
- until 1.0 ([ADR 0014](https://github.com/selimaytac/hashspan/blob/@hashspan/core@0.7.0/docs/adr/0014-core-api-boundary.md)).
97
+ releases, `send.end(hash, endTime)` and `send.fail(error, endTime, { errorType })`, and those of the confirm handle,
98
+ `end(receipt, endTime)`, `timeout(endTime)` and `fail(error, endTime)`, still work and are deprecated until 1.0 ([ADR 0014](https://github.com/selimaytac/hashspan/blob/@hashspan/core@0.9.0/docs/adr/0014-core-api-boundary.md)).
80
99
 
81
100
  ## Options
82
101
 
@@ -85,32 +104,39 @@ until 1.0 ([ADR 0014](https://github.com/selimaytac/hashspan/blob/@hashspan/core
85
104
  | `tracerProvider` | global provider | Tracer provider to use |
86
105
  | `meterProvider` | global provider | Meter provider for the [metrics](#metrics) |
87
106
  | `address` | `'raw'` | `'raw'`, `'hashed'`, `'off'`, or `{ mode: 'hashed', hash: (address) => string }` |
88
- | `errorMessages` | `'off'` | What failed spans record about the error: `'off'` (type only), `'sanitized'` (first line, addresses per `address` mode, calldata removed; in `hashed` and `off` mode any hex longer than an address) or `'raw'` (full message and stack trace). `'raw'` can record RPC URLs that include API keys, as some libraries put the request URL in the message; `'sanitized'` keeps only the first line (viem puts the URL on a later line), which is best effort. See [ADR 0006](https://github.com/selimaytac/hashspan/blob/@hashspan/core@0.7.0/docs/adr/0006-error-privacy.md) |
107
+ | `errorMessages` | `'off'` | What failed spans record about the error: `'off'` (type only), `'sanitized'` (first line, cut to 256 characters and `...`, URLs cut to their scheme, host and port, addresses per `address` mode, calldata removed; in `hashed` and `off` mode any hex longer than an address) or `'raw'` (full message and stack trace). `'raw'` can record RPC URLs that include API keys, as some libraries put the request URL in the message; `'sanitized'` keeps only the first line (viem puts the URL on a later line) and drops the path and query of any URL in it, which is best effort. See [ADR 0006](https://github.com/selimaytac/hashspan/blob/@hashspan/core@0.9.0/docs/adr/0006-error-privacy.md) |
89
108
  | `paymentResource` | `'origin'` | How much of a paid resource's URL `x402.resource` records: `'origin'` (scheme, host and port; nothing for a resource that is not a URL), `'path'` (also the path, never the query string, fragment or user info) or `'off'`. Paths often carry user or account identifiers. At most 512 characters are recorded |
90
109
  | `recordFunctionArguments` | `false` | Record `functionArguments` as a JSON array in `blockchain.contract.function.arguments`: bigints as decimal strings, addresses per `address` mode (longer hex values become `<hex>` in `hashed` and `off` mode), at most 4096 characters. Reads only own enumerable data properties: `toJSON()` and getters are never called, so a `Date` records as `{}`; a Proxy's traps still run |
91
110
  | `agent` | none | Agent `{ id, name }`; a field set here always wins, unset fields come from the Baggage entries `gen_ai.agent.id` / `gen_ai.agent.name` |
92
111
  | `agentFromBaggage` | `true` | Read agent identity fields that `agent` leaves unset from Baggage; set to `false` in services that accept requests from outside their trust boundary |
93
- | `redact` | none | `(attributes) => attributes`, runs last on every span attribute set, including exception event attributes, but not on [metrics](#metrics); if it throws, only non-sensitive identifiers are kept |
94
- | `linkTtlMs` | `600000` | How long a sent transaction can be linked from its confirmation |
95
- | `maxTrackedTransactions` | `10000` | Upper bound on transactions kept for linking |
112
+ | `redact` | none | `(attributes) => attributes`, runs last on every span attribute set, including exception event attributes, but not on [metrics](#metrics); if it throws or returns something other than an attributes object, only non-sensitive identifiers are kept |
113
+ | `linkTtlMs` | `600000` | How long a sent transaction or user operation can be linked from its confirmation, and how long after a receipt further waits for it add no confirm span |
114
+ | `maxTrackedTransactions` | `10000` | Upper bound on transactions, and separately on user operations, kept for linking and confirm deduplication |
96
115
 
97
116
  ## What is recorded
98
117
 
99
118
  Chain id, transaction hash, sender/recipient (per `address` mode), value, nonce, function name and selector, and,
100
- on confirmation, status, block number, gas used, effective gas price, L1 fee, total fee and revert reason. Decoded
119
+ on confirmation, status, block number, gas used, effective gas price, L1 fee, total fee and revert reason. For user operations: their hash,
120
+ smart account, EntryPoint, number of calls, success, gas used, cost, nonce and paymaster. For payments: payer,
121
+ recipient, asset, amount, settled amount, status and whether the settlement was verified, and for x402 the scheme and
122
+ resource. For a replaced transaction: the replacing hash and the reason. For call batches: the batch id, sender, number of
123
+ calls, outcome, status code, atomicity and transaction hashes. On every span: the agent identity. Decoded
101
124
  call arguments are recorded only with `recordFunctionArguments`, and error messages only with `errorMessages`.
102
125
  Attribute definitions:
103
- [docs/semconv.md](https://github.com/selimaytac/hashspan/blob/@hashspan/core@0.7.0/docs/semconv.md).
126
+ [docs/semconv.md](https://github.com/selimaytac/hashspan/blob/@hashspan/core@0.9.0/docs/semconv.md).
104
127
 
105
128
  ## Metrics
106
129
 
107
130
  With an OpenTelemetry metrics SDK set up (or `meterProvider`), the tracker records three histograms:
108
131
  `blockchain.client.send.duration` and `blockchain.client.confirmation.duration` in seconds, and
109
- `blockchain.client.fee` in wei. Their attributes are the chain and the outcome only, never an address, hash or
110
- agent identity. The `redact` hook does not run on metrics: a fee it removes from spans is still recorded by
132
+ `blockchain.client.fee` in wei. Their attributes are the system, the chain and the outcome (and, on samples of user
133
+ operations, `blockchain.operation.subject`), never an address, hash or agent identity; an `error.type` that is
134
+ neither an error class name ending in `Error` nor a lower-case code of letters and underscores is recorded as
135
+ `_OTHER`.
136
+ The `redact` hook does not run on metrics: a fee it removes from spans is still recorded by
111
137
  `blockchain.client.fee`. To keep a histogram out of your backend, drop it with a View of your metrics SDK (drop
112
138
  aggregation). Definitions:
113
- [docs/semconv.md](https://github.com/selimaytac/hashspan/blob/@hashspan/core@0.7.0/docs/semconv.md#metrics).
139
+ [docs/semconv.md](https://github.com/selimaytac/hashspan/blob/@hashspan/core@0.9.0/docs/semconv.md#metrics).
114
140
 
115
141
  ## Privacy notes
116
142
 
@@ -125,7 +151,7 @@ aggregation). Definitions:
125
151
  propagated, or strip the entries before outbound calls.
126
152
  - **Inbound Baggage can claim an identity.** A caller can send Baggage entries with any agent id. A field set in the
127
153
  `agent` option cannot be overridden that way; to ignore identity from Baggage entirely, set `agentFromBaggage: false`
128
- ([ADR 0011](https://github.com/selimaytac/hashspan/blob/@hashspan/core@0.7.0/docs/adr/0011-agent-identity-precedence.md)).
154
+ ([ADR 0011](https://github.com/selimaytac/hashspan/blob/@hashspan/core@0.9.0/docs/adr/0011-agent-identity-precedence.md)).
129
155
  - The redaction hook (`redact`) runs last on every span attribute set and on exception attributes; use it for
130
156
  anything else your policy forbids. It does not run on [metrics](#metrics), which carry no address or hash.
131
157
  - **Your callbacks' errors go to the diagnostic logger.** If a custom `hash` function or the `redact` hook throws,