@rainlanguage/ui-components 0.0.1-alpha.60 → 0.0.1-alpha.62
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__/stores.d.ts +0 -5
- package/dist/__mocks__/stores.js +0 -6
- package/dist/components/detail/OrderDetail.svelte +6 -8
- package/dist/components/detail/OrderDetail.svelte.d.ts +1 -3
- package/dist/components/detail/VaultDetail.svelte +3 -3
- package/dist/components/tables/OrdersListTable.svelte +8 -8
- package/dist/components/tables/OrdersListTable.svelte.d.ts +0 -3
- package/dist/components/tables/VaultsListTable.svelte +37 -41
- package/dist/components/tables/VaultsListTable.svelte.d.ts +0 -1
- package/dist/providers/wallet/useAccount.d.ts +1 -0
- package/dist/providers/wallet/useAccount.js +121 -6
- package/dist/stores/transactionStore.d.ts +1 -1
- package/dist/stores/transactionStore.js +46 -34
- package/package.json +2 -2
|
@@ -1,11 +1,6 @@
|
|
|
1
1
|
import type { ConfigSource } from '@rainlanguage/orderbook';
|
|
2
2
|
import { type Config } from '@wagmi/core';
|
|
3
3
|
import type { Page } from '@sveltejs/kit';
|
|
4
|
-
export declare const mockWalletAddressMatchesOrBlankStore: {
|
|
5
|
-
subscribe: (this: void, run: import("svelte/store").Subscriber<() => boolean>, invalidate?: import("svelte/store").Invalidator<() => boolean> | undefined) => import("svelte/store").Unsubscriber;
|
|
6
|
-
set: (this: void, value: () => boolean) => void;
|
|
7
|
-
mockSetSubscribeValue: (value: () => boolean) => void;
|
|
8
|
-
};
|
|
9
4
|
export declare const mockSettingsStore: {
|
|
10
5
|
subscribe: (this: void, run: import("svelte/store").Subscriber<ConfigSource | undefined>, invalidate?: import("svelte/store").Invalidator<ConfigSource | undefined> | undefined) => import("svelte/store").Unsubscriber;
|
|
11
6
|
set: (this: void, value: ConfigSource | undefined) => void;
|
package/dist/__mocks__/stores.js
CHANGED
|
@@ -13,17 +13,11 @@ const mockActiveNetworkRefWritable = writable('');
|
|
|
13
13
|
const mockActiveOrderbookRefWritable = writable('');
|
|
14
14
|
const mockActiveAccountsWritable = writable({});
|
|
15
15
|
const mockSubgraphUrlWritable = writable('');
|
|
16
|
-
const mockWalletAddressMatchesOrBlankWritable = writable(() => false);
|
|
17
16
|
const mockChainIdWritable = writable(0);
|
|
18
17
|
const mockConnectedWritable = writable(true);
|
|
19
18
|
const mockWagmiConfigWritable = writable(mockWeb3Config);
|
|
20
19
|
const mockShowMyItemsOnlyWritable = writable(false);
|
|
21
20
|
const mockPageWritable = writable();
|
|
22
|
-
export const mockWalletAddressMatchesOrBlankStore = {
|
|
23
|
-
subscribe: mockWalletAddressMatchesOrBlankWritable.subscribe,
|
|
24
|
-
set: mockWalletAddressMatchesOrBlankWritable.set,
|
|
25
|
-
mockSetSubscribeValue: (value) => mockWalletAddressMatchesOrBlankWritable.set(value)
|
|
26
|
-
};
|
|
27
21
|
export const mockSettingsStore = {
|
|
28
22
|
subscribe: mockSettingsWritable.subscribe,
|
|
29
23
|
set: mockSettingsWritable.set,
|
|
@@ -10,9 +10,6 @@ import ButtonVaultLink from "../ButtonVaultLink.svelte";
|
|
|
10
10
|
import OrderVaultsVolTable from "../tables/OrderVaultsVolTable.svelte";
|
|
11
11
|
import { QKEY_ORDER } from "../../queries/keys";
|
|
12
12
|
import CodeMirrorRainlang from "../CodeMirrorRainlang.svelte";
|
|
13
|
-
import {
|
|
14
|
-
getOrderByHash
|
|
15
|
-
} from "@rainlanguage/orderbook";
|
|
16
13
|
import { createQuery, useQueryClient } from "@tanstack/svelte-query";
|
|
17
14
|
import { Button, TabItem, Tabs, Tooltip } from "flowbite-svelte";
|
|
18
15
|
import { onDestroy } from "svelte";
|
|
@@ -22,7 +19,9 @@ import Refresh from "../icon/Refresh.svelte";
|
|
|
22
19
|
import { invalidateIdQuery } from "../../queries/queryClient";
|
|
23
20
|
import { ArrowDownOutline, ArrowUpOutline, InfoCircleOutline } from "flowbite-svelte-icons";
|
|
24
21
|
import { useAccount } from "../../providers/wallet/useAccount";
|
|
25
|
-
import {
|
|
22
|
+
import {
|
|
23
|
+
getOrderByHash
|
|
24
|
+
} from "@rainlanguage/orderbook";
|
|
26
25
|
export let handleQuoteDebugModal = void 0;
|
|
27
26
|
export const handleDebugTradeModal = void 0;
|
|
28
27
|
export let colorTheme;
|
|
@@ -32,14 +31,13 @@ export let orderbookAddress;
|
|
|
32
31
|
export let orderHash;
|
|
33
32
|
export let rpcUrl;
|
|
34
33
|
export let subgraphUrl;
|
|
35
|
-
export let chainId;
|
|
36
34
|
export let onRemove;
|
|
37
35
|
export let onDeposit;
|
|
38
36
|
export let onWithdraw;
|
|
39
37
|
let codeMirrorDisabled = true;
|
|
40
38
|
let codeMirrorStyles = {};
|
|
41
39
|
const queryClient = useQueryClient();
|
|
42
|
-
const {
|
|
40
|
+
const { matchesAccount } = useAccount();
|
|
43
41
|
$: orderDetailQuery = createQuery({
|
|
44
42
|
queryKey: [orderHash, QKEY_ORDER + orderHash],
|
|
45
43
|
queryFn: () => {
|
|
@@ -70,7 +68,7 @@ $: subgraphName = $page.url.pathname.split("/")[2]?.split("-")[0];
|
|
|
70
68
|
</div>
|
|
71
69
|
|
|
72
70
|
<div class="flex items-center gap-2">
|
|
73
|
-
{#if
|
|
71
|
+
{#if matchesAccount(data.order.owner)}
|
|
74
72
|
{#if data.order.active}
|
|
75
73
|
<Button
|
|
76
74
|
on:click={() => onRemove(data.order)}
|
|
@@ -128,7 +126,7 @@ $: subgraphName = $page.url.pathname.split("/")[2]?.split("-")[0];
|
|
|
128
126
|
{#each data.vaults.get(type) || [] as vault}
|
|
129
127
|
<ButtonVaultLink tokenVault={vault} {subgraphName}>
|
|
130
128
|
<svelte:fragment slot="buttons">
|
|
131
|
-
{#if
|
|
129
|
+
{#if matchesAccount(vault.owner)}
|
|
132
130
|
<div class="flex gap-1">
|
|
133
131
|
<Button
|
|
134
132
|
color="light"
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { SvelteComponent } from "svelte";
|
|
2
|
-
import { type SgOrder } from '@rainlanguage/orderbook';
|
|
3
2
|
import type { Hex } from 'viem';
|
|
4
3
|
import type { QuoteDebugModalHandler, DebugTradeModalHandler } from '../../types/modal';
|
|
5
|
-
import type
|
|
4
|
+
import { type SgOrder, type SgVault } from '@rainlanguage/orderbook';
|
|
6
5
|
declare const __propDef: {
|
|
7
6
|
props: {
|
|
8
7
|
handleQuoteDebugModal?: QuoteDebugModalHandler | undefined;
|
|
@@ -14,7 +13,6 @@ declare const __propDef: {
|
|
|
14
13
|
orderHash: string;
|
|
15
14
|
rpcUrl: string;
|
|
16
15
|
subgraphUrl: string;
|
|
17
|
-
chainId: number | undefined;
|
|
18
16
|
/** Callback function when remove action is triggered for an order
|
|
19
17
|
* @param order The order to remove
|
|
20
18
|
*/ onRemove: (order: SgOrder) => void;
|
|
@@ -6,7 +6,7 @@ import TanstackPageContentDetail from "./TanstackPageContentDetail.svelte";
|
|
|
6
6
|
import CardProperty from "../CardProperty.svelte";
|
|
7
7
|
import { QKEY_VAULT } from "../../queries/keys";
|
|
8
8
|
import { getVault } from "@rainlanguage/orderbook";
|
|
9
|
-
import { formatUnits
|
|
9
|
+
import { formatUnits } from "viem";
|
|
10
10
|
import { createQuery } from "@tanstack/svelte-query";
|
|
11
11
|
import { onDestroy } from "svelte";
|
|
12
12
|
import { useQueryClient } from "@tanstack/svelte-query";
|
|
@@ -26,7 +26,7 @@ export let onDeposit;
|
|
|
26
26
|
export let onWithdraw;
|
|
27
27
|
const subgraphUrl = $settings?.subgraphs?.[network] || "";
|
|
28
28
|
const queryClient = useQueryClient();
|
|
29
|
-
const {
|
|
29
|
+
const { matchesAccount } = useAccount();
|
|
30
30
|
$: vaultDetailQuery = createQuery({
|
|
31
31
|
queryKey: [id, QKEY_VAULT + id],
|
|
32
32
|
queryFn: () => {
|
|
@@ -59,7 +59,7 @@ onDestroy(() => {
|
|
|
59
59
|
{data.token.name}
|
|
60
60
|
</div>
|
|
61
61
|
<div class="flex items-center gap-2">
|
|
62
|
-
{#if
|
|
62
|
+
{#if matchesAccount(data.owner)}
|
|
63
63
|
<Button
|
|
64
64
|
color="light"
|
|
65
65
|
size="xs"
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
<script generics="T">import { goto } from "$app/navigation";
|
|
2
2
|
import { DotsVerticalOutline } from "flowbite-svelte-icons";
|
|
3
|
-
import {} from "@rainlanguage/orderbook";
|
|
4
3
|
import { createInfiniteQuery } from "@tanstack/svelte-query";
|
|
5
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
getOrders
|
|
6
|
+
} from "@rainlanguage/orderbook";
|
|
6
7
|
import TanstackAppTable from "../TanstackAppTable.svelte";
|
|
7
8
|
import { formatTimestampSecondsAsLocal } from "../../utils/time";
|
|
8
9
|
import ListViewOrderbookFilters from "../ListViewOrderbookFilters.svelte";
|
|
@@ -18,8 +19,7 @@ import {
|
|
|
18
19
|
TableHeadCell
|
|
19
20
|
} from "flowbite-svelte";
|
|
20
21
|
import { useAccount } from "../../providers/wallet/useAccount";
|
|
21
|
-
export
|
|
22
|
-
export const handleOrderRemoveModal = void 0;
|
|
22
|
+
export let handleOrderRemoveModal = void 0;
|
|
23
23
|
export let activeSubgraphs;
|
|
24
24
|
export let settings;
|
|
25
25
|
export let accounts;
|
|
@@ -31,7 +31,7 @@ export let showMyItemsOnly;
|
|
|
31
31
|
export let currentRoute;
|
|
32
32
|
export let activeNetworkRef;
|
|
33
33
|
export let activeOrderbookRef;
|
|
34
|
-
const { account } = useAccount();
|
|
34
|
+
const { matchesAccount, account } = useAccount();
|
|
35
35
|
$: multiSubgraphArgs = Object.entries(
|
|
36
36
|
Object.keys($activeSubgraphs ?? {}).length ? $activeSubgraphs : $settings?.subgraphs ?? {}
|
|
37
37
|
).map(([name, url]) => ({
|
|
@@ -150,10 +150,10 @@ $: isOrdersPage = currentRoute.startsWith("/orders");
|
|
|
150
150
|
<TableBodyCell data-testid="orderListRowTrades" tdClass="break-word p-2"
|
|
151
151
|
>{item.order.trades.length > 99 ? '>99' : item.order.trades.length}</TableBodyCell
|
|
152
152
|
>
|
|
153
|
-
{#if
|
|
153
|
+
{#if matchesAccount(item.order.owner) && handleOrderRemoveModal}
|
|
154
154
|
<div data-testid="wallet-actions">
|
|
155
155
|
<TableBodyCell tdClass="px-0 text-right">
|
|
156
|
-
{#if
|
|
156
|
+
{#if item.order.active}
|
|
157
157
|
<Button
|
|
158
158
|
color="alternative"
|
|
159
159
|
outline={false}
|
|
@@ -168,7 +168,7 @@ $: isOrdersPage = currentRoute.startsWith("/orders");
|
|
|
168
168
|
</Button>
|
|
169
169
|
{/if}
|
|
170
170
|
</TableBodyCell>
|
|
171
|
-
{#if
|
|
171
|
+
{#if item.order.active}
|
|
172
172
|
<Dropdown placement="bottom-end" triggeredBy={`#order-menu-${item.order.id}`}>
|
|
173
173
|
<DropdownItem
|
|
174
174
|
on:click={(e) => {
|
|
@@ -2,7 +2,6 @@ import { SvelteComponent } from "svelte";
|
|
|
2
2
|
import type { AppStoresInterface } from '../../types/appStores';
|
|
3
3
|
declare class __sveltets_Render<T> {
|
|
4
4
|
props(): {
|
|
5
|
-
walletAddressMatchesOrBlank?: any;
|
|
6
5
|
handleOrderRemoveModal?: any;
|
|
7
6
|
activeSubgraphs: AppStoresInterface["activeSubgraphs"];
|
|
8
7
|
settings: AppStoresInterface["settings"];
|
|
@@ -27,7 +26,5 @@ export type OrdersListTableProps<T> = ReturnType<__sveltets_Render<T>['props']>;
|
|
|
27
26
|
export type OrdersListTableEvents<T> = ReturnType<__sveltets_Render<T>['events']>;
|
|
28
27
|
export type OrdersListTableSlots<T> = ReturnType<__sveltets_Render<T>['slots']>;
|
|
29
28
|
export default class OrdersListTable<T> extends SvelteComponent<OrdersListTableProps<T>, OrdersListTableEvents<T>, OrdersListTableSlots<T>> {
|
|
30
|
-
get walletAddressMatchesOrBlank(): any;
|
|
31
|
-
get handleOrderRemoveModal(): any;
|
|
32
29
|
}
|
|
33
30
|
export {};
|
|
@@ -29,13 +29,12 @@ export let hideZeroBalanceVaults;
|
|
|
29
29
|
export let activeNetworkRef;
|
|
30
30
|
export let activeOrderbookRef;
|
|
31
31
|
export let activeAccounts;
|
|
32
|
-
export let walletAddressMatchesOrBlank;
|
|
33
32
|
export let handleDepositGenericModal = void 0;
|
|
34
33
|
export let handleDepositModal = void 0;
|
|
35
34
|
export let handleWithdrawModal = void 0;
|
|
36
35
|
export let currentRoute;
|
|
37
36
|
export let showMyItemsOnly;
|
|
38
|
-
const { account } = useAccount();
|
|
37
|
+
const { account, matchesAccount } = useAccount();
|
|
39
38
|
$: multiSubgraphArgs = Object.entries(
|
|
40
39
|
Object.keys($activeSubgraphs ?? {}).length ? $activeSubgraphs : $settings?.subgraphs ?? {}
|
|
41
40
|
).map(([name, url]) => ({
|
|
@@ -182,47 +181,44 @@ const AppTable = TanstackAppTable;
|
|
|
182
181
|
</div>
|
|
183
182
|
{/if}
|
|
184
183
|
</TableBodyCell>
|
|
185
|
-
{#if handleDepositModal && handleWithdrawModal &&
|
|
184
|
+
{#if handleDepositModal && handleWithdrawModal && matchesAccount(item.vault.owner)}
|
|
186
185
|
<TableBodyCell tdClass="px-0 text-right">
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
}}
|
|
197
|
-
>
|
|
198
|
-
<DotsVerticalOutline class="dark:text-white" />
|
|
199
|
-
</Button>
|
|
200
|
-
{/if}
|
|
201
|
-
</TableBodyCell>
|
|
202
|
-
{#if $walletAddressMatchesOrBlank(item.vault.owner)}
|
|
203
|
-
<Dropdown
|
|
204
|
-
data-testid="dropdown"
|
|
205
|
-
placement="bottom-end"
|
|
206
|
-
triggeredBy={`#vault-menu-${item.vault.id}`}
|
|
186
|
+
<Button
|
|
187
|
+
color="alternative"
|
|
188
|
+
outline={false}
|
|
189
|
+
data-testid="vault-menu"
|
|
190
|
+
id={`vault-menu-${item.vault.id}`}
|
|
191
|
+
class="mr-2 border-none px-2"
|
|
192
|
+
on:click={(e) => {
|
|
193
|
+
e.stopPropagation();
|
|
194
|
+
}}
|
|
207
195
|
>
|
|
208
|
-
<
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
</
|
|
225
|
-
|
|
196
|
+
<DotsVerticalOutline class="dark:text-white" />
|
|
197
|
+
</Button>
|
|
198
|
+
</TableBodyCell>
|
|
199
|
+
|
|
200
|
+
<Dropdown
|
|
201
|
+
data-testid="dropdown"
|
|
202
|
+
placement="bottom-end"
|
|
203
|
+
triggeredBy={`#vault-menu-${item.vault.id}`}
|
|
204
|
+
>
|
|
205
|
+
<DropdownItem
|
|
206
|
+
data-testid="deposit-button"
|
|
207
|
+
on:click={(e) => {
|
|
208
|
+
e.stopPropagation();
|
|
209
|
+
handleDepositModal(item.vault, $query.refetch);
|
|
210
|
+
}}
|
|
211
|
+
>Deposit
|
|
212
|
+
</DropdownItem>
|
|
213
|
+
<DropdownItem
|
|
214
|
+
data-testid="withdraw-button"
|
|
215
|
+
on:click={(e) => {
|
|
216
|
+
e.stopPropagation();
|
|
217
|
+
handleWithdrawModal(item.vault, $query.refetch);
|
|
218
|
+
}}
|
|
219
|
+
>Withdraw
|
|
220
|
+
</DropdownItem>
|
|
221
|
+
</Dropdown>
|
|
226
222
|
{/if}
|
|
227
223
|
</svelte:fragment>
|
|
228
224
|
</AppTable>
|
|
@@ -19,7 +19,6 @@ declare class __sveltets_Render<T> {
|
|
|
19
19
|
activeAccounts: Readable<{
|
|
20
20
|
[k: string]: string;
|
|
21
21
|
}>;
|
|
22
|
-
walletAddressMatchesOrBlank: Readable<(otherAddress: string) => boolean>;
|
|
23
22
|
handleDepositGenericModal?: (() => void) | undefined;
|
|
24
23
|
handleDepositModal?: ((vault: SgVault, refetch: () => void) => void) | undefined;
|
|
25
24
|
handleWithdrawModal?: ((vault: SgVault, refetch: () => void) => void) | undefined;
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { get } from 'svelte/store';
|
|
2
|
+
import { isAddress, isAddressEqual } from 'viem';
|
|
1
3
|
import { getAccountContext } from './context';
|
|
2
4
|
import { readable } from 'svelte/store';
|
|
3
5
|
/**
|
|
@@ -5,28 +7,141 @@ import { readable } from 'svelte/store';
|
|
|
5
7
|
* Must be used within a component that is a child of WalletProvider
|
|
6
8
|
*/
|
|
7
9
|
export function useAccount() {
|
|
10
|
+
/**
|
|
11
|
+
* The account store containing the current wallet address (as a Hex string) or null if not connected.
|
|
12
|
+
* This is a readable Svelte store that can be subscribed to for reactive updates.
|
|
13
|
+
* @type {import('svelte/store').Readable<Hex | null>}
|
|
14
|
+
*/
|
|
8
15
|
const account = getAccountContext();
|
|
16
|
+
/**
|
|
17
|
+
* Checks if the provided address matches the currently connected account.
|
|
18
|
+
* Returns false if no account is connected or if the provided address is invalid.
|
|
19
|
+
*/
|
|
20
|
+
const matchesAccount = (otherAddress) => {
|
|
21
|
+
if (!otherAddress)
|
|
22
|
+
return false;
|
|
23
|
+
const currentAccount = get(account);
|
|
24
|
+
if (!currentAccount) {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
if (isAddress(currentAccount) &&
|
|
28
|
+
isAddress(otherAddress) &&
|
|
29
|
+
isAddressEqual(currentAccount, otherAddress)) {
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
return false;
|
|
33
|
+
};
|
|
9
34
|
return {
|
|
10
|
-
account
|
|
35
|
+
account,
|
|
36
|
+
matchesAccount
|
|
11
37
|
};
|
|
12
38
|
}
|
|
13
39
|
if (import.meta.vitest) {
|
|
14
40
|
const { describe, it, expect, vi, beforeEach } = import.meta.vitest;
|
|
41
|
+
vi.mock('viem', async () => {
|
|
42
|
+
const actual = await vi.importActual('viem');
|
|
43
|
+
return {
|
|
44
|
+
...actual,
|
|
45
|
+
isAddress: vi.fn(),
|
|
46
|
+
isAddressEqual: vi.fn()
|
|
47
|
+
};
|
|
48
|
+
});
|
|
15
49
|
vi.mock('./context', () => ({
|
|
16
50
|
getAccountContext: vi.fn()
|
|
17
51
|
}));
|
|
52
|
+
vi.mock('svelte/store', async () => {
|
|
53
|
+
const actual = await vi.importActual('svelte/store');
|
|
54
|
+
return {
|
|
55
|
+
...actual,
|
|
56
|
+
get: vi.fn()
|
|
57
|
+
};
|
|
58
|
+
});
|
|
18
59
|
describe('useAccount', () => {
|
|
19
60
|
const mockGetAccountContext = vi.mocked(getAccountContext);
|
|
61
|
+
const mockGet = vi.mocked(get);
|
|
62
|
+
const mockIsAddress = vi.mocked(isAddress);
|
|
63
|
+
const mockIsAddressEqual = vi.mocked(isAddressEqual);
|
|
20
64
|
beforeEach(() => {
|
|
21
|
-
|
|
65
|
+
vi.clearAllMocks();
|
|
22
66
|
});
|
|
23
67
|
it('should return account wrapped in an object', () => {
|
|
24
|
-
const
|
|
25
|
-
mockGetAccountContext.mockReturnValue(
|
|
68
|
+
const mockAccountStore = readable('0x123');
|
|
69
|
+
mockGetAccountContext.mockReturnValue(mockAccountStore);
|
|
26
70
|
const result = useAccount();
|
|
27
71
|
expect(mockGetAccountContext).toHaveBeenCalled();
|
|
28
|
-
expect(result).
|
|
29
|
-
|
|
72
|
+
expect(result.account).toBe(mockAccountStore);
|
|
73
|
+
expect(result.matchesAccount).toBeInstanceOf(Function);
|
|
74
|
+
});
|
|
75
|
+
describe('matchesAccount', () => {
|
|
76
|
+
const mockAccountStore = readable('0x123');
|
|
77
|
+
const currentAccount = '0x123';
|
|
78
|
+
const testAddress1 = '0x123';
|
|
79
|
+
const testAddress2 = '0xdef';
|
|
80
|
+
const invalidAddress = 'invalid';
|
|
81
|
+
beforeEach(() => {
|
|
82
|
+
mockGetAccountContext.mockReturnValue(mockAccountStore);
|
|
83
|
+
});
|
|
84
|
+
it('should return true if addresses are valid and equal', () => {
|
|
85
|
+
// Setup mocks
|
|
86
|
+
mockGet.mockReturnValue(currentAccount);
|
|
87
|
+
mockIsAddress.mockReturnValue(true);
|
|
88
|
+
mockIsAddressEqual.mockReturnValue(true);
|
|
89
|
+
const { matchesAccount } = useAccount();
|
|
90
|
+
const result = matchesAccount(testAddress1);
|
|
91
|
+
expect(mockGet).toHaveBeenCalledWith(mockAccountStore);
|
|
92
|
+
expect(mockIsAddress).toHaveBeenCalledWith(currentAccount);
|
|
93
|
+
expect(mockIsAddress).toHaveBeenCalledWith(testAddress1);
|
|
94
|
+
expect(mockIsAddressEqual).toHaveBeenCalledWith(currentAccount, testAddress1);
|
|
95
|
+
expect(result).toBe(true);
|
|
96
|
+
});
|
|
97
|
+
it('should return false if addresses are valid but not equal', () => {
|
|
98
|
+
// Setup mocks
|
|
99
|
+
mockGet.mockReturnValue(currentAccount);
|
|
100
|
+
mockIsAddress.mockReturnValue(true);
|
|
101
|
+
mockIsAddressEqual.mockReturnValue(false);
|
|
102
|
+
const { matchesAccount } = useAccount();
|
|
103
|
+
const result = matchesAccount(testAddress2);
|
|
104
|
+
expect(mockGet).toHaveBeenCalledWith(mockAccountStore);
|
|
105
|
+
expect(mockIsAddress).toHaveBeenCalledWith(currentAccount);
|
|
106
|
+
expect(mockIsAddress).toHaveBeenCalledWith(testAddress2);
|
|
107
|
+
expect(mockIsAddressEqual).toHaveBeenCalledWith(currentAccount, testAddress2);
|
|
108
|
+
expect(result).toBe(false);
|
|
109
|
+
});
|
|
110
|
+
it('should return false if current account is not set', () => {
|
|
111
|
+
// Setup mocks
|
|
112
|
+
mockGet.mockReturnValue(null);
|
|
113
|
+
const { matchesAccount } = useAccount();
|
|
114
|
+
const result = matchesAccount(testAddress1);
|
|
115
|
+
expect(mockGet).toHaveBeenCalledWith(mockAccountStore);
|
|
116
|
+
expect(mockIsAddress).not.toHaveBeenCalled();
|
|
117
|
+
expect(mockIsAddressEqual).not.toHaveBeenCalled();
|
|
118
|
+
expect(result).toBe(false);
|
|
119
|
+
});
|
|
120
|
+
it('should return false if provided address is invalid', () => {
|
|
121
|
+
// Setup mocks
|
|
122
|
+
mockGet.mockReturnValue(currentAccount);
|
|
123
|
+
// This is crucial: we need to ensure short-circuit evaluation works correctly
|
|
124
|
+
mockIsAddress.mockImplementation((address) => {
|
|
125
|
+
return address !== invalidAddress; // Only the invalid address returns false
|
|
126
|
+
});
|
|
127
|
+
// This should never be called due to short-circuit evaluation
|
|
128
|
+
mockIsAddressEqual.mockReturnValue(false);
|
|
129
|
+
const { matchesAccount } = useAccount();
|
|
130
|
+
const result = matchesAccount(invalidAddress);
|
|
131
|
+
expect(mockGet).toHaveBeenCalledWith(mockAccountStore);
|
|
132
|
+
expect(mockIsAddress).toHaveBeenCalledWith(currentAccount);
|
|
133
|
+
expect(mockIsAddress).toHaveBeenCalledWith(invalidAddress);
|
|
134
|
+
expect(mockIsAddressEqual).not.toHaveBeenCalled(); // This should now pass
|
|
135
|
+
expect(result).toBe(false);
|
|
136
|
+
});
|
|
137
|
+
it('should return false if provided address is null', () => {
|
|
138
|
+
// Setup mocks
|
|
139
|
+
mockGet.mockReturnValue(currentAccount);
|
|
140
|
+
const { matchesAccount } = useAccount();
|
|
141
|
+
const result = matchesAccount(null);
|
|
142
|
+
expect(mockIsAddress).not.toHaveBeenCalled();
|
|
143
|
+
expect(mockIsAddressEqual).not.toHaveBeenCalled();
|
|
144
|
+
expect(result).toBe(false);
|
|
30
145
|
});
|
|
31
146
|
});
|
|
32
147
|
});
|
|
@@ -20,7 +20,7 @@ export declare enum TransactionStatus {
|
|
|
20
20
|
export declare enum TransactionErrorMessage {
|
|
21
21
|
BAD_CALLLDATA = "Bad calldata.",
|
|
22
22
|
DEPLOY_FAILED = "Lock transaction failed.",
|
|
23
|
-
TIMEOUT = "
|
|
23
|
+
TIMEOUT = "The subgraph took too long to respond. Please check the transaction link.",
|
|
24
24
|
APPROVAL_FAILED = "Approval transaction failed.",
|
|
25
25
|
USER_REJECTED_APPROVAL = "User rejected approval transaction.",
|
|
26
26
|
USER_REJECTED_TRANSACTION = "User rejected the transaction.",
|
|
@@ -22,7 +22,7 @@ export var TransactionErrorMessage;
|
|
|
22
22
|
(function (TransactionErrorMessage) {
|
|
23
23
|
TransactionErrorMessage["BAD_CALLLDATA"] = "Bad calldata.";
|
|
24
24
|
TransactionErrorMessage["DEPLOY_FAILED"] = "Lock transaction failed.";
|
|
25
|
-
TransactionErrorMessage["TIMEOUT"] = "
|
|
25
|
+
TransactionErrorMessage["TIMEOUT"] = "The subgraph took too long to respond. Please check the transaction link.";
|
|
26
26
|
TransactionErrorMessage["APPROVAL_FAILED"] = "Approval transaction failed.";
|
|
27
27
|
TransactionErrorMessage["USER_REJECTED_APPROVAL"] = "User rejected approval transaction.";
|
|
28
28
|
TransactionErrorMessage["USER_REJECTED_TRANSACTION"] = "User rejected the transaction.";
|
|
@@ -46,6 +46,10 @@ export const initialState = {
|
|
|
46
46
|
const transactionStore = () => {
|
|
47
47
|
const { subscribe, set, update } = writable(initialState);
|
|
48
48
|
const reset = () => set(initialState);
|
|
49
|
+
const returnError = (interval) => {
|
|
50
|
+
clearInterval(interval);
|
|
51
|
+
return transactionError(TransactionErrorMessage.TIMEOUT);
|
|
52
|
+
};
|
|
49
53
|
const awaitTransactionIndexing = async (subgraphUrl, txHash, successMessage) => {
|
|
50
54
|
update((state) => ({
|
|
51
55
|
...state,
|
|
@@ -56,18 +60,22 @@ const transactionStore = () => {
|
|
|
56
60
|
let newTx;
|
|
57
61
|
const interval = setInterval(async () => {
|
|
58
62
|
attempts++;
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
+
try {
|
|
64
|
+
newTx = await getTransaction(subgraphUrl, txHash);
|
|
65
|
+
if (newTx) {
|
|
66
|
+
clearInterval(interval);
|
|
67
|
+
transactionSuccess(txHash, successMessage);
|
|
68
|
+
}
|
|
69
|
+
else if (attempts >= 10) {
|
|
70
|
+
update((state) => ({
|
|
71
|
+
...state,
|
|
72
|
+
message: 'The subgraph took too long to respond. Please check again later.'
|
|
73
|
+
}));
|
|
74
|
+
return returnError(interval);
|
|
75
|
+
}
|
|
63
76
|
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
...state,
|
|
67
|
-
message: 'The subgraph took too long to respond. Please check again later.'
|
|
68
|
-
}));
|
|
69
|
-
clearInterval(interval);
|
|
70
|
-
return transactionError(TransactionErrorMessage.TIMEOUT);
|
|
77
|
+
catch {
|
|
78
|
+
return returnError(interval);
|
|
71
79
|
}
|
|
72
80
|
}, 1000);
|
|
73
81
|
};
|
|
@@ -80,18 +88,18 @@ const transactionStore = () => {
|
|
|
80
88
|
let attempts = 0;
|
|
81
89
|
const interval = setInterval(async () => {
|
|
82
90
|
attempts++;
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
+
try {
|
|
92
|
+
const addOrders = await getTransactionAddOrders(subgraphUrl, txHash);
|
|
93
|
+
if (attempts >= 10) {
|
|
94
|
+
return returnError(interval);
|
|
95
|
+
}
|
|
96
|
+
else if (addOrders?.length > 0) {
|
|
97
|
+
clearInterval(interval);
|
|
98
|
+
return transactionSuccess(txHash, '', addOrders[0].order.orderHash, network);
|
|
99
|
+
}
|
|
91
100
|
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
return transactionSuccess(txHash, '', addOrders[0].order.orderHash, network);
|
|
101
|
+
catch {
|
|
102
|
+
return returnError(interval);
|
|
95
103
|
}
|
|
96
104
|
}, 1000);
|
|
97
105
|
};
|
|
@@ -104,18 +112,22 @@ const transactionStore = () => {
|
|
|
104
112
|
let attempts = 0;
|
|
105
113
|
const interval = setInterval(async () => {
|
|
106
114
|
attempts++;
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
+
try {
|
|
116
|
+
const removeOrders = await getTransactionRemoveOrders(subgraphUrl, txHash);
|
|
117
|
+
if (attempts >= 10) {
|
|
118
|
+
update((state) => ({
|
|
119
|
+
...state,
|
|
120
|
+
message: 'The subgraph took too long to respond. Please check again later.'
|
|
121
|
+
}));
|
|
122
|
+
return returnError(interval);
|
|
123
|
+
}
|
|
124
|
+
else if (removeOrders?.length > 0) {
|
|
125
|
+
clearInterval(interval);
|
|
126
|
+
return transactionSuccess(txHash, 'Order removed successfully');
|
|
127
|
+
}
|
|
115
128
|
}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
return transactionSuccess(txHash, 'Order removed successfully');
|
|
129
|
+
catch {
|
|
130
|
+
return returnError(interval);
|
|
119
131
|
}
|
|
120
132
|
}, 1000);
|
|
121
133
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rainlanguage/ui-components",
|
|
3
|
-
"version": "0.0.1-alpha.
|
|
3
|
+
"version": "0.0.1-alpha.62",
|
|
4
4
|
"description": "A component library for building Svelte applications to be used with Raindex.",
|
|
5
5
|
"license": "LicenseRef-DCL-1.0",
|
|
6
6
|
"author": "Rain Open Source Software Ltd",
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
"@fontsource/dm-sans": "5.1.0",
|
|
54
54
|
"@imask/svelte": "7.6.1",
|
|
55
55
|
"@observablehq/plot": "0.6.16",
|
|
56
|
-
"@rainlanguage/orderbook": "0.0.1-alpha.
|
|
56
|
+
"@rainlanguage/orderbook": "0.0.1-alpha.62",
|
|
57
57
|
"@reown/appkit": "1.6.4",
|
|
58
58
|
"@reown/appkit-adapter-wagmi": "1.6.4",
|
|
59
59
|
"@sentry/sveltekit": "7.120.0",
|