@medialane/ui 0.166.0 → 0.167.0

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.
@@ -3,7 +3,7 @@ import * as React from 'react';
3
3
  import { VariantProps } from 'class-variance-authority';
4
4
 
5
5
  declare const buttonVariants: (props?: ({
6
- variant?: "link" | "default" | "destructive" | "outline" | "ghost" | "secondary" | "premium" | "tonal" | "gradient-border" | "gradient-fill" | null | undefined;
6
+ variant?: "ghost" | "link" | "default" | "destructive" | "outline" | "secondary" | "premium" | "tonal" | "gradient-border" | "gradient-fill" | null | undefined;
7
7
  size?: "icon" | "default" | "sm" | "lg" | null | undefined;
8
8
  } & class_variance_authority_types.ClassProp) | undefined) => string;
9
9
  interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof buttonVariants> {
@@ -3,7 +3,7 @@ import * as React from 'react';
3
3
  import { VariantProps } from 'class-variance-authority';
4
4
 
5
5
  declare const buttonVariants: (props?: ({
6
- variant?: "link" | "default" | "destructive" | "outline" | "ghost" | "secondary" | "premium" | "tonal" | "gradient-border" | "gradient-fill" | null | undefined;
6
+ variant?: "ghost" | "link" | "default" | "destructive" | "outline" | "secondary" | "premium" | "tonal" | "gradient-border" | "gradient-fill" | null | undefined;
7
7
  size?: "icon" | "default" | "sm" | "lg" | null | undefined;
8
8
  } & class_variance_authority_types.ClassProp) | undefined) => string;
9
9
  interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof buttonVariants> {
@@ -30,88 +30,63 @@ var import_wallet_error = require("./wallet-error.js");
30
30
  const NOT_SUBMITTED = "Request not completed. Nothing was submitted.";
31
31
  const GENERIC = "Something went wrong. Please try again.";
32
32
  const NETWORK_BUSY = "The network is busy right now. Nothing was submitted. Please try again in a moment.";
33
- function isTransientStatus(status) {
34
- return status === 408 || status === 429 || status >= 500;
35
- }
36
- function isTransientNetworkError(text) {
33
+ const notice = (title, message, description) => ({
34
+ title,
35
+ message,
36
+ description,
37
+ isUserRejection: false
38
+ });
39
+ function isTransient(error) {
40
+ if (error instanceof import_sdk.MedialaneApiError) {
41
+ return error.status === 408 || error.status === 429 || error.status >= 500;
42
+ }
37
43
  return /-32001|unable to complete request|service unavailable|temporarily unavailable|rate.?limit|too many requests|gateway time-?out|bad gateway|failed to fetch|fetch failed|network ?error|load failed/i.test(
38
- text
44
+ (0, import_wallet_error.collectErrorText)(error)
39
45
  );
40
46
  }
41
- function describeError(error, fallback) {
42
- if (error instanceof import_sdk.PasskeyCancelledError) {
43
- return {
44
- title: "Request not completed",
45
- message: NOT_SUBMITTED,
46
- description: "Your device did not confirm this request. Nothing was submitted. Try again when you are ready.",
47
- isUserRejection: true
48
- };
49
- }
50
- if ((0, import_wallet_error.isBareExecuteFailure)(error)) {
51
- return {
52
- title: "Request not completed",
53
- message: NOT_SUBMITTED,
54
- description: "Your wallet didn't complete this request. This usually means you closed or declined it, your wallet needs extra verification (like 2FA) before it can sign, or your wallet hit a temporary network hiccup. Nothing was submitted. Try again in a moment.",
55
- isUserRejection: true
56
- };
47
+ function apiReason(error) {
48
+ const body = error.details;
49
+ if (body && typeof body === "object" && "error" in body) {
50
+ const reason = body.error;
51
+ if (typeof reason === "string" && reason.trim() !== "") return reason;
57
52
  }
58
- if ((0, import_wallet_error.isUserRejectedRequest)(error)) {
53
+ return void 0;
54
+ }
55
+ function describeError(error, fallback) {
56
+ if (error instanceof import_sdk.PasskeyCancelledError || (0, import_wallet_error.isUserRejectedRequest)(error)) {
57
+ const unclear = (0, import_wallet_error.isBareExecuteFailure)(error) || error instanceof import_sdk.PasskeyCancelledError;
59
58
  return {
60
59
  title: "Request not completed",
61
60
  message: NOT_SUBMITTED,
62
- description: "Your wallet didn't complete this request. You may have closed or declined it, or it may need extra verification before it can sign. Nothing was submitted.",
61
+ description: unclear ? "Your wallet didn't complete this request. You may have closed or declined it, it may need extra verification such as 2FA before it can sign, or it may have hit a temporary network hiccup. Try again in a moment." : "Your wallet didn't complete this request. You may have closed or declined it, or it may need extra verification before it can sign.",
63
62
  isUserRejection: true
64
63
  };
65
64
  }
66
65
  if (error instanceof import_wallet_error.WrongNetworkError) {
67
- return {
68
- title: "Wrong network",
69
- message: "Your wallet is connected to the wrong network. Nothing was submitted.",
70
- description: "Switch your wallet to Starknet Mainnet, then try again.",
71
- isUserRejection: false
72
- };
66
+ return notice(
67
+ "Wrong network",
68
+ "Your wallet is connected to the wrong network. Nothing was submitted.",
69
+ "Switch your wallet to Starknet Mainnet, then try again."
70
+ );
71
+ }
72
+ if (isTransient(error)) {
73
+ return notice("Network busy", NETWORK_BUSY);
73
74
  }
74
75
  if (error instanceof import_sdk.UserFacingError) {
75
- return { title: "Something went wrong", message: error.message, isUserRejection: false };
76
+ return notice("Something went wrong", error.message);
76
77
  }
77
78
  if (error instanceof import_sdk.MedialaneApiError) {
78
- if (error.isAuthored) {
79
- return { title: "Something went wrong", message: error.message, isUserRejection: false };
80
- }
81
- if (isTransientStatus(error.status)) {
82
- return { title: "Network busy", message: NETWORK_BUSY, isUserRejection: false };
83
- }
84
- return { title: "Something went wrong", message: fallback ?? GENERIC, isUserRejection: false };
79
+ return notice("Something went wrong", apiReason(error) ?? fallback ?? GENERIC);
85
80
  }
86
- const raw = (0, import_wallet_error.collectErrorText)(error);
87
- if (isTransientNetworkError(raw)) {
88
- return { title: "Network busy", message: NETWORK_BUSY, isUserRejection: false };
89
- }
90
- const lower = raw.toLowerCase();
91
- if (lower.includes("insufficient") && /balance|allowance|funds/.test(lower)) {
92
- return {
93
- title: "Insufficient balance",
94
- message: "You don't have enough balance to complete this transaction.",
95
- isUserRejection: false
96
- };
97
- }
98
- const stack = error instanceof Error && typeof error.stack === "string" ? error.stack.toLowerCase() : "";
99
- if (lower.includes("validation failure") && (lower.includes("jscontrollererror") || stack.includes("jscontrollererror"))) {
100
- return {
101
- title: "Not enough gas",
102
- message: "Your wallet doesn't have enough STRK (or ETH) to pay for this transaction's gas fee.",
103
- description: "Add funds to your wallet, then try again.",
104
- isUserRejection: false
105
- };
106
- }
107
- if (/unknown_error/i.test(raw) || typeof error === "object" && error !== null && error.code === 163) {
108
- return {
109
- title: "Something went wrong",
110
- message: "Your wallet couldn't complete this transaction. Nothing was submitted. Try again, or try a different wallet or device if it keeps happening.",
111
- isUserRejection: false
112
- };
81
+ const text = (0, import_wallet_error.collectErrorText)(error).toLowerCase();
82
+ if (text.includes("insufficient") && /balance|allowance|funds/.test(text)) {
83
+ return notice(
84
+ "Insufficient balance",
85
+ "You don't have enough balance to complete this transaction.",
86
+ "Add funds to your wallet, then try again."
87
+ );
113
88
  }
114
- return { title: "Something went wrong", message: fallback ?? GENERIC, isUserRejection: false };
89
+ return notice("Something went wrong", fallback ?? GENERIC);
115
90
  }
116
91
  // Annotate the CommonJS export names for ESM import in node:
117
92
  0 && (module.exports = {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/describe-error.ts"],"sourcesContent":["import { MedialaneApiError, PasskeyCancelledError, UserFacingError } from \"@medialane/sdk\";\nimport {\n WrongNetworkError,\n isBareExecuteFailure,\n isUserRejectedRequest,\n collectErrorText,\n} from \"./wallet-error.js\";\n\nexport const NOT_SUBMITTED = \"Request not completed. Nothing was submitted.\";\nexport const GENERIC = \"Something went wrong. Please try again.\";\nexport const NETWORK_BUSY =\n \"The network is busy right now. Nothing was submitted. Please try again in a moment.\";\n\nexport interface ErrorNotice {\n title: string;\n message: string;\n description?: string;\n isUserRejection: boolean;\n}\n\nfunction isTransientStatus(status: number): boolean {\n return status === 408 || status === 429 || status >= 500;\n}\n\nfunction isTransientNetworkError(text: string): boolean {\n return /-32001|unable to complete request|service unavailable|temporarily unavailable|rate.?limit|too many requests|gateway time-?out|bad gateway|failed to fetch|fetch failed|network ?error|load failed/i.test(\n text,\n );\n}\n\nexport function describeError(error: unknown, fallback?: string): ErrorNotice {\n if (error instanceof PasskeyCancelledError) {\n return {\n title: \"Request not completed\",\n message: NOT_SUBMITTED,\n description: \"Your device did not confirm this request. Nothing was submitted. Try again when you are ready.\",\n isUserRejection: true,\n };\n }\n\n if (isBareExecuteFailure(error)) {\n return {\n title: \"Request not completed\",\n message: NOT_SUBMITTED,\n description: \"Your wallet didn't complete this request. This usually means you closed or declined it, your wallet needs extra verification (like 2FA) before it can sign, or your wallet hit a temporary network hiccup. Nothing was submitted. Try again in a moment.\",\n isUserRejection: true,\n };\n }\n\n if (isUserRejectedRequest(error)) {\n return {\n title: \"Request not completed\",\n message: NOT_SUBMITTED,\n description: \"Your wallet didn't complete this request. You may have closed or declined it, or it may need extra verification before it can sign. Nothing was submitted.\",\n isUserRejection: true,\n };\n }\n\n if (error instanceof WrongNetworkError) {\n return {\n title: \"Wrong network\",\n message: \"Your wallet is connected to the wrong network. Nothing was submitted.\",\n description: \"Switch your wallet to Starknet Mainnet, then try again.\",\n isUserRejection: false,\n };\n }\n\n if (error instanceof UserFacingError) {\n return { title: \"Something went wrong\", message: error.message, isUserRejection: false };\n }\n\n if (error instanceof MedialaneApiError) {\n if (error.isAuthored) {\n return { title: \"Something went wrong\", message: error.message, isUserRejection: false };\n }\n if (isTransientStatus(error.status)) {\n return { title: \"Network busy\", message: NETWORK_BUSY, isUserRejection: false };\n }\n return { title: \"Something went wrong\", message: fallback ?? GENERIC, isUserRejection: false };\n }\n\n const raw = collectErrorText(error);\n\n if (isTransientNetworkError(raw)) {\n return { title: \"Network busy\", message: NETWORK_BUSY, isUserRejection: false };\n }\n\n const lower = raw.toLowerCase();\n if (lower.includes(\"insufficient\") && /balance|allowance|funds/.test(lower)) {\n return {\n title: \"Insufficient balance\",\n message: \"You don't have enough balance to complete this transaction.\",\n isUserRejection: false,\n };\n }\n\n const stack = error instanceof Error && typeof error.stack === \"string\" ? error.stack.toLowerCase() : \"\";\n if (lower.includes(\"validation failure\") && (lower.includes(\"jscontrollererror\") || stack.includes(\"jscontrollererror\"))) {\n return {\n title: \"Not enough gas\",\n message: \"Your wallet doesn't have enough STRK (or ETH) to pay for this transaction's gas fee.\",\n description: \"Add funds to your wallet, then try again.\",\n isUserRejection: false,\n };\n }\n\n if (/unknown_error/i.test(raw) || (typeof error === \"object\" && error !== null && (error as { code?: unknown }).code === 163)) {\n return {\n title: \"Something went wrong\",\n message: \"Your wallet couldn't complete this transaction. Nothing was submitted. Try again, or try a different wallet or device if it keeps happening.\",\n isUserRejection: false,\n };\n }\n\n return { title: \"Something went wrong\", message: fallback ?? GENERIC, isUserRejection: false };\n}\n\nexport { UserFacingError };\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iBAA0E;AAC1E,0BAKO;AAEA,MAAM,gBAAgB;AACtB,MAAM,UAAU;AAChB,MAAM,eACX;AASF,SAAS,kBAAkB,QAAyB;AAClD,SAAO,WAAW,OAAO,WAAW,OAAO,UAAU;AACvD;AAEA,SAAS,wBAAwB,MAAuB;AACtD,SAAO,qMAAqM;AAAA,IAC1M;AAAA,EACF;AACF;AAEO,SAAS,cAAc,OAAgB,UAAgC;AAC5E,MAAI,iBAAiB,kCAAuB;AAC1C,WAAO;AAAA,MACL,OAAO;AAAA,MACP,SAAS;AAAA,MACT,aAAa;AAAA,MACb,iBAAiB;AAAA,IACnB;AAAA,EACF;AAEA,UAAI,0CAAqB,KAAK,GAAG;AAC/B,WAAO;AAAA,MACL,OAAO;AAAA,MACP,SAAS;AAAA,MACT,aAAa;AAAA,MACb,iBAAiB;AAAA,IACnB;AAAA,EACF;AAEA,UAAI,2CAAsB,KAAK,GAAG;AAChC,WAAO;AAAA,MACL,OAAO;AAAA,MACP,SAAS;AAAA,MACT,aAAa;AAAA,MACb,iBAAiB;AAAA,IACnB;AAAA,EACF;AAEA,MAAI,iBAAiB,uCAAmB;AACtC,WAAO;AAAA,MACL,OAAO;AAAA,MACP,SAAS;AAAA,MACT,aAAa;AAAA,MACb,iBAAiB;AAAA,IACnB;AAAA,EACF;AAEA,MAAI,iBAAiB,4BAAiB;AACpC,WAAO,EAAE,OAAO,wBAAwB,SAAS,MAAM,SAAS,iBAAiB,MAAM;AAAA,EACzF;AAEA,MAAI,iBAAiB,8BAAmB;AACtC,QAAI,MAAM,YAAY;AACpB,aAAO,EAAE,OAAO,wBAAwB,SAAS,MAAM,SAAS,iBAAiB,MAAM;AAAA,IACzF;AACA,QAAI,kBAAkB,MAAM,MAAM,GAAG;AACnC,aAAO,EAAE,OAAO,gBAAgB,SAAS,cAAc,iBAAiB,MAAM;AAAA,IAChF;AACA,WAAO,EAAE,OAAO,wBAAwB,SAAS,YAAY,SAAS,iBAAiB,MAAM;AAAA,EAC/F;AAEA,QAAM,UAAM,sCAAiB,KAAK;AAElC,MAAI,wBAAwB,GAAG,GAAG;AAChC,WAAO,EAAE,OAAO,gBAAgB,SAAS,cAAc,iBAAiB,MAAM;AAAA,EAChF;AAEA,QAAM,QAAQ,IAAI,YAAY;AAC9B,MAAI,MAAM,SAAS,cAAc,KAAK,0BAA0B,KAAK,KAAK,GAAG;AAC3E,WAAO;AAAA,MACL,OAAO;AAAA,MACP,SAAS;AAAA,MACT,iBAAiB;AAAA,IACnB;AAAA,EACF;AAEA,QAAM,QAAQ,iBAAiB,SAAS,OAAO,MAAM,UAAU,WAAW,MAAM,MAAM,YAAY,IAAI;AACtG,MAAI,MAAM,SAAS,oBAAoB,MAAM,MAAM,SAAS,mBAAmB,KAAK,MAAM,SAAS,mBAAmB,IAAI;AACxH,WAAO;AAAA,MACL,OAAO;AAAA,MACP,SAAS;AAAA,MACT,aAAa;AAAA,MACb,iBAAiB;AAAA,IACnB;AAAA,EACF;AAEA,MAAI,iBAAiB,KAAK,GAAG,KAAM,OAAO,UAAU,YAAY,UAAU,QAAS,MAA6B,SAAS,KAAM;AAC7H,WAAO;AAAA,MACL,OAAO;AAAA,MACP,SAAS;AAAA,MACT,iBAAiB;AAAA,IACnB;AAAA,EACF;AAEA,SAAO,EAAE,OAAO,wBAAwB,SAAS,YAAY,SAAS,iBAAiB,MAAM;AAC/F;","names":[]}
1
+ {"version":3,"sources":["../../src/utils/describe-error.ts"],"sourcesContent":["import { MedialaneApiError, PasskeyCancelledError, UserFacingError } from \"@medialane/sdk\";\nimport { WrongNetworkError, isBareExecuteFailure, isUserRejectedRequest, collectErrorText } from \"./wallet-error.js\";\n\nexport const NOT_SUBMITTED = \"Request not completed. Nothing was submitted.\";\nexport const GENERIC = \"Something went wrong. Please try again.\";\nexport const NETWORK_BUSY =\n \"The network is busy right now. Nothing was submitted. Please try again in a moment.\";\n\nexport interface ErrorNotice {\n title: string;\n message: string;\n description?: string;\n isUserRejection: boolean;\n}\n\nconst notice = (title: string, message: string, description?: string): ErrorNotice => ({\n title,\n message,\n description,\n isUserRejection: false,\n});\n\nfunction isTransient(error: unknown): boolean {\n if (error instanceof MedialaneApiError) {\n return error.status === 408 || error.status === 429 || error.status >= 500;\n }\n return /-32001|unable to complete request|service unavailable|temporarily unavailable|rate.?limit|too many requests|gateway time-?out|bad gateway|failed to fetch|fetch failed|network ?error|load failed/i.test(\n collectErrorText(error),\n );\n}\n\nfunction apiReason(error: MedialaneApiError): string | undefined {\n const body = error.details;\n if (body && typeof body === \"object\" && \"error\" in body) {\n const reason = (body as { error?: unknown }).error;\n if (typeof reason === \"string\" && reason.trim() !== \"\") return reason;\n }\n return undefined;\n}\n\nexport function describeError(error: unknown, fallback?: string): ErrorNotice {\n if (error instanceof PasskeyCancelledError || isUserRejectedRequest(error)) {\n const unclear = isBareExecuteFailure(error) || error instanceof PasskeyCancelledError;\n return {\n title: \"Request not completed\",\n message: NOT_SUBMITTED,\n description: unclear\n ? \"Your wallet didn't complete this request. You may have closed or declined it, it may need extra verification such as 2FA before it can sign, or it may have hit a temporary network hiccup. Try again in a moment.\"\n : \"Your wallet didn't complete this request. You may have closed or declined it, or it may need extra verification before it can sign.\",\n isUserRejection: true,\n };\n }\n\n if (error instanceof WrongNetworkError) {\n return notice(\n \"Wrong network\",\n \"Your wallet is connected to the wrong network. Nothing was submitted.\",\n \"Switch your wallet to Starknet Mainnet, then try again.\",\n );\n }\n\n if (isTransient(error)) {\n return notice(\"Network busy\", NETWORK_BUSY);\n }\n\n if (error instanceof UserFacingError) {\n return notice(\"Something went wrong\", error.message);\n }\n\n if (error instanceof MedialaneApiError) {\n return notice(\"Something went wrong\", apiReason(error) ?? fallback ?? GENERIC);\n }\n\n const text = collectErrorText(error).toLowerCase();\n if (text.includes(\"insufficient\") && /balance|allowance|funds/.test(text)) {\n return notice(\n \"Insufficient balance\",\n \"You don't have enough balance to complete this transaction.\",\n \"Add funds to your wallet, then try again.\",\n );\n }\n\n return notice(\"Something went wrong\", fallback ?? GENERIC);\n}\n\nexport { UserFacingError };\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iBAA0E;AAC1E,0BAAiG;AAE1F,MAAM,gBAAgB;AACtB,MAAM,UAAU;AAChB,MAAM,eACX;AASF,MAAM,SAAS,CAAC,OAAe,SAAiB,iBAAuC;AAAA,EACrF;AAAA,EACA;AAAA,EACA;AAAA,EACA,iBAAiB;AACnB;AAEA,SAAS,YAAY,OAAyB;AAC5C,MAAI,iBAAiB,8BAAmB;AACtC,WAAO,MAAM,WAAW,OAAO,MAAM,WAAW,OAAO,MAAM,UAAU;AAAA,EACzE;AACA,SAAO,qMAAqM;AAAA,QAC1M,sCAAiB,KAAK;AAAA,EACxB;AACF;AAEA,SAAS,UAAU,OAA8C;AAC/D,QAAM,OAAO,MAAM;AACnB,MAAI,QAAQ,OAAO,SAAS,YAAY,WAAW,MAAM;AACvD,UAAM,SAAU,KAA6B;AAC7C,QAAI,OAAO,WAAW,YAAY,OAAO,KAAK,MAAM,GAAI,QAAO;AAAA,EACjE;AACA,SAAO;AACT;AAEO,SAAS,cAAc,OAAgB,UAAgC;AAC5E,MAAI,iBAAiB,wCAAyB,2CAAsB,KAAK,GAAG;AAC1E,UAAM,cAAU,0CAAqB,KAAK,KAAK,iBAAiB;AAChE,WAAO;AAAA,MACL,OAAO;AAAA,MACP,SAAS;AAAA,MACT,aAAa,UACT,uNACA;AAAA,MACJ,iBAAiB;AAAA,IACnB;AAAA,EACF;AAEA,MAAI,iBAAiB,uCAAmB;AACtC,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,MAAI,YAAY,KAAK,GAAG;AACtB,WAAO,OAAO,gBAAgB,YAAY;AAAA,EAC5C;AAEA,MAAI,iBAAiB,4BAAiB;AACpC,WAAO,OAAO,wBAAwB,MAAM,OAAO;AAAA,EACrD;AAEA,MAAI,iBAAiB,8BAAmB;AACtC,WAAO,OAAO,wBAAwB,UAAU,KAAK,KAAK,YAAY,OAAO;AAAA,EAC/E;AAEA,QAAM,WAAO,sCAAiB,KAAK,EAAE,YAAY;AACjD,MAAI,KAAK,SAAS,cAAc,KAAK,0BAA0B,KAAK,IAAI,GAAG;AACzE,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,SAAO,OAAO,wBAAwB,YAAY,OAAO;AAC3D;","names":[]}
@@ -1,95 +1,65 @@
1
1
  import { MedialaneApiError, PasskeyCancelledError, UserFacingError } from "@medialane/sdk";
2
- import {
3
- WrongNetworkError,
4
- isBareExecuteFailure,
5
- isUserRejectedRequest,
6
- collectErrorText
7
- } from "./wallet-error.js";
2
+ import { WrongNetworkError, isBareExecuteFailure, isUserRejectedRequest, collectErrorText } from "./wallet-error.js";
8
3
  const NOT_SUBMITTED = "Request not completed. Nothing was submitted.";
9
4
  const GENERIC = "Something went wrong. Please try again.";
10
5
  const NETWORK_BUSY = "The network is busy right now. Nothing was submitted. Please try again in a moment.";
11
- function isTransientStatus(status) {
12
- return status === 408 || status === 429 || status >= 500;
13
- }
14
- function isTransientNetworkError(text) {
6
+ const notice = (title, message, description) => ({
7
+ title,
8
+ message,
9
+ description,
10
+ isUserRejection: false
11
+ });
12
+ function isTransient(error) {
13
+ if (error instanceof MedialaneApiError) {
14
+ return error.status === 408 || error.status === 429 || error.status >= 500;
15
+ }
15
16
  return /-32001|unable to complete request|service unavailable|temporarily unavailable|rate.?limit|too many requests|gateway time-?out|bad gateway|failed to fetch|fetch failed|network ?error|load failed/i.test(
16
- text
17
+ collectErrorText(error)
17
18
  );
18
19
  }
19
- function describeError(error, fallback) {
20
- if (error instanceof PasskeyCancelledError) {
21
- return {
22
- title: "Request not completed",
23
- message: NOT_SUBMITTED,
24
- description: "Your device did not confirm this request. Nothing was submitted. Try again when you are ready.",
25
- isUserRejection: true
26
- };
27
- }
28
- if (isBareExecuteFailure(error)) {
29
- return {
30
- title: "Request not completed",
31
- message: NOT_SUBMITTED,
32
- description: "Your wallet didn't complete this request. This usually means you closed or declined it, your wallet needs extra verification (like 2FA) before it can sign, or your wallet hit a temporary network hiccup. Nothing was submitted. Try again in a moment.",
33
- isUserRejection: true
34
- };
20
+ function apiReason(error) {
21
+ const body = error.details;
22
+ if (body && typeof body === "object" && "error" in body) {
23
+ const reason = body.error;
24
+ if (typeof reason === "string" && reason.trim() !== "") return reason;
35
25
  }
36
- if (isUserRejectedRequest(error)) {
26
+ return void 0;
27
+ }
28
+ function describeError(error, fallback) {
29
+ if (error instanceof PasskeyCancelledError || isUserRejectedRequest(error)) {
30
+ const unclear = isBareExecuteFailure(error) || error instanceof PasskeyCancelledError;
37
31
  return {
38
32
  title: "Request not completed",
39
33
  message: NOT_SUBMITTED,
40
- description: "Your wallet didn't complete this request. You may have closed or declined it, or it may need extra verification before it can sign. Nothing was submitted.",
34
+ description: unclear ? "Your wallet didn't complete this request. You may have closed or declined it, it may need extra verification such as 2FA before it can sign, or it may have hit a temporary network hiccup. Try again in a moment." : "Your wallet didn't complete this request. You may have closed or declined it, or it may need extra verification before it can sign.",
41
35
  isUserRejection: true
42
36
  };
43
37
  }
44
38
  if (error instanceof WrongNetworkError) {
45
- return {
46
- title: "Wrong network",
47
- message: "Your wallet is connected to the wrong network. Nothing was submitted.",
48
- description: "Switch your wallet to Starknet Mainnet, then try again.",
49
- isUserRejection: false
50
- };
39
+ return notice(
40
+ "Wrong network",
41
+ "Your wallet is connected to the wrong network. Nothing was submitted.",
42
+ "Switch your wallet to Starknet Mainnet, then try again."
43
+ );
44
+ }
45
+ if (isTransient(error)) {
46
+ return notice("Network busy", NETWORK_BUSY);
51
47
  }
52
48
  if (error instanceof UserFacingError) {
53
- return { title: "Something went wrong", message: error.message, isUserRejection: false };
49
+ return notice("Something went wrong", error.message);
54
50
  }
55
51
  if (error instanceof MedialaneApiError) {
56
- if (error.isAuthored) {
57
- return { title: "Something went wrong", message: error.message, isUserRejection: false };
58
- }
59
- if (isTransientStatus(error.status)) {
60
- return { title: "Network busy", message: NETWORK_BUSY, isUserRejection: false };
61
- }
62
- return { title: "Something went wrong", message: fallback ?? GENERIC, isUserRejection: false };
63
- }
64
- const raw = collectErrorText(error);
65
- if (isTransientNetworkError(raw)) {
66
- return { title: "Network busy", message: NETWORK_BUSY, isUserRejection: false };
67
- }
68
- const lower = raw.toLowerCase();
69
- if (lower.includes("insufficient") && /balance|allowance|funds/.test(lower)) {
70
- return {
71
- title: "Insufficient balance",
72
- message: "You don't have enough balance to complete this transaction.",
73
- isUserRejection: false
74
- };
52
+ return notice("Something went wrong", apiReason(error) ?? fallback ?? GENERIC);
75
53
  }
76
- const stack = error instanceof Error && typeof error.stack === "string" ? error.stack.toLowerCase() : "";
77
- if (lower.includes("validation failure") && (lower.includes("jscontrollererror") || stack.includes("jscontrollererror"))) {
78
- return {
79
- title: "Not enough gas",
80
- message: "Your wallet doesn't have enough STRK (or ETH) to pay for this transaction's gas fee.",
81
- description: "Add funds to your wallet, then try again.",
82
- isUserRejection: false
83
- };
84
- }
85
- if (/unknown_error/i.test(raw) || typeof error === "object" && error !== null && error.code === 163) {
86
- return {
87
- title: "Something went wrong",
88
- message: "Your wallet couldn't complete this transaction. Nothing was submitted. Try again, or try a different wallet or device if it keeps happening.",
89
- isUserRejection: false
90
- };
54
+ const text = collectErrorText(error).toLowerCase();
55
+ if (text.includes("insufficient") && /balance|allowance|funds/.test(text)) {
56
+ return notice(
57
+ "Insufficient balance",
58
+ "You don't have enough balance to complete this transaction.",
59
+ "Add funds to your wallet, then try again."
60
+ );
91
61
  }
92
- return { title: "Something went wrong", message: fallback ?? GENERIC, isUserRejection: false };
62
+ return notice("Something went wrong", fallback ?? GENERIC);
93
63
  }
94
64
  export {
95
65
  GENERIC,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/describe-error.ts"],"sourcesContent":["import { MedialaneApiError, PasskeyCancelledError, UserFacingError } from \"@medialane/sdk\";\nimport {\n WrongNetworkError,\n isBareExecuteFailure,\n isUserRejectedRequest,\n collectErrorText,\n} from \"./wallet-error.js\";\n\nexport const NOT_SUBMITTED = \"Request not completed. Nothing was submitted.\";\nexport const GENERIC = \"Something went wrong. Please try again.\";\nexport const NETWORK_BUSY =\n \"The network is busy right now. Nothing was submitted. Please try again in a moment.\";\n\nexport interface ErrorNotice {\n title: string;\n message: string;\n description?: string;\n isUserRejection: boolean;\n}\n\nfunction isTransientStatus(status: number): boolean {\n return status === 408 || status === 429 || status >= 500;\n}\n\nfunction isTransientNetworkError(text: string): boolean {\n return /-32001|unable to complete request|service unavailable|temporarily unavailable|rate.?limit|too many requests|gateway time-?out|bad gateway|failed to fetch|fetch failed|network ?error|load failed/i.test(\n text,\n );\n}\n\nexport function describeError(error: unknown, fallback?: string): ErrorNotice {\n if (error instanceof PasskeyCancelledError) {\n return {\n title: \"Request not completed\",\n message: NOT_SUBMITTED,\n description: \"Your device did not confirm this request. Nothing was submitted. Try again when you are ready.\",\n isUserRejection: true,\n };\n }\n\n if (isBareExecuteFailure(error)) {\n return {\n title: \"Request not completed\",\n message: NOT_SUBMITTED,\n description: \"Your wallet didn't complete this request. This usually means you closed or declined it, your wallet needs extra verification (like 2FA) before it can sign, or your wallet hit a temporary network hiccup. Nothing was submitted. Try again in a moment.\",\n isUserRejection: true,\n };\n }\n\n if (isUserRejectedRequest(error)) {\n return {\n title: \"Request not completed\",\n message: NOT_SUBMITTED,\n description: \"Your wallet didn't complete this request. You may have closed or declined it, or it may need extra verification before it can sign. Nothing was submitted.\",\n isUserRejection: true,\n };\n }\n\n if (error instanceof WrongNetworkError) {\n return {\n title: \"Wrong network\",\n message: \"Your wallet is connected to the wrong network. Nothing was submitted.\",\n description: \"Switch your wallet to Starknet Mainnet, then try again.\",\n isUserRejection: false,\n };\n }\n\n if (error instanceof UserFacingError) {\n return { title: \"Something went wrong\", message: error.message, isUserRejection: false };\n }\n\n if (error instanceof MedialaneApiError) {\n if (error.isAuthored) {\n return { title: \"Something went wrong\", message: error.message, isUserRejection: false };\n }\n if (isTransientStatus(error.status)) {\n return { title: \"Network busy\", message: NETWORK_BUSY, isUserRejection: false };\n }\n return { title: \"Something went wrong\", message: fallback ?? GENERIC, isUserRejection: false };\n }\n\n const raw = collectErrorText(error);\n\n if (isTransientNetworkError(raw)) {\n return { title: \"Network busy\", message: NETWORK_BUSY, isUserRejection: false };\n }\n\n const lower = raw.toLowerCase();\n if (lower.includes(\"insufficient\") && /balance|allowance|funds/.test(lower)) {\n return {\n title: \"Insufficient balance\",\n message: \"You don't have enough balance to complete this transaction.\",\n isUserRejection: false,\n };\n }\n\n const stack = error instanceof Error && typeof error.stack === \"string\" ? error.stack.toLowerCase() : \"\";\n if (lower.includes(\"validation failure\") && (lower.includes(\"jscontrollererror\") || stack.includes(\"jscontrollererror\"))) {\n return {\n title: \"Not enough gas\",\n message: \"Your wallet doesn't have enough STRK (or ETH) to pay for this transaction's gas fee.\",\n description: \"Add funds to your wallet, then try again.\",\n isUserRejection: false,\n };\n }\n\n if (/unknown_error/i.test(raw) || (typeof error === \"object\" && error !== null && (error as { code?: unknown }).code === 163)) {\n return {\n title: \"Something went wrong\",\n message: \"Your wallet couldn't complete this transaction. Nothing was submitted. Try again, or try a different wallet or device if it keeps happening.\",\n isUserRejection: false,\n };\n }\n\n return { title: \"Something went wrong\", message: fallback ?? GENERIC, isUserRejection: false };\n}\n\nexport { UserFacingError };\n"],"mappings":"AAAA,SAAS,mBAAmB,uBAAuB,uBAAuB;AAC1E;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEA,MAAM,gBAAgB;AACtB,MAAM,UAAU;AAChB,MAAM,eACX;AASF,SAAS,kBAAkB,QAAyB;AAClD,SAAO,WAAW,OAAO,WAAW,OAAO,UAAU;AACvD;AAEA,SAAS,wBAAwB,MAAuB;AACtD,SAAO,qMAAqM;AAAA,IAC1M;AAAA,EACF;AACF;AAEO,SAAS,cAAc,OAAgB,UAAgC;AAC5E,MAAI,iBAAiB,uBAAuB;AAC1C,WAAO;AAAA,MACL,OAAO;AAAA,MACP,SAAS;AAAA,MACT,aAAa;AAAA,MACb,iBAAiB;AAAA,IACnB;AAAA,EACF;AAEA,MAAI,qBAAqB,KAAK,GAAG;AAC/B,WAAO;AAAA,MACL,OAAO;AAAA,MACP,SAAS;AAAA,MACT,aAAa;AAAA,MACb,iBAAiB;AAAA,IACnB;AAAA,EACF;AAEA,MAAI,sBAAsB,KAAK,GAAG;AAChC,WAAO;AAAA,MACL,OAAO;AAAA,MACP,SAAS;AAAA,MACT,aAAa;AAAA,MACb,iBAAiB;AAAA,IACnB;AAAA,EACF;AAEA,MAAI,iBAAiB,mBAAmB;AACtC,WAAO;AAAA,MACL,OAAO;AAAA,MACP,SAAS;AAAA,MACT,aAAa;AAAA,MACb,iBAAiB;AAAA,IACnB;AAAA,EACF;AAEA,MAAI,iBAAiB,iBAAiB;AACpC,WAAO,EAAE,OAAO,wBAAwB,SAAS,MAAM,SAAS,iBAAiB,MAAM;AAAA,EACzF;AAEA,MAAI,iBAAiB,mBAAmB;AACtC,QAAI,MAAM,YAAY;AACpB,aAAO,EAAE,OAAO,wBAAwB,SAAS,MAAM,SAAS,iBAAiB,MAAM;AAAA,IACzF;AACA,QAAI,kBAAkB,MAAM,MAAM,GAAG;AACnC,aAAO,EAAE,OAAO,gBAAgB,SAAS,cAAc,iBAAiB,MAAM;AAAA,IAChF;AACA,WAAO,EAAE,OAAO,wBAAwB,SAAS,YAAY,SAAS,iBAAiB,MAAM;AAAA,EAC/F;AAEA,QAAM,MAAM,iBAAiB,KAAK;AAElC,MAAI,wBAAwB,GAAG,GAAG;AAChC,WAAO,EAAE,OAAO,gBAAgB,SAAS,cAAc,iBAAiB,MAAM;AAAA,EAChF;AAEA,QAAM,QAAQ,IAAI,YAAY;AAC9B,MAAI,MAAM,SAAS,cAAc,KAAK,0BAA0B,KAAK,KAAK,GAAG;AAC3E,WAAO;AAAA,MACL,OAAO;AAAA,MACP,SAAS;AAAA,MACT,iBAAiB;AAAA,IACnB;AAAA,EACF;AAEA,QAAM,QAAQ,iBAAiB,SAAS,OAAO,MAAM,UAAU,WAAW,MAAM,MAAM,YAAY,IAAI;AACtG,MAAI,MAAM,SAAS,oBAAoB,MAAM,MAAM,SAAS,mBAAmB,KAAK,MAAM,SAAS,mBAAmB,IAAI;AACxH,WAAO;AAAA,MACL,OAAO;AAAA,MACP,SAAS;AAAA,MACT,aAAa;AAAA,MACb,iBAAiB;AAAA,IACnB;AAAA,EACF;AAEA,MAAI,iBAAiB,KAAK,GAAG,KAAM,OAAO,UAAU,YAAY,UAAU,QAAS,MAA6B,SAAS,KAAM;AAC7H,WAAO;AAAA,MACL,OAAO;AAAA,MACP,SAAS;AAAA,MACT,iBAAiB;AAAA,IACnB;AAAA,EACF;AAEA,SAAO,EAAE,OAAO,wBAAwB,SAAS,YAAY,SAAS,iBAAiB,MAAM;AAC/F;","names":[]}
1
+ {"version":3,"sources":["../../src/utils/describe-error.ts"],"sourcesContent":["import { MedialaneApiError, PasskeyCancelledError, UserFacingError } from \"@medialane/sdk\";\nimport { WrongNetworkError, isBareExecuteFailure, isUserRejectedRequest, collectErrorText } from \"./wallet-error.js\";\n\nexport const NOT_SUBMITTED = \"Request not completed. Nothing was submitted.\";\nexport const GENERIC = \"Something went wrong. Please try again.\";\nexport const NETWORK_BUSY =\n \"The network is busy right now. Nothing was submitted. Please try again in a moment.\";\n\nexport interface ErrorNotice {\n title: string;\n message: string;\n description?: string;\n isUserRejection: boolean;\n}\n\nconst notice = (title: string, message: string, description?: string): ErrorNotice => ({\n title,\n message,\n description,\n isUserRejection: false,\n});\n\nfunction isTransient(error: unknown): boolean {\n if (error instanceof MedialaneApiError) {\n return error.status === 408 || error.status === 429 || error.status >= 500;\n }\n return /-32001|unable to complete request|service unavailable|temporarily unavailable|rate.?limit|too many requests|gateway time-?out|bad gateway|failed to fetch|fetch failed|network ?error|load failed/i.test(\n collectErrorText(error),\n );\n}\n\nfunction apiReason(error: MedialaneApiError): string | undefined {\n const body = error.details;\n if (body && typeof body === \"object\" && \"error\" in body) {\n const reason = (body as { error?: unknown }).error;\n if (typeof reason === \"string\" && reason.trim() !== \"\") return reason;\n }\n return undefined;\n}\n\nexport function describeError(error: unknown, fallback?: string): ErrorNotice {\n if (error instanceof PasskeyCancelledError || isUserRejectedRequest(error)) {\n const unclear = isBareExecuteFailure(error) || error instanceof PasskeyCancelledError;\n return {\n title: \"Request not completed\",\n message: NOT_SUBMITTED,\n description: unclear\n ? \"Your wallet didn't complete this request. You may have closed or declined it, it may need extra verification such as 2FA before it can sign, or it may have hit a temporary network hiccup. Try again in a moment.\"\n : \"Your wallet didn't complete this request. You may have closed or declined it, or it may need extra verification before it can sign.\",\n isUserRejection: true,\n };\n }\n\n if (error instanceof WrongNetworkError) {\n return notice(\n \"Wrong network\",\n \"Your wallet is connected to the wrong network. Nothing was submitted.\",\n \"Switch your wallet to Starknet Mainnet, then try again.\",\n );\n }\n\n if (isTransient(error)) {\n return notice(\"Network busy\", NETWORK_BUSY);\n }\n\n if (error instanceof UserFacingError) {\n return notice(\"Something went wrong\", error.message);\n }\n\n if (error instanceof MedialaneApiError) {\n return notice(\"Something went wrong\", apiReason(error) ?? fallback ?? GENERIC);\n }\n\n const text = collectErrorText(error).toLowerCase();\n if (text.includes(\"insufficient\") && /balance|allowance|funds/.test(text)) {\n return notice(\n \"Insufficient balance\",\n \"You don't have enough balance to complete this transaction.\",\n \"Add funds to your wallet, then try again.\",\n );\n }\n\n return notice(\"Something went wrong\", fallback ?? GENERIC);\n}\n\nexport { UserFacingError };\n"],"mappings":"AAAA,SAAS,mBAAmB,uBAAuB,uBAAuB;AAC1E,SAAS,mBAAmB,sBAAsB,uBAAuB,wBAAwB;AAE1F,MAAM,gBAAgB;AACtB,MAAM,UAAU;AAChB,MAAM,eACX;AASF,MAAM,SAAS,CAAC,OAAe,SAAiB,iBAAuC;AAAA,EACrF;AAAA,EACA;AAAA,EACA;AAAA,EACA,iBAAiB;AACnB;AAEA,SAAS,YAAY,OAAyB;AAC5C,MAAI,iBAAiB,mBAAmB;AACtC,WAAO,MAAM,WAAW,OAAO,MAAM,WAAW,OAAO,MAAM,UAAU;AAAA,EACzE;AACA,SAAO,qMAAqM;AAAA,IAC1M,iBAAiB,KAAK;AAAA,EACxB;AACF;AAEA,SAAS,UAAU,OAA8C;AAC/D,QAAM,OAAO,MAAM;AACnB,MAAI,QAAQ,OAAO,SAAS,YAAY,WAAW,MAAM;AACvD,UAAM,SAAU,KAA6B;AAC7C,QAAI,OAAO,WAAW,YAAY,OAAO,KAAK,MAAM,GAAI,QAAO;AAAA,EACjE;AACA,SAAO;AACT;AAEO,SAAS,cAAc,OAAgB,UAAgC;AAC5E,MAAI,iBAAiB,yBAAyB,sBAAsB,KAAK,GAAG;AAC1E,UAAM,UAAU,qBAAqB,KAAK,KAAK,iBAAiB;AAChE,WAAO;AAAA,MACL,OAAO;AAAA,MACP,SAAS;AAAA,MACT,aAAa,UACT,uNACA;AAAA,MACJ,iBAAiB;AAAA,IACnB;AAAA,EACF;AAEA,MAAI,iBAAiB,mBAAmB;AACtC,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,MAAI,YAAY,KAAK,GAAG;AACtB,WAAO,OAAO,gBAAgB,YAAY;AAAA,EAC5C;AAEA,MAAI,iBAAiB,iBAAiB;AACpC,WAAO,OAAO,wBAAwB,MAAM,OAAO;AAAA,EACrD;AAEA,MAAI,iBAAiB,mBAAmB;AACtC,WAAO,OAAO,wBAAwB,UAAU,KAAK,KAAK,YAAY,OAAO;AAAA,EAC/E;AAEA,QAAM,OAAO,iBAAiB,KAAK,EAAE,YAAY;AACjD,MAAI,KAAK,SAAS,cAAc,KAAK,0BAA0B,KAAK,IAAI,GAAG;AACzE,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,SAAO,OAAO,wBAAwB,YAAY,OAAO;AAC3D;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@medialane/ui",
3
- "version": "0.166.0",
3
+ "version": "0.167.0",
4
4
  "description": "Shared UI components for Medialane apps",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -51,7 +51,7 @@
51
51
  "preview": "vite --config preview/vite.config.ts"
52
52
  },
53
53
  "peerDependencies": {
54
- "@medialane/sdk": ">=0.128.0",
54
+ "@medialane/sdk": ">=0.129.0",
55
55
  "@radix-ui/react-checkbox": ">=1.1.0",
56
56
  "@radix-ui/react-collapsible": ">=1.1.0",
57
57
  "@radix-ui/react-dialog": ">=1.1.0",
@@ -79,7 +79,7 @@
79
79
  "zod": "^3.25.0"
80
80
  },
81
81
  "devDependencies": {
82
- "@medialane/sdk": "0.128.0",
82
+ "@medialane/sdk": "0.129.0",
83
83
  "@radix-ui/react-checkbox": "^1.3.8",
84
84
  "@radix-ui/react-collapsible": "^1.1.17",
85
85
  "@radix-ui/react-dialog": "^1.1.20",