@zoralabs/coins-sdk 0.5.2 → 0.7.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 (49) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/dist/actions/createCoin.d.ts +92 -7
  3. package/dist/actions/createCoin.d.ts.map +1 -1
  4. package/dist/actions/tradeCoin.d.ts +27 -2
  5. package/dist/actions/tradeCoin.d.ts.map +1 -1
  6. package/dist/actions/updateCoinURI.d.ts +35 -1
  7. package/dist/actions/updateCoinURI.d.ts.map +1 -1
  8. package/dist/actions/updatePayoutRecipient.d.ts +41 -1
  9. package/dist/actions/updatePayoutRecipient.d.ts.map +1 -1
  10. package/dist/api/api-raw.d.ts +1 -0
  11. package/dist/api/api-raw.d.ts.map +1 -1
  12. package/dist/api/index.d.ts +2 -0
  13. package/dist/api/index.d.ts.map +1 -1
  14. package/dist/api/queries.d.ts +9 -1
  15. package/dist/api/queries.d.ts.map +1 -1
  16. package/dist/api/social.d.ts +8 -0
  17. package/dist/api/social.d.ts.map +1 -0
  18. package/dist/client/sdk.gen.d.ts +144 -1
  19. package/dist/client/sdk.gen.d.ts.map +1 -1
  20. package/dist/client/types.gen.d.ts +411 -1
  21. package/dist/client/types.gen.d.ts.map +1 -1
  22. package/dist/index.cjs +724 -250
  23. package/dist/index.cjs.map +1 -1
  24. package/dist/index.d.ts +11 -5
  25. package/dist/index.d.ts.map +1 -1
  26. package/dist/index.js +701 -227
  27. package/dist/index.js.map +1 -1
  28. package/dist/metadata/validateMetadataURIContent.d.ts.map +1 -1
  29. package/dist/utils/calls.d.ts +61 -0
  30. package/dist/utils/calls.d.ts.map +1 -0
  31. package/dist/utils/userOperation.d.ts +44 -0
  32. package/dist/utils/userOperation.d.ts.map +1 -0
  33. package/package.json +1 -1
  34. package/src/actions/createCoin.ts +314 -60
  35. package/src/actions/tradeCoin.ts +237 -72
  36. package/src/actions/updateCoinURI.ts +84 -6
  37. package/src/actions/updatePayoutRecipient.ts +92 -5
  38. package/src/api/api-raw.test.ts +61 -0
  39. package/src/api/api-raw.ts +9 -0
  40. package/src/api/index.ts +4 -0
  41. package/src/api/queries.ts +36 -0
  42. package/src/api/social.ts +23 -0
  43. package/src/client/sdk.gen.ts +48 -0
  44. package/src/client/types.gen.ts +421 -1
  45. package/src/index.ts +45 -3
  46. package/src/metadata/validateMetadataURIContent.ts +17 -2
  47. package/src/utils/calls.ts +129 -0
  48. package/src/utils/userOperation.test.ts +84 -0
  49. package/src/utils/userOperation.ts +124 -0
package/dist/index.cjs CHANGED
@@ -6,131 +6,10 @@ var _protocoldeployments = require('@zoralabs/protocol-deployments');
6
6
 
7
7
 
8
8
 
9
+
9
10
  var _viem = require('viem');
10
11
  var _chains = require('viem/chains');
11
12
 
12
- // src/utils/validateClientNetwork.ts
13
-
14
- var validateClientNetwork = (publicClient) => {
15
- const clientChainId = _optionalChain([publicClient, 'optionalAccess', _ => _.chain, 'optionalAccess', _2 => _2.id]);
16
- if (clientChainId === _chains.base.id) {
17
- return;
18
- }
19
- if (clientChainId === _chains.baseSepolia.id) {
20
- return;
21
- }
22
- throw new Error(
23
- "Client network needs to be base or baseSepolia for current coin deployments."
24
- );
25
- };
26
-
27
- // src/metadata/cleanAndValidateMetadataURI.ts
28
- function cleanAndValidateMetadataURI(uri) {
29
- if (uri.startsWith("ipfs://")) {
30
- return uri.replace(
31
- "ipfs://",
32
- "https://magic.decentralized-content.com/ipfs/"
33
- );
34
- }
35
- if (uri.startsWith("ar://")) {
36
- return uri.replace("ar://", "http://arweave.net/");
37
- }
38
- if (uri.startsWith("data:")) {
39
- return uri;
40
- }
41
- if (uri.startsWith("http://") || uri.startsWith("https://")) {
42
- return uri;
43
- }
44
- throw new Error("Invalid metadata URI");
45
- }
46
-
47
- // src/metadata/validateMetadataJSON.ts
48
- function validateURIString(uri) {
49
- if (typeof uri !== "string") {
50
- throw new Error("URI must be a string");
51
- }
52
- if (uri.startsWith("ipfs://")) {
53
- return true;
54
- }
55
- if (uri.startsWith("ar://")) {
56
- return true;
57
- }
58
- if (uri.startsWith("https://")) {
59
- return true;
60
- }
61
- if (uri.startsWith("data:")) {
62
- return true;
63
- }
64
- return false;
65
- }
66
- function validateMetadataJSON(metadata) {
67
- if (typeof metadata !== "object" || !metadata) {
68
- throw new Error("Metadata must be an object and exist");
69
- }
70
- if (typeof metadata.name !== "string") {
71
- throw new Error("Metadata name is required and must be a string");
72
- }
73
- if (typeof metadata.description !== "string") {
74
- throw new Error("Metadata description is required and must be a string");
75
- }
76
- if (typeof metadata.image === "string") {
77
- if (!validateURIString(metadata.image)) {
78
- throw new Error("Metadata image is not a valid URI");
79
- }
80
- } else {
81
- throw new Error("Metadata image is required and must be a string");
82
- }
83
- if ("animation_url" in metadata) {
84
- if (typeof metadata.animation_url !== "string") {
85
- throw new Error("Metadata animation_url, if provided, must be a string");
86
- }
87
- if (!validateURIString(metadata.animation_url)) {
88
- throw new Error("Metadata animation_url is not a valid URI");
89
- }
90
- }
91
- const content = "content" in metadata && metadata.content;
92
- if (content) {
93
- if (typeof content.uri !== "string") {
94
- throw new Error("If provided, content.uri must be a string");
95
- }
96
- if (!validateURIString(content.uri)) {
97
- throw new Error("If provided, content.uri must be a valid URI string");
98
- }
99
- if (typeof content.mime !== "string") {
100
- throw new Error("If provided, content.mime must be a string");
101
- }
102
- }
103
- return true;
104
- }
105
-
106
- // src/metadata/validateMetadataURIContent.ts
107
- async function validateMetadataURIContent(metadataURI) {
108
- const cleanedURI = cleanAndValidateMetadataURI(metadataURI);
109
- const response = await fetch(cleanedURI);
110
- if (!response.ok) {
111
- throw new Error("Metadata fetch failed");
112
- }
113
- if (!["application/json", "text/plain"].includes(
114
- _nullishCoalesce(response.headers.get("content-type"), () => ( ""))
115
- )) {
116
- throw new Error("Metadata is not a valid JSON or plain text response type");
117
- }
118
- const metadataJson = await response.json();
119
- return validateMetadataJSON(metadataJson);
120
- }
121
-
122
- // src/utils/getChainFromId.ts
123
-
124
- function getChainFromId(chainId) {
125
- if (chainId === _chains.base.id) {
126
- return _chains.base;
127
- }
128
- if (chainId === _chains.baseSepolia.id) {
129
- return _chains.baseSepolia;
130
- }
131
- throw new Error(`Chain ID ${chainId} not supported`);
132
- }
133
-
134
13
  // src/client/client.gen.ts
135
14
 
136
15
 
@@ -179,6 +58,18 @@ var getCoinHolders = (options) => {
179
58
  ...options
180
59
  });
181
60
  };
61
+ var getCoinPriceHistory = (options) => {
62
+ return (_nullishCoalesce(options.client, () => ( client))).get({
63
+ security: [
64
+ {
65
+ name: "api-key",
66
+ type: "apiKey"
67
+ }
68
+ ],
69
+ url: "/coinPriceHistory",
70
+ ...options
71
+ });
72
+ };
182
73
  var getCoinSwaps = (options) => {
183
74
  return (_nullishCoalesce(options.client, () => ( client))).get({
184
75
  security: [
@@ -216,7 +107,7 @@ var getContentCoinPoolConfig = (options) => {
216
107
  });
217
108
  };
218
109
  var setCreateUploadJwt = (options) => {
219
- return (_nullishCoalesce(_optionalChain([options, 'optionalAccess', _3 => _3.client]), () => ( client))).post({
110
+ return (_nullishCoalesce(_optionalChain([options, 'optionalAccess', _ => _.client]), () => ( client))).post({
220
111
  security: [
221
112
  {
222
113
  name: "api-key",
@@ -227,12 +118,12 @@ var setCreateUploadJwt = (options) => {
227
118
  ...options,
228
119
  headers: {
229
120
  "Content-Type": "application/json",
230
- ..._optionalChain([options, 'optionalAccess', _4 => _4.headers])
121
+ ..._optionalChain([options, 'optionalAccess', _2 => _2.headers])
231
122
  }
232
123
  });
233
124
  };
234
125
  var getCreatorCoinPoolConfig = (options) => {
235
- return (_nullishCoalesce(_optionalChain([options, 'optionalAccess', _5 => _5.client]), () => ( client))).get({
126
+ return (_nullishCoalesce(_optionalChain([options, 'optionalAccess', _3 => _3.client]), () => ( client))).get({
236
127
  security: [
237
128
  {
238
129
  name: "api-key",
@@ -268,7 +159,7 @@ var getExplore = (options) => {
268
159
  });
269
160
  };
270
161
  var getFeaturedCreators = (options) => {
271
- return (_nullishCoalesce(_optionalChain([options, 'optionalAccess', _6 => _6.client]), () => ( client))).get({
162
+ return (_nullishCoalesce(_optionalChain([options, 'optionalAccess', _4 => _4.client]), () => ( client))).get({
272
163
  security: [
273
164
  {
274
165
  name: "api-key",
@@ -303,6 +194,18 @@ var getProfileBalances = (options) => {
303
194
  ...options
304
195
  });
305
196
  };
197
+ var getProfileBySocialHandle = (options) => {
198
+ return (_nullishCoalesce(options.client, () => ( client))).get({
199
+ security: [
200
+ {
201
+ name: "api-key",
202
+ type: "apiKey"
203
+ }
204
+ ],
205
+ url: "/profileBySocialHandle",
206
+ ...options
207
+ });
208
+ };
306
209
  var getProfileCoins = (options) => {
307
210
  return (_nullishCoalesce(options.client, () => ( client))).get({
308
211
  security: [
@@ -340,7 +243,7 @@ var getTokenInfo = (options) => {
340
243
  });
341
244
  };
342
245
  var getTraderLeaderboard = (options) => {
343
- return (_nullishCoalesce(_optionalChain([options, 'optionalAccess', _7 => _7.client]), () => ( client))).get({
246
+ return (_nullishCoalesce(_optionalChain([options, 'optionalAccess', _5 => _5.client]), () => ( client))).get({
344
247
  security: [
345
248
  {
346
249
  name: "api-key",
@@ -375,8 +278,20 @@ var getTrendsByName = (options) => {
375
278
  ...options
376
279
  });
377
280
  };
281
+ var getWalletTradeActivity = (options) => {
282
+ return (_nullishCoalesce(options.client, () => ( client))).get({
283
+ security: [
284
+ {
285
+ name: "api-key",
286
+ type: "apiKey"
287
+ }
288
+ ],
289
+ url: "/walletTradeActivity",
290
+ ...options
291
+ });
292
+ };
378
293
  var postQuote = (options) => {
379
- return (_nullishCoalesce(_optionalChain([options, 'optionalAccess', _8 => _8.client]), () => ( client))).post({
294
+ return (_nullishCoalesce(_optionalChain([options, 'optionalAccess', _6 => _6.client]), () => ( client))).post({
380
295
  security: [
381
296
  {
382
297
  name: "api-key",
@@ -387,12 +302,12 @@ var postQuote = (options) => {
387
302
  ...options,
388
303
  headers: {
389
304
  "Content-Type": "application/json",
390
- ..._optionalChain([options, 'optionalAccess', _9 => _9.headers])
305
+ ..._optionalChain([options, 'optionalAccess', _7 => _7.headers])
391
306
  }
392
307
  });
393
308
  };
394
309
  var postCreateContent = (options) => {
395
- return (_nullishCoalesce(_optionalChain([options, 'optionalAccess', _10 => _10.client]), () => ( client))).post({
310
+ return (_nullishCoalesce(_optionalChain([options, 'optionalAccess', _8 => _8.client]), () => ( client))).post({
396
311
  security: [
397
312
  {
398
313
  name: "api-key",
@@ -403,7 +318,7 @@ var postCreateContent = (options) => {
403
318
  ...options,
404
319
  headers: {
405
320
  "Content-Type": "application/json",
406
- ..._optionalChain([options, 'optionalAccess', _11 => _11.headers])
321
+ ..._optionalChain([options, 'optionalAccess', _9 => _9.headers])
407
322
  }
408
323
  });
409
324
  };
@@ -490,6 +405,13 @@ var getCoinHolders2 = async (query, options) => {
490
405
  ...options
491
406
  });
492
407
  };
408
+ var getCoinPriceHistory2 = async (query, options) => {
409
+ return await getCoinPriceHistory({
410
+ query,
411
+ ...getApiKeyMeta(),
412
+ ...options
413
+ });
414
+ };
493
415
  var getCoinSwaps2 = async (query, options) => {
494
416
  return await getCoinSwaps({
495
417
  query,
@@ -574,15 +496,185 @@ var getCreatorLivestreamComments2 = async (query, options) => {
574
496
  ...options
575
497
  });
576
498
  };
499
+ var getWalletTradeActivity2 = async (query, options) => {
500
+ return await getWalletTradeActivity({
501
+ query,
502
+ ...getApiKeyMeta(),
503
+ ...options
504
+ });
505
+ };
506
+
507
+ // src/api/create.ts
508
+ var postCreateContent2 = async (body, options) => {
509
+ return await postCreateContent({
510
+ ...options,
511
+ body,
512
+ ...getApiKeyMeta()
513
+ });
514
+ };
515
+
516
+ // src/api/social.ts
517
+ var getProfileBySocialHandle2 = async (query, options) => {
518
+ return await getProfileBySocialHandle({
519
+ ...options,
520
+ query,
521
+ ...getApiKeyMeta()
522
+ });
523
+ };
524
+
525
+ // src/metadata/cleanAndValidateMetadataURI.ts
526
+ function cleanAndValidateMetadataURI(uri) {
527
+ if (uri.startsWith("ipfs://")) {
528
+ return uri.replace(
529
+ "ipfs://",
530
+ "https://magic.decentralized-content.com/ipfs/"
531
+ );
532
+ }
533
+ if (uri.startsWith("ar://")) {
534
+ return uri.replace("ar://", "http://arweave.net/");
535
+ }
536
+ if (uri.startsWith("data:")) {
537
+ return uri;
538
+ }
539
+ if (uri.startsWith("http://") || uri.startsWith("https://")) {
540
+ return uri;
541
+ }
542
+ throw new Error("Invalid metadata URI");
543
+ }
544
+
545
+ // src/metadata/validateMetadataJSON.ts
546
+ function validateURIString(uri) {
547
+ if (typeof uri !== "string") {
548
+ throw new Error("URI must be a string");
549
+ }
550
+ if (uri.startsWith("ipfs://")) {
551
+ return true;
552
+ }
553
+ if (uri.startsWith("ar://")) {
554
+ return true;
555
+ }
556
+ if (uri.startsWith("https://")) {
557
+ return true;
558
+ }
559
+ if (uri.startsWith("data:")) {
560
+ return true;
561
+ }
562
+ return false;
563
+ }
564
+ function validateMetadataJSON(metadata) {
565
+ if (typeof metadata !== "object" || !metadata) {
566
+ throw new Error("Metadata must be an object and exist");
567
+ }
568
+ if (typeof metadata.name !== "string") {
569
+ throw new Error("Metadata name is required and must be a string");
570
+ }
571
+ if (typeof metadata.description !== "string") {
572
+ throw new Error("Metadata description is required and must be a string");
573
+ }
574
+ if (typeof metadata.image === "string") {
575
+ if (!validateURIString(metadata.image)) {
576
+ throw new Error("Metadata image is not a valid URI");
577
+ }
578
+ } else {
579
+ throw new Error("Metadata image is required and must be a string");
580
+ }
581
+ if ("animation_url" in metadata) {
582
+ if (typeof metadata.animation_url !== "string") {
583
+ throw new Error("Metadata animation_url, if provided, must be a string");
584
+ }
585
+ if (!validateURIString(metadata.animation_url)) {
586
+ throw new Error("Metadata animation_url is not a valid URI");
587
+ }
588
+ }
589
+ const content = "content" in metadata && metadata.content;
590
+ if (content) {
591
+ if (typeof content.uri !== "string") {
592
+ throw new Error("If provided, content.uri must be a string");
593
+ }
594
+ if (!validateURIString(content.uri)) {
595
+ throw new Error("If provided, content.uri must be a valid URI string");
596
+ }
597
+ if (typeof content.mime !== "string") {
598
+ throw new Error("If provided, content.mime must be a string");
599
+ }
600
+ }
601
+ return true;
602
+ }
603
+
604
+ // src/metadata/validateMetadataURIContent.ts
605
+ async function validateMetadataURIContent(metadataURI) {
606
+ let response;
607
+ const cleanedURI = cleanAndValidateMetadataURI(metadataURI);
608
+ try {
609
+ response = await fetch(cleanedURI);
610
+ } catch (error) {
611
+ const errorMessage = error instanceof Error ? error.message : String(error);
612
+ throw new Error(
613
+ `Metadata fetch failed for URL '${cleanedURI}': ${errorMessage}`
614
+ );
615
+ }
616
+ if (!response.ok) {
617
+ throw new Error(
618
+ `Metadata fetch failed for URL '${cleanedURI}': ${response.statusText ? `${response.statusText} (HTTP ${response.status})` : `HTTP ${response.status}`}`
619
+ );
620
+ }
621
+ if (!["application/json", "text/plain"].includes(
622
+ _nullishCoalesce(response.headers.get("content-type"), () => ( ""))
623
+ )) {
624
+ throw new Error("Metadata is not a valid JSON or plain text response type");
625
+ }
626
+ const metadataJson = await response.json();
627
+ return validateMetadataJSON(metadataJson);
628
+ }
629
+
630
+ // src/utils/calls.ts
631
+
632
+
633
+
577
634
 
578
- // src/api/create.ts
579
- var postCreateContent2 = async (body, options) => {
580
- return await postCreateContent({
581
- ...options,
582
- body,
583
- ...getApiKeyMeta()
584
- });
635
+ var EMPTY_HEX = "0x";
636
+ var isContractCall = (call) => {
637
+ return call.address !== void 0 && call.abi !== void 0 && call.functionName !== void 0;
638
+ };
639
+ var isSendCall = (call) => {
640
+ return !isContractCall(call) && call.to !== void 0;
585
641
  };
642
+ function toGenericCall(call) {
643
+ if (isSendCall(call)) {
644
+ return {
645
+ to: call.to,
646
+ value: _nullishCoalesce(call.value, () => ( 0n)),
647
+ data: EMPTY_HEX
648
+ };
649
+ }
650
+ const { dataSuffix } = call;
651
+ const callData = _viem.encodeFunctionData.call(void 0, call);
652
+ const data = dataSuffix ? _viem.concatHex.call(void 0, [callData, dataSuffix]) : callData;
653
+ return {
654
+ to: call.address,
655
+ value: _nullishCoalesce(call.value, () => ( 0n)),
656
+ data
657
+ };
658
+ }
659
+ function toUserOperationCalls(calls) {
660
+ return calls.map((call) => ({
661
+ to: call.to,
662
+ data: call.data,
663
+ value: call.value
664
+ }));
665
+ }
666
+
667
+ // src/utils/getChainFromId.ts
668
+
669
+ function getChainFromId(chainId) {
670
+ if (chainId === _chains.base.id) {
671
+ return _chains.base;
672
+ }
673
+ if (chainId === _chains.baseSepolia.id) {
674
+ return _chains.baseSepolia;
675
+ }
676
+ throw new Error(`Chain ID ${chainId} not supported`);
677
+ }
586
678
 
587
679
  // src/utils/rethrowDecodedRevert.ts
588
680
 
@@ -607,9 +699,9 @@ function rethrowDecodedRevert(err, abi) {
607
699
  const message = Array.isArray(args) && args.length > 0 ? `${name}(${args.map((a) => String(a)).join(", ")})` : name;
608
700
  throw new Error(`Create coin transaction reverted: ${message}`);
609
701
  } catch (e2) {
610
- const errorName = _optionalChain([revertError, 'access', _12 => _12.data, 'optionalAccess', _13 => _13.errorName]);
702
+ const errorName = _optionalChain([revertError, 'access', _10 => _10.data, 'optionalAccess', _11 => _11.errorName]);
611
703
  if (errorName) {
612
- const args = _optionalChain([revertError, 'access', _14 => _14.data, 'optionalAccess', _15 => _15.args]);
704
+ const args = _optionalChain([revertError, 'access', _12 => _12.data, 'optionalAccess', _13 => _13.args]);
613
705
  const message = Array.isArray(args) && args.length > 0 ? `${errorName}(${args.map((a) => String(a)).join(", ")})` : errorName;
614
706
  throw new Error(`Create coin transaction reverted: ${message}`);
615
707
  }
@@ -619,6 +711,89 @@ function rethrowDecodedRevert(err, abi) {
619
711
  throw err;
620
712
  }
621
713
 
714
+ // src/utils/userOperation.ts
715
+
716
+ var prepareUserOperation = async ({
717
+ bundlerClient,
718
+ account,
719
+ calls
720
+ }) => {
721
+ const prepared = await bundlerClient.prepareUserOperation({
722
+ account,
723
+ calls
724
+ });
725
+ return prepared;
726
+ };
727
+ var submitUserOperation = async ({
728
+ bundlerClient,
729
+ account,
730
+ userOperation
731
+ }) => {
732
+ let hash;
733
+ const signature = await account.signUserOperation(userOperation);
734
+ try {
735
+ hash = await bundlerClient.sendUserOperation({
736
+ account,
737
+ ...userOperation,
738
+ signature
739
+ });
740
+ } catch (error) {
741
+ if (isGasError(error)) {
742
+ throw new CoinbaseGasError(error);
743
+ }
744
+ throw error;
745
+ }
746
+ return bundlerClient.waitForUserOperationReceipt({ hash });
747
+ };
748
+ var CoinbaseGasError = class extends Error {
749
+ constructor(error) {
750
+ let message;
751
+ let available;
752
+ let required;
753
+ const match = error.details.match(
754
+ /precheck failed: sender balance and deposit together is (\d+)? but must be at least (\d+)? to pay for this operation/
755
+ );
756
+ if (match) {
757
+ available = match[1] ? BigInt(match[1]) : void 0;
758
+ required = match[2] ? BigInt(match[2]) : void 0;
759
+ if (available !== void 0 && required !== void 0) {
760
+ message = `Insufficient balance. You need at least ${_viem.formatEther.call(void 0, required)} ETH to pay for this operation, but you only have ${_viem.formatEther.call(void 0, available)} ETH.`;
761
+ } else if (required !== void 0) {
762
+ message = `Insufficient balance. Make sure you have at least ${_viem.formatEther.call(void 0, required)} ETH in your wallet.`;
763
+ } else {
764
+ message = `Insufficient balance. Make sure you have enough ETH to pay for this operation.`;
765
+ }
766
+ } else {
767
+ message = _nullishCoalesce(error.details, () => ( error.message));
768
+ }
769
+ super(message);
770
+ this.cause = error.cause;
771
+ this.details = error.details;
772
+ this.available = available;
773
+ this.required = required;
774
+ }
775
+ };
776
+ function isGasError(error) {
777
+ return _nullishCoalesce(_optionalChain([error, 'access', _14 => _14.details, 'optionalAccess', _15 => _15.startsWith, 'call', _16 => _16(
778
+ "precheck failed: sender balance and deposit together is"
779
+ )]), () => ( false));
780
+ }
781
+
782
+ // src/utils/validateClientNetwork.ts
783
+
784
+ var validateClientNetwork = (publicClient) => {
785
+ const clientChainId = _optionalChain([publicClient, 'optionalAccess', _17 => _17.chain, 'optionalAccess', _18 => _18.id]);
786
+ if (clientChainId === _chains.base.id) {
787
+ return;
788
+ }
789
+ if (clientChainId === _chains.baseSepolia.id) {
790
+ return;
791
+ }
792
+ throw new Error(
793
+ "Client network needs to be base or baseSepolia for current coin deployments."
794
+ );
795
+ };
796
+
622
797
  // src/actions/createCoin.ts
623
798
  var STARTING_MARKET_CAPS = {
624
799
  LOW: "LOW",
@@ -644,7 +819,8 @@ async function createCoinCall({
644
819
  payoutRecipientOverride,
645
820
  additionalOwners,
646
821
  platformReferrer,
647
- skipMetadataValidation = false
822
+ skipMetadataValidation = false,
823
+ enableSmartWalletRouting
648
824
  }) {
649
825
  if (!skipMetadataValidation) {
650
826
  await validateMetadataURIContent(metadata.uri);
@@ -658,9 +834,10 @@ async function createCoinCall({
658
834
  symbol,
659
835
  platformReferrer,
660
836
  additionalOwners,
661
- payoutRecipientOverride
837
+ payoutRecipientOverride,
838
+ enableSmartWalletRouting
662
839
  });
663
- if (!_optionalChain([createContentRequest, 'access', _16 => _16.data, 'optionalAccess', _17 => _17.calls])) {
840
+ if (!_optionalChain([createContentRequest, 'access', _19 => _19.data, 'optionalAccess', _20 => _20.calls])) {
664
841
  throw new Error("Failed to create content calldata");
665
842
  }
666
843
  return {
@@ -669,36 +846,19 @@ async function createCoinCall({
669
846
  data: data.data,
670
847
  value: BigInt(data.value)
671
848
  })),
672
- predictedCoinAddress: createContentRequest.data.predictedCoinAddress
849
+ predictedCoinAddress: createContentRequest.data.predictedCoinAddress,
850
+ usedSmartWalletRouting: createContentRequest.data.usedSmartWalletRouting
673
851
  };
674
852
  }
675
- function getCoinCreateFromLogs(receipt) {
676
- const eventLogs = _viem.parseEventLogs.call(void 0, {
677
- abi: _protocoldeployments.coinFactoryABI,
678
- logs: receipt.logs
679
- });
680
- return _optionalChain([eventLogs, 'access', _18 => _18.find, 'call', _19 => _19((log) => log.eventName === "CoinCreatedV4"), 'optionalAccess', _20 => _20.args]);
681
- }
682
- async function createCoin({
683
- call,
684
- walletClient,
685
- publicClient,
686
- options
687
- }) {
688
- validateClientNetwork(publicClient);
689
- const chainId = _nullishCoalesce(call.chainId, () => ( publicClient.chain.id));
690
- const callRequest = await createCoinCall({
691
- ...call,
692
- chainId
693
- });
694
- if (callRequest.calls.length !== 1) {
853
+ function validateCreateCoinCalls(calls, chainId) {
854
+ if (calls.length !== 1) {
695
855
  throw new Error("Only one call is supported for this SDK version");
696
856
  }
697
- const createContentCall = callRequest.calls[0];
857
+ const createContentCall = calls[0];
698
858
  if (!createContentCall) {
699
859
  throw new Error("Failed to load create content calldata from API");
700
860
  }
701
- const coinFactoryAddressForChain = _protocoldeployments.coinFactoryAddress[call.chainId];
861
+ const coinFactoryAddressForChain = _protocoldeployments.coinFactoryAddress[chainId];
702
862
  if (!_viem.isAddressEqual.call(void 0, createContentCall.to, coinFactoryAddressForChain)) {
703
863
  throw new Error("Creator coin is not supported for this SDK version");
704
864
  }
@@ -707,22 +867,87 @@ async function createCoin({
707
867
  "Creator coin and purchase is not supported for this SDK version."
708
868
  );
709
869
  }
710
- const selectedAccount = _nullishCoalesce((typeof _optionalChain([options, 'optionalAccess', _21 => _21.account]) === "string" ? void 0 : _optionalChain([options, 'optionalAccess', _22 => _22.account])), () => ( walletClient.account));
711
- if (!selectedAccount) {
870
+ }
871
+ function validateCreateCoinSmartWalletCalls(calls, { usedSmartWalletRouting }) {
872
+ if (!usedSmartWalletRouting) {
873
+ throw new Error(
874
+ "Smart wallet routing was not applied. The creator must have a linked smart wallet; otherwise use createCoin for EOA creation."
875
+ );
876
+ }
877
+ if (calls.length !== 1) {
878
+ throw new Error("Only one call is supported for this SDK version");
879
+ }
880
+ const createContentCall = calls[0];
881
+ if (!createContentCall) {
882
+ throw new Error("Failed to load create content calldata from API");
883
+ }
884
+ if (createContentCall.value !== 0n) {
885
+ throw new Error(
886
+ "Creator coin and purchase is not supported for this SDK version."
887
+ );
888
+ }
889
+ }
890
+ function getCoinCreateFromLogs(receipt) {
891
+ const eventLogs = _viem.parseEventLogs.call(void 0, {
892
+ abi: _protocoldeployments.coinFactoryABI,
893
+ logs: receipt.logs
894
+ });
895
+ return _optionalChain([eventLogs, 'access', _21 => _21.find, 'call', _22 => _22((log) => log.eventName === "CoinCreatedV4"), 'optionalAccess', _23 => _23.args]);
896
+ }
897
+ var coinbaseSmartWalletExecuteABI = [
898
+ {
899
+ type: "function",
900
+ name: "execute",
901
+ stateMutability: "payable",
902
+ inputs: [
903
+ { name: "target", type: "address" },
904
+ { name: "value", type: "uint256" },
905
+ { name: "data", type: "bytes" }
906
+ ],
907
+ outputs: []
908
+ }
909
+ ];
910
+ function unwrapSmartWalletExecuteCall(call) {
911
+ let decoded;
912
+ try {
913
+ decoded = _viem.decodeFunctionData.call(void 0, {
914
+ abi: coinbaseSmartWalletExecuteABI,
915
+ data: call.data
916
+ });
917
+ } catch (e3) {
918
+ throw new Error(
919
+ "Expected a smart wallet `execute` call from smart wallet routing, but the routed call could not be decoded."
920
+ );
921
+ }
922
+ const [target, value, data] = decoded.args;
923
+ return { to: target, value, data };
924
+ }
925
+ function selectExecutionAccount(walletClient, account) {
926
+ const selected = _nullishCoalesce((typeof account === "string" ? void 0 : account), () => ( walletClient.account));
927
+ if (!selected) {
712
928
  throw new Error("Account is required");
713
929
  }
930
+ return selected;
931
+ }
932
+ async function executeCreateContentCall({
933
+ createContentCall,
934
+ account,
935
+ walletClient,
936
+ publicClient,
937
+ skipValidateTransaction
938
+ }) {
714
939
  const viemCall = {
715
940
  ...createContentCall,
716
- account: selectedAccount
941
+ account
717
942
  };
718
- if (!_optionalChain([options, 'optionalAccess', _23 => _23.skipValidateTransaction])) {
943
+ if (!skipValidateTransaction) {
719
944
  try {
720
945
  await publicClient.call(viemCall);
721
946
  } catch (err) {
722
947
  rethrowDecodedRevert(err, _protocoldeployments.coinFactoryABI);
723
948
  }
724
949
  }
725
- const gasEstimate = _optionalChain([options, 'optionalAccess', _24 => _24.skipValidateTransaction]) ? 10000000n : await publicClient.estimateGas(viemCall);
950
+ const gasEstimate = skipValidateTransaction ? 10000000n : await publicClient.estimateGas(viemCall);
726
951
  const gasPrice = await publicClient.getGasPrice();
727
952
  const hash = await (async () => {
728
953
  try {
@@ -743,7 +968,78 @@ async function createCoin({
743
968
  return {
744
969
  hash,
745
970
  receipt,
746
- address: _optionalChain([deployment, 'optionalAccess', _25 => _25.coin]),
971
+ address: _optionalChain([deployment, 'optionalAccess', _24 => _24.coin]),
972
+ deployment,
973
+ chain: getChainFromId(publicClient.chain.id)
974
+ };
975
+ }
976
+ async function createCoin({
977
+ call,
978
+ walletClient,
979
+ publicClient,
980
+ options
981
+ }) {
982
+ validateClientNetwork(publicClient);
983
+ const chainId = _nullishCoalesce(call.chainId, () => ( publicClient.chain.id));
984
+ const { calls } = await createCoinCall({
985
+ ...call,
986
+ chainId
987
+ });
988
+ validateCreateCoinCalls(calls, chainId);
989
+ const createContentCall = calls[0];
990
+ const account = selectExecutionAccount(walletClient, _optionalChain([options, 'optionalAccess', _25 => _25.account]));
991
+ return executeCreateContentCall({
992
+ createContentCall,
993
+ account,
994
+ walletClient,
995
+ publicClient,
996
+ skipValidateTransaction: _optionalChain([options, 'optionalAccess', _26 => _26.skipValidateTransaction])
997
+ });
998
+ }
999
+ async function createCoinSmartWallet({
1000
+ call,
1001
+ bundlerClient,
1002
+ publicClient
1003
+ }) {
1004
+ validateClientNetwork(publicClient);
1005
+ const account = bundlerClient.account;
1006
+ if (!account) {
1007
+ throw new Error("Account is required: the bundler client has no account");
1008
+ }
1009
+ const chainId = _nullishCoalesce(call.chainId, () => ( publicClient.chain.id));
1010
+ const { calls, usedSmartWalletRouting } = await createCoinCall({
1011
+ ...call,
1012
+ chainId,
1013
+ enableSmartWalletRouting: true
1014
+ });
1015
+ validateCreateCoinSmartWalletCalls(calls, { usedSmartWalletRouting });
1016
+ const innerCall = unwrapSmartWalletExecuteCall(calls[0]);
1017
+ const userOperation = await prepareUserOperation({
1018
+ bundlerClient,
1019
+ account,
1020
+ calls: toUserOperationCalls([innerCall])
1021
+ });
1022
+ const userOpReceipt = await submitUserOperation({
1023
+ bundlerClient,
1024
+ account,
1025
+ userOperation
1026
+ });
1027
+ if (!userOpReceipt.success) {
1028
+ throw new Error(
1029
+ `User operation reverted${userOpReceipt.reason ? `: ${userOpReceipt.reason}` : ""}`
1030
+ );
1031
+ }
1032
+ const eventLogs = _viem.parseEventLogs.call(void 0, {
1033
+ abi: _protocoldeployments.coinFactoryABI,
1034
+ logs: userOpReceipt.logs
1035
+ });
1036
+ const deployment = _optionalChain([eventLogs, 'access', _27 => _27.find, 'call', _28 => _28(
1037
+ (log) => log.eventName === "CoinCreatedV4"
1038
+ ), 'optionalAccess', _29 => _29.args]);
1039
+ return {
1040
+ hash: userOpReceipt.receipt.transactionHash,
1041
+ receipt: userOpReceipt.receipt,
1042
+ address: _optionalChain([deployment, 'optionalAccess', _30 => _30.coin]),
747
1043
  deployment,
748
1044
  chain: getChainFromId(publicClient.chain.id)
749
1045
  };
@@ -763,13 +1059,14 @@ function getAttribution() {
763
1059
  }
764
1060
 
765
1061
  // src/actions/updateCoinURI.ts
766
- function updateCoinURICall({
767
- newURI,
768
- coin
769
- }) {
1062
+ function validateUpdateCoinURI({ newURI }) {
770
1063
  if (!newURI.startsWith("ipfs://")) {
771
1064
  throw new Error("URI needs to be an ipfs:// prefix uri");
772
1065
  }
1066
+ }
1067
+ function updateCoinURICall(args) {
1068
+ validateUpdateCoinURI(args);
1069
+ const { coin, newURI } = args;
773
1070
  return {
774
1071
  abi: _protocoldeployments.coinABI,
775
1072
  address: coin,
@@ -793,16 +1090,56 @@ async function updateCoinURI(args, walletClient, publicClient, account) {
793
1090
  );
794
1091
  return { hash, receipt, uriUpdated };
795
1092
  }
1093
+ async function updateCoinURISmartWallet(args, bundlerClient, publicClient, account) {
1094
+ const resolvedAccount = _nullishCoalesce(account, () => ( bundlerClient.account));
1095
+ if (!resolvedAccount) {
1096
+ throw new Error("Account is required");
1097
+ }
1098
+ validateClientNetwork(publicClient);
1099
+ const call = updateCoinURICall(args);
1100
+ const calls = toUserOperationCalls([toGenericCall(call)]);
1101
+ const userOp = await prepareUserOperation({
1102
+ bundlerClient,
1103
+ account: resolvedAccount,
1104
+ calls
1105
+ });
1106
+ const userOpReceipt = await submitUserOperation({
1107
+ bundlerClient,
1108
+ account: resolvedAccount,
1109
+ userOperation: userOp
1110
+ });
1111
+ if (!userOpReceipt.success) {
1112
+ throw new Error(
1113
+ `User operation reverted${userOpReceipt.reason ? `: ${userOpReceipt.reason}` : ""}`
1114
+ );
1115
+ }
1116
+ const eventLogs = _viem.parseEventLogs.call(void 0, { abi: _protocoldeployments.coinABI, logs: userOpReceipt.logs });
1117
+ const uriUpdated = eventLogs.find(
1118
+ (log) => log.eventName === "ContractURIUpdated"
1119
+ );
1120
+ return {
1121
+ hash: userOpReceipt.receipt.transactionHash,
1122
+ receipt: userOpReceipt.receipt,
1123
+ uriUpdated
1124
+ };
1125
+ }
796
1126
 
797
1127
  // src/actions/updatePayoutRecipient.ts
798
1128
 
799
1129
 
800
1130
 
801
1131
 
802
- function updatePayoutRecipientCall({
803
- newPayoutRecipient,
804
- coin
1132
+
1133
+ function validateUpdatePayoutRecipient({
1134
+ newPayoutRecipient
805
1135
  }) {
1136
+ if (!_viem.isAddress.call(void 0, newPayoutRecipient)) {
1137
+ throw new Error("Payout recipient must be a valid address");
1138
+ }
1139
+ }
1140
+ function updatePayoutRecipientCall(args) {
1141
+ validateUpdatePayoutRecipient(args);
1142
+ const { coin, newPayoutRecipient } = args;
806
1143
  return {
807
1144
  abi: _protocoldeployments.coinABI,
808
1145
  address: coin,
@@ -826,6 +1163,39 @@ async function updatePayoutRecipient(args, walletClient, publicClient, account)
826
1163
  );
827
1164
  return { hash, receipt, payoutRecipientUpdated };
828
1165
  }
1166
+ async function updatePayoutRecipientSmartWallet(args, bundlerClient, publicClient, account) {
1167
+ const resolvedAccount = _nullishCoalesce(account, () => ( bundlerClient.account));
1168
+ if (!resolvedAccount) {
1169
+ throw new Error("Account is required");
1170
+ }
1171
+ validateClientNetwork(publicClient);
1172
+ const call = updatePayoutRecipientCall(args);
1173
+ const calls = toUserOperationCalls([toGenericCall(call)]);
1174
+ const userOp = await prepareUserOperation({
1175
+ bundlerClient,
1176
+ account: resolvedAccount,
1177
+ calls
1178
+ });
1179
+ const userOpReceipt = await submitUserOperation({
1180
+ bundlerClient,
1181
+ account: resolvedAccount,
1182
+ userOperation: userOp
1183
+ });
1184
+ if (!userOpReceipt.success) {
1185
+ throw new Error(
1186
+ `User operation reverted${userOpReceipt.reason ? `: ${userOpReceipt.reason}` : ""}`
1187
+ );
1188
+ }
1189
+ const eventLogs = _viem.parseEventLogs.call(void 0, { abi: _protocoldeployments.coinABI, logs: userOpReceipt.logs });
1190
+ const payoutRecipientUpdated = eventLogs.find(
1191
+ (log) => log.eventName === "CoinPayoutRecipientUpdated"
1192
+ );
1193
+ return {
1194
+ hash: userOpReceipt.receipt.transactionHash,
1195
+ receipt: userOpReceipt.receipt,
1196
+ payoutRecipientUpdated
1197
+ };
1198
+ }
829
1199
 
830
1200
  // src/actions/tradeCoin.ts
831
1201
 
@@ -834,6 +1204,7 @@ async function updatePayoutRecipient(args, walletClient, publicClient, account)
834
1204
 
835
1205
 
836
1206
 
1207
+
837
1208
  function convertBigIntToString(permit) {
838
1209
  return {
839
1210
  ...permit,
@@ -857,6 +1228,73 @@ var PERMIT_SINGLE_TYPES = {
857
1228
  { name: "nonce", type: "uint48" }
858
1229
  ]
859
1230
  };
1231
+ async function resolveTradePermits({
1232
+ quote,
1233
+ owner,
1234
+ publicClient,
1235
+ signTypedData
1236
+ }) {
1237
+ const signatures = [];
1238
+ const approvalCalls = [];
1239
+ if (!quote.permits) {
1240
+ return { signatures, approvalCalls };
1241
+ }
1242
+ for (const permit of quote.permits) {
1243
+ const [, , nonce] = await publicClient.readContract({
1244
+ abi: _protocoldeployments.permit2ABI,
1245
+ address: _protocoldeployments.permit2Address[_chains.base.id],
1246
+ functionName: "allowance",
1247
+ args: [
1248
+ owner,
1249
+ permit.permit.details.token,
1250
+ permit.permit.spender
1251
+ ]
1252
+ });
1253
+ const permitToken = permit.permit.details.token;
1254
+ const allowance = await publicClient.readContract({
1255
+ abi: _viem.erc20Abi,
1256
+ address: permitToken,
1257
+ functionName: "allowance",
1258
+ args: [owner, _protocoldeployments.permit2Address[_chains.base.id]]
1259
+ });
1260
+ if (allowance < BigInt(permit.permit.details.amount)) {
1261
+ approvalCalls.push({
1262
+ to: permitToken,
1263
+ data: _viem.encodeFunctionData.call(void 0, {
1264
+ abi: _viem.erc20Abi,
1265
+ functionName: "approve",
1266
+ args: [_protocoldeployments.permit2Address[_chains.base.id], _viem.maxUint256]
1267
+ }),
1268
+ value: 0n
1269
+ });
1270
+ }
1271
+ const message = {
1272
+ details: {
1273
+ token: permit.permit.details.token,
1274
+ amount: BigInt(permit.permit.details.amount),
1275
+ expiration: Number(permit.permit.details.expiration),
1276
+ nonce
1277
+ },
1278
+ spender: permit.permit.spender,
1279
+ sigDeadline: BigInt(permit.permit.sigDeadline)
1280
+ };
1281
+ const signature = await signTypedData({
1282
+ domain: {
1283
+ name: "Permit2",
1284
+ chainId: _chains.base.id,
1285
+ verifyingContract: _protocoldeployments.permit2Address[_chains.base.id]
1286
+ },
1287
+ primaryType: "PermitSingle",
1288
+ types: PERMIT_SINGLE_TYPES,
1289
+ message
1290
+ });
1291
+ signatures.push({
1292
+ signature,
1293
+ permit: convertBigIntToString(message)
1294
+ });
1295
+ }
1296
+ return { signatures, approvalCalls };
1297
+ }
860
1298
  async function tradeCoin({
861
1299
  tradeParameters,
862
1300
  walletClient,
@@ -871,71 +1309,24 @@ async function tradeCoin({
871
1309
  if (!account) {
872
1310
  throw new Error("Account is required");
873
1311
  }
1312
+ const resolvedAccount = account;
1313
+ const owner = typeof resolvedAccount === "string" ? resolvedAccount : resolvedAccount.address;
874
1314
  if (!tradeParameters.recipient) {
875
- tradeParameters.recipient = typeof account === "string" ? account : account.address;
1315
+ tradeParameters.recipient = owner;
876
1316
  }
877
- const signatures = [];
878
- if (quote.permits) {
879
- for (const permit of quote.permits) {
880
- const [, , nonce] = await publicClient.readContract({
881
- abi: _protocoldeployments.permit2ABI,
882
- address: _protocoldeployments.permit2Address[_chains.base.id],
883
- functionName: "allowance",
884
- args: [
885
- typeof account === "string" ? account : account.address,
886
- permit.permit.details.token,
887
- permit.permit.spender
888
- ]
889
- });
890
- const permitToken = permit.permit.details.token;
891
- const allowance = await publicClient.readContract({
892
- abi: _viem.erc20Abi,
893
- address: permitToken,
894
- functionName: "allowance",
895
- args: [
896
- typeof account === "string" ? account : account.address,
897
- _protocoldeployments.permit2Address[_chains.base.id]
898
- ]
899
- });
900
- if (allowance < BigInt(permit.permit.details.amount)) {
901
- const approvalTx = await walletClient.writeContract({
902
- abi: _viem.erc20Abi,
903
- address: permitToken,
904
- functionName: "approve",
905
- chain: _chains.base,
906
- args: [_protocoldeployments.permit2Address[_chains.base.id], _viem.maxUint256],
907
- account
908
- });
909
- await publicClient.waitForTransactionReceipt({
910
- hash: approvalTx
911
- });
912
- }
913
- const message = {
914
- details: {
915
- token: permit.permit.details.token,
916
- amount: BigInt(permit.permit.details.amount),
917
- expiration: Number(permit.permit.details.expiration),
918
- nonce
919
- },
920
- spender: permit.permit.spender,
921
- sigDeadline: BigInt(permit.permit.sigDeadline)
922
- };
923
- const signature = await walletClient.signTypedData({
924
- domain: {
925
- name: "Permit2",
926
- chainId: _chains.base.id,
927
- verifyingContract: _protocoldeployments.permit2Address[_chains.base.id]
928
- },
929
- primaryType: "PermitSingle",
930
- types: PERMIT_SINGLE_TYPES,
931
- message,
932
- account
933
- });
934
- signatures.push({
935
- signature,
936
- permit: convertBigIntToString(message)
937
- });
938
- }
1317
+ const { signatures, approvalCalls } = await resolveTradePermits({
1318
+ quote,
1319
+ owner,
1320
+ publicClient,
1321
+ signTypedData: (typedData) => walletClient.signTypedData({ ...typedData, account: resolvedAccount })
1322
+ });
1323
+ for (const approvalCall of approvalCalls) {
1324
+ const approvalTx = await walletClient.sendTransaction({
1325
+ ...approvalCall,
1326
+ account: resolvedAccount,
1327
+ chain: _chains.base
1328
+ });
1329
+ await publicClient.waitForTransactionReceipt({ hash: approvalTx });
939
1330
  }
940
1331
  const newQuote = await createTradeCall({
941
1332
  ...tradeParameters,
@@ -946,7 +1337,7 @@ async function tradeCoin({
946
1337
  data: newQuote.call.data,
947
1338
  value: BigInt(newQuote.call.value),
948
1339
  chain: _chains.base,
949
- account
1340
+ account: resolvedAccount
950
1341
  };
951
1342
  if (validateTransaction) {
952
1343
  await publicClient.call(call);
@@ -963,13 +1354,69 @@ async function tradeCoin({
963
1354
  });
964
1355
  return receipt;
965
1356
  }
966
- async function createTradeCall(tradeParameters) {
1357
+ async function tradeCoinSmartWallet({
1358
+ tradeParameters,
1359
+ bundlerClient,
1360
+ account,
1361
+ publicClient
1362
+ }) {
1363
+ const resolvedAccount = _nullishCoalesce(account, () => ( bundlerClient.account));
1364
+ if (!resolvedAccount) {
1365
+ throw new Error("Account is required");
1366
+ }
1367
+ const owner = resolvedAccount.address;
1368
+ const params = {
1369
+ ...tradeParameters,
1370
+ sender: owner,
1371
+ recipient: _nullishCoalesce(tradeParameters.recipient, () => ( owner))
1372
+ };
1373
+ const quote = await createTradeCall(params);
1374
+ const { signatures, approvalCalls } = await resolveTradePermits({
1375
+ quote,
1376
+ owner,
1377
+ publicClient,
1378
+ signTypedData: (typedData) => resolvedAccount.signTypedData(typedData)
1379
+ });
1380
+ const newQuote = await createTradeCall({
1381
+ ...params,
1382
+ signatures
1383
+ });
1384
+ const tradeCall = {
1385
+ to: newQuote.call.target,
1386
+ data: newQuote.call.data,
1387
+ value: BigInt(newQuote.call.value)
1388
+ };
1389
+ const calls = toUserOperationCalls([...approvalCalls, tradeCall]);
1390
+ const userOp = await prepareUserOperation({
1391
+ bundlerClient,
1392
+ account: resolvedAccount,
1393
+ calls
1394
+ });
1395
+ const userOpReceipt = await submitUserOperation({
1396
+ bundlerClient,
1397
+ account: resolvedAccount,
1398
+ userOperation: userOp
1399
+ });
1400
+ if (!userOpReceipt.success) {
1401
+ throw new Error(
1402
+ `User operation reverted${userOpReceipt.reason ? `: ${userOpReceipt.reason}` : ""}`
1403
+ );
1404
+ }
1405
+ return userOpReceipt.receipt;
1406
+ }
1407
+ function validateTradeParameters(tradeParameters) {
967
1408
  if (tradeParameters.slippage && tradeParameters.slippage > 1) {
968
1409
  throw new Error("Slippage must be less than 1, max 0.99");
969
1410
  }
970
1411
  if (tradeParameters.amountIn === BigInt(0)) {
971
1412
  throw new Error("Amount in must be greater than 0");
972
1413
  }
1414
+ }
1415
+ async function createTradeCall(tradeParameters) {
1416
+ return createQuote(tradeParameters);
1417
+ }
1418
+ async function createQuote(tradeParameters) {
1419
+ validateTradeParameters(tradeParameters);
973
1420
  const quote = await postQuote({
974
1421
  body: {
975
1422
  tokenIn: tradeParameters.sell,
@@ -985,9 +1432,9 @@ async function createTradeCall(tradeParameters) {
985
1432
  if (!quote.data) {
986
1433
  console.error(quote);
987
1434
  const errorBody = quote.error;
988
- const errorMessage = _optionalChain([errorBody, 'optionalAccess', _26 => _26.error]) || "Quote failed";
1435
+ const errorMessage = _optionalChain([errorBody, 'optionalAccess', _31 => _31.error]) || "Quote failed";
989
1436
  const err = new Error(errorMessage);
990
- err.errorType = _optionalChain([errorBody, 'optionalAccess', _27 => _27.errorType]);
1437
+ err.errorType = _optionalChain([errorBody, 'optionalAccess', _32 => _32.errorType]);
991
1438
  err.errorBody = errorBody;
992
1439
  throw err;
993
1440
  }
@@ -998,6 +1445,12 @@ async function createTradeCall(tradeParameters) {
998
1445
 
999
1446
  var apiGet = (path, data) => client.get({ url: path, query: data, ...getApiKeyMeta() });
1000
1447
  var apiPost = (path, data) => client.post({ url: path, body: data, ...getApiKeyMeta() });
1448
+ var apiUrl = (path) => {
1449
+ const baseUrl = _nullishCoalesce(client.getConfig().baseUrl, () => ( ""));
1450
+ const normalizedBase = baseUrl.replace(/\/+$/, "");
1451
+ const normalizedPath = path.replace(/^\/+/, "");
1452
+ return `${normalizedBase}/${normalizedPath}`;
1453
+ };
1001
1454
  var setApiBaseUrl = (baseUrl) => {
1002
1455
  client.setConfig(_clientfetch.createConfig.call(void 0, { baseUrl }));
1003
1456
  };
@@ -1117,9 +1570,9 @@ var CoinMetadataBuilder = class {
1117
1570
  symbol: this.symbol,
1118
1571
  description: this.description,
1119
1572
  image: this.imageURL.toString(),
1120
- animation_url: _optionalChain([this, 'access', _28 => _28.mediaURL, 'optionalAccess', _29 => _29.toString, 'call', _30 => _30()]),
1573
+ animation_url: _optionalChain([this, 'access', _33 => _33.mediaURL, 'optionalAccess', _34 => _34.toString, 'call', _35 => _35()]),
1121
1574
  content: this.mediaURL ? {
1122
- uri: _optionalChain([this, 'access', _31 => _31.mediaURL, 'optionalAccess', _32 => _32.toString, 'call', _33 => _33()]),
1575
+ uri: _optionalChain([this, 'access', _36 => _36.mediaURL, 'optionalAccess', _37 => _37.toString, 'call', _38 => _38()]),
1123
1576
  mime: this.mediaMimeType
1124
1577
  } : void 0,
1125
1578
  properties: this.properties
@@ -1194,7 +1647,7 @@ var ZoraUploader = class {
1194
1647
  },
1195
1648
  { signal: combinedSignal }
1196
1649
  );
1197
- this.jwtApiKey = _optionalChain([response, 'access', _34 => _34.data, 'optionalAccess', _35 => _35.createUploadJwtFromApiKey]);
1650
+ this.jwtApiKey = _optionalChain([response, 'access', _39 => _39.data, 'optionalAccess', _40 => _40.createUploadJwtFromApiKey]);
1198
1651
  if (!this.jwtApiKey) {
1199
1652
  throw new Error("Failed to create upload JWT");
1200
1653
  }
@@ -1311,5 +1764,26 @@ function createZoraUploaderForCreator(creatorAddress) {
1311
1764
 
1312
1765
 
1313
1766
 
1314
- exports.CoinMetadataBuilder = CoinMetadataBuilder; exports.CreateConstants = CreateConstants; exports.ZoraUploader = ZoraUploader; exports.apiGet = apiGet; exports.apiPost = apiPost; exports.cleanAndValidateMetadataURI = cleanAndValidateMetadataURI; exports.createCoin = createCoin; exports.createCoinCall = createCoinCall; exports.createMetadataBuilder = createMetadataBuilder; exports.createTradeCall = createTradeCall; exports.createZoraUploaderForCreator = createZoraUploaderForCreator; exports.getCoin = getCoin2; exports.getCoinComments = getCoinComments2; exports.getCoinCreateFromLogs = getCoinCreateFromLogs; exports.getCoinHolders = getCoinHolders2; exports.getCoinSwaps = getCoinSwaps2; exports.getCoins = getCoins2; exports.getCoinsLastTraded = getCoinsLastTraded; exports.getCoinsLastTradedUnique = getCoinsLastTradedUnique; exports.getCoinsMostValuable = getCoinsMostValuable; exports.getCoinsNew = getCoinsNew; exports.getCoinsTopGainers = getCoinsTopGainers; exports.getCoinsTopVolume24h = getCoinsTopVolume24h; exports.getContentCoinPoolConfig = getContentCoinPoolConfig2; exports.getCreatorCoinPoolConfig = getCreatorCoinPoolConfig2; exports.getCreatorCoins = getCreatorCoins; exports.getCreatorLivestreamComments = getCreatorLivestreamComments2; exports.getExploreFeaturedCreators = getExploreFeaturedCreators; exports.getExploreFeaturedVideos = getExploreFeaturedVideos; exports.getExploreList = getExploreList; exports.getExploreNewAll = getExploreNewAll; exports.getExploreTopVolumeAll24h = getExploreTopVolumeAll24h; exports.getExploreTopVolumeCreators24h = getExploreTopVolumeCreators24h; exports.getFeaturedCreators = getFeaturedCreators2; exports.getMostValuableAll = getMostValuableAll; exports.getMostValuableCreatorCoins = getMostValuableCreatorCoins; exports.getMostValuableTrends = getMostValuableTrends; exports.getNewTrends = getNewTrends; exports.getProfile = getProfile2; exports.getProfileBalances = getProfileBalances2; exports.getProfileCoins = getProfileCoins2; exports.getProfileSocial = getProfileSocial2; exports.getTokenInfo = getTokenInfo2; exports.getTopVolumeTrends24h = getTopVolumeTrends24h; exports.getTraderLeaderboard = getTraderLeaderboard2; exports.getTrend = getTrend; exports.getTrendingAll = getTrendingAll; exports.getTrendingCreators = getTrendingCreators; exports.getTrendingPosts = getTrendingPosts; exports.getTrendingTrends = getTrendingTrends; exports.getTrends = getTrends; exports.getURLFromUploadResult = getURLFromUploadResult; exports.setApiBaseUrl = setApiBaseUrl; exports.setApiKey = setApiKey; exports.tradeCoin = tradeCoin; exports.updateCoinURI = updateCoinURI; exports.updateCoinURICall = updateCoinURICall; exports.updatePayoutRecipient = updatePayoutRecipient; exports.updatePayoutRecipientCall = updatePayoutRecipientCall; exports.validateImageMimeType = validateImageMimeType; exports.validateMetadataJSON = validateMetadataJSON; exports.validateMetadataURIContent = validateMetadataURIContent;
1767
+
1768
+
1769
+
1770
+
1771
+
1772
+
1773
+
1774
+
1775
+
1776
+
1777
+
1778
+
1779
+
1780
+
1781
+
1782
+
1783
+
1784
+
1785
+
1786
+
1787
+
1788
+ exports.CoinMetadataBuilder = CoinMetadataBuilder; exports.CoinbaseGasError = CoinbaseGasError; exports.CreateConstants = CreateConstants; exports.ZoraUploader = ZoraUploader; exports.apiGet = apiGet; exports.apiPost = apiPost; exports.apiUrl = apiUrl; exports.cleanAndValidateMetadataURI = cleanAndValidateMetadataURI; exports.createCoin = createCoin; exports.createCoinCall = createCoinCall; exports.createCoinSmartWallet = createCoinSmartWallet; exports.createMetadataBuilder = createMetadataBuilder; exports.createQuote = createQuote; exports.createTradeCall = createTradeCall; exports.createZoraUploaderForCreator = createZoraUploaderForCreator; exports.getCoin = getCoin2; exports.getCoinComments = getCoinComments2; exports.getCoinCreateFromLogs = getCoinCreateFromLogs; exports.getCoinHolders = getCoinHolders2; exports.getCoinPriceHistory = getCoinPriceHistory2; exports.getCoinSwaps = getCoinSwaps2; exports.getCoins = getCoins2; exports.getCoinsLastTraded = getCoinsLastTraded; exports.getCoinsLastTradedUnique = getCoinsLastTradedUnique; exports.getCoinsMostValuable = getCoinsMostValuable; exports.getCoinsNew = getCoinsNew; exports.getCoinsTopGainers = getCoinsTopGainers; exports.getCoinsTopVolume24h = getCoinsTopVolume24h; exports.getContentCoinPoolConfig = getContentCoinPoolConfig2; exports.getCreatorCoinPoolConfig = getCreatorCoinPoolConfig2; exports.getCreatorCoins = getCreatorCoins; exports.getCreatorLivestreamComments = getCreatorLivestreamComments2; exports.getExploreFeaturedCreators = getExploreFeaturedCreators; exports.getExploreFeaturedVideos = getExploreFeaturedVideos; exports.getExploreList = getExploreList; exports.getExploreNewAll = getExploreNewAll; exports.getExploreTopVolumeAll24h = getExploreTopVolumeAll24h; exports.getExploreTopVolumeCreators24h = getExploreTopVolumeCreators24h; exports.getFeaturedCreators = getFeaturedCreators2; exports.getMostValuableAll = getMostValuableAll; exports.getMostValuableCreatorCoins = getMostValuableCreatorCoins; exports.getMostValuableTrends = getMostValuableTrends; exports.getNewTrends = getNewTrends; exports.getProfile = getProfile2; exports.getProfileBalances = getProfileBalances2; exports.getProfileBySocialHandle = getProfileBySocialHandle2; exports.getProfileCoins = getProfileCoins2; exports.getProfileSocial = getProfileSocial2; exports.getTokenInfo = getTokenInfo2; exports.getTopVolumeTrends24h = getTopVolumeTrends24h; exports.getTraderLeaderboard = getTraderLeaderboard2; exports.getTrend = getTrend; exports.getTrendingAll = getTrendingAll; exports.getTrendingCreators = getTrendingCreators; exports.getTrendingPosts = getTrendingPosts; exports.getTrendingTrends = getTrendingTrends; exports.getTrends = getTrends; exports.getURLFromUploadResult = getURLFromUploadResult; exports.getWalletTradeActivity = getWalletTradeActivity2; exports.isContractCall = isContractCall; exports.isSendCall = isSendCall; exports.prepareUserOperation = prepareUserOperation; exports.setApiBaseUrl = setApiBaseUrl; exports.setApiKey = setApiKey; exports.submitUserOperation = submitUserOperation; exports.toGenericCall = toGenericCall; exports.toUserOperationCalls = toUserOperationCalls; exports.tradeCoin = tradeCoin; exports.tradeCoinSmartWallet = tradeCoinSmartWallet; exports.updateCoinURI = updateCoinURI; exports.updateCoinURICall = updateCoinURICall; exports.updateCoinURISmartWallet = updateCoinURISmartWallet; exports.updatePayoutRecipient = updatePayoutRecipient; exports.updatePayoutRecipientCall = updatePayoutRecipientCall; exports.updatePayoutRecipientSmartWallet = updatePayoutRecipientSmartWallet; exports.validateCreateCoinCalls = validateCreateCoinCalls; exports.validateCreateCoinSmartWalletCalls = validateCreateCoinSmartWalletCalls; exports.validateImageMimeType = validateImageMimeType; exports.validateMetadataJSON = validateMetadataJSON; exports.validateMetadataURIContent = validateMetadataURIContent; exports.validateTradeParameters = validateTradeParameters; exports.validateUpdateCoinURI = validateUpdateCoinURI; exports.validateUpdatePayoutRecipient = validateUpdatePayoutRecipient;
1315
1789
  //# sourceMappingURL=index.cjs.map