@hashspan/core 0.6.0 → 0.8.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.6.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.8.0/packages/viem) call it for you. Use the core directly to instrument any other send path.
16
16
 
17
17
  ## Install
18
18
 
@@ -69,37 +69,59 @@ stays the class name.
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
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.6.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
72
+ span ([ADR 0013](https://github.com/selimaytac/hashspan/blob/@hashspan/core@0.8.0/docs/adr/0013-x402-payments.md)).
73
+
74
+ `tracker.startUserOperationSend({ chainId, sender, entryPoint, callCount })` records a user operation of an ERC-4337
75
+ smart account handed to a bundler as a `send {chainId}` span; end it with `end({ userOpHash })` or `fail(error)`.
76
+ `tracker.startUserOperationConfirm({ chainId, userOpHash })` joins its confirm span, as `startConfirm` does for a
77
+ transaction, and `end(receipt)` takes the operation's receipt: `success`, `actualGasCost`, `actualGasUsed`, `sender`,
78
+ `nonce`, `paymaster`, `entryPoint`, `revertReason`, and the bundle transaction's `transactionHash` and `blockNumber`.
79
+ A receipt with `success: false` ends the span with `error.type` `reverted`; the bundle transaction's status and fee
80
+ are not recorded, since they cover every operation in the bundle
81
+ ([ADR 0021](https://github.com/selimaytac/hashspan/blob/@hashspan/core@0.8.0/docs/adr/0021-user-operations.md)).
82
+
83
+ All of these calls accept an explicit parent `Context` as a second argument. An integration that learns about a call only
75
84
  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.6.0/docs/adr/0009-telemetry-off-the-call-path.md)). Every method is safe to call: failures inside
85
+ handle method, e.g. `send.end({ hash }, { endTime })` ([ADR 0009](https://github.com/selimaytac/hashspan/blob/@hashspan/core@0.8.0/docs/adr/0009-telemetry-off-the-call-path.md)). Every method is safe to call: failures inside
77
86
  the instrumentation are reported through `diag` and never thrown into your code. The positional forms of earlier
78
87
  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.6.0/docs/adr/0014-core-api-boundary.md)).
88
+ until 1.0 ([ADR 0014](https://github.com/selimaytac/hashspan/blob/@hashspan/core@0.8.0/docs/adr/0014-core-api-boundary.md)).
80
89
 
81
90
  ## Options
82
91
 
83
92
  | Option | Default | Description |
84
93
  |---|---|---|
85
94
  | `tracerProvider` | global provider | Tracer provider to use |
95
+ | `meterProvider` | global provider | Meter provider for the [metrics](#metrics) |
86
96
  | `address` | `'raw'` | `'raw'`, `'hashed'`, `'off'`, or `{ mode: 'hashed', hash: (address) => string }` |
87
- | `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.6.0/docs/adr/0006-error-privacy.md) |
97
+ | `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.8.0/docs/adr/0006-error-privacy.md) |
88
98
  | `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 |
89
99
  | `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 |
90
100
  | `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` |
91
101
  | `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 |
92
- | `redact` | none | `(attributes) => attributes`, runs last on every attribute set, including exception event attributes; if it throws, only non-sensitive identifiers are kept |
102
+ | `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 |
93
103
  | `linkTtlMs` | `600000` | How long a sent transaction can be linked from its confirmation |
94
104
  | `maxTrackedTransactions` | `10000` | Upper bound on transactions kept for linking |
95
105
 
96
106
  ## What is recorded
97
107
 
98
108
  Chain id, transaction hash, sender/recipient (per `address` mode), value, nonce, function name and selector, and,
99
- on confirmation, status, block number, gas used, effective gas price, L1 fee, total fee and revert reason. Decoded
109
+ on confirmation, status, block number, gas used, effective gas price, L1 fee, total fee and revert reason. For user operations: their hash,
110
+ smart account, EntryPoint, number of calls, success, gas used, cost, nonce and paymaster. Decoded
100
111
  call arguments are recorded only with `recordFunctionArguments`, and error messages only with `errorMessages`.
101
112
  Attribute definitions:
102
- [docs/semconv.md](https://github.com/selimaytac/hashspan/blob/@hashspan/core@0.6.0/docs/semconv.md).
113
+ [docs/semconv.md](https://github.com/selimaytac/hashspan/blob/@hashspan/core@0.8.0/docs/semconv.md).
114
+
115
+ ## Metrics
116
+
117
+ With an OpenTelemetry metrics SDK set up (or `meterProvider`), the tracker records three histograms:
118
+ `blockchain.client.send.duration` and `blockchain.client.confirmation.duration` in seconds, and
119
+ `blockchain.client.fee` in wei. Their attributes are the chain and the outcome only, never an address, hash or
120
+ agent identity; an `error.type` that is neither an error class name nor a lower-case code is recorded as `_OTHER`.
121
+ The `redact` hook does not run on metrics: a fee it removes from spans is still recorded by
122
+ `blockchain.client.fee`. To keep a histogram out of your backend, drop it with a View of your metrics SDK (drop
123
+ aggregation). Definitions:
124
+ [docs/semconv.md](https://github.com/selimaytac/hashspan/blob/@hashspan/core@0.8.0/docs/semconv.md#metrics).
103
125
 
104
126
  ## Privacy notes
105
127
 
@@ -114,9 +136,9 @@ Attribute definitions:
114
136
  propagated, or strip the entries before outbound calls.
115
137
  - **Inbound Baggage can claim an identity.** A caller can send Baggage entries with any agent id. A field set in the
116
138
  `agent` option cannot be overridden that way; to ignore identity from Baggage entirely, set `agentFromBaggage: false`
117
- ([ADR 0011](https://github.com/selimaytac/hashspan/blob/@hashspan/core@0.6.0/docs/adr/0011-agent-identity-precedence.md)).
118
- - The redaction hook (`redact`) runs last on every attribute set and on exception attributes; use it for anything
119
- else your policy forbids.
139
+ ([ADR 0011](https://github.com/selimaytac/hashspan/blob/@hashspan/core@0.8.0/docs/adr/0011-agent-identity-precedence.md)).
140
+ - The redaction hook (`redact`) runs last on every span attribute set and on exception attributes; use it for
141
+ anything else your policy forbids. It does not run on [metrics](#metrics), which carry no address or hash.
120
142
  - **Your callbacks' errors go to the diagnostic logger.** If a custom `hash` function or the `redact` hook throws,
121
143
  its error object is logged through the OpenTelemetry `diag` logger, outside the address mode and the redaction
122
144
  hook. Errors of the instrumented call never are. Do not put sensitive values, such as the address being hashed,