@rainlanguage/ui-components 0.0.1-alpha.115 → 0.0.1-alpha.117

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.
Files changed (29) hide show
  1. package/dist/__mocks__/mockTransactionStore.js +9 -17
  2. package/dist/components/transactions/FixedBottomTransaction.svelte +63 -0
  3. package/dist/components/transactions/FixedBottomTransaction.svelte.d.ts +16 -0
  4. package/dist/components/transactions/TransactionDetail.svelte +31 -0
  5. package/dist/components/transactions/TransactionDetail.svelte.d.ts +20 -0
  6. package/dist/components/transactions/TransactionList.svelte +17 -0
  7. package/dist/components/transactions/TransactionList.svelte.d.ts +16 -0
  8. package/dist/components/transactions/getStatusEmoji.d.ts +2 -0
  9. package/dist/components/transactions/getStatusEmoji.js +20 -0
  10. package/dist/index.d.ts +12 -4
  11. package/dist/index.js +8 -1
  12. package/dist/models/Transaction.d.ts +79 -0
  13. package/dist/models/Transaction.js +110 -0
  14. package/dist/providers/transactions/TransactionManager.d.ts +92 -0
  15. package/dist/providers/transactions/TransactionManager.js +148 -0
  16. package/dist/providers/transactions/TransactionProvider.svelte +11 -0
  17. package/dist/providers/transactions/TransactionProvider.svelte.d.ts +24 -0
  18. package/dist/providers/transactions/context.d.ts +19 -0
  19. package/dist/providers/transactions/context.js +28 -0
  20. package/dist/providers/transactions/useTransactions.d.ts +13 -0
  21. package/dist/providers/transactions/useTransactions.js +18 -0
  22. package/dist/services/awaitTransactionIndexing.d.ts +8 -5
  23. package/dist/services/awaitTransactionIndexing.js +3 -5
  24. package/dist/stores/transactionStore.d.ts +13 -54
  25. package/dist/stores/transactionStore.js +17 -80
  26. package/dist/types/modal.d.ts +13 -5
  27. package/dist/types/transaction.d.ts +54 -6
  28. package/dist/types/transaction.js +26 -1
  29. package/package.json +2 -2
@@ -1,5 +1,6 @@
1
1
  import { writable } from 'svelte/store';
2
- import { TransactionStatus, initialState, TransactionErrorMessage } from '../stores/transactionStore';
2
+ import { initialState, TransactionErrorMessage } from '../stores/transactionStore';
3
+ import { TransactionStatusMessage } from '../types/transaction';
3
4
  const mockTransactionWritable = writable(initialState);
4
5
  export const mockTransactionStore = {
5
6
  subscribe: mockTransactionWritable.subscribe,
@@ -7,7 +8,7 @@ export const mockTransactionStore = {
7
8
  handleDeploymentTransaction: async () => {
8
9
  mockTransactionWritable.update((state) => ({
9
10
  ...state,
10
- status: TransactionStatus.SUCCESS,
11
+ status: TransactionStatusMessage.SUCCESS,
11
12
  message: 'Strategy deployed successfully!',
12
13
  hash: '0x123'
13
14
  }));
@@ -16,40 +17,31 @@ export const mockTransactionStore = {
16
17
  handleDepositOrWithdrawTransaction: async () => {
17
18
  mockTransactionWritable.update((state) => ({
18
19
  ...state,
19
- status: TransactionStatus.SUCCESS,
20
+ status: TransactionStatusMessage.SUCCESS,
20
21
  message: 'Transaction successful!',
21
22
  hash: '0x456'
22
23
  }));
23
24
  return Promise.resolve();
24
25
  },
25
- handleRemoveOrderTransaction: async () => {
26
- mockTransactionWritable.update((state) => ({
27
- ...state,
28
- status: TransactionStatus.SUCCESS,
29
- message: 'Order removed successfully',
30
- hash: '0x789'
31
- }));
32
- return Promise.resolve();
33
- },
34
26
  checkingWalletAllowance: (message = '') => mockTransactionWritable.update((state) => ({
35
27
  ...state,
36
- status: TransactionStatus.CHECKING_ALLOWANCE,
28
+ status: TransactionStatusMessage.CHECKING_ALLOWANCE,
37
29
  message
38
30
  })),
39
31
  awaitWalletConfirmation: (message = '') => mockTransactionWritable.update((state) => ({
40
32
  ...state,
41
- status: TransactionStatus.PENDING_WALLET,
33
+ status: TransactionStatusMessage.PENDING_WALLET,
42
34
  message
43
35
  })),
44
36
  awaitApprovalTx: (hash) => mockTransactionWritable.update((state) => ({
45
37
  ...state,
46
38
  hash,
47
- status: TransactionStatus.PENDING_APPROVAL,
39
+ status: TransactionStatusMessage.PENDING_APPROVAL,
48
40
  message: 'Approving token spend...'
49
41
  })),
50
42
  transactionSuccess: (hash, message = '', newOrderHash = '', network = '') => mockTransactionWritable.update((state) => ({
51
43
  ...state,
52
- status: TransactionStatus.SUCCESS,
44
+ status: TransactionStatusMessage.SUCCESS,
53
45
  hash,
54
46
  message,
55
47
  newOrderHash,
@@ -57,7 +49,7 @@ export const mockTransactionStore = {
57
49
  })),
58
50
  transactionError: (error, hash = '') => mockTransactionWritable.update((state) => ({
59
51
  ...state,
60
- status: TransactionStatus.ERROR,
52
+ status: TransactionStatusMessage.ERROR,
61
53
  error,
62
54
  hash
63
55
  })),
@@ -0,0 +1,63 @@
1
+ <script>import { useTransactions } from "../../providers/transactions/useTransactions";
2
+ import { CloseOutline } from "flowbite-svelte-icons";
3
+ import { writable } from "svelte/store";
4
+ import { getStatusEmoji } from "./getStatusEmoji";
5
+ const { transactions } = useTransactions();
6
+ const isDismissed = writable(false);
7
+ $: latestTransaction = $transactions.length > 0 ? $transactions[$transactions.length - 1].state : null;
8
+ $: if (latestTransaction) {
9
+ isDismissed.set(false);
10
+ }
11
+ function dismissTransaction() {
12
+ isDismissed.set(true);
13
+ }
14
+ </script>
15
+
16
+ {#if $latestTransaction && !$isDismissed}
17
+ <div
18
+ class="fixed bottom-0 left-0 right-0 z-40 border-t border-gray-200 bg-white lg:hidden dark:border-gray-700 dark:bg-gray-900"
19
+ >
20
+ <div class="flex items-start gap-3 p-3">
21
+ <!-- Transaction details -->
22
+ <div class="min-w-0 flex-1">
23
+ <div class="mb-1 flex items-center gap-2">
24
+ <span class="text-lg">{getStatusEmoji($latestTransaction.status)}</span>
25
+ <p class="truncate text-sm font-semibold text-gray-600 dark:text-gray-400">
26
+ {$latestTransaction.name}
27
+ </p>
28
+ </div>
29
+ <p class="truncate text-xs text-gray-600 dark:text-gray-400">
30
+ {$latestTransaction.status}
31
+ </p>
32
+ {#if $latestTransaction.errorDetails}
33
+ <p class="truncate text-xs text-red-600 dark:text-red-400">
34
+ {$latestTransaction.errorDetails}
35
+ </p>
36
+ {/if}
37
+ {#if $latestTransaction.links.length > 0}
38
+ <div class="mt-1 flex gap-2">
39
+ {#each $latestTransaction.links.slice(0, 2) as link}
40
+ <a
41
+ href={link.link}
42
+ target="_blank"
43
+ rel="noopener noreferrer"
44
+ class="truncate text-xs text-blue-500 hover:underline"
45
+ >
46
+ {link.label}
47
+ </a>
48
+ {/each}
49
+ </div>
50
+ {/if}
51
+ </div>
52
+
53
+ <!-- Close button -->
54
+ <button
55
+ on:click={dismissTransaction}
56
+ class="flex-shrink-0 p-1 text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200"
57
+ aria-label="Dismiss transaction"
58
+ >
59
+ <CloseOutline class="h-4 w-4" />
60
+ </button>
61
+ </div>
62
+ </div>
63
+ {/if}
@@ -0,0 +1,16 @@
1
+ import { SvelteComponent } from "svelte";
2
+ declare const __propDef: {
3
+ props: Record<string, never>;
4
+ events: {
5
+ [evt: string]: CustomEvent<any>;
6
+ };
7
+ slots: {};
8
+ exports?: {} | undefined;
9
+ bindings?: string | undefined;
10
+ };
11
+ export type FixedBottomTransactionProps = typeof __propDef.props;
12
+ export type FixedBottomTransactionEvents = typeof __propDef.events;
13
+ export type FixedBottomTransactionSlots = typeof __propDef.slots;
14
+ export default class FixedBottomTransaction extends SvelteComponent<FixedBottomTransactionProps, FixedBottomTransactionEvents, FixedBottomTransactionSlots> {
15
+ }
16
+ export {};
@@ -0,0 +1,31 @@
1
+ <script>import {} from "svelte/store";
2
+ import { getStatusEmoji } from "./getStatusEmoji";
3
+ export let state;
4
+ </script>
5
+
6
+ <div class="flex w-full flex-col gap-1 rounded-md bg-gray-300 p-2 dark:bg-gray-700">
7
+ <p class="break-words font-semibold">{$state.name}</p>
8
+ <div class="flex flex-col gap-1 text-sm">
9
+ <p class="break-words">{getStatusEmoji($state.status)} {$state.status}</p>
10
+ {#if $state.errorDetails}
11
+ <p class="break-words">{$state.errorDetails}</p>
12
+ {/if}
13
+ {#if $state.links.length > 0}
14
+ <div class="flex flex-col gap-1">
15
+ {#each $state.links as link}
16
+ <p class="break-words">
17
+ <a
18
+ href={link.link}
19
+ data-testid={`transaction-detail-link-${link.label}`}
20
+ target="_blank"
21
+ rel="noopener noreferrer"
22
+ class="text-blue-500 hover:underline"
23
+ >
24
+ {link.label}
25
+ </a>
26
+ </p>
27
+ {/each}
28
+ </div>
29
+ {/if}
30
+ </div>
31
+ </div>
@@ -0,0 +1,20 @@
1
+ import { SvelteComponent } from "svelte";
2
+ import type { TransactionStoreState } from '../../models/Transaction';
3
+ import { type Readable } from 'svelte/store';
4
+ declare const __propDef: {
5
+ props: {
6
+ state: Readable<TransactionStoreState>;
7
+ };
8
+ events: {
9
+ [evt: string]: CustomEvent<any>;
10
+ };
11
+ slots: {};
12
+ exports?: {} | undefined;
13
+ bindings?: string | undefined;
14
+ };
15
+ export type TransactionDetailProps = typeof __propDef.props;
16
+ export type TransactionDetailEvents = typeof __propDef.events;
17
+ export type TransactionDetailSlots = typeof __propDef.slots;
18
+ export default class TransactionDetail extends SvelteComponent<TransactionDetailProps, TransactionDetailEvents, TransactionDetailSlots> {
19
+ }
20
+ export {};
@@ -0,0 +1,17 @@
1
+ <script>import TransactionDetail from "./TransactionDetail.svelte";
2
+ import { useTransactions } from "../../providers/transactions/useTransactions";
3
+ const { transactions } = useTransactions();
4
+ </script>
5
+
6
+ {#if $transactions.length > 0}
7
+ <div class="h-full overflow-y-auto" data-testid="transaction-list">
8
+ <ul aria-label="Transaction list" class="flex w-full flex-col gap-4">
9
+ {#each $transactions.slice().reverse() as transaction}
10
+ {@const state = transaction.state}
11
+ <li>
12
+ <TransactionDetail {state} />
13
+ </li>
14
+ {/each}
15
+ </ul>
16
+ </div>
17
+ {/if}
@@ -0,0 +1,16 @@
1
+ import { SvelteComponent } from "svelte";
2
+ declare const __propDef: {
3
+ props: Record<string, never>;
4
+ events: {
5
+ [evt: string]: CustomEvent<any>;
6
+ };
7
+ slots: {};
8
+ exports?: {} | undefined;
9
+ bindings?: string | undefined;
10
+ };
11
+ export type TransactionListProps = typeof __propDef.props;
12
+ export type TransactionListEvents = typeof __propDef.events;
13
+ export type TransactionListSlots = typeof __propDef.slots;
14
+ export default class TransactionList extends SvelteComponent<TransactionListProps, TransactionListEvents, TransactionListSlots> {
15
+ }
16
+ export {};
@@ -0,0 +1,2 @@
1
+ import { TransactionStatusMessage } from '../../types/transaction';
2
+ export declare function getStatusEmoji(status: TransactionStatusMessage): string;
@@ -0,0 +1,20 @@
1
+ import { TransactionStatusMessage } from '../../types/transaction';
2
+ import { match } from 'ts-pattern';
3
+ export function getStatusEmoji(status) {
4
+ return match(status)
5
+ .with(TransactionStatusMessage.PENDING_RECEIPT, () => '🔄')
6
+ .with(TransactionStatusMessage.PENDING_SUBGRAPH, () => '📊')
7
+ .with(TransactionStatusMessage.SUCCESS, () => '✅')
8
+ .with(TransactionStatusMessage.ERROR, () => '❌')
9
+ .otherwise(() => '❓');
10
+ }
11
+ if (import.meta.vitest) {
12
+ describe('getStatusEmoji', () => {
13
+ it('should return the correct emoji for each status', () => {
14
+ expect(getStatusEmoji(TransactionStatusMessage.PENDING_RECEIPT)).toBe('🔄');
15
+ expect(getStatusEmoji(TransactionStatusMessage.PENDING_SUBGRAPH)).toBe('📊');
16
+ expect(getStatusEmoji(TransactionStatusMessage.SUCCESS)).toBe('✅');
17
+ expect(getStatusEmoji(TransactionStatusMessage.ERROR)).toBe('❌');
18
+ });
19
+ });
20
+ }
package/dist/index.d.ts CHANGED
@@ -64,11 +64,14 @@ export { default as DisclaimerModal } from './components/deployment/DisclaimerMo
64
64
  export { default as InvalidStrategiesSection } from './components/deployment/InvalidStrategiesSection.svelte';
65
65
  export { default as ValidStrategiesSection } from './components/deployment/ValidStrategiesSection.svelte';
66
66
  export { default as InputRegistryUrl } from './components/input/InputRegistryUrl.svelte';
67
+ export { default as TransactionList } from './components/transactions/TransactionList.svelte';
68
+ export { default as FixedBottomTransaction } from './components/transactions/FixedBottomTransaction.svelte';
67
69
  export type { AppStoresInterface } from './types/appStores.ts';
68
- export type { ConfigSource, OrderbookConfigSource, OrderbookCfgRef } from '@rainlanguage/orderbook';
69
- export { TransactionStatus, TransactionErrorMessage, type TransactionState, type ExtendedApprovalCalldata } from './stores/transactionStore';
70
- export type { DeploymentArgs, VaultActionArgs, OrderRemoveArgs } from './types/transaction';
71
- export type { VaultActionModalProps, OrderRemoveModalProps, QuoteDebugModalHandler, DebugTradeModalHandler, DeployModalProps, DisclaimerModalProps } from './types/modal';
70
+ export type { OrderbookConfigSource, OrderbookCfgRef } from '@rainlanguage/orderbook';
71
+ export { TransactionStatusMessage, TransactionStoreErrorMessage, type ExtendedApprovalCalldata, type TransactionArgs } from './types/transaction';
72
+ export type { TransactionErrorMessage } from './stores/transactionStore';
73
+ export type { DeploymentArgs, VaultActionArgs } from './types/transaction';
74
+ export type { VaultActionModalProps, QuoteDebugModalHandler, DebugTradeModalHandler, DeployModalProps, DisclaimerModalProps, TransactionConfirmationProps } from './types/modal';
72
75
  export type { ValidStrategyDetail, InvalidStrategyDetail } from './types/strategy';
73
76
  export type { ToastProps } from './types/toast';
74
77
  export { createResolvableQuery, createResolvableInfiniteQuery } from './__mocks__/queries';
@@ -78,6 +81,7 @@ export { vaultBalanceDisplay } from './utils/vault';
78
81
  export { bigintToFloat } from './utils/number';
79
82
  export { getExplorerLink } from './services/getExplorerLink';
80
83
  export { invalidateTanstackQueries } from './queries/queryClient';
84
+ export { getToastsContext } from './providers/toasts/context';
81
85
  export { DEFAULT_PAGE_SIZE, DEFAULT_REFRESH_INTERVAL } from './queries/constants';
82
86
  export { QKEY_VAULTS, QKEY_VAULT, QKEY_VAULT_CHANGES, QKEY_ORDERS, QKEY_ORDER, QKEY_ORDER_TRADES_LIST, QKEY_ORDER_QUOTE, QKEY_VAULTS_VOL_LIST, QKEY_ORDER_APY } from './queries/keys';
83
87
  export { darkChartTheme, lightChartTheme } from './utils/lightweightChartsThemes';
@@ -90,11 +94,15 @@ export { default as GuiProvider } from './providers/GuiProvider.svelte';
90
94
  export { default as WalletProvider } from './providers/wallet/WalletProvider.svelte';
91
95
  export { default as RegistryProvider } from './providers/registry/RegistryProvider.svelte';
92
96
  export { default as ToastProvider } from './providers/toasts/ToastProvider.svelte';
97
+ export { default as TransactionProvider } from './providers/transactions/TransactionProvider.svelte';
93
98
  export { useGui } from './hooks/useGui';
94
99
  export { useAccount } from './providers/wallet/useAccount';
95
100
  export { useRegistry } from './providers/registry/useRegistry';
96
101
  export { useToasts } from './providers/toasts/useToasts';
102
+ export { useTransactions } from './providers/transactions/useTransactions';
97
103
  export { RegistryManager } from './providers/registry/RegistryManager';
104
+ export { TransactionStore } from './models/Transaction';
105
+ export { TransactionManager } from './providers/transactions/TransactionManager';
98
106
  export { mockPageStore } from './__mocks__/stores';
99
107
  export { mockConfigSource } from './__mocks__/settings';
100
108
  export { mockSettingsStore } from './__mocks__/settings';
package/dist/index.js CHANGED
@@ -65,7 +65,9 @@ export { default as DisclaimerModal } from './components/deployment/DisclaimerMo
65
65
  export { default as InvalidStrategiesSection } from './components/deployment/InvalidStrategiesSection.svelte';
66
66
  export { default as ValidStrategiesSection } from './components/deployment/ValidStrategiesSection.svelte';
67
67
  export { default as InputRegistryUrl } from './components/input/InputRegistryUrl.svelte';
68
- export { TransactionStatus, TransactionErrorMessage } from './stores/transactionStore';
68
+ export { default as TransactionList } from './components/transactions/TransactionList.svelte';
69
+ export { default as FixedBottomTransaction } from './components/transactions/FixedBottomTransaction.svelte';
70
+ export { TransactionStatusMessage, TransactionStoreErrorMessage } from './types/transaction';
69
71
  // Functions
70
72
  export { createResolvableQuery, createResolvableInfiniteQuery } from './__mocks__/queries';
71
73
  export { formatTimestampSecondsAsLocal, timestampSecondsToUTCTimestamp, promiseTimeout } from './services/time';
@@ -74,6 +76,7 @@ export { vaultBalanceDisplay } from './utils/vault';
74
76
  export { bigintToFloat } from './utils/number';
75
77
  export { getExplorerLink } from './services/getExplorerLink';
76
78
  export { invalidateTanstackQueries } from './queries/queryClient';
79
+ export { getToastsContext } from './providers/toasts/context';
77
80
  // Constants
78
81
  export { DEFAULT_PAGE_SIZE, DEFAULT_REFRESH_INTERVAL } from './queries/constants';
79
82
  export { QKEY_VAULTS, QKEY_VAULT, QKEY_VAULT_CHANGES, QKEY_ORDERS, QKEY_ORDER, QKEY_ORDER_TRADES_LIST, QKEY_ORDER_QUOTE, QKEY_VAULTS_VOL_LIST, QKEY_ORDER_APY } from './queries/keys';
@@ -90,13 +93,17 @@ export { default as GuiProvider } from './providers/GuiProvider.svelte';
90
93
  export { default as WalletProvider } from './providers/wallet/WalletProvider.svelte';
91
94
  export { default as RegistryProvider } from './providers/registry/RegistryProvider.svelte';
92
95
  export { default as ToastProvider } from './providers/toasts/ToastProvider.svelte';
96
+ export { default as TransactionProvider } from './providers/transactions/TransactionProvider.svelte';
93
97
  // Hooks
94
98
  export { useGui } from './hooks/useGui';
95
99
  export { useAccount } from './providers/wallet/useAccount';
96
100
  export { useRegistry } from './providers/registry/useRegistry';
97
101
  export { useToasts } from './providers/toasts/useToasts';
102
+ export { useTransactions } from './providers/transactions/useTransactions';
98
103
  // Classes
99
104
  export { RegistryManager } from './providers/registry/RegistryManager';
105
+ export { TransactionStore } from './models/Transaction';
106
+ export { TransactionManager } from './providers/transactions/TransactionManager';
100
107
  // Mocks
101
108
  export { mockPageStore } from './__mocks__/stores';
102
109
  export { mockConfigSource } from './__mocks__/settings';
@@ -0,0 +1,79 @@
1
+ import { TransactionStatusMessage, TransactionStoreErrorMessage } from '../types/transaction';
2
+ import type { TransactionArgs, TransactionName } from '../types/transaction';
3
+ import type { Config } from '@wagmi/core';
4
+ import { type Writable } from 'svelte/store';
5
+ /**
6
+ * Represents the state of a transaction.
7
+ * @typedef {Object} TransactionStoreState
8
+ * @property {TransactionName} name - The user-friendly name of the transaction (e.g., "Order Removal").
9
+ * @property {TransactionStatusMessage} status - The current status of the transaction (e.g., PENDING_RECEIPT, SUCCESS, ERROR).
10
+ * @property {TransactionStoreErrorMessage} [errorDetails] - Optional error message if the transaction failed.
11
+ * @property {Array<{link: string, label: string}>} links - An array of relevant links for the transaction (e.g., explorer link, link to the affected entity).
12
+ */
13
+ export type TransactionStoreState = {
14
+ name: TransactionName;
15
+ status: TransactionStatusMessage;
16
+ errorDetails?: TransactionStoreErrorMessage;
17
+ links: {
18
+ link: string;
19
+ label: string;
20
+ }[];
21
+ };
22
+ /**
23
+ * Interface defining the structure of a transaction object.
24
+ * @interface Transaction
25
+ * @property {Writable<TransactionStoreState>} state - A writable store holding the current state of the transaction.
26
+ */
27
+ export type Transaction = {
28
+ readonly state: Writable<TransactionStoreState>;
29
+ };
30
+ /**
31
+ * Manages the lifecycle of an individual transaction, including waiting for
32
+ * blockchain confirmation (receipt) and subgraph indexing.
33
+ * It exposes its state as a Svelte writable store.
34
+ * @class TransactionStore
35
+ * @implements {Transaction}
36
+ */
37
+ export declare class TransactionStore implements Transaction {
38
+ private name;
39
+ private config;
40
+ private txHash;
41
+ private links;
42
+ private onSuccess;
43
+ private onError;
44
+ private awaitSubgraphConfig;
45
+ readonly state: Writable<TransactionStoreState>;
46
+ /**
47
+ * Creates a new TransactionStore instance.
48
+ * @param {TransactionArgs & { config: Config }} args - Configuration arguments for the transaction, including the wagmi `Config`.
49
+ * @param {() => void} onSuccess - Callback invoked when the transaction successfully completes (including indexing).
50
+ * @param {() => void} onError - Callback invoked if the transaction fails at any stage.
51
+ */
52
+ constructor(args: TransactionArgs & {
53
+ config: Config;
54
+ }, onSuccess: () => void, onError: () => void);
55
+ /**
56
+ * Updates the internal Svelte store with new state values.
57
+ * @param {Partial<TransactionStoreState>} partialState - An object containing the state properties to update.
58
+ * @private
59
+ */
60
+ private updateState;
61
+ /**
62
+ * Executes the transaction and begins monitoring its status
63
+ * @returns {Promise<void>}
64
+ */
65
+ execute(): Promise<void>;
66
+ /**
67
+ * Waits for the transaction receipt to be confirmed on the blockchain
68
+ * @param {Hex} hash - The transaction hash to monitor
69
+ * @returns {Promise<void>}
70
+ * @private
71
+ */
72
+ private waitForTxReceipt;
73
+ /**
74
+ * Monitors the transaction indexing status in the subgraph
75
+ * @returns {Promise<void>}
76
+ * @private
77
+ */
78
+ private indexTransaction;
79
+ }
@@ -0,0 +1,110 @@
1
+ import { waitForTransactionReceipt } from '@wagmi/core';
2
+ import { TransactionStatusMessage, TransactionStoreErrorMessage } from '../types/transaction';
3
+ import { awaitSubgraphIndexing } from '../services/awaitTransactionIndexing';
4
+ import { writable } from 'svelte/store';
5
+ /**
6
+ * Manages the lifecycle of an individual transaction, including waiting for
7
+ * blockchain confirmation (receipt) and subgraph indexing.
8
+ * It exposes its state as a Svelte writable store.
9
+ * @class TransactionStore
10
+ * @implements {Transaction}
11
+ */
12
+ export class TransactionStore {
13
+ name;
14
+ config;
15
+ txHash;
16
+ links;
17
+ onSuccess;
18
+ onError;
19
+ awaitSubgraphConfig;
20
+ state;
21
+ /**
22
+ * Creates a new TransactionStore instance.
23
+ * @param {TransactionArgs & { config: Config }} args - Configuration arguments for the transaction, including the wagmi `Config`.
24
+ * @param {() => void} onSuccess - Callback invoked when the transaction successfully completes (including indexing).
25
+ * @param {() => void} onError - Callback invoked if the transaction fails at any stage.
26
+ */
27
+ constructor(args, onSuccess, onError) {
28
+ this.config = args.config;
29
+ this.txHash = args.txHash;
30
+ this.name = args.name;
31
+ this.links = args.toastLinks;
32
+ this.state = writable({
33
+ name: this.name,
34
+ status: TransactionStatusMessage.IDLE,
35
+ links: this.links
36
+ });
37
+ this.awaitSubgraphConfig = args.awaitSubgraphConfig;
38
+ this.onSuccess = onSuccess;
39
+ this.onError = onError;
40
+ }
41
+ /**
42
+ * Updates the internal Svelte store with new state values.
43
+ * @param {Partial<TransactionStoreState>} partialState - An object containing the state properties to update.
44
+ * @private
45
+ */
46
+ updateState(partialState) {
47
+ this.state.update((currentState) => ({
48
+ ...currentState,
49
+ ...partialState
50
+ }));
51
+ }
52
+ /**
53
+ * Executes the transaction and begins monitoring its status
54
+ * @returns {Promise<void>}
55
+ */
56
+ async execute() {
57
+ this.updateState({
58
+ status: TransactionStatusMessage.PENDING_RECEIPT
59
+ });
60
+ await this.waitForTxReceipt(this.txHash);
61
+ }
62
+ /**
63
+ * Waits for the transaction receipt to be confirmed on the blockchain
64
+ * @param {Hex} hash - The transaction hash to monitor
65
+ * @returns {Promise<void>}
66
+ * @private
67
+ */
68
+ async waitForTxReceipt(hash) {
69
+ try {
70
+ await waitForTransactionReceipt(this.config, { hash });
71
+ await this.indexTransaction();
72
+ }
73
+ catch {
74
+ this.updateState({
75
+ status: TransactionStatusMessage.ERROR,
76
+ errorDetails: TransactionStoreErrorMessage.RECEIPT_FAILED
77
+ });
78
+ return this.onError();
79
+ }
80
+ }
81
+ /**
82
+ * Monitors the transaction indexing status in the subgraph
83
+ * @returns {Promise<void>}
84
+ * @private
85
+ */
86
+ async indexTransaction() {
87
+ this.updateState({
88
+ status: TransactionStatusMessage.PENDING_SUBGRAPH
89
+ });
90
+ const result = await awaitSubgraphIndexing(this.awaitSubgraphConfig);
91
+ if (result.error === TransactionStoreErrorMessage.SUBGRAPH_TIMEOUT_ERROR) {
92
+ this.updateState({
93
+ status: TransactionStatusMessage.ERROR,
94
+ errorDetails: TransactionStoreErrorMessage.SUBGRAPH_TIMEOUT_ERROR
95
+ });
96
+ return this.onError();
97
+ }
98
+ if (result.value) {
99
+ this.updateState({
100
+ status: TransactionStatusMessage.SUCCESS
101
+ });
102
+ return this.onSuccess();
103
+ }
104
+ this.updateState({
105
+ status: TransactionStatusMessage.ERROR,
106
+ errorDetails: TransactionStoreErrorMessage.SUBGRAPH_FAILED
107
+ });
108
+ return this.onError();
109
+ }
110
+ }
@@ -0,0 +1,92 @@
1
+ import { type Readable } from 'svelte/store';
2
+ import type { QueryClient } from '@tanstack/svelte-query';
3
+ import { type Transaction } from '../../models/Transaction';
4
+ import type { InternalTransactionArgs } from '../../types/transaction';
5
+ import type { Config } from '@wagmi/core';
6
+ import type { ToastProps } from '../../types/toast';
7
+ /**
8
+ * Function type for adding toast notifications to the UI
9
+ * @param toast - The toast notification configuration object
10
+ * @param toast.message - The message text to display in the toast
11
+ * @param toast.type - The type of toast notification (success, error, or info)
12
+ * @param toast.color - The color theme of the toast
13
+ * @param toast.links - Optional array of links to display in the toast
14
+ */
15
+ export type AddToastFunction = (toast: Omit<ToastProps, 'id'>) => void;
16
+ /**
17
+ * Manages blockchain transactions with toast notifications and query invalidation.
18
+ * Handles transaction lifecycle, status updates, and UI feedback.
19
+ * Provides functionality for creating, tracking, and managing blockchain transactions.
20
+ *
21
+ * @class TransactionManager
22
+ * @description A class that manages the lifecycle of blockchain transactions, including
23
+ * tracking their status, displaying notifications, and invalidating relevant queries.
24
+ */
25
+ export declare class TransactionManager {
26
+ /** Writable store tracking all active transactions */
27
+ private transactions;
28
+ /** Query client for cache invalidation after successful transactions */
29
+ private queryClient;
30
+ /** Function to display toast notifications in the UI */
31
+ private addToast;
32
+ /** Wagmi configuration for blockchain interactions */
33
+ private wagmiConfig;
34
+ /**
35
+ * Initializes a new TransactionManager instance
36
+ * @param queryClient - Query client for cache invalidation
37
+ * @param addToast - Function to display toast notifications
38
+ * @param wagmiConfig - Wagmi configuration for blockchain interactions
39
+ * @throws {Error} If required dependencies are not provided
40
+ */
41
+ constructor(queryClient: QueryClient, addToast: AddToastFunction, wagmiConfig: Config);
42
+ /**
43
+ * Creates and initializes a new transaction for removing an order from the orderbook
44
+ * @param args - Configuration for the remove order transaction
45
+ * @param args.subgraphUrl - URL of the subgraph to query for transaction status
46
+ * @param args.txHash - Hash of the transaction to track
47
+ * @param args.orderHash - Hash of the order to be removed
48
+ * @param args.chainId - Chain ID where the transaction is being executed
49
+ * @param args.queryKey - Key for query invalidation and UI links, often the order hash.
50
+ * @param args.networkKey - Network identifier for UI links.
51
+ * @returns A new Transaction instance configured for order removal
52
+ * @throws {Error} If required transaction parameters are missing
53
+ * @example
54
+ * const tx = await manager.createRemoveOrderTransaction({
55
+ * subgraphUrl: 'https://api.thegraph.com/subgraphs/name/...',
56
+ * txHash: '0x123...',
57
+ * orderHash: '0x456...',
58
+ * chainId: 1
59
+ * });
60
+ */
61
+ createRemoveOrderTransaction(args: InternalTransactionArgs): Promise<Transaction>;
62
+ /**
63
+ * Creates and executes a new transaction instance
64
+ * @param args - Configuration for the transaction
65
+ * @param args.pendingMessage - Message to display on pending transaction
66
+ * @param args.errorMessage - Message to display on transaction failure
67
+ * @param args.successMessage - Message to display on transaction success
68
+ * @param args.queryKey - Key used for query invalidation
69
+ * @param args.toastLinks - Array of links to display in toast notifications
70
+ * @returns A new Transaction instance that has been initialized and started
71
+ * @throws {Error} If transaction creation fails
72
+ * @private
73
+ */
74
+ private createTransaction;
75
+ /**
76
+ * Retrieves the store containing all active transactions
77
+ * @returns A writable store containing all active Transaction instances
78
+ * @throws {Error} If transaction store is not initialized
79
+ * @example
80
+ * const transactions = manager.getTransactions();
81
+ * $: console.log($transactions); // Log all active transactions
82
+ */
83
+ getTransactions(): Readable<Transaction[]>;
84
+ /**
85
+ * Removes all transactions from the store
86
+ * Resets the transaction tracking state
87
+ * @throws {Error} If transaction store is not initialized
88
+ * @example
89
+ * manager.clearTransactions(); // Clear all tracked transactions
90
+ */
91
+ clearTransactions(): void;
92
+ }