@spicenet-io/spiceflow-ui 1.9.28 → 1.9.29
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/index.cjs.js +51 -73
- package/dist/index.js +51 -73
- package/dist/utils/relayer/index.d.ts +0 -9
- package/package.json +7 -7
package/dist/index.cjs.js
CHANGED
|
@@ -390,7 +390,7 @@ const CHAIN_CONFIGS = {
|
|
|
390
390
|
}
|
|
391
391
|
},
|
|
392
392
|
viemChain: chains.citreaTestnet,
|
|
393
|
-
delegateContract: "
|
|
393
|
+
delegateContract: "0x9DE3D53419a8F821b6E2039A7249c5738004FB94",
|
|
394
394
|
icon: {
|
|
395
395
|
symbol: "C",
|
|
396
396
|
backgroundColor: "#EA4B4B",
|
|
@@ -3310,47 +3310,6 @@ class RelayerService {
|
|
|
3310
3310
|
return { success: false, errorMessage: msg };
|
|
3311
3311
|
}
|
|
3312
3312
|
}
|
|
3313
|
-
// EIP-7702 transaction
|
|
3314
|
-
async submitTransaction(request) {
|
|
3315
|
-
try {
|
|
3316
|
-
const response = await fetch(`${this.baseUrl}/transaction/submit`, {
|
|
3317
|
-
method: "POST",
|
|
3318
|
-
headers: {
|
|
3319
|
-
"Content-Type": "application/json"
|
|
3320
|
-
},
|
|
3321
|
-
body: JSON.stringify(
|
|
3322
|
-
request,
|
|
3323
|
-
(key, value) => typeof value === "bigint" ? value.toString() : value
|
|
3324
|
-
)
|
|
3325
|
-
});
|
|
3326
|
-
if (!response.ok) {
|
|
3327
|
-
const errorText = await response.text();
|
|
3328
|
-
throw new Error(`Relayer API error: ${response.status} - ${errorText}`);
|
|
3329
|
-
}
|
|
3330
|
-
const result = await response.json();
|
|
3331
|
-
return {
|
|
3332
|
-
hash: result.hash,
|
|
3333
|
-
intentId: result.intentId || request.intentAuthorization.signature
|
|
3334
|
-
};
|
|
3335
|
-
} catch (error) {
|
|
3336
|
-
throw error;
|
|
3337
|
-
}
|
|
3338
|
-
}
|
|
3339
|
-
// Status check methods when submit route is used
|
|
3340
|
-
async checkStepStatusSubmitRoute(intentId, stepId) {
|
|
3341
|
-
try {
|
|
3342
|
-
const response = await fetch(
|
|
3343
|
-
`${this.baseUrl}/intent/${intentId}/step/${stepId}/status`
|
|
3344
|
-
);
|
|
3345
|
-
if (!response.ok) {
|
|
3346
|
-
throw new Error(`Intent step status check failed: ${response.status}`);
|
|
3347
|
-
}
|
|
3348
|
-
return await response.json();
|
|
3349
|
-
} catch (error) {
|
|
3350
|
-
console.error(`Error checking intent step ${stepId} status:`, error);
|
|
3351
|
-
throw error;
|
|
3352
|
-
}
|
|
3353
|
-
}
|
|
3354
3313
|
}
|
|
3355
3314
|
const relayerService = new RelayerService();
|
|
3356
3315
|
const createInitialSteps = (chainBatches, customGetChainName) => {
|
|
@@ -5195,7 +5154,8 @@ const DepositWidget = ({
|
|
|
5195
5154
|
provider,
|
|
5196
5155
|
actions
|
|
5197
5156
|
} = wallet;
|
|
5198
|
-
React.useContext(SpiceFlowProviderContext);
|
|
5157
|
+
const spiceFlowContext = React.useContext(SpiceFlowProviderContext);
|
|
5158
|
+
const mode = spiceFlowContext?.mode || "7702";
|
|
5199
5159
|
const [selectedDepositAsset, setSelectedDepositAsset] = React.useState(null);
|
|
5200
5160
|
const {
|
|
5201
5161
|
assets: spiceAssets,
|
|
@@ -5215,7 +5175,7 @@ const DepositWidget = ({
|
|
|
5215
5175
|
const [isDepositPressed, setIsDepositPressed] = React.useState(false);
|
|
5216
5176
|
const spiceDepositSubmittedRef = React.useRef(null);
|
|
5217
5177
|
const { intentStatus, startStatusPolling, clearStatus } = useStatus({
|
|
5218
|
-
checkStepStatus: (intentId, stepId) => relayerService.
|
|
5178
|
+
checkStepStatus: (intentId, stepId) => relayerService.checkStepStatus(intentId, stepId)
|
|
5219
5179
|
});
|
|
5220
5180
|
React.useEffect(() => {
|
|
5221
5181
|
if (intentStatus?.overallStatus === "success" && intentStatus.intentId && spiceDepositSubmittedRef.current !== intentStatus.intentId && selectedDepositAsset && address) {
|
|
@@ -5284,12 +5244,16 @@ const DepositWidget = ({
|
|
|
5284
5244
|
const handleDeposit = async () => {
|
|
5285
5245
|
if (!selectedDepositAsset || !address || depositBatches.length === 0)
|
|
5286
5246
|
return;
|
|
5287
|
-
if (!ready || !authenticated) {
|
|
5247
|
+
if (mode === "7702" && (!ready || !authenticated)) {
|
|
5288
5248
|
setError(
|
|
5289
5249
|
`Please authenticate with ${provider || "wallet provider"} to continue`
|
|
5290
5250
|
);
|
|
5291
5251
|
return;
|
|
5292
5252
|
}
|
|
5253
|
+
if (mode !== "7702") {
|
|
5254
|
+
setError("Only EIP-7702 mode is currently supported for DepositWidget.");
|
|
5255
|
+
return;
|
|
5256
|
+
}
|
|
5293
5257
|
setIsExecuting(true);
|
|
5294
5258
|
setError(null);
|
|
5295
5259
|
try {
|
|
@@ -5311,41 +5275,55 @@ const DepositWidget = ({
|
|
|
5311
5275
|
nonce: Number(nonce)
|
|
5312
5276
|
});
|
|
5313
5277
|
authorizations.push(auth);
|
|
5314
|
-
console.log("auth for chain", chainId, auth);
|
|
5315
5278
|
}
|
|
5316
5279
|
const hashedChainBatches = spiceflowCoreTest.hashChainBatches(allChainBatches);
|
|
5317
5280
|
const digest = spiceflowCoreTest.getAuthorizationHash(hashedChainBatches);
|
|
5318
|
-
const
|
|
5319
|
-
|
|
5320
|
-
|
|
5321
|
-
const
|
|
5322
|
-
|
|
5323
|
-
|
|
5324
|
-
|
|
5325
|
-
|
|
5326
|
-
|
|
5327
|
-
|
|
5328
|
-
|
|
5329
|
-
|
|
5281
|
+
const signatureResult = await actions.signMessage(digest);
|
|
5282
|
+
const signature = typeof signatureResult === "string" ? signatureResult : signatureResult.signature;
|
|
5283
|
+
if (!signature) throw new Error("Failed to sign intent authorization");
|
|
5284
|
+
const intent = {
|
|
5285
|
+
mode: "7702",
|
|
5286
|
+
signatureType: "eip712",
|
|
5287
|
+
signature,
|
|
5288
|
+
nbf: 0,
|
|
5289
|
+
exp: 0,
|
|
5290
|
+
chainBatches: hashedChainBatches.map((b) => ({
|
|
5291
|
+
hash: b.hash,
|
|
5292
|
+
chainId: b.chainId,
|
|
5293
|
+
tokenTransfers: [
|
|
5330
5294
|
{
|
|
5331
|
-
|
|
5332
|
-
|
|
5333
|
-
|
|
5334
|
-
|
|
5335
|
-
),
|
|
5336
|
-
receiver: address
|
|
5295
|
+
from: "solver",
|
|
5296
|
+
to: address,
|
|
5297
|
+
token: tokenAddress,
|
|
5298
|
+
amount: viem.parseUnits(selectedDepositAsset.amount, tokenDecimals)
|
|
5337
5299
|
}
|
|
5338
|
-
]
|
|
5339
|
-
|
|
5300
|
+
],
|
|
5301
|
+
calls: b.calls
|
|
5302
|
+
}))
|
|
5303
|
+
};
|
|
5304
|
+
const request = {
|
|
5305
|
+
user: address,
|
|
5306
|
+
chainAuthorizations: authorizations.map((auth) => ({
|
|
5307
|
+
r: auth.r,
|
|
5308
|
+
s: auth.s,
|
|
5309
|
+
yParity: auth.yParity,
|
|
5310
|
+
address: auth.address,
|
|
5311
|
+
chainId: auth.chainId,
|
|
5312
|
+
nonce: Number(auth.nonce)
|
|
5313
|
+
})),
|
|
5314
|
+
intents: [intent]
|
|
5340
5315
|
};
|
|
5341
|
-
const result = await relayerService.
|
|
5316
|
+
const result = await relayerService.createAction(request);
|
|
5342
5317
|
if (result) {
|
|
5343
|
-
const
|
|
5344
|
-
|
|
5345
|
-
|
|
5346
|
-
|
|
5347
|
-
|
|
5348
|
-
|
|
5318
|
+
const initialSteps = createInitialSteps(allChainBatches, getChainName$1);
|
|
5319
|
+
startStatusPolling(result.intentIds[0], initialSteps);
|
|
5320
|
+
for (let stepIdx = 0; stepIdx < allChainBatches.length; stepIdx++) {
|
|
5321
|
+
await relayerService.executeStep(result.actionId, 0, stepIdx, {
|
|
5322
|
+
action: "execute"
|
|
5323
|
+
});
|
|
5324
|
+
}
|
|
5325
|
+
onDepositSuccess?.(result.intentIds[0]);
|
|
5326
|
+
refreshSpiceAssets();
|
|
5349
5327
|
}
|
|
5350
5328
|
} catch (error2) {
|
|
5351
5329
|
const errorMessage = error2 instanceof Error ? error2.message : "Deposit failed";
|
package/dist/index.js
CHANGED
|
@@ -388,7 +388,7 @@ const CHAIN_CONFIGS = {
|
|
|
388
388
|
}
|
|
389
389
|
},
|
|
390
390
|
viemChain: citreaTestnet,
|
|
391
|
-
delegateContract: "
|
|
391
|
+
delegateContract: "0x9DE3D53419a8F821b6E2039A7249c5738004FB94",
|
|
392
392
|
icon: {
|
|
393
393
|
symbol: "C",
|
|
394
394
|
backgroundColor: "#EA4B4B",
|
|
@@ -3308,47 +3308,6 @@ class RelayerService {
|
|
|
3308
3308
|
return { success: false, errorMessage: msg };
|
|
3309
3309
|
}
|
|
3310
3310
|
}
|
|
3311
|
-
// EIP-7702 transaction
|
|
3312
|
-
async submitTransaction(request) {
|
|
3313
|
-
try {
|
|
3314
|
-
const response = await fetch(`${this.baseUrl}/transaction/submit`, {
|
|
3315
|
-
method: "POST",
|
|
3316
|
-
headers: {
|
|
3317
|
-
"Content-Type": "application/json"
|
|
3318
|
-
},
|
|
3319
|
-
body: JSON.stringify(
|
|
3320
|
-
request,
|
|
3321
|
-
(key, value) => typeof value === "bigint" ? value.toString() : value
|
|
3322
|
-
)
|
|
3323
|
-
});
|
|
3324
|
-
if (!response.ok) {
|
|
3325
|
-
const errorText = await response.text();
|
|
3326
|
-
throw new Error(`Relayer API error: ${response.status} - ${errorText}`);
|
|
3327
|
-
}
|
|
3328
|
-
const result = await response.json();
|
|
3329
|
-
return {
|
|
3330
|
-
hash: result.hash,
|
|
3331
|
-
intentId: result.intentId || request.intentAuthorization.signature
|
|
3332
|
-
};
|
|
3333
|
-
} catch (error) {
|
|
3334
|
-
throw error;
|
|
3335
|
-
}
|
|
3336
|
-
}
|
|
3337
|
-
// Status check methods when submit route is used
|
|
3338
|
-
async checkStepStatusSubmitRoute(intentId, stepId) {
|
|
3339
|
-
try {
|
|
3340
|
-
const response = await fetch(
|
|
3341
|
-
`${this.baseUrl}/intent/${intentId}/step/${stepId}/status`
|
|
3342
|
-
);
|
|
3343
|
-
if (!response.ok) {
|
|
3344
|
-
throw new Error(`Intent step status check failed: ${response.status}`);
|
|
3345
|
-
}
|
|
3346
|
-
return await response.json();
|
|
3347
|
-
} catch (error) {
|
|
3348
|
-
console.error(`Error checking intent step ${stepId} status:`, error);
|
|
3349
|
-
throw error;
|
|
3350
|
-
}
|
|
3351
|
-
}
|
|
3352
3311
|
}
|
|
3353
3312
|
const relayerService = new RelayerService();
|
|
3354
3313
|
const createInitialSteps = (chainBatches, customGetChainName) => {
|
|
@@ -5193,7 +5152,8 @@ const DepositWidget = ({
|
|
|
5193
5152
|
provider,
|
|
5194
5153
|
actions
|
|
5195
5154
|
} = wallet;
|
|
5196
|
-
useContext(SpiceFlowProviderContext);
|
|
5155
|
+
const spiceFlowContext = useContext(SpiceFlowProviderContext);
|
|
5156
|
+
const mode = spiceFlowContext?.mode || "7702";
|
|
5197
5157
|
const [selectedDepositAsset, setSelectedDepositAsset] = useState(null);
|
|
5198
5158
|
const {
|
|
5199
5159
|
assets: spiceAssets,
|
|
@@ -5213,7 +5173,7 @@ const DepositWidget = ({
|
|
|
5213
5173
|
const [isDepositPressed, setIsDepositPressed] = useState(false);
|
|
5214
5174
|
const spiceDepositSubmittedRef = useRef(null);
|
|
5215
5175
|
const { intentStatus, startStatusPolling, clearStatus } = useStatus({
|
|
5216
|
-
checkStepStatus: (intentId, stepId) => relayerService.
|
|
5176
|
+
checkStepStatus: (intentId, stepId) => relayerService.checkStepStatus(intentId, stepId)
|
|
5217
5177
|
});
|
|
5218
5178
|
useEffect(() => {
|
|
5219
5179
|
if (intentStatus?.overallStatus === "success" && intentStatus.intentId && spiceDepositSubmittedRef.current !== intentStatus.intentId && selectedDepositAsset && address) {
|
|
@@ -5282,12 +5242,16 @@ const DepositWidget = ({
|
|
|
5282
5242
|
const handleDeposit = async () => {
|
|
5283
5243
|
if (!selectedDepositAsset || !address || depositBatches.length === 0)
|
|
5284
5244
|
return;
|
|
5285
|
-
if (!ready || !authenticated) {
|
|
5245
|
+
if (mode === "7702" && (!ready || !authenticated)) {
|
|
5286
5246
|
setError(
|
|
5287
5247
|
`Please authenticate with ${provider || "wallet provider"} to continue`
|
|
5288
5248
|
);
|
|
5289
5249
|
return;
|
|
5290
5250
|
}
|
|
5251
|
+
if (mode !== "7702") {
|
|
5252
|
+
setError("Only EIP-7702 mode is currently supported for DepositWidget.");
|
|
5253
|
+
return;
|
|
5254
|
+
}
|
|
5291
5255
|
setIsExecuting(true);
|
|
5292
5256
|
setError(null);
|
|
5293
5257
|
try {
|
|
@@ -5309,41 +5273,55 @@ const DepositWidget = ({
|
|
|
5309
5273
|
nonce: Number(nonce)
|
|
5310
5274
|
});
|
|
5311
5275
|
authorizations.push(auth);
|
|
5312
|
-
console.log("auth for chain", chainId, auth);
|
|
5313
5276
|
}
|
|
5314
5277
|
const hashedChainBatches = hashChainBatches(allChainBatches);
|
|
5315
5278
|
const digest = getAuthorizationHash(hashedChainBatches);
|
|
5316
|
-
const
|
|
5317
|
-
|
|
5318
|
-
|
|
5319
|
-
const
|
|
5320
|
-
|
|
5321
|
-
|
|
5322
|
-
|
|
5323
|
-
|
|
5324
|
-
|
|
5325
|
-
|
|
5326
|
-
|
|
5327
|
-
|
|
5279
|
+
const signatureResult = await actions.signMessage(digest);
|
|
5280
|
+
const signature = typeof signatureResult === "string" ? signatureResult : signatureResult.signature;
|
|
5281
|
+
if (!signature) throw new Error("Failed to sign intent authorization");
|
|
5282
|
+
const intent = {
|
|
5283
|
+
mode: "7702",
|
|
5284
|
+
signatureType: "eip712",
|
|
5285
|
+
signature,
|
|
5286
|
+
nbf: 0,
|
|
5287
|
+
exp: 0,
|
|
5288
|
+
chainBatches: hashedChainBatches.map((b) => ({
|
|
5289
|
+
hash: b.hash,
|
|
5290
|
+
chainId: b.chainId,
|
|
5291
|
+
tokenTransfers: [
|
|
5328
5292
|
{
|
|
5329
|
-
|
|
5330
|
-
|
|
5331
|
-
|
|
5332
|
-
|
|
5333
|
-
),
|
|
5334
|
-
receiver: address
|
|
5293
|
+
from: "solver",
|
|
5294
|
+
to: address,
|
|
5295
|
+
token: tokenAddress,
|
|
5296
|
+
amount: parseUnits(selectedDepositAsset.amount, tokenDecimals)
|
|
5335
5297
|
}
|
|
5336
|
-
]
|
|
5337
|
-
|
|
5298
|
+
],
|
|
5299
|
+
calls: b.calls
|
|
5300
|
+
}))
|
|
5301
|
+
};
|
|
5302
|
+
const request = {
|
|
5303
|
+
user: address,
|
|
5304
|
+
chainAuthorizations: authorizations.map((auth) => ({
|
|
5305
|
+
r: auth.r,
|
|
5306
|
+
s: auth.s,
|
|
5307
|
+
yParity: auth.yParity,
|
|
5308
|
+
address: auth.address,
|
|
5309
|
+
chainId: auth.chainId,
|
|
5310
|
+
nonce: Number(auth.nonce)
|
|
5311
|
+
})),
|
|
5312
|
+
intents: [intent]
|
|
5338
5313
|
};
|
|
5339
|
-
const result = await relayerService.
|
|
5314
|
+
const result = await relayerService.createAction(request);
|
|
5340
5315
|
if (result) {
|
|
5341
|
-
const
|
|
5342
|
-
|
|
5343
|
-
|
|
5344
|
-
|
|
5345
|
-
|
|
5346
|
-
|
|
5316
|
+
const initialSteps = createInitialSteps(allChainBatches, getChainName$1);
|
|
5317
|
+
startStatusPolling(result.intentIds[0], initialSteps);
|
|
5318
|
+
for (let stepIdx = 0; stepIdx < allChainBatches.length; stepIdx++) {
|
|
5319
|
+
await relayerService.executeStep(result.actionId, 0, stepIdx, {
|
|
5320
|
+
action: "execute"
|
|
5321
|
+
});
|
|
5322
|
+
}
|
|
5323
|
+
onDepositSuccess?.(result.intentIds[0]);
|
|
5324
|
+
refreshSpiceAssets();
|
|
5347
5325
|
}
|
|
5348
5326
|
} catch (error2) {
|
|
5349
5327
|
const errorMessage = error2 instanceof Error ? error2.message : "Deposit failed";
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { CreateActionRequest, CreateActionResponse, ExecuteStepRequest } from "../../types/unified";
|
|
2
2
|
import { SwapStep } from "../../types/status";
|
|
3
3
|
import { ChainBatch } from "../../types/authorization";
|
|
4
|
-
import { RelayerSubmitRequest, RelayerSubmitResponse } from "@/types/relayer";
|
|
5
4
|
export declare const RELAYER_API_URL: string;
|
|
6
5
|
export declare class RelayerService {
|
|
7
6
|
private baseUrl;
|
|
@@ -40,14 +39,6 @@ export declare class RelayerService {
|
|
|
40
39
|
amount?: string;
|
|
41
40
|
errorMessage?: string;
|
|
42
41
|
}>;
|
|
43
|
-
submitTransaction(request: RelayerSubmitRequest): Promise<RelayerSubmitResponse>;
|
|
44
|
-
checkStepStatusSubmitRoute(intentId: string, stepId: number): Promise<{
|
|
45
|
-
success: boolean;
|
|
46
|
-
data: {
|
|
47
|
-
status: "created" | "executing" | "success" | "reverted";
|
|
48
|
-
transactionHash?: string;
|
|
49
|
-
};
|
|
50
|
-
}>;
|
|
51
42
|
}
|
|
52
43
|
export declare const relayerService: RelayerService;
|
|
53
44
|
export declare const createInitialSteps: (chainBatches: ChainBatch[], customGetChainName?: (chainId: number) => string) => SwapStep[];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@spicenet-io/spiceflow-ui",
|
|
3
|
-
"version": "1.9.
|
|
3
|
+
"version": "1.9.29",
|
|
4
4
|
"description": "Spiceflow UI SDK",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.cjs.js",
|
|
@@ -103,41 +103,41 @@
|
|
|
103
103
|
"@dynamic-labs/wallet-connector-core": "^3.9.13",
|
|
104
104
|
"@privy-io/react-auth": "^2.24.0",
|
|
105
105
|
"@rollup/plugin-commonjs": "^28.0.6",
|
|
106
|
+
"axios": "^1.11.0",
|
|
106
107
|
"@rollup/plugin-image": "^3.0.3",
|
|
107
108
|
"@rollup/plugin-json": "^6.1.0",
|
|
108
109
|
"@rollup/plugin-node-resolve": "^16.0.1",
|
|
109
110
|
"@rollup/plugin-replace": "^6.0.2",
|
|
110
111
|
"@rollup/plugin-typescript": "^12.1.4",
|
|
112
|
+
"esbuild": "^0.24.0",
|
|
113
|
+
"rollup-plugin-esbuild": "^6.1.1",
|
|
111
114
|
"@tanstack/react-query": "^5.90.5",
|
|
112
115
|
"@types/node": "^24.3.0",
|
|
113
116
|
"@types/react": "^18.3.3",
|
|
114
117
|
"@types/react-dom": "^18.3.0",
|
|
115
118
|
"@typescript-eslint/eslint-plugin": "^6.0.0",
|
|
116
119
|
"@typescript-eslint/parser": "^6.0.0",
|
|
117
|
-
"axios": "^1.11.0",
|
|
118
|
-
"esbuild": "^0.24.0",
|
|
119
120
|
"eslint": "^8.45.0",
|
|
120
121
|
"eslint-config-prettier": "^10.1.8",
|
|
121
122
|
"eslint-plugin-react": "^7.33.0",
|
|
122
123
|
"eslint-plugin-react-hooks": "^4.6.0",
|
|
123
124
|
"husky": "^9.1.7",
|
|
124
125
|
"lint-staged": "^16.2.5",
|
|
125
|
-
"lucide-react": "^0.562.0",
|
|
126
126
|
"postcss": "^8.5.6",
|
|
127
127
|
"postcss-import": "^16.1.1",
|
|
128
128
|
"prettier": "3.6.2",
|
|
129
|
+
"jest": "^29.6.0",
|
|
129
130
|
"react": "^18.3.1",
|
|
130
131
|
"react-dom": "^18.3.1",
|
|
131
132
|
"rollup": "^4.50.0",
|
|
132
133
|
"rollup-plugin-copy": "^3.5.0",
|
|
133
|
-
"rollup-plugin-esbuild": "^6.1.1",
|
|
134
134
|
"rollup-plugin-peer-deps-external": "^2.2.4",
|
|
135
135
|
"rollup-plugin-postcss": "^4.0.2",
|
|
136
|
-
"spiceflow-core-test": "^0.1.0",
|
|
137
136
|
"ts-node": "^10.9.2",
|
|
138
137
|
"typescript": "^5.9.2",
|
|
139
138
|
"viem": "2.33.1",
|
|
140
|
-
"wagmi": "^2.18.2"
|
|
139
|
+
"wagmi": "^2.18.2",
|
|
140
|
+
"spiceflow-core-test": "^0.1.0"
|
|
141
141
|
},
|
|
142
142
|
"lint-staged": {
|
|
143
143
|
"*.{ts,tsx,js,jsx,json,md}": "prettier --write"
|