@keplr-wallet/hooks-starknet 0.12.133-rc.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.
Files changed (62) hide show
  1. package/.eslintignore +2 -0
  2. package/.prettierignore +2 -0
  3. package/LICENSE +209 -0
  4. package/build/index.d.ts +1 -0
  5. package/build/index.js +18 -0
  6. package/build/index.js.map +1 -0
  7. package/build/tx/amount.d.ts +27 -0
  8. package/build/tx/amount.js +230 -0
  9. package/build/tx/amount.js.map +1 -0
  10. package/build/tx/chain.d.ts +11 -0
  11. package/build/tx/chain.js +37 -0
  12. package/build/tx/chain.js.map +1 -0
  13. package/build/tx/errors.d.ts +48 -0
  14. package/build/tx/errors.js +132 -0
  15. package/build/tx/errors.js.map +1 -0
  16. package/build/tx/fee.d.ts +30 -0
  17. package/build/tx/fee.js +167 -0
  18. package/build/tx/fee.js.map +1 -0
  19. package/build/tx/gas-simulator.d.ts +72 -0
  20. package/build/tx/gas-simulator.js +491 -0
  21. package/build/tx/gas-simulator.js.map +1 -0
  22. package/build/tx/gas.d.ts +14 -0
  23. package/build/tx/gas.js +116 -0
  24. package/build/tx/gas.js.map +1 -0
  25. package/build/tx/index.d.ts +12 -0
  26. package/build/tx/index.js +29 -0
  27. package/build/tx/index.js.map +1 -0
  28. package/build/tx/noop-amount.d.ts +20 -0
  29. package/build/tx/noop-amount.js +90 -0
  30. package/build/tx/noop-amount.js.map +1 -0
  31. package/build/tx/recipient.d.ts +12 -0
  32. package/build/tx/recipient.js +80 -0
  33. package/build/tx/recipient.js.map +1 -0
  34. package/build/tx/send-tx.d.ts +9 -0
  35. package/build/tx/send-tx.js +22 -0
  36. package/build/tx/send-tx.js.map +1 -0
  37. package/build/tx/sender.d.ts +14 -0
  38. package/build/tx/sender.js +88 -0
  39. package/build/tx/sender.js.map +1 -0
  40. package/build/tx/types.d.ts +63 -0
  41. package/build/tx/types.js +3 -0
  42. package/build/tx/types.js.map +1 -0
  43. package/build/tx/validate.d.ts +11 -0
  44. package/build/tx/validate.js +52 -0
  45. package/build/tx/validate.js.map +1 -0
  46. package/jest.config.js +5 -0
  47. package/package.json +43 -0
  48. package/src/index.ts +1 -0
  49. package/src/tx/amount.ts +275 -0
  50. package/src/tx/chain.ts +32 -0
  51. package/src/tx/errors.ts +127 -0
  52. package/src/tx/fee.ts +209 -0
  53. package/src/tx/gas-simulator.ts +571 -0
  54. package/src/tx/gas.ts +131 -0
  55. package/src/tx/index.ts +12 -0
  56. package/src/tx/noop-amount.ts +92 -0
  57. package/src/tx/recipient.ts +82 -0
  58. package/src/tx/send-tx.ts +53 -0
  59. package/src/tx/sender.ts +104 -0
  60. package/src/tx/types.ts +97 -0
  61. package/src/tx/validate.ts +70 -0
  62. package/tsconfig.json +13 -0
@@ -0,0 +1,571 @@
1
+ import { IFeeConfig, IGasConfig, IGasSimulator, UIProperties } from "./types";
2
+ import {
3
+ action,
4
+ autorun,
5
+ computed,
6
+ IReactionDisposer,
7
+ makeObservable,
8
+ observable,
9
+ runInAction,
10
+ } from "mobx";
11
+ import { useEffect, useState } from "react";
12
+ import { KVStore } from "@keplr-wallet/common";
13
+ import { ChainIdHelper } from "@keplr-wallet/cosmos";
14
+ import { TxChainSetter } from "./chain";
15
+ import { ChainGetter, MakeTxResponse } from "@keplr-wallet/stores";
16
+ import { Coin, StdFee } from "@keplr-wallet/types";
17
+ import { isSimpleFetchError } from "@keplr-wallet/simple-fetch";
18
+
19
+ type TxSimulate = Pick<MakeTxResponse, "simulate">;
20
+ export type SimulateGasFn = () => TxSimulate;
21
+
22
+ class GasSimulatorState {
23
+ @observable
24
+ protected _outdatedCosmosSdk: boolean = false;
25
+
26
+ // If the initialGasEstimated is null, it means that there is no value stored or being loaded.
27
+ @observable
28
+ protected _initialGasEstimated: number | null = null;
29
+
30
+ @observable
31
+ protected _isInitialized: boolean = false;
32
+
33
+ @observable
34
+ protected _recentGasEstimated: number | undefined = undefined;
35
+
36
+ @observable.ref
37
+ protected _tx: TxSimulate | undefined = undefined;
38
+ @observable.ref
39
+ protected _stdFee: StdFee | undefined = undefined;
40
+ @observable.ref
41
+ protected _error: Error | undefined = undefined;
42
+
43
+ constructor() {
44
+ makeObservable(this);
45
+ }
46
+
47
+ get outdatedCosmosSdk(): boolean {
48
+ return this._outdatedCosmosSdk;
49
+ }
50
+
51
+ @action
52
+ setIsInitialized(value: boolean) {
53
+ this._isInitialized = value;
54
+ }
55
+
56
+ get isInitialized(): boolean {
57
+ return this._isInitialized;
58
+ }
59
+
60
+ @action
61
+ setOutdatedCosmosSdk(value: boolean) {
62
+ this._outdatedCosmosSdk = value;
63
+ }
64
+
65
+ get initialGasEstimated(): number | null {
66
+ return this._initialGasEstimated;
67
+ }
68
+
69
+ @action
70
+ setInitialGasEstimated(value: number) {
71
+ this._initialGasEstimated = value;
72
+ }
73
+
74
+ get recentGasEstimated(): number | undefined {
75
+ return this._recentGasEstimated;
76
+ }
77
+
78
+ @action
79
+ setRecentGasEstimated(value: number) {
80
+ this._recentGasEstimated = value;
81
+ }
82
+
83
+ get tx(): TxSimulate | undefined {
84
+ return this._tx;
85
+ }
86
+
87
+ @action
88
+ refreshTx(tx: TxSimulate | undefined) {
89
+ this._tx = tx;
90
+ }
91
+
92
+ get stdFee(): StdFee | undefined {
93
+ return this._stdFee;
94
+ }
95
+
96
+ @action
97
+ refreshStdFee(fee: StdFee | undefined) {
98
+ this._stdFee = fee;
99
+ }
100
+
101
+ get error(): Error | undefined {
102
+ return this._error;
103
+ }
104
+
105
+ @action
106
+ setError(error: Error | undefined) {
107
+ this._error = error;
108
+ }
109
+
110
+ static isZeroFee(amount: readonly Coin[] | undefined): boolean {
111
+ if (!amount) {
112
+ return true;
113
+ }
114
+
115
+ for (const coin of amount) {
116
+ if (coin.amount !== "0") {
117
+ return false;
118
+ }
119
+ }
120
+
121
+ return true;
122
+ }
123
+ }
124
+
125
+ export class GasSimulator extends TxChainSetter implements IGasSimulator {
126
+ @observable
127
+ protected _key: string;
128
+
129
+ @observable
130
+ protected _gasAdjustmentValue: string = "1";
131
+
132
+ @observable
133
+ protected _enabled: boolean = false;
134
+
135
+ @observable
136
+ protected _forceDisabled: boolean = false;
137
+ @observable
138
+ protected _forceDisableReason: Error | undefined = undefined;
139
+
140
+ @observable
141
+ protected _isSimulating: boolean = false;
142
+
143
+ // Key is the store key (probably, ${chainIdentifier}/${key})
144
+ @observable.shallow
145
+ protected _stateMap: Map<string, GasSimulatorState> = new Map();
146
+
147
+ protected _disposers: IReactionDisposer[] = [];
148
+
149
+ constructor(
150
+ // TODO: Add comment about the reason why kvStore field is not observable.
151
+ protected kvStore: KVStore,
152
+ chainGetter: ChainGetter,
153
+ initialChainId: string,
154
+ protected readonly gasConfig: IGasConfig,
155
+ protected readonly feeConfig: IFeeConfig,
156
+ protected readonly initialKey: string,
157
+ // TODO: Add comment about the reason why simulateGasFn field is not observable.
158
+ protected simulateGasFn: SimulateGasFn
159
+ ) {
160
+ super(chainGetter, initialChainId);
161
+
162
+ this._key = initialKey;
163
+
164
+ makeObservable(this);
165
+
166
+ this.init();
167
+ }
168
+
169
+ setKVStore(kvStore: KVStore) {
170
+ this.kvStore = kvStore;
171
+ }
172
+
173
+ get key(): string {
174
+ return this._key;
175
+ }
176
+
177
+ @action
178
+ setKey(value: string) {
179
+ this._key = value;
180
+ }
181
+
182
+ get isSimulating(): boolean {
183
+ return this._isSimulating;
184
+ }
185
+
186
+ setSimulateGasFn(simulateGasFn: SimulateGasFn) {
187
+ this.simulateGasFn = simulateGasFn;
188
+ }
189
+
190
+ get enabled(): boolean {
191
+ if (this._forceDisabled) {
192
+ return false;
193
+ }
194
+
195
+ return this._enabled;
196
+ }
197
+
198
+ @action
199
+ setEnabled(value: boolean) {
200
+ if (this._forceDisabled && value) {
201
+ console.log(
202
+ "Gas simulator is disabled by force. You can not enable the gas simulator"
203
+ );
204
+ return;
205
+ }
206
+
207
+ this._enabled = value;
208
+ }
209
+
210
+ get forceDisabled(): boolean {
211
+ return this._forceDisabled;
212
+ }
213
+
214
+ get forceDisableReason(): Error | undefined {
215
+ return this._forceDisableReason;
216
+ }
217
+
218
+ @action
219
+ forceDisable(valueOrReason: boolean | Error) {
220
+ if (!valueOrReason) {
221
+ this._forceDisabled = false;
222
+ this._forceDisableReason = undefined;
223
+ } else {
224
+ if (this.enabled) {
225
+ this.setEnabled(false);
226
+ }
227
+ this._forceDisabled = true;
228
+ if (typeof valueOrReason !== "boolean") {
229
+ this._forceDisableReason = valueOrReason;
230
+ }
231
+ }
232
+ }
233
+
234
+ get outdatedCosmosSdk(): boolean {
235
+ const key = this.storeKey;
236
+ const state = this.getState(key);
237
+ return state.outdatedCosmosSdk;
238
+ }
239
+
240
+ get error(): Error | undefined {
241
+ const key = this.storeKey;
242
+ const state = this.getState(key);
243
+ return state.error;
244
+ }
245
+
246
+ get gasEstimated(): number | undefined {
247
+ const key = this.storeKey;
248
+ const state = this.getState(key);
249
+ if (state.recentGasEstimated != null) {
250
+ return state.recentGasEstimated;
251
+ }
252
+
253
+ if (state.initialGasEstimated != null) {
254
+ return state.initialGasEstimated;
255
+ }
256
+
257
+ return undefined;
258
+ }
259
+
260
+ get gasAdjustment(): number {
261
+ if (this._gasAdjustmentValue === "") {
262
+ return 0;
263
+ }
264
+
265
+ const num = parseFloat(this._gasAdjustmentValue);
266
+ if (Number.isNaN(num) || num < 0) {
267
+ return 0;
268
+ }
269
+
270
+ return num;
271
+ }
272
+
273
+ get gasAdjustmentValue(): string {
274
+ return this._gasAdjustmentValue;
275
+ }
276
+
277
+ @action
278
+ setGasAdjustmentValue(gasAdjustment: string | number) {
279
+ if (typeof gasAdjustment === "number") {
280
+ if (gasAdjustment < 0 || gasAdjustment > 2) {
281
+ return;
282
+ }
283
+
284
+ this._gasAdjustmentValue = gasAdjustment.toString();
285
+ return;
286
+ }
287
+
288
+ if (gasAdjustment === "") {
289
+ this._gasAdjustmentValue = "";
290
+ return;
291
+ }
292
+
293
+ if (gasAdjustment.startsWith(".")) {
294
+ this._gasAdjustmentValue = "0" + gasAdjustment;
295
+ }
296
+
297
+ const num = parseFloat(gasAdjustment);
298
+ if (Number.isNaN(num) || num < 0 || num > 2) {
299
+ return;
300
+ }
301
+
302
+ this._gasAdjustmentValue = gasAdjustment;
303
+ }
304
+
305
+ protected init() {
306
+ this._disposers.push(
307
+ autorun(() => {
308
+ if (!this.enabled) {
309
+ return;
310
+ }
311
+
312
+ const key = this.storeKey;
313
+ const state = this.getState(key);
314
+
315
+ this.kvStore.get<number>(key).then((saved) => {
316
+ if (saved) {
317
+ state.setInitialGasEstimated(saved);
318
+ }
319
+
320
+ state.setIsInitialized(true);
321
+ });
322
+ })
323
+ );
324
+
325
+ // autorun is intentionally split.
326
+ // The main reason for this implementation is that the gas when paying the fee is somewhat different from when there is a zero fee.
327
+ // In order to calculate the gas more accurately, the fee should be included in the simulation,
328
+ // but in the current reactive logic, the gas change by the simulation changes the fee and causes the simulation again.
329
+ // Even though the implementation is not intuitive, the goals are
330
+ // - Every time the observable used in simulateGasFn is updated, the simulation is refreshed.
331
+ // - The simulation is refreshed only when changing from zero fee to paying fee or vice versa.
332
+ // - feemarket 등에서 문제를 일으켜서 fee의 currency 자체가 바뀔때도 refresh 하도록 수정되었다. 이 경우 원활한 처리를 위해서 (귀찮아서) storeKey setter에서 적용된다.
333
+ this._disposers.push(
334
+ autorun(() => {
335
+ if (!this.enabled) {
336
+ return;
337
+ }
338
+
339
+ try {
340
+ const key = this.storeKey;
341
+ const state = this.getState(key);
342
+
343
+ if (!state.isInitialized) {
344
+ return;
345
+ }
346
+
347
+ const tx = this.simulateGasFn();
348
+ // TODO
349
+ // const fee = this.feeConfig.toStdFee();
350
+
351
+ runInAction(() => {
352
+ if (
353
+ (state.recentGasEstimated == null || state.error != null) &&
354
+ !state.outdatedCosmosSdk
355
+ // || GasSimulatorState.isZeroFee(state.stdFee?.amount) !==
356
+ // GasSimulatorState.isZeroFee(fee.amount)
357
+ ) {
358
+ state.refreshTx(tx);
359
+ // state.refreshStdFee(fee);
360
+ }
361
+ });
362
+ } catch (e) {
363
+ console.log(e);
364
+ return;
365
+ }
366
+ })
367
+ );
368
+
369
+ this._disposers.push(
370
+ autorun(() => {
371
+ // TODO: Add debounce logic?
372
+
373
+ const key = this.storeKey;
374
+ const state = this.getState(key);
375
+
376
+ if (!state.tx) {
377
+ return;
378
+ }
379
+
380
+ const promise = state.tx.simulate(state.stdFee);
381
+
382
+ runInAction(() => {
383
+ this._isSimulating = true;
384
+ });
385
+
386
+ promise
387
+ .then(({ gasUsed }) => {
388
+ // Changing the gas in the gas config definitely will make the reaction to the fee config,
389
+ // and, this reaction can potentially create a reaction in the amount config as well (Ex, when the "Max" option set).
390
+ // These potential reactions can create repeated meaningless reactions.
391
+ // To avoid this potential problem, change the value when there is a meaningful change in the gas estimated.
392
+ if (
393
+ !state.recentGasEstimated ||
394
+ Math.abs(state.recentGasEstimated - gasUsed) /
395
+ state.recentGasEstimated >
396
+ 0.02
397
+ ) {
398
+ state.setRecentGasEstimated(gasUsed);
399
+ }
400
+
401
+ state.setOutdatedCosmosSdk(false);
402
+ state.setError(undefined);
403
+
404
+ this.kvStore.set(key, gasUsed).catch((e) => {
405
+ console.log(e);
406
+ });
407
+ })
408
+ .catch((e) => {
409
+ console.log(e);
410
+ if (isSimpleFetchError(e) && e.response) {
411
+ const response = e.response;
412
+ if (
413
+ response.status === 400 &&
414
+ response.data?.message &&
415
+ typeof response.data.message === "string" &&
416
+ response.data.message.includes("invalid empty tx")
417
+ ) {
418
+ state.setOutdatedCosmosSdk(true);
419
+ return;
420
+ }
421
+
422
+ let message = "";
423
+ const contentType: string = e.response.headers
424
+ ? e.response.headers.get("content-type") || ""
425
+ : "";
426
+ // Try to figure out the message from the response.
427
+ // If the contentType in the header is specified, try to use the message from the response.
428
+ if (
429
+ contentType.startsWith("text/plain") &&
430
+ typeof e.response.data === "string"
431
+ ) {
432
+ message = e.response.data;
433
+ }
434
+ // If the response is an object and "message" field exists, it is used as a message.
435
+ if (
436
+ contentType.startsWith("application/json") &&
437
+ e.response.data?.message &&
438
+ typeof e.response.data?.message === "string"
439
+ ) {
440
+ message = e.response.data.message;
441
+ }
442
+
443
+ if (message !== "") {
444
+ state.setError(new Error(message));
445
+ return;
446
+ }
447
+ }
448
+
449
+ state.setError(e);
450
+ })
451
+ .finally(() => {
452
+ runInAction(() => {
453
+ this._isSimulating = false;
454
+ });
455
+ });
456
+ })
457
+ );
458
+
459
+ this._disposers.push(
460
+ autorun(() => {
461
+ if (this.enabled && this.gasEstimated != null) {
462
+ this.gasConfig.setValue(this.gasEstimated * this.gasAdjustment);
463
+ }
464
+ })
465
+ );
466
+ }
467
+
468
+ dispose() {
469
+ for (const disposer of this._disposers) {
470
+ disposer();
471
+ }
472
+ }
473
+
474
+ get uiProperties(): UIProperties {
475
+ const key = this.storeKey;
476
+ const state = this.getState(key);
477
+
478
+ return {
479
+ warning: (() => {
480
+ if (this.outdatedCosmosSdk) {
481
+ return new Error("Outdated Cosmos SDK");
482
+ }
483
+
484
+ if (this.forceDisableReason) {
485
+ return this.forceDisableReason;
486
+ }
487
+
488
+ if (this.error) {
489
+ return this.error;
490
+ }
491
+ })(),
492
+ loadingState: (() => {
493
+ if (!this.enabled) {
494
+ return;
495
+ }
496
+
497
+ if (this.isSimulating) {
498
+ // If there is no saved result of the last simulation, user interaction is blocked.
499
+ return state.initialGasEstimated == null
500
+ ? "loading-block"
501
+ : "loading";
502
+ }
503
+ })(),
504
+ };
505
+ }
506
+
507
+ protected getState(key: string): GasSimulatorState {
508
+ if (!this._stateMap.has(key)) {
509
+ runInAction(() => {
510
+ this._stateMap.set(key, new GasSimulatorState());
511
+ });
512
+ }
513
+
514
+ return this._stateMap.get(key)!;
515
+ }
516
+
517
+ @computed
518
+ protected get storeKey(): string {
519
+ const chainIdentifier = ChainIdHelper.parse(this.chainId);
520
+ const fees = "TODO";
521
+ // TODO
522
+ // const fees = this.feeConfig
523
+ // .toStdFee()
524
+ // .amount.map((coin) => coin.denom)
525
+ // .join("/");
526
+ return `${chainIdentifier.identifier}/${fees}/${this.key}}`;
527
+ }
528
+ }
529
+
530
+ // CONTRACT: Use with `observer`
531
+ export const useGasSimulator = (
532
+ kvStore: KVStore,
533
+ chainGetter: ChainGetter,
534
+ chainId: string,
535
+ gasConfig: IGasConfig,
536
+ feeConfig: IFeeConfig,
537
+ key: string,
538
+ simulateGasFn: SimulateGasFn,
539
+ initialDisabled?: boolean
540
+ ) => {
541
+ const [gasSimulator] = useState(() => {
542
+ const gasSimulator = new GasSimulator(
543
+ kvStore,
544
+ chainGetter,
545
+ chainId,
546
+ gasConfig,
547
+ feeConfig,
548
+ key,
549
+ simulateGasFn
550
+ );
551
+ if (initialDisabled) {
552
+ gasSimulator.setEnabled(false);
553
+ } else {
554
+ gasSimulator.setEnabled(true);
555
+ }
556
+
557
+ return gasSimulator;
558
+ });
559
+ gasSimulator.setKVStore(kvStore);
560
+ gasSimulator.setChain(chainId);
561
+ gasSimulator.setKey(key);
562
+ gasSimulator.setSimulateGasFn(simulateGasFn);
563
+
564
+ useEffect(() => {
565
+ return () => {
566
+ gasSimulator.dispose();
567
+ };
568
+ }, [gasSimulator]);
569
+
570
+ return gasSimulator;
571
+ };
package/src/tx/gas.ts ADDED
@@ -0,0 +1,131 @@
1
+ import { IGasConfig, UIProperties } from "./types";
2
+ import { TxChainSetter } from "./chain";
3
+ import { ChainGetter } from "@keplr-wallet/stores";
4
+ import { action, computed, makeObservable, observable } from "mobx";
5
+ import { useState } from "react";
6
+
7
+ export class GasConfig extends TxChainSetter implements IGasConfig {
8
+ /*
9
+ This field is used to handle the value from the input more flexibly.
10
+ We use string because there is no guarantee that only number is input in input component.
11
+ */
12
+ @observable
13
+ protected _value: string = "";
14
+
15
+ /*
16
+ There are services that sometimes use invalid tx to sign arbitrary data on the sign page.
17
+ In this case, there is no obligation to deal with it, but 0 gas is favorably allowed. This option is used for this case.
18
+ */
19
+ @observable
20
+ protected _allowZeroGas?: boolean = undefined;
21
+
22
+ constructor(
23
+ chainGetter: ChainGetter,
24
+ initialChainId: string,
25
+ initialGas?: number,
26
+ allowZeroGas?: boolean
27
+ ) {
28
+ super(chainGetter, initialChainId);
29
+
30
+ if (initialGas) {
31
+ this._value = initialGas.toString();
32
+ }
33
+ this._allowZeroGas = allowZeroGas;
34
+
35
+ makeObservable(this);
36
+ }
37
+
38
+ get value(): string {
39
+ return this._value;
40
+ }
41
+
42
+ @action
43
+ setValue(value: string | number): void {
44
+ if (typeof value === "number") {
45
+ this._value = Math.ceil(value).toString();
46
+ } else {
47
+ this._value = value;
48
+ }
49
+ }
50
+
51
+ get gas(): number {
52
+ if (this.value.trim() === "") {
53
+ return 0;
54
+ }
55
+
56
+ const num = Number.parseInt(this.value);
57
+ if (Number.isNaN(num)) {
58
+ return 0;
59
+ }
60
+
61
+ return num;
62
+ }
63
+
64
+ @computed
65
+ get uiProperties(): UIProperties {
66
+ if (this.value.trim() === "") {
67
+ return {
68
+ error: new Error("Gas not set"),
69
+ };
70
+ }
71
+
72
+ const parsed = Number.parseFloat(this.value);
73
+ if (Number.isNaN(parsed)) {
74
+ return {
75
+ error: new Error("Gas is not valid number"),
76
+ };
77
+ }
78
+
79
+ if (this.value.includes(".") || !Number.isInteger(parsed)) {
80
+ return {
81
+ error: new Error("Gas is not integer"),
82
+ };
83
+ }
84
+
85
+ if (!this._allowZeroGas) {
86
+ if (this.gas <= 0) {
87
+ return {
88
+ error: new Error("Gas should be greater than 0"),
89
+ };
90
+ }
91
+ } else {
92
+ if (this.gas < 0) {
93
+ return {
94
+ error: new Error("Gas should be greater or equal than 0"),
95
+ };
96
+ }
97
+ }
98
+
99
+ return {};
100
+ }
101
+ }
102
+
103
+ export const useGasConfig = (
104
+ chainGetter: ChainGetter,
105
+ chainId: string,
106
+ initialGas?: number
107
+ ) => {
108
+ const [txConfig] = useState(
109
+ () => new GasConfig(chainGetter, chainId, initialGas)
110
+ );
111
+ txConfig.setChain(chainId);
112
+
113
+ return txConfig;
114
+ };
115
+
116
+ /*
117
+ There are services that sometimes use invalid tx to sign arbitrary data on the sign page.
118
+ In this case, there is no obligation to deal with it, but 0 gas is favorably allowed. This option is used for this case.
119
+ */
120
+ export const useZeroAllowedGasConfig = (
121
+ chainGetter: ChainGetter,
122
+ chainId: string,
123
+ initialGas?: number
124
+ ) => {
125
+ const [txConfig] = useState(
126
+ () => new GasConfig(chainGetter, chainId, initialGas, true)
127
+ );
128
+ txConfig.setChain(chainId);
129
+
130
+ return txConfig;
131
+ };
@@ -0,0 +1,12 @@
1
+ export * from "./errors";
2
+ export * from "./types";
3
+ export * from "./fee";
4
+ export * from "./gas";
5
+ export * from "./recipient";
6
+ export * from "./amount";
7
+ export * from "./sender";
8
+ export * from "./send-tx";
9
+ export * from "./chain";
10
+ export * from "./gas-simulator";
11
+ export * from "./validate";
12
+ export * from "./noop-amount";