@rainlanguage/ui-components 0.0.1-alpha.47 → 0.0.1-alpha.49

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.
@@ -1,22 +1,25 @@
1
1
  <script>import { Button } from "flowbite-svelte";
2
2
  import Hash, { HashType } from "./Hash.svelte";
3
+ import {
4
+ constructHashLink,
5
+ isOrderOrVaultActive,
6
+ extractHash
7
+ } from "../utils/constructHashLink";
3
8
  export let orderOrVault;
4
9
  export let type;
5
10
  export let network;
6
11
  export let updateActiveNetworkAndOrderbook;
7
- let hash;
8
- $: isOrder = "orderHash" in (orderOrVault || {});
9
- $: slug = isOrder ? orderOrVault.orderHash : orderOrVault?.id;
10
- $: hash = isOrder ? orderOrVault.orderHash : orderOrVault?.id || "";
11
- $: isActive = isOrder ? orderOrVault.active : false;
12
+ $: hash = extractHash(orderOrVault);
13
+ $: isActive = isOrderOrVaultActive(orderOrVault);
14
+ $: linkPath = constructHashLink(orderOrVault, type, network);
12
15
  </script>
13
16
 
14
- <a href={`/${type}/${network}-${slug}`}>
17
+ <a data-testid="order-or-vault-hash" href={linkPath}>
15
18
  <Button
16
19
  class="mr-1 mt-1 px-2 py-1 text-sm"
17
20
  color={isActive ? 'green' : 'yellow'}
18
21
  data-testid="vault-order-input"
19
- data-id={slug}
22
+ data-id={hash}
20
23
  on:click={() => {
21
24
  updateActiveNetworkAndOrderbook(network);
22
25
  }}><Hash type={HashType.Identifier} value={hash} copyOnClick={false} /></Button
@@ -1,4 +1,4 @@
1
- <script>import { Alert } from "flowbite-svelte";
1
+ <script>import { Alert, Button, Spinner } from "flowbite-svelte";
2
2
  import TokenIOInput from "./TokenIOInput.svelte";
3
3
  import ComposedRainlangModal from "./ComposedRainlangModal.svelte";
4
4
  import {
@@ -7,12 +7,10 @@ import WalletConnect from "../wallet/WalletConnect.svelte";
7
7
  import {
8
8
  } from "@rainlanguage/orderbook/js_api";
9
9
  import { fade } from "svelte/transition";
10
- import { Button, Toggle, Spinner } from "flowbite-svelte";
11
- import {} from "@wagmi/core";
10
+ import { Toggle } from "flowbite-svelte";
12
11
  import {} from "svelte/store";
13
12
  import ShareChoicesButton from "./ShareChoicesButton.svelte";
14
13
  import { handleShareChoices } from "../../services/handleShareChoices";
15
- import { getDeploymentTransactionArgs } from "./getDeploymentTransactionArgs";
16
14
  import { DeploymentStepsError, DeploymentStepsErrorCode } from "../../errors";
17
15
  import { onMount } from "svelte";
18
16
  import FieldDefinitionInput from "./FieldDefinitionInput.svelte";
@@ -21,12 +19,14 @@ import SelectToken from "./SelectToken.svelte";
21
19
  import DeploymentSectionHeader from "./DeploymentSectionHeader.svelte";
22
20
  import { useGui } from "../../hooks/useGui";
23
21
  import { useAccount } from "../../providers/wallet/useAccount";
24
- export let settings;
25
- export let dotrain;
22
+ import { handleDeployment } from "./handleDeployment";
23
+ import {} from "../../types/transaction";
26
24
  export let deployment;
27
25
  export let strategyDetail;
28
- export let handleDeployModal;
29
- export let handleDisclaimerModal;
26
+ export let onDeploy;
27
+ export let wagmiConnected;
28
+ export let appKitModal;
29
+ export let settings;
30
30
  export let registryUrl;
31
31
  let allDepositFields = [];
32
32
  let allTokenOutputs = [];
@@ -34,28 +34,25 @@ let allFieldDefinitionsWithoutDefaults = [];
34
34
  let allFieldDefinitionsWithDefaults = [];
35
35
  let allTokensSelected = false;
36
36
  let showAdvancedOptions = false;
37
- let checkingDeployment = false;
38
37
  let allTokenInfos = [];
38
+ let selectTokens = void 0;
39
+ let checkingDeployment = false;
40
+ let subgraphUrl = void 0;
39
41
  const { account } = useAccount();
40
42
  const gui = useGui();
41
- let selectTokens = void 0;
42
- let networkKey = "";
43
- $: subgraphUrl = $settings?.subgraphs?.[networkKey] ?? "";
44
43
  let deploymentStepsError = DeploymentStepsError.error;
45
- export let wagmiConfig;
46
- export let wagmiConnected;
47
- export let appKitModal;
48
44
  onMount(async () => {
49
45
  const selectTokensResult = gui.getSelectTokens();
50
46
  if (selectTokensResult.error) {
51
47
  throw new Error(selectTokensResult.error.msg);
52
48
  }
53
49
  selectTokens = selectTokensResult.value;
54
- const networkKeyResult = gui.getNetworkKey();
55
- if (networkKeyResult.error) {
56
- throw new Error(networkKeyResult.error.msg);
50
+ const { value, error } = gui.getNetworkKey();
51
+ if (error) {
52
+ DeploymentStepsError.catch(error, DeploymentStepsErrorCode.NO_NETWORK_KEY);
53
+ } else if (value) {
54
+ subgraphUrl = $settings?.subgraphs?.[value];
57
55
  }
58
- networkKey = networkKeyResult.value;
59
56
  await areAllTokensSelected();
60
57
  });
61
58
  function getAllFieldDefinitions() {
@@ -141,54 +138,6 @@ async function onSelectTokenSelect() {
141
138
  }
142
139
  }
143
140
  }
144
- async function handleDeployButtonClick() {
145
- DeploymentStepsError.clear();
146
- if (!allTokenOutputs) {
147
- DeploymentStepsError.catch(null, DeploymentStepsErrorCode.NO_TOKEN_OUTPUTS);
148
- return;
149
- }
150
- if (!wagmiConfig) {
151
- DeploymentStepsError.catch(null, DeploymentStepsErrorCode.NO_CHAIN);
152
- return;
153
- }
154
- if (!networkKey) {
155
- DeploymentStepsError.catch(null, DeploymentStepsErrorCode.NO_CHAIN);
156
- return;
157
- }
158
- if (!$account) {
159
- DeploymentStepsError.catch(null, DeploymentStepsErrorCode.NO_WALLET);
160
- return;
161
- }
162
- let result = null;
163
- checkingDeployment = true;
164
- try {
165
- result = await getDeploymentTransactionArgs(gui, $account);
166
- } catch (e) {
167
- DeploymentStepsError.catch(e, DeploymentStepsErrorCode.ADD_ORDER_FAILED);
168
- checkingDeployment = false;
169
- return;
170
- }
171
- checkingDeployment = false;
172
- const onAccept = () => {
173
- if (!networkKey) {
174
- DeploymentStepsError.catch(null, DeploymentStepsErrorCode.NO_CHAIN);
175
- return;
176
- }
177
- handleDeployModal({
178
- open: true,
179
- args: {
180
- ...result,
181
- subgraphUrl,
182
- network: networkKey,
183
- account
184
- }
185
- });
186
- };
187
- handleDisclaimerModal({
188
- open: true,
189
- onAccept
190
- });
191
- }
192
141
  const areAllTokensSelected = async () => {
193
142
  try {
194
143
  const areAllTokensSelectedResult = gui.areAllTokensSelected();
@@ -217,97 +166,115 @@ const areAllTokensSelected = async () => {
217
166
  DeploymentStepsError.catch(e, DeploymentStepsErrorCode.NO_SELECT_TOKENS);
218
167
  }
219
168
  };
169
+ async function handleDeployButtonClick() {
170
+ if (checkingDeployment) {
171
+ return;
172
+ }
173
+ checkingDeployment = true;
174
+ try {
175
+ if (!$account) {
176
+ DeploymentStepsError.catch(
177
+ "No wallet connected",
178
+ DeploymentStepsErrorCode.ADD_ORDER_FAILED
179
+ );
180
+ return;
181
+ }
182
+ DeploymentStepsError.clear();
183
+ const deploymentArgs = await handleDeployment(gui, $account, subgraphUrl);
184
+ return await onDeploy(deploymentArgs);
185
+ } catch (e) {
186
+ DeploymentStepsError.catch(e, DeploymentStepsErrorCode.ADD_ORDER_FAILED);
187
+ } finally {
188
+ checkingDeployment = false;
189
+ }
190
+ }
220
191
  </script>
221
192
 
222
- <div class="py-6">
223
- {#if dotrain}
224
- {#if gui}
225
- <div class="flex max-w-3xl flex-col gap-12" in:fade>
226
- {#if deployment}
227
- <div class="flex max-w-2xl flex-col gap-4 text-start">
228
- <h1 class=" text-4xl font-semibold text-gray-900 lg:text-6xl dark:text-white">
229
- {strategyDetail.name}
230
- </h1>
231
- <p class="text-xl text-gray-600 lg:text-2xl dark:text-gray-400">
232
- {deployment.description}
233
- </p>
234
- </div>
235
- {/if}
193
+ <div>
194
+ {#if gui}
195
+ <div class="flex max-w-3xl flex-col gap-12" in:fade>
196
+ {#if deployment}
197
+ <div class="flex max-w-2xl flex-col gap-4 text-start">
198
+ <h1 class="text-4xl font-semibold text-gray-900 lg:text-6xl dark:text-white">
199
+ {strategyDetail.name}
200
+ </h1>
201
+ <p class="text-xl text-gray-600 lg:text-2xl dark:text-gray-400">
202
+ {deployment.description}
203
+ </p>
204
+ </div>
205
+ {/if}
236
206
 
237
- {#if selectTokens && selectTokens.length > 0}
238
- <div class="flex w-full flex-col gap-4">
239
- <DeploymentSectionHeader
240
- title="Select Tokens"
241
- description="Select the tokens that you want to use in your order."
242
- />
243
- {#each selectTokens as token}
244
- <SelectToken {token} {onSelectTokenSelect} />
245
- {/each}
246
- </div>
207
+ {#if selectTokens && selectTokens.length > 0}
208
+ <div class="flex w-full flex-col gap-4">
209
+ <DeploymentSectionHeader
210
+ title="Select Tokens"
211
+ description="Select the tokens that you want to use in your order."
212
+ />
213
+ {#each selectTokens as token}
214
+ <SelectToken {token} {onSelectTokenSelect} />
215
+ {/each}
216
+ </div>
217
+ {/if}
218
+
219
+ {#if allTokensSelected || selectTokens?.length === 0}
220
+ {#if allFieldDefinitionsWithoutDefaults.length > 0}
221
+ {#each allFieldDefinitionsWithoutDefaults as fieldDefinition}
222
+ <FieldDefinitionInput {fieldDefinition} />
223
+ {/each}
247
224
  {/if}
248
225
 
249
- {#if allTokensSelected || selectTokens?.length === 0}
250
- {#if allFieldDefinitionsWithoutDefaults.length > 0}
251
- {#each allFieldDefinitionsWithoutDefaults as fieldDefinition}
252
- <FieldDefinitionInput {fieldDefinition} />
253
- {/each}
254
- {/if}
226
+ <Toggle bind:checked={showAdvancedOptions}>Show advanced options</Toggle>
255
227
 
256
- <Toggle bind:checked={showAdvancedOptions}>Show advanced options</Toggle>
228
+ {#if showAdvancedOptions}
229
+ {#each allFieldDefinitionsWithDefaults as fieldDefinition}
230
+ <FieldDefinitionInput {fieldDefinition} />
231
+ {/each}
257
232
 
258
- {#if allFieldDefinitionsWithDefaults.length > 0 && showAdvancedOptions}
259
- {#each allFieldDefinitionsWithDefaults as fieldDefinition}
260
- <FieldDefinitionInput {fieldDefinition} />
261
- {/each}
262
- {/if}
233
+ {#each allDepositFields as deposit}
234
+ <DepositInput {deposit} />
235
+ {/each}
263
236
 
264
- {#if showAdvancedOptions}
265
- {#each allDepositFields as deposit}
266
- <DepositInput {deposit} />
267
- {/each}
268
- {/if}
237
+ {#each allTokenInputs as input, i}
238
+ <TokenIOInput {i} label="Input" vault={input} />
239
+ {/each}
269
240
 
270
- {#if showAdvancedOptions}
271
- {#each allTokenInputs as input, i}
272
- <TokenIOInput {i} label="Input" vault={input} />
273
- {/each}
241
+ {#each allTokenOutputs as output, i}
242
+ <TokenIOInput {i} label="Output" vault={output} />
243
+ {/each}
244
+ {/if}
274
245
 
275
- {#each allTokenOutputs as output, i}
276
- <TokenIOInput {i} label="Output" vault={output} />
277
- {/each}
278
- {/if}
246
+ {#if $deploymentStepsError}
247
+ <Alert color="red">
248
+ <p class="text-red-500">{$deploymentStepsError.code}</p>
249
+ {#if $deploymentStepsError.details}
250
+ <p class="text-red-500">{$deploymentStepsError.details}</p>
251
+ {/if}
252
+ </Alert>
253
+ {/if}
279
254
 
280
- {#if $deploymentStepsError}
281
- <Alert color="red">
282
- <p class="text-red-500">{$deploymentStepsError.code}</p>
283
- {#if $deploymentStepsError.details}
284
- <p class="text-red-500">{$deploymentStepsError.details}</p>
255
+ <div class="flex flex-wrap items-start justify-start gap-2">
256
+ {#if $account}
257
+ <Button
258
+ data-testid="deploy-button"
259
+ size="lg"
260
+ disabled={checkingDeployment}
261
+ on:click={handleDeployButtonClick}
262
+ class="bg-gradient-to-br from-blue-600 to-violet-600"
263
+ >
264
+ {#if checkingDeployment}
265
+ <Spinner size="4" color="white" />
266
+ <span class="ml-2">Checking deployment...</span>
267
+ {:else}
268
+ Deploy Strategy
285
269
  {/if}
286
- </Alert>
270
+ </Button>
271
+ {:else}
272
+ <WalletConnect {appKitModal} connected={wagmiConnected} />
287
273
  {/if}
288
-
289
- <div class="flex flex-wrap items-start justify-start gap-2">
290
- {#if $wagmiConnected}
291
- <Button
292
- size="lg"
293
- on:click={handleDeployButtonClick}
294
- class="bg-gradient-to-br from-blue-600 to-violet-600"
295
- >
296
- {#if checkingDeployment}
297
- <Spinner size="4" color="white" />
298
- <span class="ml-2">Checking deployment...</span>
299
- {:else}
300
- Deploy Strategy
301
- {/if}
302
- </Button>
303
- {:else}
304
- <WalletConnect {appKitModal} connected={wagmiConnected} />
305
- {/if}
306
- <ComposedRainlangModal />
307
- <ShareChoicesButton handleShareChoices={_handleShareChoices} />
308
- </div>
309
- {/if}
310
- </div>
311
- {/if}
274
+ <ComposedRainlangModal />
275
+ <ShareChoicesButton handleShareChoices={_handleShareChoices} />
276
+ </div>
277
+ {/if}
278
+ </div>
312
279
  {/if}
313
280
  </div>
@@ -1,26 +1,22 @@
1
1
  import { SvelteComponent } from "svelte";
2
2
  import { type ConfigSource } from '@rainlanguage/orderbook/js_api';
3
3
  import { type NameAndDescriptionCfg } from '@rainlanguage/orderbook/js_api';
4
- import { type Config } from '@wagmi/core';
5
4
  import { type Writable } from 'svelte/store';
6
5
  import type { AppKit } from '@reown/appkit';
7
- import type { DisclaimerModalProps, DeployModalProps } from '../../types/modal';
6
+ import { type DeploymentArgs } from '../../types/transaction';
8
7
  declare const __propDef: {
9
8
  props: {
10
- settings: Writable<ConfigSource>;
11
- dotrain: string;
12
- deployment: {
9
+ /** The deployment configuration containing key, name and description */ deployment: {
13
10
  key: string;
14
11
  name: string;
15
12
  description: string;
16
13
  };
17
- strategyDetail: NameAndDescriptionCfg;
18
- handleDeployModal: (args: DeployModalProps) => void;
19
- handleDisclaimerModal: (args: DisclaimerModalProps) => void;
20
- registryUrl: string;
21
- wagmiConfig: Writable<Config | undefined>;
14
+ /** Strategy details containing name and description configuration */ strategyDetail: NameAndDescriptionCfg;
15
+ /** Handlers for deployment modals */ onDeploy: (deploymentArgs: DeploymentArgs) => void;
22
16
  wagmiConnected: Writable<boolean>;
23
17
  appKitModal: Writable<AppKit>;
18
+ settings: Writable<ConfigSource>;
19
+ registryUrl: string;
24
20
  };
25
21
  events: {
26
22
  [evt: string]: CustomEvent<any>;
@@ -0,0 +1,11 @@
1
+ import type { DotrainOrderGui } from '@rainlanguage/orderbook/js_api';
2
+ import type { DeploymentArgs } from '../../types/transaction';
3
+ export declare enum AddOrderErrors {
4
+ ADD_ORDER_FAILED = "Failed to add order",
5
+ MISSING_GUI = "Order GUI is required",
6
+ MISSING_CONFIG = "Wagmi config is required",
7
+ NO_ACCOUNT_CONNECTED = "No wallet address found",
8
+ ERROR_GETTING_ARGS = "Error getting deployment transaction args",
9
+ ERROR_GETTING_NETWORK_KEY = "Error getting network key"
10
+ }
11
+ export declare function handleDeployment(gui: DotrainOrderGui, account: string | null, subgraphUrl?: string): Promise<DeploymentArgs>;
@@ -0,0 +1,33 @@
1
+ export var AddOrderErrors;
2
+ (function (AddOrderErrors) {
3
+ AddOrderErrors["ADD_ORDER_FAILED"] = "Failed to add order";
4
+ AddOrderErrors["MISSING_GUI"] = "Order GUI is required";
5
+ AddOrderErrors["MISSING_CONFIG"] = "Wagmi config is required";
6
+ AddOrderErrors["NO_ACCOUNT_CONNECTED"] = "No wallet address found";
7
+ AddOrderErrors["ERROR_GETTING_ARGS"] = "Error getting deployment transaction args";
8
+ AddOrderErrors["ERROR_GETTING_NETWORK_KEY"] = "Error getting network key";
9
+ })(AddOrderErrors || (AddOrderErrors = {}));
10
+ export async function handleDeployment(gui, account, subgraphUrl) {
11
+ const networkKeyResult = gui.getNetworkKey();
12
+ if (networkKeyResult.error) {
13
+ throw new Error(AddOrderErrors.ERROR_GETTING_NETWORK_KEY);
14
+ }
15
+ const network = networkKeyResult.value;
16
+ if (!account) {
17
+ throw new Error(AddOrderErrors.NO_ACCOUNT_CONNECTED);
18
+ }
19
+ const result = await gui.getDeploymentTransactionArgs(account);
20
+ if (result.error) {
21
+ throw new Error(result.error.msg);
22
+ }
23
+ const { approvals, deploymentCalldata, orderbookAddress, chainId } = result.value;
24
+ return {
25
+ approvals,
26
+ deploymentCalldata,
27
+ // Cast to Hex, since js_api returns a string
28
+ orderbookAddress: orderbookAddress,
29
+ chainId,
30
+ network,
31
+ subgraphUrl
32
+ };
33
+ }
@@ -10,6 +10,7 @@ export declare enum DeploymentStepsErrorCode {
10
10
  NO_TOKEN_OUTPUTS = "Error loading token outputs",
11
11
  NO_GUI_DETAILS = "Error getting GUI details",
12
12
  NO_CHAIN = "Unsupported chain ID",
13
+ NO_NETWORK_KEY = "No network key found",
13
14
  SERIALIZE_ERROR = "Error serializing state",
14
15
  ADD_ORDER_FAILED = "Failed to add order",
15
16
  NO_WALLET = "No account address found"
@@ -12,6 +12,7 @@ export var DeploymentStepsErrorCode;
12
12
  DeploymentStepsErrorCode["NO_TOKEN_OUTPUTS"] = "Error loading token outputs";
13
13
  DeploymentStepsErrorCode["NO_GUI_DETAILS"] = "Error getting GUI details";
14
14
  DeploymentStepsErrorCode["NO_CHAIN"] = "Unsupported chain ID";
15
+ DeploymentStepsErrorCode["NO_NETWORK_KEY"] = "No network key found";
15
16
  DeploymentStepsErrorCode["SERIALIZE_ERROR"] = "Error serializing state";
16
17
  DeploymentStepsErrorCode["ADD_ORDER_FAILED"] = "Failed to add order";
17
18
  DeploymentStepsErrorCode["NO_WALLET"] = "No account address found";
@@ -1,6 +1,7 @@
1
1
  import type { Hex } from 'viem';
2
2
  import type { Config } from '@wagmi/core';
3
- import type { ApprovalCalldata, DepositCalldataResult, RemoveOrderCalldata, SgVault, WithdrawCalldataResult, DepositAndAddOrderCalldataResult } from '@rainlanguage/orderbook/js_api';
3
+ import type { ApprovalCalldata, DepositCalldataResult, RemoveOrderCalldata, SgVault, WithdrawCalldataResult } from '@rainlanguage/orderbook/js_api';
4
+ import type { DeploymentArgs } from '../types/transaction';
4
5
  export declare const ADDRESS_ZERO = "0x0000000000000000000000000000000000000000";
5
6
  export declare const ONE: bigint;
6
7
  export declare enum TransactionStatus {
@@ -32,14 +33,9 @@ export declare enum TransactionErrorMessage {
32
33
  export type ExtendedApprovalCalldata = ApprovalCalldata & {
33
34
  symbol?: string;
34
35
  };
35
- export type DeploymentTransactionArgs = {
36
+ export type DeploymentArgsWithoutAccount = Omit<DeploymentArgs, 'account'>;
37
+ export type DeploymentTransactionArgs = DeploymentArgsWithoutAccount & {
36
38
  config: Config;
37
- approvals: ExtendedApprovalCalldata[];
38
- deploymentCalldata: DepositAndAddOrderCalldataResult;
39
- orderbookAddress: Hex;
40
- chainId: number;
41
- subgraphUrl: string;
42
- network: string;
43
39
  };
44
40
  export type DepositOrWithdrawTransactionArgs = {
45
41
  config: Config;
@@ -200,7 +200,10 @@ const transactionStore = () => {
200
200
  const transactionExplorerLink = await getExplorerLink(hash, chainId, 'tx');
201
201
  awaitTx(hash, TransactionStatus.PENDING_DEPLOYMENT, transactionExplorerLink);
202
202
  await waitForTransactionReceipt(config, { hash });
203
- return awaitNewOrderIndexing(subgraphUrl, hash, network);
203
+ if (subgraphUrl) {
204
+ return awaitNewOrderIndexing(subgraphUrl, hash, network);
205
+ }
206
+ return transactionSuccess(hash, 'Deployment successful. Check the Orders page for your new order.', '', network);
204
207
  }
205
208
  catch {
206
209
  return transactionError(TransactionErrorMessage.DEPLOYMENT_FAILED);
@@ -7,9 +7,8 @@ export type DeploymentArgs = {
7
7
  deploymentCalldata: DepositAndAddOrderCalldataResult;
8
8
  orderbookAddress: Hex;
9
9
  chainId: number;
10
- subgraphUrl: string;
10
+ subgraphUrl?: string;
11
11
  network: string;
12
- account: Account;
13
12
  };
14
13
  export type DepositOrWithdrawArgs = {
15
14
  vault: SgVault;
@@ -0,0 +1,23 @@
1
+ import type { SgOrder, SgOrderAsIO, SgVault } from '@rainlanguage/orderbook/js_api';
2
+ type OrderOrVault = SgOrder | SgOrderAsIO | SgVault;
3
+ /**
4
+ * Constructs a link path for an order or vault based on its type and network
5
+ * @param orderOrVault - The order or vault object
6
+ * @param type - The type of resource ('orders' or 'vaults')
7
+ * @param network - The network name
8
+ * @returns The constructed link path
9
+ */
10
+ export declare function constructHashLink(orderOrVault: OrderOrVault, type: 'orders' | 'vaults', network: string): string;
11
+ /**
12
+ * Determines if an order or vault is active
13
+ * @param orderOrVault - The order or vault object
14
+ * @returns True if the order is active, false otherwise
15
+ */
16
+ export declare function isOrderOrVaultActive(orderOrVault: OrderOrVault): boolean;
17
+ /**
18
+ * Extracts the hash value from an order or vault
19
+ * @param orderOrVault - The order or vault object
20
+ * @returns The hash value
21
+ */
22
+ export declare function extractHash(orderOrVault: OrderOrVault): string;
23
+ export {};
@@ -0,0 +1,110 @@
1
+ import fc from 'fast-check';
2
+ import { test } from '@fast-check/vitest';
3
+ function isOrder(obj) {
4
+ return obj && 'orderHash' in obj;
5
+ }
6
+ /**
7
+ * Constructs a link path for an order or vault based on its type and network
8
+ * @param orderOrVault - The order or vault object
9
+ * @param type - The type of resource ('orders' or 'vaults')
10
+ * @param network - The network name
11
+ * @returns The constructed link path
12
+ */
13
+ export function constructHashLink(orderOrVault, type, network) {
14
+ if (!orderOrVault) {
15
+ return `/${type}/${network}`;
16
+ }
17
+ const slug = isOrder(orderOrVault) ? orderOrVault.orderHash : orderOrVault?.id;
18
+ return `/${type}/${network}-${slug || ''}`;
19
+ }
20
+ /**
21
+ * Determines if an order or vault is active
22
+ * @param orderOrVault - The order or vault object
23
+ * @returns True if the order is active, false otherwise
24
+ */
25
+ export function isOrderOrVaultActive(orderOrVault) {
26
+ const _isOrder = isOrder(orderOrVault);
27
+ return _isOrder ? orderOrVault.active : false;
28
+ }
29
+ /**
30
+ * Extracts the hash value from an order or vault
31
+ * @param orderOrVault - The order or vault object
32
+ * @returns The hash value
33
+ */
34
+ export function extractHash(orderOrVault) {
35
+ const _isOrder = isOrder(orderOrVault);
36
+ return _isOrder ? orderOrVault.orderHash : orderOrVault?.id || '';
37
+ }
38
+ if (import.meta.vitest) {
39
+ const { expect, it, describe } = import.meta.vitest;
40
+ describe('constructHashLink', () => {
41
+ test.prop([
42
+ fc.record({
43
+ orderHash: fc.string(),
44
+ active: fc.boolean()
45
+ }),
46
+ fc.oneof(fc.constant('orders'), fc.constant('vaults')),
47
+ fc.string()
48
+ ])('constructs correct link for orders', (order, type, network) => {
49
+ const result = constructHashLink(order, type, network);
50
+ expect(result).toBe(`/${type}/${network}-${order.orderHash}`);
51
+ });
52
+ test.prop([
53
+ fc.record({
54
+ id: fc.string(),
55
+ owner: fc.string()
56
+ }),
57
+ fc.oneof(fc.constant('orders'), fc.constant('vaults')),
58
+ fc.string()
59
+ ])('constructs correct link for vaults', (vault, type, network) => {
60
+ const result = constructHashLink(vault, type, network);
61
+ expect(result).toBe(`/${type}/${network}-${vault.id}`);
62
+ });
63
+ });
64
+ describe('isOrderOrVaultActive', () => {
65
+ test.prop([
66
+ fc.record({
67
+ orderHash: fc.string(),
68
+ active: fc.boolean()
69
+ })
70
+ ])('returns correct active status for orders', (order) => {
71
+ const result = isOrderOrVaultActive(order);
72
+ expect(result).toBe(order.active);
73
+ });
74
+ test.prop([
75
+ fc.record({
76
+ id: fc.string(),
77
+ owner: fc.string()
78
+ })
79
+ ])('returns false for vaults', (vault) => {
80
+ const result = isOrderOrVaultActive(vault);
81
+ expect(result).toBe(false);
82
+ });
83
+ });
84
+ describe('extractHash', () => {
85
+ test.prop([
86
+ fc.record({
87
+ orderHash: fc.string(),
88
+ active: fc.boolean()
89
+ })
90
+ ])('extracts hash from orders', (order) => {
91
+ const result = extractHash(order);
92
+ expect(result).toBe(order.orderHash);
93
+ });
94
+ test.prop([
95
+ fc.record({
96
+ id: fc.string(),
97
+ owner: fc.string()
98
+ })
99
+ ])('extracts hash from vaults', (vault) => {
100
+ const result = extractHash(vault);
101
+ expect(result).toBe(vault.id);
102
+ });
103
+ it('handles undefined vault id', () => {
104
+ // Create a partial vault object with undefined id
105
+ const vault = { id: undefined };
106
+ const result = extractHash(vault);
107
+ expect(result).toBe('');
108
+ });
109
+ });
110
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rainlanguage/ui-components",
3
- "version": "0.0.1-alpha.47",
3
+ "version": "0.0.1-alpha.49",
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.47",
56
+ "@rainlanguage/orderbook": "0.0.1-alpha.49",
57
57
  "@reown/appkit": "1.6.4",
58
58
  "@reown/appkit-adapter-wagmi": "1.6.4",
59
59
  "@sentry/sveltekit": "7.120.0",
@@ -1,13 +0,0 @@
1
- import type { DepositAndAddOrderCalldataResult, DotrainOrderGui } from '@rainlanguage/orderbook/js_api';
2
- import type { Hex } from 'viem';
3
- import type { ExtendedApprovalCalldata } from '../../stores/transactionStore';
4
- export declare enum AddOrderErrors {
5
- ADD_ORDER_FAILED = "Failed to add order"
6
- }
7
- export interface HandleAddOrderResult {
8
- approvals: ExtendedApprovalCalldata[];
9
- deploymentCalldata: DepositAndAddOrderCalldataResult;
10
- orderbookAddress: Hex;
11
- chainId: number;
12
- }
13
- export declare function getDeploymentTransactionArgs(gui: DotrainOrderGui, account: Hex): Promise<HandleAddOrderResult>;
@@ -1,17 +0,0 @@
1
- export var AddOrderErrors;
2
- (function (AddOrderErrors) {
3
- AddOrderErrors["ADD_ORDER_FAILED"] = "Failed to add order";
4
- })(AddOrderErrors || (AddOrderErrors = {}));
5
- export async function getDeploymentTransactionArgs(gui, account) {
6
- const result = await gui.getDeploymentTransactionArgs(account);
7
- if (result.error) {
8
- throw new Error(result.error.msg);
9
- }
10
- const { approvals, deploymentCalldata, orderbookAddress, chainId } = result.value;
11
- return {
12
- approvals,
13
- deploymentCalldata,
14
- orderbookAddress: orderbookAddress,
15
- chainId
16
- };
17
- }