@tuwaio/nova-transactions 0.6.0 → 0.7.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/README.md CHANGED
@@ -1,167 +1,105 @@
1
1
  # @tuwaio/nova-transactions
2
2
 
3
3
  [![NPM Version](https://img.shields.io/npm/v/@tuwaio/nova-transactions.svg)](https://www.npmjs.com/package/@tuwaio/nova-transactions)
4
- [![License](https://img.shields.io/npm/l/@tuwaio/nova-transactions.svg)](./LICENSE)
4
+ [![License](https://img.shields.io/npm/l/@tuwaio/nova-transactions.svg)](https://github.com/TuwaIO/nova-uikit/blob/main/packages/nova-transactions/LICENSE)
5
5
 
6
- `@tuwaio/nova-transactions` is the **UI Components (L7)** package of the TUWA Ecosystem transaction lifecycle tracking system. It provides the visual layer to monitor, display, and manage active on-chain transactions, consuming state directly from the headless **[Pulsar Engine](https://github.com/TuwaIO/pulsar-core)** state machine.
7
-
8
- By coupling the UI manager to Pulsar stores, it automatically handles pending loaders, speed-up options, failure overlays, and success notifications, keeping the user in the loop even during congested block space periods.
6
+ `@tuwaio/nova-transactions` is the transactions Layer 7 (L7) package of **Nova UI Kit**, the user interface project of TUWA Stage 4 ("User Interface"). Built on **`react`**, **`react-toastify`**, **`framer-motion`** and [`@tuwaio/nova-core`](https://stories.tuwa.io/?path=/docs/packages-nova-core-overview--docs), it renders the transactions of a [Pulsar](https://pulsar.docs.tuwa.io) store: progress toasts, a tracking modal and the transaction history. It keeps no transaction state of its own: the state, the trackers and the wallet actions stay in `@tuwaio/pulsar-core`.
9
7
 
10
8
  ---
11
9
 
12
10
  ## 🏛️ Core Capabilities
13
11
 
14
- - **🧩 Interactive Visual Nodes:** Built-in dialogs and widget cards (`TrackingTxModal` for individual status, `TransactionsInfoModal` for full transaction lists, and `ToastTransaction` feeds).
15
- - **⚡ ERC-4337 Account Abstraction & Two-Stage Presentation:** Native handling of UserOperation tracking. Displays `UserOp Hash` while in the bundler mempool (Stage 1), automatically transitioning to the mined on-chain transaction hash (Stage 2) with native explorer links.
16
- - **🔌 Isolated Provider Hooks:** The `<NovaTransactionsProvider />` bridges your React tree with Pulsar's transaction history pools and signature polling events.
17
- - **🎨 Custom Styling overrides:** Style sub-components via CSS variables from `@tuwaio/nova-core` or replace components using the `customization` property.
18
- - **🌍 Dynamic Internationalization:** Supports overriding labels configuration to localize status messages (`pending`, `success`, `failed`, `replaced`) and actions.
12
+ - **Provider:** `NovaTransactionsProvider` (`/providers`) takes the Pulsar store values (`transactionsPool`, `initialTx`, `executeTxAction`, `closeTxTrackedModal`) and the Pulsar adapters, and renders, each behind a feature flag that is on by default: a toast for every tracked transaction, a tracking modal for the latest one, the transaction history modal, and an error toast when `executeTxAction` fails before the transaction reaches the pool.
13
+ - **Transaction actions:** the toasts and the tracking modal offer speed-up and cancel for a pending, unconfirmed EVM transaction (`ethereum` tracker) sent with MetaMask, when the adapter has `speedUpTxAction` and `cancelTxAction` (the toast also requires the connected wallet to be the sender); the tracking modal offers retry through the adapter's `retryTxAction` while the `initialTx` of the failed submission is in the store. Explorer links come from the adapter's `getExplorerTxUrl` and `getExplorerUrl`; a link is hidden when the adapter returns no URL.
14
+ - **Components:** `ToastTransaction`, `TrackingTxModal` (with `TxStatusVisual`, `TxProgressIndicator`, `TxInfoBlock`, `TxErrorBlock`), `TransactionsInfoModal`, `TransactionsHistory`, `TransactionHistoryItem`, `TransactionDetails`, `TransactionKey`, `HashLink`, `TransactionStatusBadge`, `StatusAwareText` and `TxActionButton` can also be rendered on their own. Many of them take a `customization` prop with class name functions and replacement components for their parts.
15
+ - **Labels:** `defaultLabels` (English) are merged with the `labels` prop of the provider; `NovaTransactionsLabelsProvider` and `useLabels` give the labels to custom components.
19
16
 
20
17
  ---
21
18
 
22
19
  ## 💾 Installation
23
20
 
24
- ```bash
25
- pnpm add @tuwaio/nova-transactions @tuwaio/nova-core @tuwaio/pulsar-core @tuwaio/orbit-core @web3icons/react @web3icons/common @heroicons/react @radix-ui/react-dialog framer-motion react-toastify dayjs react
26
- ```
21
+ The package has two entry points:
27
22
 
28
- > [!IMPORTANT]
29
- > All peer dependencies listed above must be present in your project for `@tuwaio/nova-transactions` to operate correctly.
23
+ | Import path | Provides |
24
+ | ------------------------------------- | ------------------------------------------------------------------------------- |
25
+ | `@tuwaio/nova-transactions` | The components, `defaultLabels` and the label types |
26
+ | `@tuwaio/nova-transactions/providers` | `NovaTransactionsProvider`, `NovaTransactionsLabelsProvider`, the error context |
30
27
 
31
- ---
28
+ Importing the package adds the `relativeTime` plugin to `dayjs`. Both entry points need the same peer dependencies: `@tuwaio/nova-core`, `@tuwaio/pulsar-core` (>=0.7), `@tuwaio/orbit-core` (>=0.3), `react` (>=19.2.3), `react-toastify` (>=11), `framer-motion`, `@heroicons/react` (2.x) and `dayjs` (1.x), plus the peer dependencies of `@tuwaio/nova-core`:
32
29
 
33
- ## ⚡ ERC-4337 Support & Hash Labels
30
+ ```bash
31
+ pnpm add @tuwaio/nova-transactions @tuwaio/nova-core @tuwaio/pulsar-core @tuwaio/orbit-core react react-toastify framer-motion @heroicons/react dayjs @radix-ui/react-dialog @web3icons/react @web3icons/common clsx tailwind-merge
32
+ ```
34
33
 
35
- When tracking ERC-4337 Smart Account transactions (dispatched via Pimlico or native bundlers):
34
+ Import the stylesheets of `@tuwaio/nova-core` (theme variables) and of this package (the component styles, Tailwind CSS v4 utilities prefixed with `novatx:`):
36
35
 
37
- 1. **UserOp Hash (Mempool Stage)**: While the operation is pending execution by the bundler, the UI displays the transaction key labeled as **`UserOp Hash`** (`hashLabels.erc4337 = 'UserOp Hash'`).
38
- 2. **On-Chain Settlement (Mined Stage)**: Once the UserOp is bundled into an on-chain transaction, the UI updates seamlessly to show the mined block transaction hash, linking directly to the standard blockchain explorer (e.g. Etherscan `/tx/${hash}`).
39
- 3. **Custom Labels**: Localize or customize hash labels via `NovaTransactionsLabelsProvider` or the `labels` prop on `NovaTransactionsProvider`.
36
+ ```css
37
+ @import '@tuwaio/nova-core/dist/index.css';
38
+ @import '@tuwaio/nova-transactions/dist/index.css';
39
+ ```
40
40
 
41
41
  ---
42
42
 
43
- ## 🚀 Quick Start Setup
44
-
45
- ### 1. Create the Transaction Store (Pulsar)
43
+ ## 🚀 Usage
46
44
 
47
- Initialize the local-first persistent transaction store with chain-specific state adapters:
45
+ Render the provider once, next to your app, with the values of your Pulsar store:
48
46
 
49
47
  ```tsx
50
- // src/hooks/usePulsarStore.ts
51
48
  'use client';
52
49
 
53
- import { createBoundedUseStore, createPulsarStore, Transaction } from '@tuwaio/pulsar-core';
50
+ import { NovaTransactionsProvider } from '@tuwaio/nova-transactions/providers';
51
+ import { OrbitAdapter } from '@tuwaio/orbit-core';
52
+ import { createBoundedUseStore, createPulsarStore, type Transaction } from '@tuwaio/pulsar-core';
54
53
  import { pulsarEvmAdapter } from '@tuwaio/pulsar-evm';
55
- import { pulsarSolanaAdapter } from '@tuwaio/pulsar-solana';
56
- import { wagmiConfig, appEVMChains, solanaRPCUrls } from '@/config/appConfig';
57
-
58
- const storageName = 'transactions-tracking-storage';
59
-
60
- export enum TxType {
61
- swap = 'swap',
62
- }
63
-
64
- type SwapTx = Transaction & {
65
- type: TxType.swap;
66
- payload: { from: string; to: string; amount: string };
67
- };
54
+ import { useInitializeTransactionsPool } from '@tuwaio/pulsar-react';
55
+ import { createConfig, http, injected } from '@wagmi/core';
56
+ import { mainnet } from 'viem/chains';
68
57
 
69
- export type TransactionUnion = SwapTx;
58
+ const appChains = [mainnet] as const;
59
+ const wagmiConfig = createConfig({ chains: appChains, connectors: [injected()], transports: { [mainnet.id]: http() } });
70
60
 
71
61
  export const usePulsarStore = createBoundedUseStore(
72
- createPulsarStore<TransactionUnion>({
73
- name: storageName,
74
- adapter: [pulsarEvmAdapter(wagmiConfig, appEVMChains), pulsarSolanaAdapter({ rpcUrls: solanaRPCUrls })],
75
- maxTransactions: 50, // prevent localStorage bloat
76
- }),
62
+ createPulsarStore<Transaction>({ name: 'pulsar-transactions', adapter: pulsarEvmAdapter(wagmiConfig, appChains) }),
77
63
  );
78
- ```
79
-
80
- ### 2. Setup the Transactions UI Provider
81
-
82
- Create a bridge component connecting your Pulsar store parameters and Satellite wallet state with the Nova Transactions UI:
83
-
84
- ```tsx
85
- // src/providers/NovaTransactionsWrapper.tsx
86
- 'use client';
87
-
88
- import { useSatelliteConnectStore } from '@tuwaio/nova-connect/satellite';
89
- import { NovaTransactionsProvider as NTP } from '@tuwaio/nova-transactions/providers';
90
- import { getAdapterFromConnectorType } from '@tuwaio/orbit-core';
91
- import { useInitializeTransactionsPool } from '@tuwaio/pulsar-react';
92
64
 
93
- import { usePulsarStore } from '@/hooks/usePulsarStore';
94
-
95
- export function NovaTransactionsWrapper() {
96
- const getAdapter = usePulsarStore((state) => state.getAdapter);
97
- const initialTx = usePulsarStore((state) => state.initialTx);
98
- const closeTxTrackedModal = usePulsarStore((state) => state.closeTxTrackedModal);
65
+ export function TransactionsUI({ walletAddress }: { walletAddress?: string }) {
99
66
  const transactionsPool = usePulsarStore((state) => state.transactionsPool);
67
+ const initialTx = usePulsarStore((state) => state.initialTx);
100
68
  const executeTxAction = usePulsarStore((state) => state.executeTxAction);
69
+ const closeTxTrackedModal = usePulsarStore((state) => state.closeTxTrackedModal);
101
70
  const initializeTransactionsPool = usePulsarStore((state) => state.initializeTransactionsPool);
71
+ const getAdapter = usePulsarStore((state) => state.getAdapter);
102
72
 
103
- const activeConnection = useSatelliteConnectStore((state) => state.activeConnection);
104
-
105
- // Resume tracking for active pending signatures on mount
106
73
  useInitializeTransactionsPool({ initializeTransactionsPool });
107
74
 
108
75
  return (
109
- <NTP
76
+ <NovaTransactionsProvider
77
+ adapter={getAdapter()}
110
78
  transactionsPool={transactionsPool}
111
79
  initialTx={initialTx}
112
- closeTxTrackedModal={closeTxTrackedModal}
113
80
  executeTxAction={executeTxAction}
114
- connectedWalletAddress={activeConnection?.isConnected ? activeConnection.address : undefined}
115
- connectedAdapterType={getAdapterFromConnectorType(activeConnection?.connectorType ?? 'evm:')}
116
- adapter={getAdapter()}
81
+ closeTxTrackedModal={closeTxTrackedModal}
82
+ connectedWalletAddress={walletAddress}
83
+ connectedAdapterType={OrbitAdapter.EVM}
117
84
  />
118
85
  );
119
86
  }
120
87
  ```
121
88
 
122
- ### 3. Usage in Action Buttons
89
+ Start transactions with the store's `executeTxAction`. A full app with Satellite Connect, Nova Connect, SIWX and a Pulsar store synced with a server is in the **[TUWA SDK documentation](https://sdk.docs.tuwa.io/full-stack)**, and every component can be tried in the Storybook sections **Nova Transactions** of [stories.tuwa.io](https://stories.tuwa.io/).
123
90
 
124
- Call the action wrapper to trigger on-chain operations and auto-render status modals:
91
+ ---
125
92
 
126
- ```tsx
127
- import { usePulsarStore, TxType } from '@/hooks/usePulsarStore';
128
- import { OrbitAdapter } from '@tuwaio/orbit-core';
129
- import { mainnet } from 'viem/chains';
93
+ ## 🌐 External Services
130
94
 
131
- export function SwapButton() {
132
- const executeTxAction = usePulsarStore((state) => state.executeTxAction);
95
+ The package sends no network requests. Explorer links are built by the Pulsar adapters and opened by the browser only when clicked; the RPC requests of the trackers are made by Pulsar. The package does not use `localStorage` (the Pulsar store persists the transactions).
133
96
 
134
- const triggerSwap = async () => {
135
- const swapFunction = async () => {
136
- // Execute smart contract write method or UserOperation and return the hash
137
- return '0x...';
138
- };
139
-
140
- await executeTxAction({
141
- actionFunction: swapFunction,
142
- onSuccess: (tx) => console.log('Transaction succeeded!', tx.hash),
143
- params: {
144
- type: TxType.swap,
145
- adapter: OrbitAdapter.EVM,
146
- desiredChainID: mainnet.id,
147
- title: 'Swap ETH',
148
- description: 'Swapping 1 ETH for USDC',
149
- payload: { from: 'ETH', to: 'USDC', amount: '1' },
150
- withTrackedModal: true, // opens tracking overlay automatically
151
- },
152
- });
153
- };
97
+ ---
154
98
 
155
- return (
156
- <button onClick={triggerSwap} className="btn-primary">
157
- Execute Swap
158
- </button>
159
- );
160
- }
161
- ```
99
+ ## 📚 API Reference
162
100
 
163
- ---
101
+ Every export, with signatures and types generated from the source, is documented at **[stories.tuwa.io → Packages → nova-transactions](https://stories.tuwa.io/?path=/docs/packages-nova-transactions-overview--docs)**.
164
102
 
165
103
  ## 📄 License
166
104
 
167
- Licensed under the **Apache-2.0 License**. See the [LICENSE](./LICENSE) file for details.
105
+ Licensed under the **Apache-2.0 License**. See the [LICENSE](https://github.com/TuwaIO/nova-uikit/blob/main/packages/nova-transactions/LICENSE) file for details.