@zoralabs/coins-sdk 0.0.2-sdkalpha.2 → 0.0.2-sdkalpha.4

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 (46) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +448 -18
  3. package/dist/actions/createCoin.d.ts.map +1 -1
  4. package/dist/actions/{getCoinDetails.d.ts → getOnchainCoinDetails.d.ts} +9 -8
  5. package/dist/actions/getOnchainCoinDetails.d.ts.map +1 -0
  6. package/dist/api/api-key.d.ts +9 -0
  7. package/dist/api/api-key.d.ts.map +1 -0
  8. package/dist/api/explore.d.ts +347 -0
  9. package/dist/api/explore.d.ts.map +1 -0
  10. package/dist/api/index.d.ts +4 -0
  11. package/dist/api/index.d.ts.map +1 -0
  12. package/dist/api/queries.d.ts +345 -0
  13. package/dist/api/queries.d.ts.map +1 -0
  14. package/dist/client/client.gen.d.ts +13 -0
  15. package/dist/client/client.gen.d.ts.map +1 -0
  16. package/dist/client/index.d.ts +3 -0
  17. package/dist/client/index.d.ts.map +1 -0
  18. package/dist/client/sdk.gen.d.ts +366 -0
  19. package/dist/client/sdk.gen.d.ts.map +1 -0
  20. package/dist/client/types.gen.d.ts +549 -0
  21. package/dist/client/types.gen.d.ts.map +1 -0
  22. package/dist/index.cjs +185 -33
  23. package/dist/index.cjs.map +1 -1
  24. package/dist/index.d.ts +5 -3
  25. package/dist/index.d.ts.map +1 -1
  26. package/dist/index.js +179 -33
  27. package/dist/index.js.map +1 -1
  28. package/dist/utils/genericPublicClient.d.ts +3 -0
  29. package/dist/utils/genericPublicClient.d.ts.map +1 -0
  30. package/dist/utils/validateClientNetwork.d.ts +1 -1
  31. package/dist/utils/validateClientNetwork.d.ts.map +1 -1
  32. package/package.json +7 -4
  33. package/src/actions/createCoin.ts +5 -0
  34. package/src/actions/{getCoinDetails.ts → getOnchainCoinDetails.ts} +111 -76
  35. package/src/api/api-key.ts +15 -0
  36. package/src/api/explore.ts +55 -0
  37. package/src/api/index.ts +8 -0
  38. package/src/api/queries.ts +60 -0
  39. package/src/client/client.gen.ts +18 -0
  40. package/src/client/index.ts +3 -0
  41. package/src/client/sdk.gen.ts +117 -0
  42. package/src/client/types.gen.ts +580 -0
  43. package/src/index.ts +18 -4
  44. package/src/utils/genericPublicClient.ts +5 -0
  45. package/src/utils/validateClientNetwork.ts +16 -12
  46. package/dist/actions/getCoinDetails.d.ts.map +0 -1
@@ -1,8 +1,17 @@
1
1
  import { coinABI, iUniswapV3PoolABI } from "@zoralabs/coins";
2
- import { SUPERCHAIN_WETH_ADDRESS, USDC_WETH_POOLS_BY_CHAIN } from "src/constants";
2
+ import {
3
+ SUPERCHAIN_WETH_ADDRESS,
4
+ USDC_WETH_POOLS_BY_CHAIN,
5
+ } from "src/constants";
6
+ import { GenericPublicClient } from "src/utils/genericPublicClient";
3
7
  import { validateClientNetwork } from "src/utils/validateClientNetwork";
4
- import { Address, erc20Abi, formatEther, isAddressEqual, PublicClient, zeroAddress } from "viem";
5
-
8
+ import {
9
+ Address,
10
+ erc20Abi,
11
+ formatEther,
12
+ isAddressEqual,
13
+ zeroAddress,
14
+ } from "viem";
6
15
 
7
16
  type Slot0Result = {
8
17
  sqrtPriceX96: bigint;
@@ -15,15 +24,15 @@ type Slot0Result = {
15
24
  };
16
25
 
17
26
  type PricingResult = {
18
- eth: bigint,
19
- usdc: bigint | null,
20
- usdcDecimal: number | null,
21
- ethDecimal: number,
22
- }
27
+ eth: bigint;
28
+ usdc: bigint | null;
29
+ usdcDecimal: number | null;
30
+ ethDecimal: number;
31
+ };
23
32
 
24
33
  /**
25
34
  * Represents the current state of a coin
26
- * @typedef {Object} CoinDetails
35
+ * @typedef {Object} OnchainCoinDetails
27
36
  * @property {bigint} balance - The user's balance of the coin
28
37
  * @property {PricingResult} marketCap - The market cap of the coin
29
38
  * @property {PricingResult} liquidity - The liquidity of the coin
@@ -32,14 +41,14 @@ type PricingResult = {
32
41
  * @property {Address[]} owners - List of owners for the coin
33
42
  * @property {Address} payoutRecipient - The payout recipient address
34
43
  */
35
- export type CoinDetails = {
44
+ export type OnchainCoinDetails = {
36
45
  balance: bigint;
37
46
  marketCap: PricingResult;
38
47
  liquidity: PricingResult;
39
48
  pool: Address;
40
49
  poolState: Slot0Result;
41
- owners: readonly Address[],
42
- payoutRecipient: Address,
50
+ owners: readonly Address[];
51
+ payoutRecipient: Address;
43
52
  };
44
53
 
45
54
  /**
@@ -48,101 +57,118 @@ export type CoinDetails = {
48
57
  * @param {Address} params.coin - The coin contract address
49
58
  * @param {Address} params.user - The user address to check balance for
50
59
  * @param {PublicClient} params.publicClient - The viem public client instance
51
- * @returns {Promise<CoinDetails>} The coin's current state
60
+ * @returns {Promise<OnchainCoinDetails>} The coin's current state
52
61
  */
53
- export async function getCoinDetails({
62
+ export async function getOnchainCoinDetails({
54
63
  coin,
55
64
  user = zeroAddress,
56
65
  publicClient,
57
66
  }: {
58
67
  coin: Address;
59
68
  user?: Address;
60
- publicClient: PublicClient;
61
- }): Promise<CoinDetails> {
69
+ publicClient: GenericPublicClient;
70
+ }): Promise<OnchainCoinDetails> {
62
71
  validateClientNetwork(publicClient);
63
- const [balance, pool, owners, payoutRecipient] = await publicClient.multicall({
72
+ const [balance, pool, owners, payoutRecipient] = await publicClient.multicall(
73
+ {
74
+ contracts: [
75
+ {
76
+ address: coin,
77
+ abi: coinABI,
78
+ functionName: "balanceOf",
79
+ args: [user],
80
+ },
81
+ {
82
+ address: coin,
83
+ abi: coinABI,
84
+ functionName: "poolAddress",
85
+ },
86
+ {
87
+ address: coin,
88
+ abi: coinABI,
89
+ functionName: "owners",
90
+ },
91
+ {
92
+ address: coin,
93
+ abi: coinABI,
94
+ functionName: "payoutRecipient",
95
+ },
96
+ ],
97
+ allowFailure: false,
98
+ },
99
+ );
100
+
101
+ const USDC_WETH_POOL = USDC_WETH_POOLS_BY_CHAIN[publicClient.chain?.id || 0];
102
+
103
+ const [
104
+ coinWethPoolSlot0,
105
+ coinWethPoolToken0,
106
+ coinReservesRaw,
107
+ coinTotalSupply,
108
+ wethReservesRaw,
109
+ usdcWethSlot0,
110
+ ] = await publicClient.multicall({
64
111
  contracts: [
112
+ {
113
+ address: pool,
114
+ abi: iUniswapV3PoolABI,
115
+ functionName: "slot0",
116
+ },
117
+ {
118
+ address: pool,
119
+ abi: iUniswapV3PoolABI,
120
+ functionName: "token0",
121
+ },
65
122
  {
66
123
  address: coin,
67
- abi: coinABI,
124
+ abi: erc20Abi,
68
125
  functionName: "balanceOf",
69
- args: [user],
126
+ args: [pool],
70
127
  },
71
128
  {
72
129
  address: coin,
73
130
  abi: coinABI,
74
- functionName: "poolAddress",
131
+ functionName: "totalSupply",
75
132
  },
76
133
  {
77
- address: coin,
78
- abi: coinABI,
79
- functionName: 'owners',
134
+ address: SUPERCHAIN_WETH_ADDRESS,
135
+ abi: erc20Abi,
136
+ functionName: "balanceOf",
137
+ args: [pool],
80
138
  },
81
139
  {
82
- address: coin,
83
- abi: coinABI,
84
- functionName: 'payoutRecipient',
85
- }
140
+ address: USDC_WETH_POOL ?? coin,
141
+ abi: iUniswapV3PoolABI,
142
+ functionName: "slot0",
143
+ },
86
144
  ],
87
145
  allowFailure: false,
88
146
  });
89
147
 
90
- const USDC_WETH_POOL = USDC_WETH_POOLS_BY_CHAIN[publicClient.chain?.id || 0];
91
-
92
- const [coinWethPoolSlot0, coinWethPoolToken0, coinReservesRaw, coinTotalSupply, wethReservesRaw, usdcWethSlot0] = await publicClient.multicall({
93
- contracts: [{
94
- address: pool,
95
- abi: iUniswapV3PoolABI,
96
- functionName: "slot0",
97
- },
98
- {
99
- address: pool,
100
- abi: iUniswapV3PoolABI,
101
- functionName: 'token0'
102
- }, {
103
- address: coin,
104
- abi: erc20Abi,
105
- functionName: 'balanceOf',
106
- args: [pool],
107
- },
108
- {
109
- address: coin,
110
- abi: coinABI,
111
- functionName: 'totalSupply',
112
- }, {
113
- address: SUPERCHAIN_WETH_ADDRESS,
114
- abi: erc20Abi,
115
- functionName: 'balanceOf',
116
- args: [pool],
117
- }, {
118
- address: USDC_WETH_POOL ?? coin,
119
- abi: iUniswapV3PoolABI,
120
- functionName: 'slot0',
121
- }], allowFailure: false
122
- });
123
-
124
- const wethPriceInUsdc = USDC_WETH_POOL ? uniswapV3SqrtPriceToBigIntScaled(
125
- usdcWethSlot0.sqrtPriceX96,
126
- 18,
127
- 6,
128
- true,
129
- 18
130
- ) : null;
148
+ const wethPriceInUsdc = USDC_WETH_POOL
149
+ ? uniswapV3SqrtPriceToBigIntScaled(
150
+ usdcWethSlot0.sqrtPriceX96,
151
+ 18,
152
+ 6,
153
+ true,
154
+ 18,
155
+ )
156
+ : null;
131
157
 
132
158
  const coinPriceInWeth = uniswapV3SqrtPriceToBigIntScaled(
133
159
  coinWethPoolSlot0.sqrtPriceX96,
134
160
  18,
135
161
  18,
136
162
  isAddressEqual(coinWethPoolToken0, coin),
137
- 18
163
+ 18,
138
164
  );
139
165
 
140
166
  // Divide by 10^18 to remove percision from `coinPriceInWeth` after math since bigint is decimal.
141
- const marketCap = coinPriceInWeth * coinTotalSupply / 10n ** 18n;
167
+ const marketCap = (coinPriceInWeth * coinTotalSupply) / 10n ** 18n;
142
168
 
143
169
  const wethLiquidity = wethReservesRaw;
144
170
  // Divide by 10^18 to remove percision from `coinPriceInWeth` after math since bigint is decimal.
145
- const tokenLiquidity = coinReservesRaw * coinPriceInWeth / 10n ** 18n;
171
+ const tokenLiquidity = (coinReservesRaw * coinPriceInWeth) / 10n ** 18n;
146
172
 
147
173
  return {
148
174
  balance,
@@ -150,14 +176,23 @@ export async function getCoinDetails({
150
176
  owners,
151
177
  payoutRecipient,
152
178
  marketCap: convertEthOutput(marketCap, wethPriceInUsdc),
153
- liquidity: convertEthOutput(wethLiquidity + tokenLiquidity, wethPriceInUsdc),
179
+ liquidity: convertEthOutput(
180
+ wethLiquidity + tokenLiquidity,
181
+ wethPriceInUsdc,
182
+ ),
154
183
  poolState: coinWethPoolSlot0,
155
184
  };
156
185
  }
157
186
 
158
-
159
187
  function convertEthOutput(amountETH: bigint, wethToUsdc: bigint | null) {
160
- return { eth: amountETH, ethDecimal: parseFloat(formatEther(amountETH)), usdc: wethToUsdc ? amountETH * wethToUsdc : null, usdcDecimal: wethToUsdc ? parseFloat(formatEther(amountETH * wethToUsdc / 10n ** 18n)) : null }
188
+ return {
189
+ eth: amountETH,
190
+ ethDecimal: parseFloat(formatEther(amountETH)),
191
+ usdc: wethToUsdc ? amountETH * wethToUsdc : null,
192
+ usdcDecimal: wethToUsdc
193
+ ? parseFloat(formatEther((amountETH * wethToUsdc) / 10n ** 18n))
194
+ : null,
195
+ };
161
196
  }
162
197
 
163
198
  function uniswapV3SqrtPriceToBigIntScaled(
@@ -165,7 +200,7 @@ function uniswapV3SqrtPriceToBigIntScaled(
165
200
  token0Decimals: number,
166
201
  token1Decimals: number,
167
202
  isToken0Coin: boolean,
168
- scaleDecimals: number = 18
203
+ scaleDecimals: number = 18,
169
204
  ): bigint {
170
205
  // (sqrtPrice^2 / 2^192) => ratio
171
206
  // We'll do: ratioScaled = (sqrtPrice^2 * 10^scaleDecimals) / 2^192
@@ -182,7 +217,7 @@ function uniswapV3SqrtPriceToBigIntScaled(
182
217
  if (decimalsDiff > 0n) {
183
218
  ratioScaled *= 10n ** decimalsDiff;
184
219
  } else if (decimalsDiff < 0n) {
185
- ratioScaled /= 10n ** (-decimalsDiff);
220
+ ratioScaled /= 10n ** -decimalsDiff;
186
221
  }
187
222
 
188
223
  if (!isToken0Coin) {
@@ -0,0 +1,15 @@
1
+ let apiKey: string | undefined;
2
+ export function setApiKey(key: string) {
3
+ apiKey = key;
4
+ }
5
+
6
+ export function getApiKeyMeta() {
7
+ if (!apiKey) {
8
+ return {};
9
+ }
10
+ return {
11
+ headers: {
12
+ "api-key": apiKey,
13
+ },
14
+ };
15
+ }
@@ -0,0 +1,55 @@
1
+ import { getExplore as getExploreSDK } from "../client/sdk.gen";
2
+ import type { GetExploreData } from "../client/types.gen";
3
+ import { Options } from "@hey-api/client-fetch";
4
+ import { getApiKeyMeta } from "./api-key";
5
+
6
+ /**
7
+ * The inner type for the explore queries that omits listType.
8
+ * This is used to create the query object for the explore queries.
9
+ */
10
+ type QueryInnerType = {
11
+ query: Omit<GetExploreData["query"], "listType">;
12
+ } & Omit<GetExploreData, "query">;
13
+
14
+ /**
15
+ * Creates an explore query with the specified list type
16
+ */
17
+ const createExploreQuery = <T extends boolean = false>(
18
+ listType: GetExploreData["query"]["listType"],
19
+ options?: Options<QueryInnerType, T>,
20
+ ) =>
21
+ getExploreSDK({
22
+ ...options,
23
+ query: { ...options?.query, listType },
24
+ meta: getApiKeyMeta(),
25
+ });
26
+
27
+ /** Get top gaining coins */
28
+ export const getExploreTopGainers = <T extends boolean = false>(
29
+ options?: Options<QueryInnerType, T>,
30
+ ) => createExploreQuery("TOP_GAINERS", options);
31
+
32
+ /** Get coins with highest 24h volume */
33
+ export const getExploreTopVolume24h = <T extends boolean = false>(
34
+ options?: Options<QueryInnerType, T>,
35
+ ) => createExploreQuery("TOP_VOLUME_24H", options);
36
+
37
+ /** Get most valuable coins */
38
+ export const getExploreMostValuable = <T extends boolean = false>(
39
+ options?: Options<QueryInnerType, T>,
40
+ ) => createExploreQuery("MOST_VALUABLE", options);
41
+
42
+ /** Get newly created coins */
43
+ export const getExploreNew = <T extends boolean = false>(
44
+ options?: Options<QueryInnerType, T>,
45
+ ) => createExploreQuery("NEW", options);
46
+
47
+ /** Get recently traded coins */
48
+ export const getExploreLastTraded = <T extends boolean = false>(
49
+ options?: Options<QueryInnerType, T>,
50
+ ) => createExploreQuery("LAST_TRADED", options);
51
+
52
+ /** Get recently traded unique coins */
53
+ export const getExploreLastTradedUnique = <T extends boolean = false>(
54
+ options?: Options<QueryInnerType, T>,
55
+ ) => createExploreQuery("LAST_TRADED_UNIQUE", options);
@@ -0,0 +1,8 @@
1
+ // Export all of the explore queries
2
+ export * from "./explore";
3
+ // Export all of the queries
4
+ export * from "./queries";
5
+
6
+ // Only export the set function for external use.
7
+ // All other exports are for internal use.
8
+ export { setApiKey } from "./api-key";
@@ -0,0 +1,60 @@
1
+ import {
2
+ GetCoinCommentsData,
3
+ GetCoinData,
4
+ GetProfileData,
5
+ GetProfileOwnedData,
6
+ } from "src/client";
7
+ import {
8
+ getCoin as getCoinSDK,
9
+ getCoins as getCoinsSDK,
10
+ getCoinComments as getCoinCommentsSDK,
11
+ getProfile as getProfileSDK,
12
+ getProfileOwned as getProfileOwnedSDK,
13
+ } from "../client/sdk.gen";
14
+ import { getApiKeyMeta } from "./api-key";
15
+
16
+ export const getCoin = async (query: GetCoinData["query"]) => {
17
+ return await getCoinSDK({
18
+ query,
19
+ meta: getApiKeyMeta(),
20
+ });
21
+ };
22
+
23
+ export const getCoins = async ({
24
+ coinAddresses,
25
+ chainId,
26
+ }: {
27
+ coinAddresses: string[];
28
+ chainId?: number;
29
+ }) => {
30
+ return await getCoinsSDK({
31
+ query: {
32
+ coins: coinAddresses.map((collectionAddress) => ({
33
+ chainId,
34
+ collectionAddress,
35
+ })),
36
+ },
37
+ meta: getApiKeyMeta(),
38
+ });
39
+ };
40
+
41
+ export const getCoinComments = async (query: GetCoinCommentsData["query"]) => {
42
+ return await getCoinCommentsSDK({
43
+ query,
44
+ meta: getApiKeyMeta(),
45
+ });
46
+ };
47
+
48
+ export const getProfile = async (query: GetProfileData["query"]) => {
49
+ return await getProfileSDK({
50
+ query,
51
+ meta: getApiKeyMeta(),
52
+ });
53
+ };
54
+
55
+ export const getProfileOwned = async (query: GetProfileOwnedData["query"]) => {
56
+ return await getProfileOwnedSDK({
57
+ query,
58
+ meta: getApiKeyMeta(),
59
+ });
60
+ };
@@ -0,0 +1,18 @@
1
+ // This file is auto-generated by @hey-api/openapi-ts
2
+
3
+ import type { ClientOptions } from './types.gen';
4
+ import { type Config, type ClientOptions as DefaultClientOptions, createClient, createConfig } from '@hey-api/client-fetch';
5
+
6
+ /**
7
+ * The `createClientConfig()` function will be called on client initialization
8
+ * and the returned object will become the client's initial configuration.
9
+ *
10
+ * You may want to initialize your client this way instead of calling
11
+ * `setConfig()`. This is useful for example if you're using Next.js
12
+ * to ensure your client always has the correct values.
13
+ */
14
+ export type CreateClientConfig<T extends DefaultClientOptions = ClientOptions> = (override?: Config<DefaultClientOptions & T>) => Config<Required<DefaultClientOptions> & T>;
15
+
16
+ export const client = createClient(createConfig<ClientOptions>({
17
+ baseUrl: 'https://api-sdk.zora.engineering/'
18
+ }));
@@ -0,0 +1,3 @@
1
+ // This file is auto-generated by @hey-api/openapi-ts
2
+ export * from './types.gen';
3
+ export * from './sdk.gen';
@@ -0,0 +1,117 @@
1
+ // This file is auto-generated by @hey-api/openapi-ts
2
+
3
+ import type {
4
+ Options as ClientOptions,
5
+ TDataShape,
6
+ Client,
7
+ } from "@hey-api/client-fetch";
8
+ import type {
9
+ GetCoinData,
10
+ GetCoinResponse,
11
+ GetCoinCommentsData,
12
+ GetCoinCommentsResponse,
13
+ GetCoinsData,
14
+ GetCoinsResponse,
15
+ GetExploreData,
16
+ GetExploreResponse,
17
+ GetProfileData,
18
+ GetProfileResponse,
19
+ GetProfileOwnedData,
20
+ GetProfileOwnedResponse,
21
+ } from "./types.gen";
22
+ import { client as _heyApiClient } from "./client.gen";
23
+
24
+ export type Options<
25
+ TData extends TDataShape = TDataShape,
26
+ ThrowOnError extends boolean = boolean,
27
+ > = ClientOptions<TData, ThrowOnError> & {
28
+ /**
29
+ * You can provide a client instance returned by `createClient()` instead of
30
+ * individual options. This might be also useful if you want to implement a
31
+ * custom client.
32
+ */
33
+ client?: Client;
34
+ /**
35
+ * You can pass arbitrary values through the `meta` object. This can be
36
+ * used to access values that aren't defined as part of the SDK function.
37
+ */
38
+ meta?: Record<string, unknown>;
39
+ };
40
+
41
+ export const getCoin = <ThrowOnError extends boolean = false>(
42
+ options: Options<GetCoinData, ThrowOnError>,
43
+ ) => {
44
+ return (options.client ?? _heyApiClient).get<
45
+ GetCoinResponse,
46
+ unknown,
47
+ ThrowOnError
48
+ >({
49
+ url: "/coin",
50
+ ...options,
51
+ });
52
+ };
53
+
54
+ export const getCoinComments = <ThrowOnError extends boolean = false>(
55
+ options: Options<GetCoinCommentsData, ThrowOnError>,
56
+ ) => {
57
+ return (options.client ?? _heyApiClient).get<
58
+ GetCoinCommentsResponse,
59
+ unknown,
60
+ ThrowOnError
61
+ >({
62
+ url: "/coinComments",
63
+ ...options,
64
+ });
65
+ };
66
+
67
+ export const getCoins = <ThrowOnError extends boolean = false>(
68
+ options: Options<GetCoinsData, ThrowOnError>,
69
+ ) => {
70
+ return (options.client ?? _heyApiClient).get<
71
+ GetCoinsResponse,
72
+ unknown,
73
+ ThrowOnError
74
+ >({
75
+ url: "/coins",
76
+ ...options,
77
+ });
78
+ };
79
+
80
+ export const getExplore = <ThrowOnError extends boolean = false>(
81
+ options: Options<GetExploreData, ThrowOnError>,
82
+ ) => {
83
+ return (options.client ?? _heyApiClient).get<
84
+ GetExploreResponse,
85
+ unknown,
86
+ ThrowOnError
87
+ >({
88
+ url: "/explore",
89
+ ...options,
90
+ });
91
+ };
92
+
93
+ export const getProfile = <ThrowOnError extends boolean = false>(
94
+ options: Options<GetProfileData, ThrowOnError>,
95
+ ) => {
96
+ return (options.client ?? _heyApiClient).get<
97
+ GetProfileResponse,
98
+ unknown,
99
+ ThrowOnError
100
+ >({
101
+ url: "/profile",
102
+ ...options,
103
+ });
104
+ };
105
+
106
+ export const getProfileOwned = <ThrowOnError extends boolean = false>(
107
+ options: Options<GetProfileOwnedData, ThrowOnError>,
108
+ ) => {
109
+ return (options.client ?? _heyApiClient).get<
110
+ GetProfileOwnedResponse,
111
+ unknown,
112
+ ThrowOnError
113
+ >({
114
+ url: "/profileOwned",
115
+ ...options,
116
+ });
117
+ };