@valve-tech/wallet-adapter 0.3.1
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/CHANGELOG.md +55 -0
- package/LICENSE +21 -0
- package/README.md +234 -0
- package/dist/hooks.d.ts +157 -0
- package/dist/hooks.d.ts.map +1 -0
- package/dist/hooks.js +34 -0
- package/dist/hooks.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/receipt.d.ts +72 -0
- package/dist/receipt.d.ts.map +1 -0
- package/dist/receipt.js +74 -0
- package/dist/receipt.js.map +1 -0
- package/dist/send.d.ts +86 -0
- package/dist/send.d.ts.map +1 -0
- package/dist/send.js +89 -0
- package/dist/send.js.map +1 -0
- package/dist/tx-status.d.ts +113 -0
- package/dist/tx-status.d.ts.map +1 -0
- package/dist/tx-status.js +68 -0
- package/dist/tx-status.js.map +1 -0
- package/dist/wallet.d.ts +66 -0
- package/dist/wallet.d.ts.map +1 -0
- package/dist/wallet.js +10 -0
- package/dist/wallet.js.map +1 -0
- package/package.json +54 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `@valve-tech/wallet-adapter` are documented in
|
|
4
|
+
this file.
|
|
5
|
+
|
|
6
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
7
|
+
and this project adheres to [Semantic Versioning](https://semver.org/).
|
|
8
|
+
|
|
9
|
+
## [Unreleased]
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- Initial implementation. Vocabulary lifted from a real-world dapp
|
|
14
|
+
(Provex) where SDK / UI / tx-tracker each redefined the same shapes
|
|
15
|
+
separately; this is the first upstream packaging.
|
|
16
|
+
- `WalletAdapter` interface plus `WalletSendTransactionRequest` and
|
|
17
|
+
`WalletReadContractRequest` request shapes.
|
|
18
|
+
- `WriteHookParams` — full lifecycle contract. Six named callbacks
|
|
19
|
+
(`onAwaitingSignature`, `onTransactionHash`, `onConfirmed`,
|
|
20
|
+
`onFailed`, `onDropped`, `onReplaced`) plus a complementary
|
|
21
|
+
single-callback `onPhase(event)` shape with a discriminated-union
|
|
22
|
+
payload. Fire-ers fire BOTH shapes for every transition.
|
|
23
|
+
- `WritePhase` (`'preparing' | 'awaiting-signature' | 'pending' |
|
|
24
|
+
'confirmed' | 'failed' | 'dropped' | 'replaced'`) and
|
|
25
|
+
`WritePhaseEvent` discriminated union for `onPhase` consumers.
|
|
26
|
+
- `TX_STATUS` lifecycle const, `TrackedTxStatus` type, `TrackedTx`
|
|
27
|
+
shape, `TrackedTxGas`, `TxConfirmedCallback`.
|
|
28
|
+
- `TX_FLOW` extension point (ships empty), `TxFlow = string`.
|
|
29
|
+
- `STALE_TX_AGE_MS` / `CONFIRMED_DISPLAY_MS` / `FAILED_DISPLAY_MS`
|
|
30
|
+
display-window defaults.
|
|
31
|
+
- Unit tests covering the runtime constants and type-level shape
|
|
32
|
+
guarantees (status-value uniqueness, phase literal union, hook
|
|
33
|
+
parameter typing, `TrackedTx` pre-hash and post-hash construction).
|
|
34
|
+
- `sendTransactionWithHooks(options)` — wallet-side runtime helper.
|
|
35
|
+
Fires `onAwaitingSignature` + `onPhase('awaiting-signature')`
|
|
36
|
+
immediately before `sendTransaction`; fires per-call + global
|
|
37
|
+
`onTransactionHash` and `onPhase('pending', { hash })` after the
|
|
38
|
+
wallet returns; fires `onFailed` + `onPhase('failed', ...)` on any
|
|
39
|
+
thrown error before re-throwing.
|
|
40
|
+
- `awaitReceiptWithHooks(options)` — chain-side runtime helper.
|
|
41
|
+
Awaits `waitForTransactionReceipt`; fires `onConfirmed` +
|
|
42
|
+
`onPhase('confirmed', { hash, receipt })` on success; fires
|
|
43
|
+
`onFailed` with a `ContractRevertedError` + `onPhase('failed', ...)`
|
|
44
|
+
on `status: reverted`; fires `onFailed` with the original error +
|
|
45
|
+
`onPhase('failed', ...)` on any other receipt-await failure.
|
|
46
|
+
- `WalletRejectedError` — `Error` subclass thrown by
|
|
47
|
+
`sendTransactionWithHooks` on user rejection; preserves the original
|
|
48
|
+
error as `cause`.
|
|
49
|
+
- `ContractRevertedError` — `Error` subclass thrown by
|
|
50
|
+
`awaitReceiptWithHooks` on `status: reverted`; carries the `hash`
|
|
51
|
+
and full `receipt` so consumers can extract revert reasons / log
|
|
52
|
+
data without re-fetching.
|
|
53
|
+
- Runtime dependency on `@valve-tech/viem-errors` for the
|
|
54
|
+
three-signal rejection detection (EIP-1193 `code === 4001`, viem
|
|
55
|
+
class name, message regex — anywhere in the cause chain).
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Valve Tech
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
# `@valve-tech/wallet-adapter`
|
|
2
|
+
|
|
3
|
+
Framework-agnostic vocabulary for EVM dapp wallet integration. Pure
|
|
4
|
+
types + a few `as const` lifecycle constants — no runtime
|
|
5
|
+
implementation, no opinion about which wallet library you use.
|
|
6
|
+
|
|
7
|
+
Five concerns under one package so SDK authors, UI authors, and apps
|
|
8
|
+
all agree on the same surface:
|
|
9
|
+
|
|
10
|
+
1. **`WalletAdapter`** — the contract an SDK accepts in lieu of
|
|
11
|
+
coupling to wagmi / ethers / viem direct / a smart account.
|
|
12
|
+
2. **`WriteHookParams`** — every phase a tracked tx can be in. Six
|
|
13
|
+
named hooks (`onAwaitingSignature`, `onTransactionHash`,
|
|
14
|
+
`onConfirmed`, `onFailed`, `onDropped`, `onReplaced`) plus a
|
|
15
|
+
complementary single-callback shape (`onPhase(event)`) with a
|
|
16
|
+
discriminated-union payload. Fire-ers fire BOTH shapes for every
|
|
17
|
+
transition — exactly once each — so wiring named hooks doesn't
|
|
18
|
+
preclude `onPhase` and vice versa.
|
|
19
|
+
3. **`sendTransactionWithHooks(options)`** — wallet-side helper. Fires
|
|
20
|
+
the pre-wallet (`onAwaitingSignature`, `onPhase('awaiting-signature')`)
|
|
21
|
+
and post-hash (`onTransactionHash`, `onPhase('pending', { hash })`)
|
|
22
|
+
transitions. Converts wallet rejections to a typed
|
|
23
|
+
`WalletRejectedError`, fires `onFailed` + `onPhase('failed', { error })`,
|
|
24
|
+
then throws.
|
|
25
|
+
4. **`awaitReceiptWithHooks(options)`** — chain-side helper. Awaits
|
|
26
|
+
`waitForTransactionReceipt`, fires `onConfirmed` +
|
|
27
|
+
`onPhase('confirmed', { hash, receipt })` on success, or `onFailed`
|
|
28
|
+
+ `onPhase('failed', ...)` with a typed `ContractRevertedError` on
|
|
29
|
+
`status: 'reverted'`. Other receipt-await errors re-thrown unchanged
|
|
30
|
+
after firing the failure hooks.
|
|
31
|
+
5. **`TX_STATUS` / `TrackedTx`** — vocabulary for "this transaction is
|
|
32
|
+
in flight" UIs (toast strips, inline indicators, history panes) so
|
|
33
|
+
they can sit on top of any tracker without redefining state names.
|
|
34
|
+
|
|
35
|
+
The two helpers split by concern: the wallet side and the chain side.
|
|
36
|
+
SDKs chain them with whatever protocol-specific work goes in the
|
|
37
|
+
middle (gating-service signatures, log decoding, indexer sync). The
|
|
38
|
+
only runtime dependency is `@valve-tech/viem-errors` for the
|
|
39
|
+
rejection-detection check; viem is a peer dependency for the `Hex`
|
|
40
|
+
and `TransactionReceipt` types.
|
|
41
|
+
|
|
42
|
+
**`onDropped` and `onReplaced` are part of the contract; the helpers
|
|
43
|
+
in this package don't fire them.** Honestly distinguishing "still
|
|
44
|
+
propagating" from "permanently dropped" requires observing the tx
|
|
45
|
+
across many blocks with a configurable timeout policy, and detecting
|
|
46
|
+
replacement requires nonce-watching across the same nonce — that's
|
|
47
|
+
`@valve-tech/tx-tracker`'s job (per-tx state machine). The contract
|
|
48
|
+
defines the hooks here so consumers wire one set of callbacks; the
|
|
49
|
+
tracker fires them when it ships. Wiring `onDropped` / `onReplaced`
|
|
50
|
+
against `awaitReceiptWithHooks` is harmless but they will not fire
|
|
51
|
+
from this package.
|
|
52
|
+
|
|
53
|
+
## Why
|
|
54
|
+
|
|
55
|
+
Every SDK invents its own wallet shape; every dapp invents its own
|
|
56
|
+
"awaiting signature" state machine; every UI invents its own list of
|
|
57
|
+
status names. The result is a small ecosystem where the same word
|
|
58
|
+
means slightly different things at every boundary, and dapps end up
|
|
59
|
+
writing translation glue between them.
|
|
60
|
+
|
|
61
|
+
This package is the shared vocabulary. Use `WalletAdapter` so a single
|
|
62
|
+
wagmi/ethers/smart-account adapter works across every SDK. Use
|
|
63
|
+
`WriteHookParams` so the UI sees consistent transitions across every
|
|
64
|
+
SDK write. Use `TX_STATUS` so the in-flight strip and the receipt-poll
|
|
65
|
+
agree on what `'pending'` means.
|
|
66
|
+
|
|
67
|
+
## Install
|
|
68
|
+
|
|
69
|
+
```sh
|
|
70
|
+
npm install @valve-tech/wallet-adapter viem
|
|
71
|
+
# or
|
|
72
|
+
yarn add @valve-tech/wallet-adapter viem
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Quick start
|
|
76
|
+
|
|
77
|
+
### Defining an SDK that accepts any wallet
|
|
78
|
+
|
|
79
|
+
```ts
|
|
80
|
+
import {
|
|
81
|
+
sendTransactionWithHooks,
|
|
82
|
+
awaitReceiptWithHooks,
|
|
83
|
+
WalletRejectedError,
|
|
84
|
+
ContractRevertedError,
|
|
85
|
+
type WalletAdapter,
|
|
86
|
+
type WriteHookParams,
|
|
87
|
+
} from '@valve-tech/wallet-adapter'
|
|
88
|
+
|
|
89
|
+
export interface MyWriteParams { depositId: bigint; amount: bigint }
|
|
90
|
+
|
|
91
|
+
export class MyClient {
|
|
92
|
+
constructor(
|
|
93
|
+
private wallet: WalletAdapter,
|
|
94
|
+
private chainId: number,
|
|
95
|
+
private escrow: `0x${string}`,
|
|
96
|
+
/** Optional global / analytics channel — fires alongside the per-call hook. */
|
|
97
|
+
private onTransactionHash?: (hash: `0x${string}`) => void,
|
|
98
|
+
) {}
|
|
99
|
+
|
|
100
|
+
async deposit(params: MyWriteParams & WriteHookParams) {
|
|
101
|
+
try {
|
|
102
|
+
const hash = await sendTransactionWithHooks({
|
|
103
|
+
wallet: this.wallet,
|
|
104
|
+
request: {
|
|
105
|
+
to: this.escrow,
|
|
106
|
+
data: this.encodeDeposit(params),
|
|
107
|
+
chainId: this.chainId,
|
|
108
|
+
},
|
|
109
|
+
hooks: params,
|
|
110
|
+
onTransactionHash: this.onTransactionHash,
|
|
111
|
+
})
|
|
112
|
+
const receipt = await awaitReceiptWithHooks({
|
|
113
|
+
publicClient: this.publicClient,
|
|
114
|
+
hash,
|
|
115
|
+
hooks: params,
|
|
116
|
+
})
|
|
117
|
+
// protocol-specific work here (decode logs, etc.) — onConfirmed already fired
|
|
118
|
+
return { hash, receipt }
|
|
119
|
+
} catch (err) {
|
|
120
|
+
if (err instanceof WalletRejectedError) {
|
|
121
|
+
throw new MySdkError('WALLET_REJECTED', err.message, err.cause)
|
|
122
|
+
}
|
|
123
|
+
if (err instanceof ContractRevertedError) {
|
|
124
|
+
throw new MySdkError('TX_REVERTED', err.message, err)
|
|
125
|
+
}
|
|
126
|
+
throw new MySdkError('CONTRACT_ERROR', (err as Error).message, err as Error)
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
`sendTransactionWithHooks` guarantees:
|
|
133
|
+
|
|
134
|
+
- `onAwaitingSignature` fires **once**, **immediately before**
|
|
135
|
+
`wallet.sendTransaction`.
|
|
136
|
+
- `onTransactionHash` (per-call **and** global) fires **once each**,
|
|
137
|
+
**after** `sendTransaction` resolves and **before** any receipt-await.
|
|
138
|
+
- Wallet rejections — detected via the three-signal check in
|
|
139
|
+
`@valve-tech/viem-errors` (EIP-1193 `code === 4001`, viem class name,
|
|
140
|
+
message regex, anywhere in the cause chain) — are thrown as
|
|
141
|
+
`WalletRejectedError`. `onFailed` fires with the rejection error
|
|
142
|
+
before the throw.
|
|
143
|
+
- Any other thrown error fires `onFailed` and re-throws unchanged so
|
|
144
|
+
the SDK keeps control of its error mapping.
|
|
145
|
+
|
|
146
|
+
`awaitReceiptWithHooks` guarantees:
|
|
147
|
+
|
|
148
|
+
- On `receipt.status === 'success'`: fires `onConfirmed(receipt)` and
|
|
149
|
+
resolves with the receipt.
|
|
150
|
+
- On `receipt.status === 'reverted'`: fires `onFailed` with a
|
|
151
|
+
`ContractRevertedError` (carrying `hash` + the full `receipt` for
|
|
152
|
+
log inspection) and throws it.
|
|
153
|
+
- On any thrown error during the receipt-await (network / RPC /
|
|
154
|
+
abort): fires `onFailed` with the original error and re-throws
|
|
155
|
+
unchanged.
|
|
156
|
+
|
|
157
|
+
A `WriteHookParams` consumer (toast strip, inline indicator, etc.)
|
|
158
|
+
that wires all four hooks can drive its full state machine — pre-wallet
|
|
159
|
+
"preparing", post-wallet "pending", terminal "confirmed" or "failed" —
|
|
160
|
+
purely from the contract, without any SDK-specific glue.
|
|
161
|
+
|
|
162
|
+
### A tx-flight UI built on `TX_STATUS`
|
|
163
|
+
|
|
164
|
+
```ts
|
|
165
|
+
import { TX_STATUS, type TrackedTx } from '@valve-tech/wallet-adapter'
|
|
166
|
+
|
|
167
|
+
function subtitle(tx: TrackedTx): string {
|
|
168
|
+
switch (tx.status) {
|
|
169
|
+
case TX_STATUS.preparing: return 'preparing transaction'
|
|
170
|
+
case TX_STATUS.awaitingSignature: return 'awaiting wallet signature'
|
|
171
|
+
case TX_STATUS.pending: return 'waiting for inclusion'
|
|
172
|
+
case TX_STATUS.mined: return 'confirmed on-chain'
|
|
173
|
+
case TX_STATUS.failed: return tx.notes ?? 'transaction failed'
|
|
174
|
+
case TX_STATUS.dropped: return 'dropped from mempool'
|
|
175
|
+
case TX_STATUS.replaced: return 'replaced by speed-up'
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
## Exports
|
|
181
|
+
|
|
182
|
+
| Export | Kind | Shape |
|
|
183
|
+
| --- | --- | --- |
|
|
184
|
+
| `WalletAdapter` | type | `{ address?, sendTransaction(req), readContract?(req) }` |
|
|
185
|
+
| `WalletSendTransactionRequest` | type | EIP-1559 send shape — `{ to, data, value?, chainId, maxFeePerGas?, maxPriorityFeePerGas? }` |
|
|
186
|
+
| `WalletReadContractRequest` | type | `{ address, abi, functionName, args?, chainId? }` |
|
|
187
|
+
| `WriteHookParams` | type | six named hooks (`onAwaitingSignature`, `onTransactionHash`, `onConfirmed`, `onFailed`, `onDropped`, `onReplaced`) + `onPhase(event)` |
|
|
188
|
+
| `WritePhase` | type | `'preparing' \| 'awaiting-signature' \| 'pending' \| 'confirmed' \| 'failed' \| 'dropped' \| 'replaced'` |
|
|
189
|
+
| `WritePhaseEvent` | type | discriminated union of phase + payload |
|
|
190
|
+
| `sendTransactionWithHooks(opts)` | function | `{ wallet, request, hooks?, onTransactionHash? } → Promise<Hex>`. Wallet-side helper. |
|
|
191
|
+
| `awaitReceiptWithHooks(opts)` | function | `{ publicClient, hash, hooks? } → Promise<TransactionReceipt>`. Chain-side helper. |
|
|
192
|
+
| `WalletRejectedError` | class | `Error` subclass with `cause: Error`. Thrown by `sendTransactionWithHooks` on user rejection. |
|
|
193
|
+
| `ContractRevertedError` | class | `Error` subclass with `hash` + `receipt`. Thrown by `awaitReceiptWithHooks` on `status: reverted`. |
|
|
194
|
+
| `SendTransactionWithHooksOptions` / `AwaitReceiptWithHooksOptions` / `ReceiptAwaiter` | type | options + minimal client shape |
|
|
195
|
+
| `TX_STATUS` | const | lifecycle states |
|
|
196
|
+
| `TX_FLOW` | const | empty by design — protocols extend |
|
|
197
|
+
| `TrackedTx` | type | `{ id, hash?, chainId, flow, submittedAt, ... status, notes? }` |
|
|
198
|
+
| `STALE_TX_AGE_MS` / `CONFIRMED_DISPLAY_MS` / `FAILED_DISPLAY_MS` | const | window defaults |
|
|
199
|
+
|
|
200
|
+
## Design notes
|
|
201
|
+
|
|
202
|
+
- **One hook contract, two complementary shapes.** `WriteHookParams`
|
|
203
|
+
describes every phase a tracked tx can be in. Six named callbacks
|
|
204
|
+
cover the common transitions; `onPhase(event)` provides the same
|
|
205
|
+
information as a discriminated-union single-callback shape for
|
|
206
|
+
state-machine consumers. Fire-ers fire BOTH shapes for every
|
|
207
|
+
transition — exactly once each. Wiring named hooks doesn't preclude
|
|
208
|
+
`onPhase` and vice versa.
|
|
209
|
+
- **`onFailed` is the unified failure callback for revert / rejection /
|
|
210
|
+
network errors.** Wallet rejection, on-chain revert, and network
|
|
211
|
+
errors all flow through it. `instanceof` against
|
|
212
|
+
`WalletRejectedError` / `ContractRevertedError` discriminates the
|
|
213
|
+
source. Distinct from `onDropped` (no inclusion observed) and
|
|
214
|
+
`onReplaced` (different tx mined for the same nonce) — those are
|
|
215
|
+
their own terminal states with their own typed payloads.
|
|
216
|
+
- **`onDropped` and `onReplaced` are part of the contract; this
|
|
217
|
+
package's helpers don't fire them.** Detecting drop vs replacement
|
|
218
|
+
requires multi-block observation with nonce-watching — that's
|
|
219
|
+
`@valve-tech/tx-tracker`'s job. The hooks live in `WriteHookParams`
|
|
220
|
+
so consumers wire one set of callbacks; the tracker fires them when
|
|
221
|
+
it ships.
|
|
222
|
+
- **`TX_FLOW` is intentionally empty.** Every protocol's flow names
|
|
223
|
+
(`fulfillIntent`, `addFunds`, `mintNFT`, etc.) are its own concern.
|
|
224
|
+
Extend the `TxFlow` type via your own union.
|
|
225
|
+
- **Pre-hash states are first-class.** `preparing` and
|
|
226
|
+
`awaiting-signature` carry no `hash` — they exist so the UI has
|
|
227
|
+
something to show during the wallet-sign window.
|
|
228
|
+
- **`id` is stable, `hash` is not.** Registries assign `id` at
|
|
229
|
+
`beginTx` time and attach `hash` later. This lets pre-hash UI render
|
|
230
|
+
before the wallet returns.
|
|
231
|
+
|
|
232
|
+
## License
|
|
233
|
+
|
|
234
|
+
MIT
|
package/dist/hooks.d.ts
ADDED
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Per-call lifecycle hooks for any SDK method that opens a
|
|
3
|
+
* wallet popup, awaits inclusion, and may later observe replacement or
|
|
4
|
+
* mempool drop.
|
|
5
|
+
*
|
|
6
|
+
* The contract describes EVERY phase a tracked tx can be in. Different
|
|
7
|
+
* fire-ers cover different slices:
|
|
8
|
+
*
|
|
9
|
+
* - `sendTransactionWithHooks` fires the wallet-side phases
|
|
10
|
+
* (`awaiting-signature`, `pending`, plus `failed` on rejection /
|
|
11
|
+
* wallet-side network error).
|
|
12
|
+
* - `awaitReceiptWithHooks` fires the chain-side terminal phases
|
|
13
|
+
* (`confirmed` or `failed` on revert / receipt-await error).
|
|
14
|
+
* - `@valve-tech/tx-tracker` (per-tx state machine, observes across
|
|
15
|
+
* blocks) fires `dropped` and `replaced` once it ships, plus may
|
|
16
|
+
* re-emit transitions if a tx surfaces / vanishes / surfaces again
|
|
17
|
+
* across reorgs.
|
|
18
|
+
* - The SDK itself may fire `preparing` at the very start of its
|
|
19
|
+
* write method, before any pre-wallet work begins.
|
|
20
|
+
*
|
|
21
|
+
* Two shapes are available — complementary, not alternatives:
|
|
22
|
+
*
|
|
23
|
+
* - **Named hooks** (`onAwaitingSignature`, `onConfirmed`, etc.) —
|
|
24
|
+
* ergonomic, easy to wire from a hook-like API, narrow types per
|
|
25
|
+
* callback.
|
|
26
|
+
* - **`onPhase(event)`** — single-callback discriminated union.
|
|
27
|
+
* Better for state-machine consumers that need a single transition
|
|
28
|
+
* point and exhaustive `switch`-coverage on the phase name.
|
|
29
|
+
*
|
|
30
|
+
* Fire-ers fire BOTH shapes for every transition — exactly once each —
|
|
31
|
+
* so consumers can choose which to wire without affecting the other.
|
|
32
|
+
*/
|
|
33
|
+
import type { Hex, TransactionReceipt } from 'viem';
|
|
34
|
+
/**
|
|
35
|
+
* Every lifecycle phase a tracked transaction can be in, from intent
|
|
36
|
+
* through terminal observation. Carriers (helpers, trackers, SDKs)
|
|
37
|
+
* fire transitions in roughly this order, though `dropped` and
|
|
38
|
+
* `replaced` may arrive late or interleave with re-emissions on reorg.
|
|
39
|
+
*/
|
|
40
|
+
export type WritePhase = 'preparing' | 'awaiting-signature' | 'pending' | 'confirmed' | 'failed' | 'dropped' | 'replaced';
|
|
41
|
+
/**
|
|
42
|
+
* Discriminated-union event payload for the `onPhase` callback. Switch
|
|
43
|
+
* on `event.phase` and TypeScript narrows the rest of the fields
|
|
44
|
+
* automatically — no `event.context?.receipt` indirection.
|
|
45
|
+
*/
|
|
46
|
+
export type WritePhaseEvent = {
|
|
47
|
+
phase: 'preparing';
|
|
48
|
+
} | {
|
|
49
|
+
phase: 'awaiting-signature';
|
|
50
|
+
} | {
|
|
51
|
+
phase: 'pending';
|
|
52
|
+
hash: Hex;
|
|
53
|
+
} | {
|
|
54
|
+
phase: 'confirmed';
|
|
55
|
+
hash: Hex;
|
|
56
|
+
receipt: TransactionReceipt;
|
|
57
|
+
} | {
|
|
58
|
+
phase: 'failed';
|
|
59
|
+
error: Error;
|
|
60
|
+
hash?: Hex;
|
|
61
|
+
receipt?: TransactionReceipt;
|
|
62
|
+
} | {
|
|
63
|
+
phase: 'dropped';
|
|
64
|
+
hash: Hex;
|
|
65
|
+
} | {
|
|
66
|
+
phase: 'replaced';
|
|
67
|
+
original: Hex;
|
|
68
|
+
replacement: Hex;
|
|
69
|
+
receipt?: TransactionReceipt;
|
|
70
|
+
};
|
|
71
|
+
/**
|
|
72
|
+
* Per-call hooks fired at real boundaries during a tracked tx's
|
|
73
|
+
* lifecycle. Every field is optional. SDKs and trackers fire whichever
|
|
74
|
+
* subset corresponds to phases they actually observe; consumers wire
|
|
75
|
+
* only the ones their UI needs.
|
|
76
|
+
*
|
|
77
|
+
* Named hooks vs `onPhase`: complementary, not alternatives. A
|
|
78
|
+
* fire-er fires both for every transition — the named hook (if a
|
|
79
|
+
* consumer wired it) and `onPhase` (if a consumer wired it) — so no
|
|
80
|
+
* transition is observable from one shape but not the other.
|
|
81
|
+
*/
|
|
82
|
+
export interface WriteHookParams {
|
|
83
|
+
/**
|
|
84
|
+
* Called once, immediately before `wallet.sendTransaction`. UI flips
|
|
85
|
+
* from "preparing" to "awaiting wallet signature" at the precise
|
|
86
|
+
* boundary, regardless of how much pre-wallet work the SDK did.
|
|
87
|
+
*/
|
|
88
|
+
onAwaitingSignature?: () => void;
|
|
89
|
+
/**
|
|
90
|
+
* Called once with the on-chain tx hash, immediately after
|
|
91
|
+
* `sendTransaction` resolves and *before* any receipt-await. UI flips
|
|
92
|
+
* from "awaiting" to "pending" the moment the hash exists.
|
|
93
|
+
*
|
|
94
|
+
* Per-call vs constructor-level: SDKs may also expose a separate
|
|
95
|
+
* constructor-level `onTransactionHash` channel for analytics /
|
|
96
|
+
* global observers — they're complementary, fire on the same line.
|
|
97
|
+
*/
|
|
98
|
+
onTransactionHash?: (hash: Hex) => void;
|
|
99
|
+
/**
|
|
100
|
+
* Called once with the mined receipt when `receipt.status === 'success'`.
|
|
101
|
+
* UI flips to a terminal "confirmed" state. Receives the full receipt
|
|
102
|
+
* so consumers can extract block number, gas used, decoded events.
|
|
103
|
+
*/
|
|
104
|
+
onConfirmed?: (receipt: TransactionReceipt) => void;
|
|
105
|
+
/**
|
|
106
|
+
* Called once with the underlying error on any terminal failure that
|
|
107
|
+
* is NOT a replacement or a drop:
|
|
108
|
+
* - wallet rejection (`WalletRejectedError`)
|
|
109
|
+
* - on-chain revert (`ContractRevertedError`)
|
|
110
|
+
* - any other thrown error from the wallet or RPC.
|
|
111
|
+
*
|
|
112
|
+
* Use `instanceof` against `WalletRejectedError` / `ContractRevertedError`
|
|
113
|
+
* to discriminate; everything else is a plain `Error`.
|
|
114
|
+
*/
|
|
115
|
+
onFailed?: (error: Error) => void;
|
|
116
|
+
/**
|
|
117
|
+
* Called once when a tracker has determined the tx will not be
|
|
118
|
+
* included — typically: not seen in mempool for N consecutive blocks
|
|
119
|
+
* AND no receipt arrived AND no replacement nonce mined. The exact
|
|
120
|
+
* timeout policy is the tracker's call (configurable per consumer).
|
|
121
|
+
*
|
|
122
|
+
* Helpers in THIS package never fire `onDropped` — distinguishing
|
|
123
|
+
* "still propagating" from "permanently dropped" requires multi-block
|
|
124
|
+
* observation. Wire this against a `tx-tracker` instance, not against
|
|
125
|
+
* `awaitReceiptWithHooks`.
|
|
126
|
+
*/
|
|
127
|
+
onDropped?: (info: {
|
|
128
|
+
hash: Hex;
|
|
129
|
+
}) => void;
|
|
130
|
+
/**
|
|
131
|
+
* Called once when a tracker observes that a *different* tx with the
|
|
132
|
+
* same nonce mined in place of the one we were watching — typically
|
|
133
|
+
* the user's own speed-up / cancel from their wallet, or a
|
|
134
|
+
* fee-replacement broadcast separately.
|
|
135
|
+
*
|
|
136
|
+
* `replacement.receipt` is included when the replacement has been
|
|
137
|
+
* mined; trackers may emit `replaced` with no receipt if they only
|
|
138
|
+
* saw the replacement in the mempool.
|
|
139
|
+
*/
|
|
140
|
+
onReplaced?: (info: {
|
|
141
|
+
original: Hex;
|
|
142
|
+
replacement: Hex;
|
|
143
|
+
receipt?: TransactionReceipt;
|
|
144
|
+
}) => void;
|
|
145
|
+
/**
|
|
146
|
+
* Single-callback complement to the named hooks. Fires for every
|
|
147
|
+
* lifecycle transition with a discriminated-union payload. Useful
|
|
148
|
+
* for state-machine consumers that prefer one transition point and
|
|
149
|
+
* exhaustive `switch`-coverage over wiring six separate callbacks.
|
|
150
|
+
*
|
|
151
|
+
* Fire-ers fire BOTH `onPhase` and the matching named hook on each
|
|
152
|
+
* transition — exactly once each — so wiring one shape doesn't
|
|
153
|
+
* preclude the other.
|
|
154
|
+
*/
|
|
155
|
+
onPhase?: (event: WritePhaseEvent) => void;
|
|
156
|
+
}
|
|
157
|
+
//# sourceMappingURL=hooks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../src/hooks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,OAAO,KAAK,EAAE,GAAG,EAAE,kBAAkB,EAAE,MAAM,MAAM,CAAA;AAEnD;;;;;GAKG;AACH,MAAM,MAAM,UAAU,GAClB,WAAW,GACX,oBAAoB,GACpB,SAAS,GACT,WAAW,GACX,QAAQ,GACR,SAAS,GACT,UAAU,CAAA;AAEd;;;;GAIG;AACH,MAAM,MAAM,eAAe,GACvB;IAAE,KAAK,EAAE,WAAW,CAAA;CAAE,GACtB;IAAE,KAAK,EAAE,oBAAoB,CAAA;CAAE,GAC/B;IAAE,KAAK,EAAE,SAAS,CAAC;IAAC,IAAI,EAAE,GAAG,CAAA;CAAE,GAC/B;IAAE,KAAK,EAAE,WAAW,CAAC;IAAC,IAAI,EAAE,GAAG,CAAC;IAAC,OAAO,EAAE,kBAAkB,CAAA;CAAE,GAC9D;IAAE,KAAK,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,KAAK,CAAC;IAAC,IAAI,CAAC,EAAE,GAAG,CAAC;IAAC,OAAO,CAAC,EAAE,kBAAkB,CAAA;CAAE,GAC3E;IAAE,KAAK,EAAE,SAAS,CAAC;IAAC,IAAI,EAAE,GAAG,CAAA;CAAE,GAC/B;IAAE,KAAK,EAAE,UAAU,CAAC;IAAC,QAAQ,EAAE,GAAG,CAAC;IAAC,WAAW,EAAE,GAAG,CAAC;IAAC,OAAO,CAAC,EAAE,kBAAkB,CAAA;CAAE,CAAA;AAExF;;;;;;;;;;GAUG;AACH,MAAM,WAAW,eAAe;IAC9B;;;;OAIG;IACH,mBAAmB,CAAC,EAAE,MAAM,IAAI,CAAA;IAChC;;;;;;;;OAQG;IACH,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,IAAI,CAAA;IACvC;;;;OAIG;IACH,WAAW,CAAC,EAAE,CAAC,OAAO,EAAE,kBAAkB,KAAK,IAAI,CAAA;IACnD;;;;;;;;;OASG;IACH,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAA;IACjC;;;;;;;;;;OAUG;IACH,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,IAAI,EAAE,GAAG,CAAA;KAAE,KAAK,IAAI,CAAA;IACzC;;;;;;;;;OASG;IACH,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,QAAQ,EAAE,GAAG,CAAC;QAAC,WAAW,EAAE,GAAG,CAAC;QAAC,OAAO,CAAC,EAAE,kBAAkB,CAAA;KAAE,KAAK,IAAI,CAAA;IAC9F;;;;;;;;;OASG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,CAAA;CAC3C"}
|
package/dist/hooks.js
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Per-call lifecycle hooks for any SDK method that opens a
|
|
3
|
+
* wallet popup, awaits inclusion, and may later observe replacement or
|
|
4
|
+
* mempool drop.
|
|
5
|
+
*
|
|
6
|
+
* The contract describes EVERY phase a tracked tx can be in. Different
|
|
7
|
+
* fire-ers cover different slices:
|
|
8
|
+
*
|
|
9
|
+
* - `sendTransactionWithHooks` fires the wallet-side phases
|
|
10
|
+
* (`awaiting-signature`, `pending`, plus `failed` on rejection /
|
|
11
|
+
* wallet-side network error).
|
|
12
|
+
* - `awaitReceiptWithHooks` fires the chain-side terminal phases
|
|
13
|
+
* (`confirmed` or `failed` on revert / receipt-await error).
|
|
14
|
+
* - `@valve-tech/tx-tracker` (per-tx state machine, observes across
|
|
15
|
+
* blocks) fires `dropped` and `replaced` once it ships, plus may
|
|
16
|
+
* re-emit transitions if a tx surfaces / vanishes / surfaces again
|
|
17
|
+
* across reorgs.
|
|
18
|
+
* - The SDK itself may fire `preparing` at the very start of its
|
|
19
|
+
* write method, before any pre-wallet work begins.
|
|
20
|
+
*
|
|
21
|
+
* Two shapes are available — complementary, not alternatives:
|
|
22
|
+
*
|
|
23
|
+
* - **Named hooks** (`onAwaitingSignature`, `onConfirmed`, etc.) —
|
|
24
|
+
* ergonomic, easy to wire from a hook-like API, narrow types per
|
|
25
|
+
* callback.
|
|
26
|
+
* - **`onPhase(event)`** — single-callback discriminated union.
|
|
27
|
+
* Better for state-machine consumers that need a single transition
|
|
28
|
+
* point and exhaustive `switch`-coverage on the phase name.
|
|
29
|
+
*
|
|
30
|
+
* Fire-ers fire BOTH shapes for every transition — exactly once each —
|
|
31
|
+
* so consumers can choose which to wire without affecting the other.
|
|
32
|
+
*/
|
|
33
|
+
export {};
|
|
34
|
+
//# sourceMappingURL=hooks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hooks.js","sourceRoot":"","sources":["../src/hooks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Public API of `@valve-tech/wallet-adapter`.
|
|
3
|
+
*/
|
|
4
|
+
export type { WalletAdapter, WalletSendTransactionRequest, WalletReadContractRequest, } from './wallet.js';
|
|
5
|
+
export type { WriteHookParams, WritePhase, WritePhaseEvent, } from './hooks.js';
|
|
6
|
+
export { TX_STATUS, TX_FLOW, STALE_TX_AGE_MS, CONFIRMED_DISPLAY_MS, FAILED_DISPLAY_MS, } from './tx-status.js';
|
|
7
|
+
export type { TrackedTx, TrackedTxGas, TrackedTxStatus, TxFlow, TxConfirmedCallback, } from './tx-status.js';
|
|
8
|
+
export { sendTransactionWithHooks, WalletRejectedError, type SendTransactionWithHooksOptions, } from './send.js';
|
|
9
|
+
export { awaitReceiptWithHooks, ContractRevertedError, type AwaitReceiptWithHooksOptions, type ReceiptAwaiter, } from './receipt.js';
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,YAAY,EACV,aAAa,EACb,4BAA4B,EAC5B,yBAAyB,GAC1B,MAAM,aAAa,CAAA;AAEpB,YAAY,EACV,eAAe,EACf,UAAU,EACV,eAAe,GAChB,MAAM,YAAY,CAAA;AAEnB,OAAO,EACL,SAAS,EACT,OAAO,EACP,eAAe,EACf,oBAAoB,EACpB,iBAAiB,GAClB,MAAM,gBAAgB,CAAA;AAEvB,YAAY,EACV,SAAS,EACT,YAAY,EACZ,eAAe,EACf,MAAM,EACN,mBAAmB,GACpB,MAAM,gBAAgB,CAAA;AAEvB,OAAO,EACL,wBAAwB,EACxB,mBAAmB,EACnB,KAAK,+BAA+B,GACrC,MAAM,WAAW,CAAA;AAElB,OAAO,EACL,qBAAqB,EACrB,qBAAqB,EACrB,KAAK,4BAA4B,EACjC,KAAK,cAAc,GACpB,MAAM,cAAc,CAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Public API of `@valve-tech/wallet-adapter`.
|
|
3
|
+
*/
|
|
4
|
+
export { TX_STATUS, TX_FLOW, STALE_TX_AGE_MS, CONFIRMED_DISPLAY_MS, FAILED_DISPLAY_MS, } from './tx-status.js';
|
|
5
|
+
export { sendTransactionWithHooks, WalletRejectedError, } from './send.js';
|
|
6
|
+
export { awaitReceiptWithHooks, ContractRevertedError, } from './receipt.js';
|
|
7
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAcH,OAAO,EACL,SAAS,EACT,OAAO,EACP,eAAe,EACf,oBAAoB,EACpB,iBAAiB,GAClB,MAAM,gBAAgB,CAAA;AAUvB,OAAO,EACL,wBAAwB,EACxB,mBAAmB,GAEpB,MAAM,WAAW,CAAA;AAElB,OAAO,EACL,qBAAqB,EACrB,qBAAqB,GAGtB,MAAM,cAAc,CAAA"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview The chain-side complement of `sendTransactionWithHooks`.
|
|
3
|
+
*
|
|
4
|
+
* After the wallet returns a hash, an SDK has to:
|
|
5
|
+
* 1. Await the receipt.
|
|
6
|
+
* 2. Distinguish `success` from `reverted`.
|
|
7
|
+
* 3. Fire `onConfirmed` (success) or `onFailed` with a typed revert
|
|
8
|
+
* error (reverted), plus `onPhase` for the same transition, so any
|
|
9
|
+
* UI wired against `WriteHookParams` flips to a terminal state.
|
|
10
|
+
*
|
|
11
|
+
* Without a helper for this, every SDK re-implements the receipt-await +
|
|
12
|
+
* status-check + typed-error-throw block — the same drift trap
|
|
13
|
+
* `sendTransactionWithHooks` was added to fix on the wallet side.
|
|
14
|
+
*
|
|
15
|
+
* Drop detection (tx vanished from mempool without inclusion) and
|
|
16
|
+
* replacement detection are deliberately NOT in this helper. They
|
|
17
|
+
* require observing the tx across many blocks with a configurable
|
|
18
|
+
* timeout policy and nonce-watching — that's
|
|
19
|
+
* `@valve-tech/tx-tracker`'s job. The `WriteHookParams` contract
|
|
20
|
+
* defines `onDropped` / `onReplaced` so consumers can wire them once;
|
|
21
|
+
* this helper just doesn't fire them.
|
|
22
|
+
*/
|
|
23
|
+
import type { Hex, TransactionReceipt } from 'viem';
|
|
24
|
+
import type { WriteHookParams } from './hooks.js';
|
|
25
|
+
/**
|
|
26
|
+
* Thrown by `awaitReceiptWithHooks` when the receipt arrives with
|
|
27
|
+
* `status === 'reverted'`. The full receipt is preserved so consumers
|
|
28
|
+
* can extract revert reasons from logs, gas usage, etc.
|
|
29
|
+
*
|
|
30
|
+
* Distinct from a thrown error during the receipt-await itself
|
|
31
|
+
* (network / RPC issues, timeouts) — those are re-thrown unchanged so
|
|
32
|
+
* the SDK can map them to its own error vocabulary.
|
|
33
|
+
*/
|
|
34
|
+
export declare class ContractRevertedError extends Error {
|
|
35
|
+
/** The hash of the reverted transaction. */
|
|
36
|
+
readonly hash: Hex;
|
|
37
|
+
/** The full receipt with `status === 'reverted'`. */
|
|
38
|
+
readonly receipt: TransactionReceipt;
|
|
39
|
+
constructor(hash: Hex, receipt: TransactionReceipt);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Minimal viem `PublicClient` slice the helper needs. Defining it
|
|
43
|
+
* locally lets consumers pass a viem client OR a hand-rolled mock
|
|
44
|
+
* without depending on the full `PublicClient` surface.
|
|
45
|
+
*/
|
|
46
|
+
export interface ReceiptAwaiter {
|
|
47
|
+
waitForTransactionReceipt(args: {
|
|
48
|
+
hash: Hex;
|
|
49
|
+
}): Promise<TransactionReceipt>;
|
|
50
|
+
}
|
|
51
|
+
export interface AwaitReceiptWithHooksOptions {
|
|
52
|
+
/** A viem `PublicClient` (or anything with the same `waitForTransactionReceipt` shape). */
|
|
53
|
+
publicClient: ReceiptAwaiter;
|
|
54
|
+
/** The hash returned by `sendTransactionWithHooks` (or any other broadcast path). */
|
|
55
|
+
hash: Hex;
|
|
56
|
+
/** Per-call hooks. `onMined` and `onFailed` fire from this helper. */
|
|
57
|
+
hooks?: WriteHookParams;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Await a transaction receipt and fire the post-hash lifecycle hooks.
|
|
61
|
+
* Throws `ContractRevertedError` on revert. Other errors during the
|
|
62
|
+
* receipt-await are re-thrown unchanged after `onFailed` fires.
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* ```ts
|
|
66
|
+
* const hash = await sendTransactionWithHooks({ wallet, request, hooks })
|
|
67
|
+
* const receipt = await awaitReceiptWithHooks({ publicClient, hash, hooks })
|
|
68
|
+
* // Both onMined / onFailed have fired by the time we get here.
|
|
69
|
+
* ```
|
|
70
|
+
*/
|
|
71
|
+
export declare function awaitReceiptWithHooks(options: AwaitReceiptWithHooksOptions): Promise<TransactionReceipt>;
|
|
72
|
+
//# sourceMappingURL=receipt.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"receipt.d.ts","sourceRoot":"","sources":["../src/receipt.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EAAE,GAAG,EAAE,kBAAkB,EAAE,MAAM,MAAM,CAAA;AACnD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAEjD;;;;;;;;GAQG;AACH,qBAAa,qBAAsB,SAAQ,KAAK;IAC9C,4CAA4C;IAC5C,QAAQ,CAAC,IAAI,EAAE,GAAG,CAAA;IAClB,qDAAqD;IACrD,QAAQ,CAAC,OAAO,EAAE,kBAAkB,CAAA;gBAExB,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,kBAAkB;CAMnD;AAED;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC7B,yBAAyB,CAAC,IAAI,EAAE;QAAE,IAAI,EAAE,GAAG,CAAA;KAAE,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAA;CAC5E;AAED,MAAM,WAAW,4BAA4B;IAC3C,2FAA2F;IAC3F,YAAY,EAAE,cAAc,CAAA;IAC5B,qFAAqF;IACrF,IAAI,EAAE,GAAG,CAAA;IACT,sEAAsE;IACtE,KAAK,CAAC,EAAE,eAAe,CAAA;CACxB;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,4BAA4B,GACpC,OAAO,CAAC,kBAAkB,CAAC,CAuB7B"}
|
package/dist/receipt.js
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview The chain-side complement of `sendTransactionWithHooks`.
|
|
3
|
+
*
|
|
4
|
+
* After the wallet returns a hash, an SDK has to:
|
|
5
|
+
* 1. Await the receipt.
|
|
6
|
+
* 2. Distinguish `success` from `reverted`.
|
|
7
|
+
* 3. Fire `onConfirmed` (success) or `onFailed` with a typed revert
|
|
8
|
+
* error (reverted), plus `onPhase` for the same transition, so any
|
|
9
|
+
* UI wired against `WriteHookParams` flips to a terminal state.
|
|
10
|
+
*
|
|
11
|
+
* Without a helper for this, every SDK re-implements the receipt-await +
|
|
12
|
+
* status-check + typed-error-throw block — the same drift trap
|
|
13
|
+
* `sendTransactionWithHooks` was added to fix on the wallet side.
|
|
14
|
+
*
|
|
15
|
+
* Drop detection (tx vanished from mempool without inclusion) and
|
|
16
|
+
* replacement detection are deliberately NOT in this helper. They
|
|
17
|
+
* require observing the tx across many blocks with a configurable
|
|
18
|
+
* timeout policy and nonce-watching — that's
|
|
19
|
+
* `@valve-tech/tx-tracker`'s job. The `WriteHookParams` contract
|
|
20
|
+
* defines `onDropped` / `onReplaced` so consumers can wire them once;
|
|
21
|
+
* this helper just doesn't fire them.
|
|
22
|
+
*/
|
|
23
|
+
/**
|
|
24
|
+
* Thrown by `awaitReceiptWithHooks` when the receipt arrives with
|
|
25
|
+
* `status === 'reverted'`. The full receipt is preserved so consumers
|
|
26
|
+
* can extract revert reasons from logs, gas usage, etc.
|
|
27
|
+
*
|
|
28
|
+
* Distinct from a thrown error during the receipt-await itself
|
|
29
|
+
* (network / RPC issues, timeouts) — those are re-thrown unchanged so
|
|
30
|
+
* the SDK can map them to its own error vocabulary.
|
|
31
|
+
*/
|
|
32
|
+
export class ContractRevertedError extends Error {
|
|
33
|
+
constructor(hash, receipt) {
|
|
34
|
+
super('Transaction reverted on-chain.');
|
|
35
|
+
this.name = 'ContractRevertedError';
|
|
36
|
+
this.hash = hash;
|
|
37
|
+
this.receipt = receipt;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Await a transaction receipt and fire the post-hash lifecycle hooks.
|
|
42
|
+
* Throws `ContractRevertedError` on revert. Other errors during the
|
|
43
|
+
* receipt-await are re-thrown unchanged after `onFailed` fires.
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* ```ts
|
|
47
|
+
* const hash = await sendTransactionWithHooks({ wallet, request, hooks })
|
|
48
|
+
* const receipt = await awaitReceiptWithHooks({ publicClient, hash, hooks })
|
|
49
|
+
* // Both onMined / onFailed have fired by the time we get here.
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
52
|
+
export async function awaitReceiptWithHooks(options) {
|
|
53
|
+
const { publicClient, hash, hooks } = options;
|
|
54
|
+
let receipt;
|
|
55
|
+
try {
|
|
56
|
+
receipt = await publicClient.waitForTransactionReceipt({ hash });
|
|
57
|
+
}
|
|
58
|
+
catch (err) {
|
|
59
|
+
const failure = err instanceof Error ? err : new Error(String(err));
|
|
60
|
+
hooks?.onFailed?.(failure);
|
|
61
|
+
hooks?.onPhase?.({ phase: 'failed', error: failure, hash });
|
|
62
|
+
throw failure;
|
|
63
|
+
}
|
|
64
|
+
if (receipt.status === 'reverted') {
|
|
65
|
+
const revert = new ContractRevertedError(hash, receipt);
|
|
66
|
+
hooks?.onFailed?.(revert);
|
|
67
|
+
hooks?.onPhase?.({ phase: 'failed', error: revert, hash, receipt });
|
|
68
|
+
throw revert;
|
|
69
|
+
}
|
|
70
|
+
hooks?.onConfirmed?.(receipt);
|
|
71
|
+
hooks?.onPhase?.({ phase: 'confirmed', hash, receipt });
|
|
72
|
+
return receipt;
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=receipt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"receipt.js","sourceRoot":"","sources":["../src/receipt.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAKH;;;;;;;;GAQG;AACH,MAAM,OAAO,qBAAsB,SAAQ,KAAK;IAM9C,YAAY,IAAS,EAAE,OAA2B;QAChD,KAAK,CAAC,gCAAgC,CAAC,CAAA;QACvC,IAAI,CAAC,IAAI,GAAG,uBAAuB,CAAA;QACnC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;QAChB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAA;IACxB,CAAC;CACF;AAoBD;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,OAAqC;IAErC,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,OAAO,CAAA;IAE7C,IAAI,OAA2B,CAAA;IAC/B,IAAI,CAAC;QACH,OAAO,GAAG,MAAM,YAAY,CAAC,yBAAyB,CAAC,EAAE,IAAI,EAAE,CAAC,CAAA;IAClE,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAA;QACnE,KAAK,EAAE,QAAQ,EAAE,CAAC,OAAO,CAAC,CAAA;QAC1B,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAA;QAC3D,MAAM,OAAO,CAAA;IACf,CAAC;IAED,IAAI,OAAO,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;QAClC,MAAM,MAAM,GAAG,IAAI,qBAAqB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;QACvD,KAAK,EAAE,QAAQ,EAAE,CAAC,MAAM,CAAC,CAAA;QACzB,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAA;QACnE,MAAM,MAAM,CAAA;IACd,CAAC;IAED,KAAK,EAAE,WAAW,EAAE,CAAC,OAAO,CAAC,CAAA;IAC7B,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAA;IACvD,OAAO,OAAO,CAAA;AAChB,CAAC"}
|
package/dist/send.d.ts
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview The single SDK helper for sending a transaction with
|
|
3
|
+
* lifecycle hooks fired at the real boundaries.
|
|
4
|
+
*
|
|
5
|
+
* This is the runtime piece of the lifecycle contract. SDK authors call
|
|
6
|
+
* this from inside any write method that opens a wallet popup; it
|
|
7
|
+
* guarantees:
|
|
8
|
+
* - `onAwaitingSignature` fires exactly once, immediately before
|
|
9
|
+
* `wallet.sendTransaction(...)`.
|
|
10
|
+
* - `onTransactionHash` (per-call) and the global `onTransactionHash`
|
|
11
|
+
* channel fire exactly once each, after `sendTransaction` resolves
|
|
12
|
+
* and BEFORE the SDK awaits any receipt — so callers can flip their
|
|
13
|
+
* UI from `awaiting-signature` to `pending` the moment a hash exists
|
|
14
|
+
* instead of stalling for the full inclusion window.
|
|
15
|
+
* - Wallet rejections (EIP-1193 `code === 4001`, viem's
|
|
16
|
+
* `UserRejectedRequestError`, or matching message text — see
|
|
17
|
+
* `@valve-tech/viem-errors` for the detection signals) are converted
|
|
18
|
+
* to a `WalletRejectedError` so consumers can `instanceof`-check
|
|
19
|
+
* them. Non-rejection errors are re-thrown unchanged so the SDK
|
|
20
|
+
* can map them to its own typed error vocabulary.
|
|
21
|
+
*
|
|
22
|
+
* Without this helper, every SDK that wants the contract has to
|
|
23
|
+
* re-implement: the error-mapping `try/catch` block (with the
|
|
24
|
+
* three-signal rejection check), the constructor-vs-per-call hook
|
|
25
|
+
* fan-out, and the precise ordering relative to `sendTransaction`.
|
|
26
|
+
*/
|
|
27
|
+
import type { Hex } from 'viem';
|
|
28
|
+
import type { WalletAdapter, WalletSendTransactionRequest } from './wallet.js';
|
|
29
|
+
import type { WriteHookParams } from './hooks.js';
|
|
30
|
+
/**
|
|
31
|
+
* Thrown by `sendTransactionWithHooks` when the wallet rejection is
|
|
32
|
+
* detected at any level of the cause chain. The original error is
|
|
33
|
+
* preserved as `cause` so consumers can still inspect it (locale
|
|
34
|
+
* details, exact wallet phrasing, etc.) when they map this to their
|
|
35
|
+
* own typed error vocabulary.
|
|
36
|
+
*/
|
|
37
|
+
export declare class WalletRejectedError extends Error {
|
|
38
|
+
/** The original rejection thrown by the wallet adapter. */
|
|
39
|
+
readonly cause: Error;
|
|
40
|
+
constructor(cause: Error);
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Options accepted by `sendTransactionWithHooks`.
|
|
44
|
+
*/
|
|
45
|
+
export interface SendTransactionWithHooksOptions {
|
|
46
|
+
/** The wallet adapter that will sign + broadcast the request. */
|
|
47
|
+
wallet: WalletAdapter;
|
|
48
|
+
/** The fully-formed send request (calldata, gas inputs, chainId). */
|
|
49
|
+
request: WalletSendTransactionRequest;
|
|
50
|
+
/** Per-call lifecycle hooks. Both fields are optional. */
|
|
51
|
+
hooks?: WriteHookParams;
|
|
52
|
+
/**
|
|
53
|
+
* Optional global / constructor-level `onTransactionHash` channel.
|
|
54
|
+
* Fires alongside `hooks.onTransactionHash` on the same line —
|
|
55
|
+
* complementary, not alternatives. Use this for analytics or
|
|
56
|
+
* debug-logging that should observe every write regardless of which
|
|
57
|
+
* caller fired it.
|
|
58
|
+
*/
|
|
59
|
+
onTransactionHash?: (hash: Hex) => void;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Submit a transaction through the wallet adapter, firing lifecycle
|
|
63
|
+
* hooks at the real boundaries and converting wallet rejections to a
|
|
64
|
+
* typed `WalletRejectedError`.
|
|
65
|
+
*
|
|
66
|
+
* @example
|
|
67
|
+
* ```ts
|
|
68
|
+
* try {
|
|
69
|
+
* const hash = await sendTransactionWithHooks({
|
|
70
|
+
* wallet: this.wallet,
|
|
71
|
+
* request: { ...prepared, ...gasInputs },
|
|
72
|
+
* hooks: params, // user-supplied per-call hooks
|
|
73
|
+
* onTransactionHash: this.onHash, // constructor-level / analytics
|
|
74
|
+
* })
|
|
75
|
+
* const receipt = await this.publicClient.waitForTransactionReceipt({ hash })
|
|
76
|
+
* return { hash, receipt }
|
|
77
|
+
* } catch (err) {
|
|
78
|
+
* if (err instanceof WalletRejectedError) {
|
|
79
|
+
* throw new MySdkError('WALLET_REJECTED', err.message, err.cause)
|
|
80
|
+
* }
|
|
81
|
+
* throw new MySdkError('CONTRACT_ERROR', (err as Error).message, err as Error)
|
|
82
|
+
* }
|
|
83
|
+
* ```
|
|
84
|
+
*/
|
|
85
|
+
export declare function sendTransactionWithHooks(options: SendTransactionWithHooksOptions): Promise<Hex>;
|
|
86
|
+
//# sourceMappingURL=send.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"send.d.ts","sourceRoot":"","sources":["../src/send.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,MAAM,CAAA;AAE/B,OAAO,KAAK,EAAE,aAAa,EAAE,4BAA4B,EAAE,MAAM,aAAa,CAAA;AAC9E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAEjD;;;;;;GAMG;AACH,qBAAa,mBAAoB,SAAQ,KAAK;IAC5C,2DAA2D;IAC3D,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAA;gBAET,KAAK,EAAE,KAAK;CAKzB;AAED;;GAEG;AACH,MAAM,WAAW,+BAA+B;IAC9C,iEAAiE;IACjE,MAAM,EAAE,aAAa,CAAA;IACrB,qEAAqE;IACrE,OAAO,EAAE,4BAA4B,CAAA;IACrC,0DAA0D;IAC1D,KAAK,CAAC,EAAE,eAAe,CAAA;IACvB;;;;;;OAMG;IACH,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,IAAI,CAAA;CACxC;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAsB,wBAAwB,CAC5C,OAAO,EAAE,+BAA+B,GACvC,OAAO,CAAC,GAAG,CAAC,CAuBd"}
|
package/dist/send.js
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview The single SDK helper for sending a transaction with
|
|
3
|
+
* lifecycle hooks fired at the real boundaries.
|
|
4
|
+
*
|
|
5
|
+
* This is the runtime piece of the lifecycle contract. SDK authors call
|
|
6
|
+
* this from inside any write method that opens a wallet popup; it
|
|
7
|
+
* guarantees:
|
|
8
|
+
* - `onAwaitingSignature` fires exactly once, immediately before
|
|
9
|
+
* `wallet.sendTransaction(...)`.
|
|
10
|
+
* - `onTransactionHash` (per-call) and the global `onTransactionHash`
|
|
11
|
+
* channel fire exactly once each, after `sendTransaction` resolves
|
|
12
|
+
* and BEFORE the SDK awaits any receipt — so callers can flip their
|
|
13
|
+
* UI from `awaiting-signature` to `pending` the moment a hash exists
|
|
14
|
+
* instead of stalling for the full inclusion window.
|
|
15
|
+
* - Wallet rejections (EIP-1193 `code === 4001`, viem's
|
|
16
|
+
* `UserRejectedRequestError`, or matching message text — see
|
|
17
|
+
* `@valve-tech/viem-errors` for the detection signals) are converted
|
|
18
|
+
* to a `WalletRejectedError` so consumers can `instanceof`-check
|
|
19
|
+
* them. Non-rejection errors are re-thrown unchanged so the SDK
|
|
20
|
+
* can map them to its own typed error vocabulary.
|
|
21
|
+
*
|
|
22
|
+
* Without this helper, every SDK that wants the contract has to
|
|
23
|
+
* re-implement: the error-mapping `try/catch` block (with the
|
|
24
|
+
* three-signal rejection check), the constructor-vs-per-call hook
|
|
25
|
+
* fan-out, and the precise ordering relative to `sendTransaction`.
|
|
26
|
+
*/
|
|
27
|
+
import { isUserRejectionError } from '@valve-tech/viem-errors';
|
|
28
|
+
/**
|
|
29
|
+
* Thrown by `sendTransactionWithHooks` when the wallet rejection is
|
|
30
|
+
* detected at any level of the cause chain. The original error is
|
|
31
|
+
* preserved as `cause` so consumers can still inspect it (locale
|
|
32
|
+
* details, exact wallet phrasing, etc.) when they map this to their
|
|
33
|
+
* own typed error vocabulary.
|
|
34
|
+
*/
|
|
35
|
+
export class WalletRejectedError extends Error {
|
|
36
|
+
constructor(cause) {
|
|
37
|
+
super('Transaction was rejected in wallet.');
|
|
38
|
+
this.name = 'WalletRejectedError';
|
|
39
|
+
this.cause = cause;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Submit a transaction through the wallet adapter, firing lifecycle
|
|
44
|
+
* hooks at the real boundaries and converting wallet rejections to a
|
|
45
|
+
* typed `WalletRejectedError`.
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* ```ts
|
|
49
|
+
* try {
|
|
50
|
+
* const hash = await sendTransactionWithHooks({
|
|
51
|
+
* wallet: this.wallet,
|
|
52
|
+
* request: { ...prepared, ...gasInputs },
|
|
53
|
+
* hooks: params, // user-supplied per-call hooks
|
|
54
|
+
* onTransactionHash: this.onHash, // constructor-level / analytics
|
|
55
|
+
* })
|
|
56
|
+
* const receipt = await this.publicClient.waitForTransactionReceipt({ hash })
|
|
57
|
+
* return { hash, receipt }
|
|
58
|
+
* } catch (err) {
|
|
59
|
+
* if (err instanceof WalletRejectedError) {
|
|
60
|
+
* throw new MySdkError('WALLET_REJECTED', err.message, err.cause)
|
|
61
|
+
* }
|
|
62
|
+
* throw new MySdkError('CONTRACT_ERROR', (err as Error).message, err as Error)
|
|
63
|
+
* }
|
|
64
|
+
* ```
|
|
65
|
+
*/
|
|
66
|
+
export async function sendTransactionWithHooks(options) {
|
|
67
|
+
const { wallet, request, hooks, onTransactionHash } = options;
|
|
68
|
+
let hash;
|
|
69
|
+
try {
|
|
70
|
+
hooks?.onAwaitingSignature?.();
|
|
71
|
+
hooks?.onPhase?.({ phase: 'awaiting-signature' });
|
|
72
|
+
hash = await wallet.sendTransaction(request);
|
|
73
|
+
}
|
|
74
|
+
catch (err) {
|
|
75
|
+
const failure = isUserRejectionError(err)
|
|
76
|
+
? new WalletRejectedError(err instanceof Error ? err : new Error(String(err)))
|
|
77
|
+
: err instanceof Error
|
|
78
|
+
? err
|
|
79
|
+
: new Error(String(err));
|
|
80
|
+
hooks?.onFailed?.(failure);
|
|
81
|
+
hooks?.onPhase?.({ phase: 'failed', error: failure });
|
|
82
|
+
throw failure;
|
|
83
|
+
}
|
|
84
|
+
onTransactionHash?.(hash);
|
|
85
|
+
hooks?.onTransactionHash?.(hash);
|
|
86
|
+
hooks?.onPhase?.({ phase: 'pending', hash });
|
|
87
|
+
return hash;
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=send.js.map
|
package/dist/send.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"send.js","sourceRoot":"","sources":["../src/send.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAGH,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAA;AAI9D;;;;;;GAMG;AACH,MAAM,OAAO,mBAAoB,SAAQ,KAAK;IAI5C,YAAY,KAAY;QACtB,KAAK,CAAC,qCAAqC,CAAC,CAAA;QAC5C,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAA;QACjC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAA;IACpB,CAAC;CACF;AAsBD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC5C,OAAwC;IAExC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,iBAAiB,EAAE,GAAG,OAAO,CAAA;IAE7D,IAAI,IAAS,CAAA;IACb,IAAI,CAAC;QACH,KAAK,EAAE,mBAAmB,EAAE,EAAE,CAAA;QAC9B,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,oBAAoB,EAAE,CAAC,CAAA;QACjD,IAAI,GAAG,MAAM,MAAM,CAAC,eAAe,CAAC,OAAO,CAAC,CAAA;IAC9C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,OAAO,GAAG,oBAAoB,CAAC,GAAG,CAAC;YACvC,CAAC,CAAC,IAAI,mBAAmB,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;YAC9E,CAAC,CAAC,GAAG,YAAY,KAAK;gBACpB,CAAC,CAAC,GAAG;gBACL,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAA;QAC5B,KAAK,EAAE,QAAQ,EAAE,CAAC,OAAO,CAAC,CAAA;QAC1B,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAA;QACrD,MAAM,OAAO,CAAA;IACf,CAAC;IAED,iBAAiB,EAAE,CAAC,IAAI,CAAC,CAAA;IACzB,KAAK,EAAE,iBAAiB,EAAE,CAAC,IAAI,CAAC,CAAA;IAChC,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IAC5C,OAAO,IAAI,CAAA;AACb,CAAC"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Lifecycle vocabulary for tracked transactions.
|
|
3
|
+
*
|
|
4
|
+
* Defines the shared status / flow constants and the `TrackedTx` shape
|
|
5
|
+
* so any SDK or UI can speak the same vocabulary about a transaction
|
|
6
|
+
* in flight. This is the **opinion** layer that an in-flight UI sits on
|
|
7
|
+
* top of `@valve-tech/tx-tracker`'s neutral observations.
|
|
8
|
+
*
|
|
9
|
+
* Why constants instead of plain string types: consumers MUST reference
|
|
10
|
+
* via `TX_STATUS.preparing` / `TX_FLOW.signalIntent` rather than
|
|
11
|
+
* writing raw strings, so a rename here propagates through the type
|
|
12
|
+
* system instead of leaving stale literals at call sites.
|
|
13
|
+
*/
|
|
14
|
+
import type { Hex } from 'viem';
|
|
15
|
+
/**
|
|
16
|
+
* Canonical lifecycle states for a tracked transaction.
|
|
17
|
+
*
|
|
18
|
+
* Lifecycle:
|
|
19
|
+
* preparing → awaiting-signature → pending → confirmed | failed | dropped
|
|
20
|
+
* ↘ replaced (on speed-up)
|
|
21
|
+
*
|
|
22
|
+
* The two pre-hash states (`preparing`, `awaitingSignature`) carry no
|
|
23
|
+
* `hash` and cannot be receipt-polled. They exist so the UI has
|
|
24
|
+
* something to show during gas-estimation + wallet-sign — without them
|
|
25
|
+
* the strip would stay blank until after the wallet returns.
|
|
26
|
+
*
|
|
27
|
+
* Naming: `confirmed` (not `mined`) matches the user-facing UI label
|
|
28
|
+
* and the `WritePhase` / `onConfirmed` hook surface. The receipt has
|
|
29
|
+
* arrived and the tx succeeded; consumers that need block-confirmation
|
|
30
|
+
* counts can layer that on top.
|
|
31
|
+
*/
|
|
32
|
+
export declare const TX_STATUS: {
|
|
33
|
+
readonly preparing: "preparing";
|
|
34
|
+
readonly awaitingSignature: "awaiting-signature";
|
|
35
|
+
readonly pending: "pending";
|
|
36
|
+
readonly confirmed: "confirmed";
|
|
37
|
+
readonly failed: "failed";
|
|
38
|
+
readonly replaced: "replaced";
|
|
39
|
+
readonly dropped: "dropped";
|
|
40
|
+
};
|
|
41
|
+
export type TrackedTxStatus = typeof TX_STATUS[keyof typeof TX_STATUS];
|
|
42
|
+
/**
|
|
43
|
+
* The "what is the user doing" label for a tracked transaction. Distinct
|
|
44
|
+
* from `status` (which is the lifecycle phase): `flow` describes the
|
|
45
|
+
* action and stays constant for the whole lifecycle, while `status`
|
|
46
|
+
* advances over time.
|
|
47
|
+
*
|
|
48
|
+
* This is a generic / extensible enum — protocols add their own flow
|
|
49
|
+
* names by extending the type. The base set ships none of its own,
|
|
50
|
+
* intentionally: every protocol's flow vocabulary is its own.
|
|
51
|
+
*/
|
|
52
|
+
export declare const TX_FLOW: {};
|
|
53
|
+
export type TxFlow = string;
|
|
54
|
+
/**
|
|
55
|
+
* Gas the wallet actually sent the transaction with. Captured at submit
|
|
56
|
+
* time so a speed-up replacement can compute the EIP-1559 ≥10% bump
|
|
57
|
+
* relative to what's actually in the mempool, not what the oracle
|
|
58
|
+
* estimated when the user clicked.
|
|
59
|
+
*/
|
|
60
|
+
export interface TrackedTxGas {
|
|
61
|
+
maxFeePerGas: bigint;
|
|
62
|
+
maxPriorityFeePerGas: bigint;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* One in-flight (or recently-terminal) transaction the UI is showing.
|
|
66
|
+
*
|
|
67
|
+
* `id` is the stable identifier — assigned at the registry's `beginTx`
|
|
68
|
+
* time, before any hash exists. `hash` is attached later (when
|
|
69
|
+
* `wallet.sendTransaction` resolves). For post-hash callers using a
|
|
70
|
+
* legacy `trackTx({ hash, ... })` API, registries SHOULD default `id`
|
|
71
|
+
* to `hash` so existing code keeps working unchanged.
|
|
72
|
+
*
|
|
73
|
+
* `submittedTier` is a string so this type doesn't need to depend on
|
|
74
|
+
* `@valve-tech/gas-oracle`'s `TierName`. Consumers using the oracle
|
|
75
|
+
* can refine it locally.
|
|
76
|
+
*/
|
|
77
|
+
export interface TrackedTx {
|
|
78
|
+
id: string;
|
|
79
|
+
hash?: Hex;
|
|
80
|
+
chainId: number;
|
|
81
|
+
flow: TxFlow;
|
|
82
|
+
submittedAt: number;
|
|
83
|
+
confirmedAt?: number;
|
|
84
|
+
submittedGas?: TrackedTxGas;
|
|
85
|
+
submittedTier: string;
|
|
86
|
+
status: TrackedTxStatus;
|
|
87
|
+
replacedBy?: Hex;
|
|
88
|
+
replaces?: Hex;
|
|
89
|
+
/**
|
|
90
|
+
* Human-readable note for terminal-with-detail states. UIs SHOULD
|
|
91
|
+
* prefer `notes` over generic copy when rendering `failed` /
|
|
92
|
+
* `dropped` so a "cancelled in wallet" or decoded error name surfaces
|
|
93
|
+
* instead of a flat "transaction failed".
|
|
94
|
+
*/
|
|
95
|
+
notes?: string;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* How long a stale (older than this) tracked tx may be ignored by
|
|
99
|
+
* receipt-polling logic. Default mirrors the chosen UX in tx-flight
|
|
100
|
+
* surfaces: 10 minutes is long enough for a slow inclusion, short
|
|
101
|
+
* enough to garbage-collect zombie entries.
|
|
102
|
+
*/
|
|
103
|
+
export declare const STALE_TX_AGE_MS: number;
|
|
104
|
+
/**
|
|
105
|
+
* Symmetric linger windows for terminal-with-detail states. These let
|
|
106
|
+
* confirmed/failed states stay on screen long enough for the user to
|
|
107
|
+
* read the outcome without permanently occupying the UI surface.
|
|
108
|
+
*/
|
|
109
|
+
export declare const CONFIRMED_DISPLAY_MS = 10000;
|
|
110
|
+
export declare const FAILED_DISPLAY_MS = 10000;
|
|
111
|
+
/** Fired once when a tracked tx becomes `mined`. */
|
|
112
|
+
export type TxConfirmedCallback = (tx: TrackedTx) => void | Promise<void>;
|
|
113
|
+
//# sourceMappingURL=tx-status.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tx-status.d.ts","sourceRoot":"","sources":["../src/tx-status.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,MAAM,CAAA;AAI/B;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,SAAS;;;;;;;;CAQZ,CAAA;AAEV,MAAM,MAAM,eAAe,GAAG,OAAO,SAAS,CAAC,MAAM,OAAO,SAAS,CAAC,CAAA;AAItE;;;;;;;;;GASG;AACH,eAAO,MAAM,OAAO,IAAc,CAAA;AAElC,MAAM,MAAM,MAAM,GAAG,MAAM,CAAA;AAI3B;;;;;GAKG;AACH,MAAM,WAAW,YAAY;IAC3B,YAAY,EAAE,MAAM,CAAA;IACpB,oBAAoB,EAAE,MAAM,CAAA;CAC7B;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,CAAC,EAAE,GAAG,CAAA;IACV,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,YAAY,CAAC,EAAE,YAAY,CAAA;IAC3B,aAAa,EAAE,MAAM,CAAA;IACrB,MAAM,EAAE,eAAe,CAAA;IACvB,UAAU,CAAC,EAAE,GAAG,CAAA;IAChB,QAAQ,CAAC,EAAE,GAAG,CAAA;IACd;;;;;OAKG;IACH,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAID;;;;;GAKG;AACH,eAAO,MAAM,eAAe,QAAiB,CAAA;AAE7C;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,QAAS,CAAA;AAC1C,eAAO,MAAM,iBAAiB,QAAS,CAAA;AAIvC,oDAAoD;AACpD,MAAM,MAAM,mBAAmB,GAAG,CAAC,EAAE,EAAE,SAAS,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Lifecycle vocabulary for tracked transactions.
|
|
3
|
+
*
|
|
4
|
+
* Defines the shared status / flow constants and the `TrackedTx` shape
|
|
5
|
+
* so any SDK or UI can speak the same vocabulary about a transaction
|
|
6
|
+
* in flight. This is the **opinion** layer that an in-flight UI sits on
|
|
7
|
+
* top of `@valve-tech/tx-tracker`'s neutral observations.
|
|
8
|
+
*
|
|
9
|
+
* Why constants instead of plain string types: consumers MUST reference
|
|
10
|
+
* via `TX_STATUS.preparing` / `TX_FLOW.signalIntent` rather than
|
|
11
|
+
* writing raw strings, so a rename here propagates through the type
|
|
12
|
+
* system instead of leaving stale literals at call sites.
|
|
13
|
+
*/
|
|
14
|
+
// ─── Status ────────────────────────────────────────────────────────────────
|
|
15
|
+
/**
|
|
16
|
+
* Canonical lifecycle states for a tracked transaction.
|
|
17
|
+
*
|
|
18
|
+
* Lifecycle:
|
|
19
|
+
* preparing → awaiting-signature → pending → confirmed | failed | dropped
|
|
20
|
+
* ↘ replaced (on speed-up)
|
|
21
|
+
*
|
|
22
|
+
* The two pre-hash states (`preparing`, `awaitingSignature`) carry no
|
|
23
|
+
* `hash` and cannot be receipt-polled. They exist so the UI has
|
|
24
|
+
* something to show during gas-estimation + wallet-sign — without them
|
|
25
|
+
* the strip would stay blank until after the wallet returns.
|
|
26
|
+
*
|
|
27
|
+
* Naming: `confirmed` (not `mined`) matches the user-facing UI label
|
|
28
|
+
* and the `WritePhase` / `onConfirmed` hook surface. The receipt has
|
|
29
|
+
* arrived and the tx succeeded; consumers that need block-confirmation
|
|
30
|
+
* counts can layer that on top.
|
|
31
|
+
*/
|
|
32
|
+
export const TX_STATUS = {
|
|
33
|
+
preparing: 'preparing',
|
|
34
|
+
awaitingSignature: 'awaiting-signature',
|
|
35
|
+
pending: 'pending',
|
|
36
|
+
confirmed: 'confirmed',
|
|
37
|
+
failed: 'failed',
|
|
38
|
+
replaced: 'replaced',
|
|
39
|
+
dropped: 'dropped',
|
|
40
|
+
};
|
|
41
|
+
// ─── Flow ──────────────────────────────────────────────────────────────────
|
|
42
|
+
/**
|
|
43
|
+
* The "what is the user doing" label for a tracked transaction. Distinct
|
|
44
|
+
* from `status` (which is the lifecycle phase): `flow` describes the
|
|
45
|
+
* action and stays constant for the whole lifecycle, while `status`
|
|
46
|
+
* advances over time.
|
|
47
|
+
*
|
|
48
|
+
* This is a generic / extensible enum — protocols add their own flow
|
|
49
|
+
* names by extending the type. The base set ships none of its own,
|
|
50
|
+
* intentionally: every protocol's flow vocabulary is its own.
|
|
51
|
+
*/
|
|
52
|
+
export const TX_FLOW = {};
|
|
53
|
+
// ─── Display windows ───────────────────────────────────────────────────────
|
|
54
|
+
/**
|
|
55
|
+
* How long a stale (older than this) tracked tx may be ignored by
|
|
56
|
+
* receipt-polling logic. Default mirrors the chosen UX in tx-flight
|
|
57
|
+
* surfaces: 10 minutes is long enough for a slow inclusion, short
|
|
58
|
+
* enough to garbage-collect zombie entries.
|
|
59
|
+
*/
|
|
60
|
+
export const STALE_TX_AGE_MS = 10 * 60 * 1000; // 10 minutes
|
|
61
|
+
/**
|
|
62
|
+
* Symmetric linger windows for terminal-with-detail states. These let
|
|
63
|
+
* confirmed/failed states stay on screen long enough for the user to
|
|
64
|
+
* read the outcome without permanently occupying the UI surface.
|
|
65
|
+
*/
|
|
66
|
+
export const CONFIRMED_DISPLAY_MS = 10000;
|
|
67
|
+
export const FAILED_DISPLAY_MS = 10000;
|
|
68
|
+
//# sourceMappingURL=tx-status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tx-status.js","sourceRoot":"","sources":["../src/tx-status.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAIH,8EAA8E;AAE9E;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG;IACvB,SAAS,EAAU,WAAW;IAC9B,iBAAiB,EAAE,oBAAoB;IACvC,OAAO,EAAY,SAAS;IAC5B,SAAS,EAAU,WAAW;IAC9B,MAAM,EAAa,QAAQ;IAC3B,QAAQ,EAAW,UAAU;IAC7B,OAAO,EAAY,SAAS;CACpB,CAAA;AAIV,8EAA8E;AAE9E;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,EAAW,CAAA;AAmDlC,8EAA8E;AAE9E;;;;;GAKG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAA,CAAC,aAAa;AAE3D;;;;GAIG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,KAAM,CAAA;AAC1C,MAAM,CAAC,MAAM,iBAAiB,GAAG,KAAM,CAAA"}
|
package/dist/wallet.d.ts
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview The framework-agnostic wallet contract.
|
|
3
|
+
*
|
|
4
|
+
* Decouples SDKs from any specific wallet library. A `WalletAdapter` is
|
|
5
|
+
* the only seam an SDK needs to sign and send a transaction; the dapp
|
|
6
|
+
* decides whether that backend is wagmi, ethers, viem direct, a smart
|
|
7
|
+
* account, a multisig, or a relayer.
|
|
8
|
+
*/
|
|
9
|
+
import type { Hex } from 'viem';
|
|
10
|
+
/**
|
|
11
|
+
* The minimal request shape an SDK passes to a wallet for sign + send.
|
|
12
|
+
*
|
|
13
|
+
* Fields:
|
|
14
|
+
* - `to` — destination address.
|
|
15
|
+
* - `data` — encoded calldata (`0x...`).
|
|
16
|
+
* - `value` — native-token amount in wei. Defaults to 0 if omitted.
|
|
17
|
+
* - `chainId` — chain to sign for. Wallets MUST validate this against
|
|
18
|
+
* the connected chain and throw rather than silently
|
|
19
|
+
* sign for the wrong network.
|
|
20
|
+
* - `maxFeePerGas` / `maxPriorityFeePerGas` — EIP-1559 gas pricing in
|
|
21
|
+
* wei. Optional so a wallet can defer to its own gas
|
|
22
|
+
* logic; if both are present, the wallet should honour
|
|
23
|
+
* them.
|
|
24
|
+
*/
|
|
25
|
+
export interface WalletSendTransactionRequest {
|
|
26
|
+
to: Hex;
|
|
27
|
+
data: Hex;
|
|
28
|
+
value?: bigint;
|
|
29
|
+
chainId: number;
|
|
30
|
+
maxFeePerGas?: bigint;
|
|
31
|
+
maxPriorityFeePerGas?: bigint;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Optional read-from-contract escape hatch. Wallets that proxy reads
|
|
35
|
+
* (e.g. account abstraction with custom RPC) implement this; the SDK
|
|
36
|
+
* falls back to a public RPC when omitted.
|
|
37
|
+
*/
|
|
38
|
+
export interface WalletReadContractRequest {
|
|
39
|
+
address: Hex;
|
|
40
|
+
abi: readonly unknown[];
|
|
41
|
+
functionName: string;
|
|
42
|
+
args?: readonly unknown[];
|
|
43
|
+
chainId?: number;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Framework-agnostic wallet interface. Works with wagmi, viem direct,
|
|
47
|
+
* ethers, smart accounts, and relayers — anything that can sign and
|
|
48
|
+
* send a transaction.
|
|
49
|
+
*
|
|
50
|
+
* SDKs should accept a `WalletAdapter` rather than tying themselves to
|
|
51
|
+
* a specific wallet library, so the same SDK works across the whole
|
|
52
|
+
* downstream landscape without per-wallet code paths.
|
|
53
|
+
*/
|
|
54
|
+
export interface WalletAdapter {
|
|
55
|
+
/** Connected address, or undefined if disconnected. */
|
|
56
|
+
address?: Hex;
|
|
57
|
+
/** Sign and send a transaction. Returns the on-chain tx hash. */
|
|
58
|
+
sendTransaction(request: WalletSendTransactionRequest): Promise<Hex>;
|
|
59
|
+
/**
|
|
60
|
+
* Optional contract read. SDKs SHOULD prefer this when present (lets a
|
|
61
|
+
* smart-account / paymaster-aware wallet route reads through its own
|
|
62
|
+
* pipeline) and fall back to a public RPC client otherwise.
|
|
63
|
+
*/
|
|
64
|
+
readContract?(request: WalletReadContractRequest): Promise<unknown>;
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=wallet.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wallet.d.ts","sourceRoot":"","sources":["../src/wallet.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,MAAM,CAAA;AAE/B;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,4BAA4B;IAC3C,EAAE,EAAE,GAAG,CAAA;IACP,IAAI,EAAE,GAAG,CAAA;IACT,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,MAAM,CAAA;IACf,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,oBAAoB,CAAC,EAAE,MAAM,CAAA;CAC9B;AAED;;;;GAIG;AACH,MAAM,WAAW,yBAAyB;IACxC,OAAO,EAAE,GAAG,CAAA;IACZ,GAAG,EAAE,SAAS,OAAO,EAAE,CAAA;IACvB,YAAY,EAAE,MAAM,CAAA;IACpB,IAAI,CAAC,EAAE,SAAS,OAAO,EAAE,CAAA;IACzB,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,aAAa;IAC5B,uDAAuD;IACvD,OAAO,CAAC,EAAE,GAAG,CAAA;IACb,iEAAiE;IACjE,eAAe,CAAC,OAAO,EAAE,4BAA4B,GAAG,OAAO,CAAC,GAAG,CAAC,CAAA;IACpE;;;;OAIG;IACH,YAAY,CAAC,CAAC,OAAO,EAAE,yBAAyB,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;CACpE"}
|
package/dist/wallet.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview The framework-agnostic wallet contract.
|
|
3
|
+
*
|
|
4
|
+
* Decouples SDKs from any specific wallet library. A `WalletAdapter` is
|
|
5
|
+
* the only seam an SDK needs to sign and send a transaction; the dapp
|
|
6
|
+
* decides whether that backend is wagmi, ethers, viem direct, a smart
|
|
7
|
+
* account, a multisig, or a relayer.
|
|
8
|
+
*/
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=wallet.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wallet.js","sourceRoot":"","sources":["../src/wallet.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG"}
|
package/package.json
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@valve-tech/wallet-adapter",
|
|
3
|
+
"version": "0.3.1",
|
|
4
|
+
"description": "Framework-agnostic vocabulary for EVM dapp wallet integration: WalletAdapter interface (sign + send), WriteHookParams lifecycle hooks (onAwaitingSignature, per-call onTransactionHash), and TX_STATUS / TX_FLOW / TrackedTx for tx-state UI. Pure types, no runtime dependencies. Lets SDKs and dapps share one contract instead of each redefining it. Part of the valve-tech/evm-toolkit synchronized release line.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"homepage": "https://github.com/valve-tech/evm-toolkit/tree/main/packages/wallet-adapter#readme",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/valve-tech/evm-toolkit.git",
|
|
10
|
+
"directory": "packages/wallet-adapter"
|
|
11
|
+
},
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/valve-tech/evm-toolkit/issues"
|
|
14
|
+
},
|
|
15
|
+
"keywords": [
|
|
16
|
+
"ethereum",
|
|
17
|
+
"evm",
|
|
18
|
+
"viem",
|
|
19
|
+
"wagmi",
|
|
20
|
+
"wallet",
|
|
21
|
+
"wallet-adapter",
|
|
22
|
+
"tx-status",
|
|
23
|
+
"lifecycle-hooks"
|
|
24
|
+
],
|
|
25
|
+
"type": "module",
|
|
26
|
+
"main": "dist/index.js",
|
|
27
|
+
"types": "dist/index.d.ts",
|
|
28
|
+
"exports": {
|
|
29
|
+
".": {
|
|
30
|
+
"types": "./dist/index.d.ts",
|
|
31
|
+
"import": "./dist/index.js"
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
"files": [
|
|
35
|
+
"dist",
|
|
36
|
+
"README.md",
|
|
37
|
+
"CHANGELOG.md",
|
|
38
|
+
"LICENSE"
|
|
39
|
+
],
|
|
40
|
+
"scripts": {
|
|
41
|
+
"build": "tsc -p .",
|
|
42
|
+
"typecheck": "tsc -p . --noEmit",
|
|
43
|
+
"lint": "eslint src",
|
|
44
|
+
"test": "vitest run",
|
|
45
|
+
"test:coverage": "vitest run --coverage",
|
|
46
|
+
"prepare": "yarn build"
|
|
47
|
+
},
|
|
48
|
+
"dependencies": {
|
|
49
|
+
"@valve-tech/viem-errors": "workspace:^"
|
|
50
|
+
},
|
|
51
|
+
"peerDependencies": {
|
|
52
|
+
"viem": "^2.0.0"
|
|
53
|
+
}
|
|
54
|
+
}
|