@0xsequence/marketplace-sdk 0.4.0 → 0.4.2

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 (152) hide show
  1. package/dist/{chunk-L6GSYPCR.js → chunk-2OJB35FS.js} +11 -11
  2. package/dist/{chunk-L6GSYPCR.js.map → chunk-2OJB35FS.js.map} +1 -1
  3. package/dist/{chunk-EK5ZSW4M.js → chunk-4RKM3VUV.js} +2 -2
  4. package/dist/{chunk-7NJETFMF.js → chunk-FI723DGL.js} +3 -3
  5. package/dist/{chunk-7NJETFMF.js.map → chunk-FI723DGL.js.map} +1 -1
  6. package/dist/{chunk-GVDLVCR5.js → chunk-GSDUAHL3.js} +1 -1
  7. package/dist/chunk-GSDUAHL3.js.map +1 -0
  8. package/dist/{chunk-SBVLWSRZ.js → chunk-LF44FCG5.js} +2 -2
  9. package/dist/{chunk-SBVLWSRZ.js.map → chunk-LF44FCG5.js.map} +1 -1
  10. package/dist/{chunk-PAHT6PTD.js → chunk-LSMQVX77.js} +5 -6
  11. package/dist/{chunk-PAHT6PTD.js.map → chunk-LSMQVX77.js.map} +1 -1
  12. package/dist/chunk-MQ5WSFDH.js +435 -0
  13. package/dist/chunk-MQ5WSFDH.js.map +1 -0
  14. package/dist/{chunk-6HEMV2OR.js → chunk-MTFS5SED.js} +1426 -1179
  15. package/dist/chunk-MTFS5SED.js.map +1 -0
  16. package/dist/{chunk-4ESPWOBV.js → chunk-NC4KGXXE.js} +3 -3
  17. package/dist/{chunk-4ESPWOBV.js.map → chunk-NC4KGXXE.js.map} +1 -1
  18. package/dist/{chunk-QTQH5I2E.js → chunk-OPMDGQFB.js} +38 -36
  19. package/dist/chunk-OPMDGQFB.js.map +1 -0
  20. package/dist/{chunk-P3EQRM7K.js → chunk-S5IPE7TH.js} +5 -4
  21. package/dist/{chunk-P3EQRM7K.js.map → chunk-S5IPE7TH.js.map} +1 -1
  22. package/dist/chunk-T5T6JNB2.js +171 -0
  23. package/dist/chunk-T5T6JNB2.js.map +1 -0
  24. package/dist/{chunk-O642NH7U.js → chunk-TDTORZHC.js} +3 -3
  25. package/dist/{chunk-O642NH7U.js.map → chunk-TDTORZHC.js.map} +1 -1
  26. package/dist/{chunk-6AYHE7ZA.js → chunk-WBJKZOQ7.js} +264 -138
  27. package/dist/chunk-WBJKZOQ7.js.map +1 -0
  28. package/dist/{chunk-Y7YO5TLE.js → chunk-XXML5K3X.js} +5 -2
  29. package/dist/chunk-XXML5K3X.js.map +1 -0
  30. package/dist/{chunk-AY2MZHZN.js → chunk-ZWIRTV7A.js} +5 -6
  31. package/dist/{chunk-AY2MZHZN.js.map → chunk-ZWIRTV7A.js.map} +1 -1
  32. package/dist/{create-config-CgtmCzvb.d.ts → create-config-8sffBvlt.d.ts} +1 -1
  33. package/dist/index.js +4 -4
  34. package/dist/react/_internal/api/index.js +2 -2
  35. package/dist/react/_internal/index.d.ts +1 -1
  36. package/dist/react/_internal/index.js +3 -3
  37. package/dist/react/_internal/wagmi/index.d.ts +1 -1
  38. package/dist/react/_internal/wagmi/index.js +2 -2
  39. package/dist/react/hooks/index.d.ts +664 -77
  40. package/dist/react/hooks/index.js +8 -8
  41. package/dist/react/index.css +17 -0
  42. package/dist/react/index.css.map +1 -1
  43. package/dist/react/index.d.ts +1 -1
  44. package/dist/react/index.js +13 -13
  45. package/dist/react/ssr/index.js +1 -1
  46. package/dist/react/ssr/index.js.map +1 -1
  47. package/dist/react/ui/components/index.css +17 -0
  48. package/dist/react/ui/components/index.css.map +1 -1
  49. package/dist/react/ui/components/index.js +13 -13
  50. package/dist/react/ui/icons/index.js +4 -4
  51. package/dist/react/ui/icons/index.js.map +1 -1
  52. package/dist/react/ui/index.css +17 -0
  53. package/dist/react/ui/index.css.map +1 -1
  54. package/dist/react/ui/index.d.ts +15 -8
  55. package/dist/react/ui/index.js +13 -13
  56. package/dist/react/ui/modals/_internal/components/actionModal/index.css +22 -0
  57. package/dist/react/ui/modals/_internal/components/actionModal/index.css.map +1 -1
  58. package/dist/react/ui/modals/_internal/components/actionModal/index.d.ts +17 -9
  59. package/dist/react/ui/modals/_internal/components/actionModal/index.js +9 -5
  60. package/dist/react/ui/styles/index.d.ts +1 -1
  61. package/dist/react/ui/styles/index.js +1 -1
  62. package/dist/styles/index.d.ts +1 -1
  63. package/dist/styles/index.js +5 -5
  64. package/dist/types/index.js +3 -3
  65. package/dist/utils/index.js +2 -2
  66. package/package.json +26 -26
  67. package/src/react/_internal/api/marketplace-api.ts +3 -2
  68. package/src/react/_internal/transaction-machine/execute-transaction.ts +95 -122
  69. package/src/react/_internal/transaction-machine/useTransactionMachine.ts +33 -17
  70. package/src/react/_internal/transaction-machine/utils.ts +50 -0
  71. package/src/react/_internal/transaction-machine/wallet.ts +180 -0
  72. package/src/react/hooks/useBuyCollectable.tsx +24 -8
  73. package/src/react/hooks/useCancelOrder.tsx +11 -7
  74. package/src/react/hooks/useCreateListing.tsx +71 -10
  75. package/src/react/hooks/useCurrencies.tsx +1 -1
  76. package/src/react/hooks/useCurrencyBalance.tsx +1 -1
  77. package/src/react/hooks/useCurrencyOptions.tsx +1 -1
  78. package/src/react/hooks/useGenerateListingTransaction.tsx +1 -3
  79. package/src/react/hooks/useGenerateOfferTransaction.tsx +1 -3
  80. package/src/react/hooks/useMakeOffer.tsx +70 -11
  81. package/src/react/hooks/useSell.tsx +69 -11
  82. package/src/react/ui/components/_internals/action-button/ActionButton.tsx +1 -7
  83. package/src/react/ui/components/_internals/action-button/types.ts +7 -0
  84. package/src/react/ui/components/_internals/custom-select/CustomSelect.tsx +18 -15
  85. package/src/react/ui/components/collectible-card/CollectibleCard.tsx +5 -7
  86. package/src/react/ui/components/collectible-card/Footer.tsx +5 -7
  87. package/src/react/ui/components/collectible-card/styles.css.ts +1 -1
  88. package/src/react/ui/icons/ArrowUp.tsx +3 -0
  89. package/src/react/ui/icons/Bell.tsx +3 -0
  90. package/src/react/ui/icons/CalendarIcon.tsx +3 -0
  91. package/src/react/ui/icons/DiamondEye.tsx +3 -0
  92. package/src/react/ui/icons/InfoIcon.tsx +3 -0
  93. package/src/react/ui/icons/InventoryIcon.tsx +3 -0
  94. package/src/react/ui/icons/MinusIcon.tsx +3 -0
  95. package/src/react/ui/icons/PlusIcon.tsx +3 -0
  96. package/src/react/ui/icons/PositiveCircleIcon.tsx +3 -0
  97. package/src/react/ui/modals/BuyModal/index.tsx +43 -10
  98. package/src/react/ui/modals/CreateListingModal/Modal.tsx +252 -0
  99. package/src/react/ui/modals/CreateListingModal/index.tsx +6 -245
  100. package/src/react/ui/modals/CreateListingModal/store.ts +76 -0
  101. package/src/react/ui/modals/MakeOfferModal/Modal.tsx +254 -0
  102. package/src/react/ui/modals/MakeOfferModal/index.tsx +8 -244
  103. package/src/react/ui/modals/MakeOfferModal/{_store.ts → store.ts} +28 -15
  104. package/src/react/ui/modals/SellModal/Modal.tsx +218 -0
  105. package/src/react/ui/modals/SellModal/index.tsx +8 -188
  106. package/src/react/ui/modals/SellModal/{_store.ts → store.ts} +13 -9
  107. package/src/react/ui/modals/TransferModal/_store.ts +1 -1
  108. package/src/react/ui/modals/TransferModal/_views/enterWalletAddress/index.tsx +4 -2
  109. package/src/react/ui/modals/TransferModal/_views/enterWalletAddress/useHandleTransfer.tsx +5 -5
  110. package/src/react/ui/modals/TransferModal/index.tsx +1 -1
  111. package/src/react/ui/modals/_internal/components/actionModal/ActionModal.tsx +29 -8
  112. package/src/react/ui/modals/_internal/components/actionModal/ErrorModal.tsx +15 -5
  113. package/src/react/ui/modals/_internal/components/actionModal/LoadingModal.tsx +15 -5
  114. package/src/react/ui/modals/_internal/components/actionModal/store.ts +6 -0
  115. package/src/react/ui/modals/_internal/components/calendar/index.tsx +1 -1
  116. package/src/react/ui/modals/_internal/components/currencyImage/index.tsx +3 -3
  117. package/src/react/ui/modals/_internal/components/currencyOptionsSelect/index.tsx +11 -10
  118. package/src/react/ui/modals/_internal/components/expirationDateSelect/index.tsx +14 -19
  119. package/src/react/ui/modals/_internal/components/priceInput/index.tsx +34 -12
  120. package/src/react/ui/modals/_internal/components/quantityInput/index.tsx +3 -3
  121. package/src/react/ui/modals/_internal/components/switchChainModal/index.tsx +7 -4
  122. package/src/react/ui/modals/_internal/components/tokenPreview/index.tsx +1 -0
  123. package/src/react/ui/modals/_internal/components/transaction-footer/index.tsx +6 -5
  124. package/src/react/ui/modals/_internal/components/transactionDetails/index.tsx +9 -5
  125. package/src/react/ui/modals/_internal/components/transactionPreview/index.tsx +4 -4
  126. package/src/react/ui/modals/_internal/components/transactionPreview/useTransactionPreviewTitle.tsx +1 -1
  127. package/src/react/ui/modals/_internal/components/transactionStatusModal/index.tsx +53 -30
  128. package/src/react/ui/modals/_internal/components/transactionStatusModal/store.ts +2 -2
  129. package/src/react/ui/modals/_internal/components/transactionStatusModal/util/getFormattedType.ts +1 -1
  130. package/src/react/ui/modals/_internal/components/transactionStatusModal/util/getMessage.ts +2 -2
  131. package/src/react/ui/modals/_internal/components/transactionStatusModal/util/getTitle.ts +6 -3
  132. package/src/react/ui/modals/_internal/components/waasFeeOptionsBox/index.tsx +146 -0
  133. package/src/react/ui/modals/_internal/components/waasFeeOptionsBox/store.ts +12 -0
  134. package/src/react/ui/modals/_internal/components/waasFeeOptionsBox/styles.css.ts +53 -0
  135. package/src/react/ui/modals/_internal/components/waasFeeOptionsSelect/WaasFeeOptionsSelect.tsx +117 -0
  136. package/src/react/ui/modals/modal-provider.tsx +3 -3
  137. package/src/utils/_internal/error/transaction.ts +2 -2
  138. package/src/utils/date.ts +2 -0
  139. package/src/utils/price.ts +3 -4
  140. package/tsconfig.json +1 -21
  141. package/tsconfig.tsbuildinfo +1 -1
  142. package/dist/chunk-6AYHE7ZA.js.map +0 -1
  143. package/dist/chunk-6HEMV2OR.js.map +0 -1
  144. package/dist/chunk-FFCNYF3S.js +0 -153
  145. package/dist/chunk-FFCNYF3S.js.map +0 -1
  146. package/dist/chunk-GVDLVCR5.js.map +0 -1
  147. package/dist/chunk-NMCGA2TB.js +0 -98
  148. package/dist/chunk-NMCGA2TB.js.map +0 -1
  149. package/dist/chunk-QTQH5I2E.js.map +0 -1
  150. package/dist/chunk-Y7YO5TLE.js.map +0 -1
  151. package/src/react/ui/modals/CreateListingModal/_store.ts +0 -52
  152. /package/dist/{chunk-EK5ZSW4M.js.map → chunk-4RKM3VUV.js.map} +0 -0
@@ -1,18 +1,10 @@
1
1
  import type { SelectPaymentSettings } from '@0xsequence/kit-checkout';
2
- import type {
3
- Chain,
4
- Hash,
5
- Hex,
6
- PublicClient,
7
- TypedDataDomain,
8
- WalletClient,
9
- } from 'viem';
2
+ import type { Chain, Hash, Hex } from 'viem';
10
3
  import { avalanche, optimism } from 'viem/chains';
11
4
  import {
12
5
  type AdditionalFee,
13
6
  type SequenceMarketplace,
14
7
  TransactionSwapProvider,
15
- type WalletKind,
16
8
  WebrpcError,
17
9
  getMarketplaceClient,
18
10
  } from '..';
@@ -28,21 +20,16 @@ import {
28
20
  StepType,
29
21
  } from '../../../types';
30
22
  import {
31
- ChainIdUnavailableError,
32
23
  ChainSwitchError,
33
24
  CheckoutOptionsError,
34
- InvalidSignatureStepError,
35
- MissingPostStepError,
36
25
  MissingSignatureDataError,
37
26
  MissingStepDataError,
38
27
  NoExecutionStepError,
39
28
  NoStepsFoundError,
40
- NoWalletConnectedError,
41
29
  OrderNotFoundError,
42
30
  OrdersFetchError,
43
31
  PaymentModalError,
44
32
  PaymentModalTransactionError,
45
- SignatureExecutionError,
46
33
  StepExecutionError,
47
34
  StepGenerationError,
48
35
  TransactionError,
@@ -51,6 +38,11 @@ import {
51
38
  UnknownTransactionTypeError,
52
39
  } from '../../../utils/_internal/error/transaction';
53
40
  import { type TransactionLogger, createLogger } from './logger';
41
+ import type {
42
+ SignatureStep,
43
+ TransactionStep as StepForTransaction,
44
+ } from './utils';
45
+ import type { WalletInstance } from './wallet';
54
46
 
55
47
  export enum TransactionState {
56
48
  IDLE = 'IDLE',
@@ -74,13 +66,11 @@ export enum TransactionType {
74
66
 
75
67
  export interface TransactionConfig {
76
68
  type: TransactionType;
77
- walletKind: WalletKind;
78
69
  chainId: string;
79
70
  chains: readonly Chain[];
80
71
  collectionAddress: string;
81
72
  sdkConfig: SdkConfig;
82
73
  marketplaceConfig: MarketplaceConfig;
83
- isWaaS: boolean;
84
74
  orderbookKind?: OrderbookKind;
85
75
  }
86
76
 
@@ -88,6 +78,7 @@ interface StateConfig {
88
78
  config: TransactionConfig;
89
79
  onTransactionSent?: (hash?: Hash, orderId?: string) => void;
90
80
  onSuccess?: (hash: Hash) => void;
81
+ onApprovalSuccess?: (hash: Hash) => void;
91
82
  }
92
83
 
93
84
  export interface BuyInput {
@@ -147,9 +138,10 @@ type TransactionInput =
147
138
  props: CancelInput;
148
139
  };
149
140
 
150
- interface TransactionStep {
141
+ export interface TransactionStep {
151
142
  isPending: boolean;
152
143
  isExecuting: boolean;
144
+ isSuccess?: boolean;
153
145
  }
154
146
 
155
147
  export interface TransactionSteps {
@@ -176,12 +168,12 @@ export class TransactionMachine {
176
168
 
177
169
  constructor(
178
170
  private readonly config: StateConfig,
179
- private readonly walletClient: WalletClient,
180
- private readonly publicClient: PublicClient,
171
+ private readonly wallet: WalletInstance,
181
172
  private readonly openSelectPaymentModal: (
182
173
  settings: SelectPaymentSettings,
183
174
  ) => void,
184
175
  private readonly switchChainFn: (chainId: string) => Promise<void>,
176
+ private readonly onPaymentModalLoaded?: () => void,
185
177
  ) {
186
178
  this.currentState = TransactionState.IDLE;
187
179
  this.logger = createLogger('TransactionMachine');
@@ -189,14 +181,7 @@ export class TransactionMachine {
189
181
  config.config.chainId,
190
182
  config.config.sdkConfig,
191
183
  );
192
- }
193
-
194
- private getAccount() {
195
- const account = this.walletClient.account;
196
- if (!account) {
197
- throw new NoWalletConnectedError();
198
- }
199
- return account;
184
+ this.onPaymentModalLoaded = onPaymentModalLoaded;
200
185
  }
201
186
 
202
187
  private getMarketplaceFee(collectionAddress: string) {
@@ -205,15 +190,17 @@ export class TransactionMachine {
205
190
  '0x858dB1cbF6D09D447C96A11603189b49B2D1C219';
206
191
  const avalancheAndOptimismPlatformFeeRecipient =
207
192
  '0x400cdab4676c17aec07e8ec748a5fc3b674bca41';
193
+
194
+ const chainId = Number(this.config.config.chainId);
208
195
  const collection = this.config.config.marketplaceConfig.collections.find(
209
196
  (collection) =>
210
197
  collection.collectionAddress.toLowerCase() ===
211
198
  collectionAddress.toLowerCase() &&
212
- this.getChainId() === Number(collection.chainId),
199
+ chainId === Number(collection.chainId),
213
200
  );
214
201
 
215
202
  const avalancheOrOptimism =
216
- this.getChainId() === avalanche.id || this.getChainId() === optimism.id;
203
+ chainId === avalanche.id || chainId === optimism.id;
217
204
  const receiver = avalancheOrOptimism
218
205
  ? avalancheAndOptimismPlatformFeeRecipient
219
206
  : defaultPlatformFeeRecipient;
@@ -229,17 +216,13 @@ export class TransactionMachine {
229
216
  } satisfies AdditionalFee;
230
217
  }
231
218
 
232
- private getAccountAddress() {
233
- return this.getAccount().address;
234
- }
235
-
236
219
  private async generateSteps({
237
220
  type,
238
221
  props,
239
222
  }: TransactionInput): Promise<Step[]> {
240
223
  this.logger.debug('Generating steps', { type, props });
241
224
  const { collectionAddress } = this.config.config;
242
- const address = this.getAccountAddress();
225
+ const address = await this.wallet.address();
243
226
 
244
227
  try {
245
228
  switch (type) {
@@ -248,7 +231,7 @@ export class TransactionMachine {
248
231
  .generateBuyTransaction({
249
232
  collectionAddress,
250
233
  buyer: address,
251
- walletType: this.config.config.walletKind,
234
+ walletType: this.wallet.walletKind,
252
235
  marketplace: props.marketplace,
253
236
  ordersData: [
254
237
  {
@@ -265,7 +248,7 @@ export class TransactionMachine {
265
248
  .generateSellTransaction({
266
249
  collectionAddress,
267
250
  seller: address,
268
- walletType: this.config.config.walletKind,
251
+ walletType: this.wallet.walletKind,
269
252
  marketplace: props.marketplace,
270
253
  ordersData: [
271
254
  {
@@ -273,7 +256,7 @@ export class TransactionMachine {
273
256
  quantity: props.quantity || '1',
274
257
  },
275
258
  ],
276
- additionalFees: [],
259
+ additionalFees: [this.getMarketplaceFee(collectionAddress)],
277
260
  })
278
261
  .then((resp) => resp.steps);
279
262
 
@@ -287,7 +270,7 @@ export class TransactionMachine {
287
270
  .generateListingTransaction({
288
271
  collectionAddress,
289
272
  owner: address,
290
- walletType: this.config.config.walletKind,
273
+ walletType: this.wallet.walletKind,
291
274
  contractType: props.contractType,
292
275
  orderbook: this.config.config.orderbookKind,
293
276
  listing: props.listing,
@@ -304,7 +287,7 @@ export class TransactionMachine {
304
287
  .generateOfferTransaction({
305
288
  collectionAddress,
306
289
  maker: address,
307
- walletType: this.config.config.walletKind,
290
+ walletType: this.wallet.walletKind,
308
291
  contractType: props.contractType,
309
292
  orderbook: this.config.config.orderbookKind,
310
293
  offer: props.offer,
@@ -343,51 +326,44 @@ export class TransactionMachine {
343
326
  this.clearMemoizedSteps();
344
327
  }
345
328
 
346
- private getChainId(): number {
347
- const chainId = this.walletClient.chain?.id;
348
- if (!chainId) {
349
- throw new ChainIdUnavailableError();
350
- }
351
- return chainId;
352
- }
353
-
354
- private getChainForTransaction() {
355
- const chainId = this.config.config.chainId;
356
- return this.config.config.chains.find(
357
- (chain) => chain.id === Number(chainId),
358
- );
359
- }
360
-
361
- private isOnCorrectChain() {
362
- return this.getChainId() === Number(this.config.config.chainId);
363
- }
364
-
365
- private async switchChain(): Promise<void> {
329
+ private async switchChain() {
366
330
  this.logger.debug('Checking chain', {
367
- currentChain: this.getChainId(),
331
+ currentChain: await this.wallet.getChainId(),
368
332
  targetChain: Number(this.config.config.chainId),
369
333
  });
370
334
 
371
- if (!this.isOnCorrectChain()) {
372
- const currentChain = this.getChainId();
335
+ const correctChain = await this.isOnCorrectChain();
336
+
337
+ if (!correctChain) {
338
+ const currentChain = await this.wallet.getChainId();
373
339
  const targetChain = Number(this.config.config.chainId);
374
340
 
375
341
  await this.transition(TransactionState.SWITCH_CHAIN);
376
342
  try {
377
- if (!this.config.config.isWaaS) {
343
+ if (this.wallet.isWaaS) {
344
+ await this.wallet.switchChain(targetChain);
345
+ } else {
378
346
  await this.switchChainFn(this.config.config.chainId);
379
347
  }
380
348
 
381
- await this.walletClient.switchChain({
382
- id: Number(this.config.config.chainId),
383
- });
384
- this.logger.debug('Switched chain');
349
+ if (!this.isOnCorrectChain()) {
350
+ throw new Error('Chain switch verification failed');
351
+ }
352
+
353
+ this.logger.debug('Switched chain successfully');
385
354
  } catch (error) {
355
+ this.logger.debug('Chain switch failed', error);
386
356
  throw new ChainSwitchError(currentChain, targetChain);
387
357
  }
388
358
  }
389
359
  }
390
360
 
361
+ private async isOnCorrectChain() {
362
+ return (
363
+ (await this.wallet.getChainId()) === Number(this.config.config.chainId)
364
+ );
365
+ }
366
+
391
367
  async start(props: Input) {
392
368
  this.logger.debug('Starting transaction', props);
393
369
 
@@ -406,23 +382,41 @@ export class TransactionMachine {
406
382
  await this.transition(TransactionState.SUCCESS);
407
383
  }
408
384
 
409
- private async handleTransactionSuccess(hash?: Hash) {
385
+ private async handleTransactionSuccess(
386
+ hash?: Hash,
387
+ isApproval?: boolean,
388
+ orderId?: string,
389
+ ) {
410
390
  if (!hash) {
411
391
  // TODO: This is to handle signature steps, but it's not ideal
412
392
  await this.transition(TransactionState.SUCCESS);
393
+ this.config.onTransactionSent?.(undefined, orderId);
413
394
  return;
414
395
  }
396
+
415
397
  await this.transition(TransactionState.CONFIRMING);
416
- this.config.onTransactionSent?.(hash);
398
+
399
+ // Only notify of transaction sent, don't show success toast yet
400
+ if (!isApproval) {
401
+ this.config.onTransactionSent?.(hash);
402
+ }
417
403
 
418
404
  try {
419
- const receipt = await this.publicClient.waitForTransactionReceipt({
405
+ const receipt = await this.wallet.handleConfirmTransactionStep(
420
406
  hash,
421
- });
407
+ await this.wallet.getChainId(),
408
+ );
422
409
  this.logger.debug('Transaction confirmed', receipt);
423
410
 
424
411
  await this.transition(TransactionState.SUCCESS);
425
- this.config.onSuccess?.(hash);
412
+
413
+ // Only trigger success notification for the final confirmation
414
+ if (isApproval) {
415
+ this.config.onApprovalSuccess?.(hash);
416
+ } else {
417
+ console.log('onSuccess', hash);
418
+ this.config.onSuccess?.(hash);
419
+ }
426
420
  } catch (error) {
427
421
  throw new TransactionReceiptError(hash, error as Error);
428
422
  }
@@ -432,19 +426,21 @@ export class TransactionMachine {
432
426
  try {
433
427
  await this.switchChain();
434
428
 
435
- const transactionData = {
436
- account: this.getAccount(),
437
- chain: this.getChainForTransaction(),
438
- to: step.to as Hex,
439
- data: step.data as Hex,
440
- value: BigInt(step.value || '0'),
441
- };
429
+ if (step.id === StepType.tokenApproval) {
430
+ await this.transition(TransactionState.TOKEN_APPROVAL);
431
+ }
442
432
 
443
- this.logger.debug('Executing transaction', transactionData);
444
- const hash = await this.walletClient.sendTransaction(transactionData);
433
+ this.logger.debug('Executing transaction', step);
434
+ const hash = await this.wallet.handleSendTransactionStep(
435
+ Number(this.config.config.chainId),
436
+ step as StepForTransaction,
437
+ );
445
438
  this.logger.debug('Transaction submitted', { hash });
446
439
 
447
- await this.handleTransactionSuccess(hash);
440
+ await this.handleTransactionSuccess(
441
+ hash,
442
+ step.id === StepType.tokenApproval,
443
+ );
448
444
  return hash;
449
445
  } catch (error) {
450
446
  throw new StepExecutionError(step.id, error as Error);
@@ -452,48 +448,27 @@ export class TransactionMachine {
452
448
  }
453
449
 
454
450
  private async executeSignature(step: Step) {
455
- this.logger.debug('Executing signature', { stepId: step.id });
456
- if (!step.post) {
457
- throw new MissingPostStepError();
458
- }
459
-
460
451
  await this.switchChain();
461
452
 
462
- let signature: Hex;
463
453
  if (!step.signature) {
464
454
  throw new MissingSignatureDataError();
465
455
  }
466
456
 
467
- switch (step.id) {
468
- case StepType.signEIP712:
469
- signature = await this.walletClient.signTypedData({
470
- domain: step.signature.domain as TypedDataDomain,
471
- types: step.signature.types,
472
- primaryType: step.signature.primaryType,
473
- account: this.getAccountAddress(),
474
- message: step.signature.value,
475
- });
476
- break;
477
- case StepType.signEIP191:
478
- signature = await this.walletClient.signMessage({
479
- message: step.data,
480
- account: step.to as Hex,
481
- });
482
- break;
483
- default:
484
- throw new InvalidSignatureStepError(step.id);
485
- }
486
-
487
457
  try {
488
- const { orderId } = await this.marketplaceClient.execute({
489
- signature,
458
+ const signature = await this.wallet.handleSignMessageStep(
459
+ step as SignatureStep,
460
+ );
461
+
462
+ const result = await this.marketplaceClient.execute({
463
+ signature: signature as string,
490
464
  executeType: ExecuteType.order,
491
- body: step.post.body,
465
+ body: step.post?.body,
492
466
  });
493
467
 
494
- this.config.onTransactionSent?.(undefined, orderId);
468
+ await this.handleTransactionSuccess(undefined, false, result.orderId);
495
469
  } catch (error) {
496
- throw new SignatureExecutionError(step.id, error as Error);
470
+ this.logger.error('Signature execution failed', { error });
471
+ throw new StepExecutionError(step.id, error as Error);
497
472
  }
498
473
  }
499
474
 
@@ -532,7 +507,7 @@ export class TransactionMachine {
532
507
  const [checkoutOptions, orders] = await Promise.all([
533
508
  this.marketplaceClient
534
509
  .checkoutOptionsMarketplace({
535
- wallet: this.getAccountAddress(),
510
+ wallet: await this.wallet.address(),
536
511
  orders: [
537
512
  {
538
513
  contractAddress: this.config.config.collectionAddress,
@@ -569,7 +544,7 @@ export class TransactionMachine {
569
544
  }
570
545
 
571
546
  const paymentModalProps = {
572
- chain: this.getChainId()!,
547
+ chain: this.config.config.chainId,
573
548
  collectibles: [
574
549
  {
575
550
  tokenId: order.tokenId,
@@ -578,11 +553,11 @@ export class TransactionMachine {
578
553
  },
579
554
  ],
580
555
  currencyAddress: order.priceCurrencyAddress,
581
- price: order.priceAmount,
556
+ price: step.value,
582
557
  targetContractAddress: step.to,
583
558
  txData: step.data as Hex,
584
559
  collectionAddress: this.config.config.collectionAddress,
585
- recipientAddress: this.getAccountAddress(),
560
+ recipientAddress: await this.wallet.address(),
586
561
  enableMainCurrencyPayment: true,
587
562
  enableSwapPayments: !!checkoutOptions.options?.swap?.includes(
588
563
  TransactionSwapProvider.zerox,
@@ -591,6 +566,9 @@ export class TransactionMachine {
591
566
  };
592
567
 
593
568
  this.logger.debug('Opening payment modal', paymentModalProps);
569
+
570
+ this.onPaymentModalLoaded?.();
571
+
594
572
  await this.openPaymentModalWithPromise(paymentModalProps);
595
573
  } catch (error) {
596
574
  if (error instanceof TransactionError) {
@@ -631,11 +609,6 @@ export class TransactionMachine {
631
609
  }
632
610
 
633
611
  const hash = await this.executeTransaction(step);
634
-
635
- if (step.id !== StepType.tokenApproval) {
636
- this.config.onSuccess?.(hash);
637
- }
638
-
639
612
  return { hash };
640
613
  } catch (error) {
641
614
  if (error instanceof TransactionError) {
@@ -1,7 +1,6 @@
1
1
  import { useSelectPaymentModal } from '@0xsequence/kit-checkout';
2
2
  import type { Hash } from 'viem';
3
3
  import { useAccount, useSwitchChain, useWalletClient } from 'wagmi';
4
- import { getPublicRpcClient } from '../../../utils';
5
4
  import {
6
5
  NoMarketplaceConfigError,
7
6
  NoWalletConnectedError,
@@ -9,24 +8,39 @@ import {
9
8
  } from '../../../utils/_internal/error/transaction';
10
9
  import { useConfig, useMarketplaceConfig } from '../../hooks';
11
10
  import { useSwitchChainModal } from '../../ui/modals/_internal/components/switchChainModal';
12
- import { WalletKind } from '../api';
13
11
  import {
14
12
  type Input,
15
13
  type TransactionConfig,
16
14
  TransactionMachine,
17
15
  } from './execute-transaction';
16
+ import { wallet } from './wallet';
18
17
 
19
18
  export type UseTransactionMachineConfig = Omit<
20
19
  TransactionConfig,
21
- 'sdkConfig' | 'marketplaceConfig' | 'walletKind' | 'chains' | 'isWaaS'
20
+ 'sdkConfig' | 'marketplaceConfig' | 'walletKind' | 'chains'
22
21
  >;
23
22
 
24
- export const useTransactionMachine = (
25
- config: UseTransactionMachineConfig,
26
- onSuccess?: (hash: Hash) => void,
27
- onError?: (error: TransactionError) => void,
28
- onTransactionSent?: (hash?: Hash, orderId?: string) => void,
29
- ) => {
23
+ export const useTransactionMachine = ({
24
+ config,
25
+ enabled,
26
+ onSuccess,
27
+ onError,
28
+ onTransactionSent,
29
+ onApprovalSuccess,
30
+ onPaymentModalLoaded,
31
+ }: {
32
+ config: UseTransactionMachineConfig;
33
+ enabled: boolean;
34
+ onSuccess?: (hash: Hash) => void;
35
+ onError?: (error: TransactionError) => void;
36
+ onTransactionSent?: (
37
+ hash?: Hash,
38
+ orderId?: string,
39
+ isApproval?: boolean,
40
+ ) => void;
41
+ onApprovalSuccess?: (hash: Hash) => void;
42
+ onPaymentModalLoaded?: () => void;
43
+ }) => {
30
44
  const { data: walletClient, isLoading: walletClientIsLoading } =
31
45
  useWalletClient();
32
46
  const { show: showSwitchChainModal } = useSwitchChainModal();
@@ -40,11 +54,8 @@ export const useTransactionMachine = (
40
54
  const { chains } = useSwitchChain();
41
55
 
42
56
  const { connector, isConnected } = useAccount();
43
- const walletKind =
44
- connector?.id === 'sequence' ? WalletKind.sequence : WalletKind.unknown;
45
57
 
46
- // TODO: remove this once we have a better way to check if the wallet is a WAAS wallet
47
- const isWaaS = connector?.id.endsWith('waas') || false;
58
+ if (!enabled) return { machine: null, error: null, isLoading: false };
48
59
 
49
60
  if (!isConnected) {
50
61
  // No wallet connected, TODO: add some sort of state for this
@@ -75,21 +86,25 @@ export const useTransactionMachine = (
75
86
  return { machine: null, error };
76
87
  }
77
88
 
89
+ const walletInstance = wallet({
90
+ wallet: walletClient,
91
+ chains,
92
+ connector: connector!,
93
+ });
94
+
78
95
  const machine = new TransactionMachine(
79
96
  {
80
97
  config: {
81
98
  sdkConfig,
82
99
  marketplaceConfig,
83
- walletKind,
84
100
  chains,
85
101
  ...config,
86
- isWaaS,
87
102
  },
88
103
  onSuccess,
89
104
  onTransactionSent,
105
+ onApprovalSuccess,
90
106
  },
91
- walletClient,
92
- getPublicRpcClient(config.chainId),
107
+ walletInstance,
93
108
  openSelectPaymentModal,
94
109
  async () =>
95
110
  new Promise((resolve, reject) => {
@@ -100,6 +115,7 @@ export const useTransactionMachine = (
100
115
  onClose: reject,
101
116
  });
102
117
  }),
118
+ onPaymentModalLoaded,
103
119
  );
104
120
 
105
121
  return {
@@ -0,0 +1,50 @@
1
+ import type { TypedData, TypedDataDomain } from 'viem';
2
+ import type { Hex } from 'viem';
3
+ import { type PostRequest, type Signature, type Step, StepType } from '../api';
4
+
5
+ export interface SignatureStep {
6
+ id: StepType.signEIP191 | StepType.signEIP712;
7
+ domain?: TypedDataDomain;
8
+ types?: TypedData;
9
+ primaryType?: string;
10
+ to: Hex; // TODO: This should not be here, its wrongly typed in webrpc
11
+ data: string;
12
+ value: string;
13
+ signature?: Signature;
14
+ post: PostRequest;
15
+ }
16
+
17
+ export interface TransactionStep {
18
+ id:
19
+ | StepType.buy
20
+ | StepType.sell
21
+ | StepType.cancel
22
+ | StepType.createOffer
23
+ | StepType.createListing;
24
+ data: Hex;
25
+ to: Hex;
26
+ value: Hex;
27
+ maxFeePerGas?: Hex;
28
+ maxPriorityFeePerGas?: Hex;
29
+ gas?: Hex;
30
+ }
31
+ export interface ApprovalStep {
32
+ id: StepType.tokenApproval;
33
+ data: string;
34
+ to: Hex;
35
+ value: string;
36
+ }
37
+
38
+ export function isSignatureStep(step: Step): step is SignatureStep {
39
+ return step.id === StepType.signEIP191 || step.id === StepType.signEIP712;
40
+ }
41
+
42
+ export function isTransactionStep(step: Step): step is TransactionStep {
43
+ return [
44
+ StepType.buy,
45
+ StepType.sell,
46
+ StepType.cancel,
47
+ StepType.createOffer,
48
+ StepType.createListing,
49
+ ].includes(step.id);
50
+ }