@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.
- package/dist/__mocks__/mockTransactionStore.js +9 -17
- package/dist/components/transactions/FixedBottomTransaction.svelte +63 -0
- package/dist/components/transactions/FixedBottomTransaction.svelte.d.ts +16 -0
- package/dist/components/transactions/TransactionDetail.svelte +31 -0
- package/dist/components/transactions/TransactionDetail.svelte.d.ts +20 -0
- package/dist/components/transactions/TransactionList.svelte +17 -0
- package/dist/components/transactions/TransactionList.svelte.d.ts +16 -0
- package/dist/components/transactions/getStatusEmoji.d.ts +2 -0
- package/dist/components/transactions/getStatusEmoji.js +20 -0
- package/dist/index.d.ts +12 -4
- package/dist/index.js +8 -1
- package/dist/models/Transaction.d.ts +79 -0
- package/dist/models/Transaction.js +110 -0
- package/dist/providers/transactions/TransactionManager.d.ts +92 -0
- package/dist/providers/transactions/TransactionManager.js +148 -0
- package/dist/providers/transactions/TransactionProvider.svelte +11 -0
- package/dist/providers/transactions/TransactionProvider.svelte.d.ts +24 -0
- package/dist/providers/transactions/context.d.ts +19 -0
- package/dist/providers/transactions/context.js +28 -0
- package/dist/providers/transactions/useTransactions.d.ts +13 -0
- package/dist/providers/transactions/useTransactions.js +18 -0
- package/dist/services/awaitTransactionIndexing.d.ts +8 -5
- package/dist/services/awaitTransactionIndexing.js +3 -5
- package/dist/stores/transactionStore.d.ts +13 -54
- package/dist/stores/transactionStore.js +17 -80
- package/dist/types/modal.d.ts +13 -5
- package/dist/types/transaction.d.ts +54 -6
- package/dist/types/transaction.js +26 -1
- package/package.json +2 -2
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { writable } from 'svelte/store';
|
|
2
|
-
import {
|
|
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:
|
|
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:
|
|
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:
|
|
28
|
+
status: TransactionStatusMessage.CHECKING_ALLOWANCE,
|
|
37
29
|
message
|
|
38
30
|
})),
|
|
39
31
|
awaitWalletConfirmation: (message = '') => mockTransactionWritable.update((state) => ({
|
|
40
32
|
...state,
|
|
41
|
-
status:
|
|
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:
|
|
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:
|
|
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:
|
|
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,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 {
|
|
69
|
-
export {
|
|
70
|
-
export type {
|
|
71
|
-
export type {
|
|
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 {
|
|
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
|
+
}
|