levr-sdk 0.0.1

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 (179) hide show
  1. package/LICENSE.md +201 -0
  2. package/README.md +711 -0
  3. package/dist/esm/abis/IClankerAirdrop.js +443 -0
  4. package/dist/esm/abis/IClankerHookDynamicFee.js +198 -0
  5. package/dist/esm/abis/IClankerHookStaticFee.js +75 -0
  6. package/dist/esm/abis/IClankerLPLocker.js +402 -0
  7. package/dist/esm/abis/IClankerLpLockerMultiple.js +609 -0
  8. package/dist/esm/abis/IClankerToken.js +421 -0
  9. package/dist/esm/abis/LevrFactory_v1.js +608 -0
  10. package/dist/esm/abis/LevrForwarder_v1.js +622 -0
  11. package/dist/esm/abis/LevrGovernor_v1.js +726 -0
  12. package/dist/esm/abis/LevrStakedToken_v1.js +441 -0
  13. package/dist/esm/abis/LevrStaking_v1.js +607 -0
  14. package/dist/esm/abis/LevrTreasury_v1.js +219 -0
  15. package/dist/esm/abis/Permit2.js +29 -0
  16. package/dist/esm/abis/V4Quoter.js +466 -0
  17. package/dist/esm/abis/WETH9.js +153 -0
  18. package/dist/esm/abis/index.js +23 -0
  19. package/dist/esm/balance.js +72 -0
  20. package/dist/esm/balance.js.map +1 -0
  21. package/dist/esm/build-calldatas-v4.js +98 -0
  22. package/dist/esm/build-calldatas-v4.js.map +1 -0
  23. package/dist/esm/build-clanker-v4.js +128 -0
  24. package/dist/esm/build-clanker-v4.js.map +1 -0
  25. package/dist/esm/client/hook/index.js +36 -0
  26. package/dist/esm/client/hook/index.js.map +1 -0
  27. package/dist/esm/client/hook/use-balance.js +56 -0
  28. package/dist/esm/client/hook/use-balance.js.map +1 -0
  29. package/dist/esm/client/hook/use-clanker.js +57 -0
  30. package/dist/esm/client/hook/use-clanker.js.map +1 -0
  31. package/dist/esm/client/hook/use-deploy.js +16 -0
  32. package/dist/esm/client/hook/use-deploy.js.map +1 -0
  33. package/dist/esm/client/hook/use-fee-receivers.js +54 -0
  34. package/dist/esm/client/hook/use-fee-receivers.js.map +1 -0
  35. package/dist/esm/client/hook/use-governance.js +389 -0
  36. package/dist/esm/client/hook/use-governance.js.map +1 -0
  37. package/dist/esm/client/hook/use-prepare.js +47 -0
  38. package/dist/esm/client/hook/use-prepare.js.map +1 -0
  39. package/dist/esm/client/hook/use-project.js +29 -0
  40. package/dist/esm/client/hook/use-project.js.map +1 -0
  41. package/dist/esm/client/hook/use-projects.js +22 -0
  42. package/dist/esm/client/hook/use-projects.js.map +1 -0
  43. package/dist/esm/client/hook/use-proposals.js +31 -0
  44. package/dist/esm/client/hook/use-proposals.js.map +1 -0
  45. package/dist/esm/client/hook/use-register.js +101 -0
  46. package/dist/esm/client/hook/use-register.js.map +1 -0
  47. package/dist/esm/client/hook/use-stake.js +327 -0
  48. package/dist/esm/client/hook/use-stake.js.map +1 -0
  49. package/dist/esm/client/hook/use-swap.js +110 -0
  50. package/dist/esm/client/hook/use-swap.js.map +1 -0
  51. package/dist/esm/client/index.js +4 -0
  52. package/dist/esm/client/index.js.map +1 -0
  53. package/dist/esm/client/levr-provider.js +201 -0
  54. package/dist/esm/client/levr-provider.js.map +1 -0
  55. package/dist/esm/client/query-keys.js +61 -0
  56. package/dist/esm/client/query-keys.js.map +1 -0
  57. package/dist/esm/constants.js +182 -0
  58. package/dist/esm/constants.js.map +1 -0
  59. package/dist/esm/deploy-v4.js +46 -0
  60. package/dist/esm/deploy-v4.js.map +1 -0
  61. package/dist/esm/fee-receivers.js +52 -0
  62. package/dist/esm/fee-receivers.js.map +1 -0
  63. package/dist/esm/governance.js +555 -0
  64. package/dist/esm/governance.js.map +1 -0
  65. package/dist/esm/index.js +18 -0
  66. package/dist/esm/index.js.map +1 -0
  67. package/dist/esm/project.js +146 -0
  68. package/dist/esm/project.js.map +1 -0
  69. package/dist/esm/projects.js +212 -0
  70. package/dist/esm/projects.js.map +1 -0
  71. package/dist/esm/proposals.js +98 -0
  72. package/dist/esm/proposals.js.map +1 -0
  73. package/dist/esm/quote-v4.js +169 -0
  74. package/dist/esm/quote-v4.js.map +1 -0
  75. package/dist/esm/schema/base.schema.js +11 -0
  76. package/dist/esm/schema/base.schema.js.map +1 -0
  77. package/dist/esm/schema/clanker.schema.js +191 -0
  78. package/dist/esm/schema/clanker.schema.js.map +1 -0
  79. package/dist/esm/schema/index.js +4 -0
  80. package/dist/esm/schema/index.js.map +1 -0
  81. package/dist/esm/schema/levr.schema.js +114 -0
  82. package/dist/esm/schema/levr.schema.js.map +1 -0
  83. package/dist/esm/stake.js +384 -0
  84. package/dist/esm/stake.js.map +1 -0
  85. package/dist/esm/swap-v4.js +281 -0
  86. package/dist/esm/swap-v4.js.map +1 -0
  87. package/dist/esm/types.js +2 -0
  88. package/dist/esm/types.js.map +1 -0
  89. package/dist/esm/util.js +19 -0
  90. package/dist/esm/util.js.map +1 -0
  91. package/dist/types/abis/IClankerAirdrop.d.ts +348 -0
  92. package/dist/types/abis/IClankerHookDynamicFee.d.ts +156 -0
  93. package/dist/types/abis/IClankerHookStaticFee.d.ts +58 -0
  94. package/dist/types/abis/IClankerLPLocker.d.ts +316 -0
  95. package/dist/types/abis/IClankerLpLockerMultiple.d.ts +481 -0
  96. package/dist/types/abis/IClankerToken.d.ts +326 -0
  97. package/dist/types/abis/LevrFactory_v1.d.ts +471 -0
  98. package/dist/types/abis/LevrForwarder_v1.d.ts +478 -0
  99. package/dist/types/abis/LevrGovernor_v1.d.ts +562 -0
  100. package/dist/types/abis/LevrStakedToken_v1.d.ts +338 -0
  101. package/dist/types/abis/LevrStaking_v1.d.ts +468 -0
  102. package/dist/types/abis/LevrTreasury_v1.d.ts +169 -0
  103. package/dist/types/abis/Permit2.d.ts +54 -0
  104. package/dist/types/abis/V4Quoter.d.ts +496 -0
  105. package/dist/types/abis/WETH9.d.ts +244 -0
  106. package/dist/types/abis/index.d.ts +15 -0
  107. package/dist/types/balance.d.ts +24 -0
  108. package/dist/types/balance.d.ts.map +1 -0
  109. package/dist/types/build-calldatas-v4.d.ts +20 -0
  110. package/dist/types/build-calldatas-v4.d.ts.map +1 -0
  111. package/dist/types/build-clanker-v4.d.ts +12 -0
  112. package/dist/types/build-clanker-v4.d.ts.map +1 -0
  113. package/dist/types/client/hook/index.d.ts +32 -0
  114. package/dist/types/client/hook/index.d.ts.map +1 -0
  115. package/dist/types/client/hook/use-balance.d.ts +18 -0
  116. package/dist/types/client/hook/use-balance.d.ts.map +1 -0
  117. package/dist/types/client/hook/use-clanker.d.ts +23 -0
  118. package/dist/types/client/hook/use-clanker.d.ts.map +1 -0
  119. package/dist/types/client/hook/use-deploy.d.ts +45 -0
  120. package/dist/types/client/hook/use-deploy.d.ts.map +1 -0
  121. package/dist/types/client/hook/use-fee-receivers.d.ts +26 -0
  122. package/dist/types/client/hook/use-fee-receivers.d.ts.map +1 -0
  123. package/dist/types/client/hook/use-governance.d.ts +145 -0
  124. package/dist/types/client/hook/use-governance.d.ts.map +1 -0
  125. package/dist/types/client/hook/use-prepare.d.ts +21 -0
  126. package/dist/types/client/hook/use-prepare.d.ts.map +1 -0
  127. package/dist/types/client/hook/use-project.d.ts +11 -0
  128. package/dist/types/client/hook/use-project.d.ts.map +1 -0
  129. package/dist/types/client/hook/use-projects.d.ts +6 -0
  130. package/dist/types/client/hook/use-projects.d.ts.map +1 -0
  131. package/dist/types/client/hook/use-proposals.d.ts +16 -0
  132. package/dist/types/client/hook/use-proposals.d.ts.map +1 -0
  133. package/dist/types/client/hook/use-register.d.ts +31 -0
  134. package/dist/types/client/hook/use-register.d.ts.map +1 -0
  135. package/dist/types/client/hook/use-stake.d.ts +195 -0
  136. package/dist/types/client/hook/use-stake.d.ts.map +1 -0
  137. package/dist/types/client/hook/use-swap.d.ts +59 -0
  138. package/dist/types/client/hook/use-swap.d.ts.map +1 -0
  139. package/dist/types/client/index.d.ts +4 -0
  140. package/dist/types/client/index.d.ts.map +1 -0
  141. package/dist/types/client/levr-provider.d.ts +127 -0
  142. package/dist/types/client/levr-provider.d.ts.map +1 -0
  143. package/dist/types/client/query-keys.d.ts +61 -0
  144. package/dist/types/client/query-keys.d.ts.map +1 -0
  145. package/dist/types/constants.d.ts +101 -0
  146. package/dist/types/constants.d.ts.map +1 -0
  147. package/dist/types/deploy-v4.d.ts +13 -0
  148. package/dist/types/deploy-v4.d.ts.map +1 -0
  149. package/dist/types/fee-receivers.d.ts +29 -0
  150. package/dist/types/fee-receivers.d.ts.map +1 -0
  151. package/dist/types/governance.d.ts +205 -0
  152. package/dist/types/governance.d.ts.map +1 -0
  153. package/dist/types/index.d.ts +18 -0
  154. package/dist/types/index.d.ts.map +1 -0
  155. package/dist/types/project.d.ts +51 -0
  156. package/dist/types/project.d.ts.map +1 -0
  157. package/dist/types/projects.d.ts +20 -0
  158. package/dist/types/projects.d.ts.map +1 -0
  159. package/dist/types/proposals.d.ts +20 -0
  160. package/dist/types/proposals.d.ts.map +1 -0
  161. package/dist/types/quote-v4.d.ts +54 -0
  162. package/dist/types/quote-v4.d.ts.map +1 -0
  163. package/dist/types/schema/base.schema.d.ts +5 -0
  164. package/dist/types/schema/base.schema.d.ts.map +1 -0
  165. package/dist/types/schema/clanker.schema.d.ts +104 -0
  166. package/dist/types/schema/clanker.schema.d.ts.map +1 -0
  167. package/dist/types/schema/index.d.ts +4 -0
  168. package/dist/types/schema/index.d.ts.map +1 -0
  169. package/dist/types/schema/levr.schema.d.ts +34 -0
  170. package/dist/types/schema/levr.schema.d.ts.map +1 -0
  171. package/dist/types/stake.d.ts +137 -0
  172. package/dist/types/stake.d.ts.map +1 -0
  173. package/dist/types/swap-v4.d.ts +97 -0
  174. package/dist/types/swap-v4.d.ts.map +1 -0
  175. package/dist/types/types.d.ts +20 -0
  176. package/dist/types/types.d.ts.map +1 -0
  177. package/dist/types/util.d.ts +5 -0
  178. package/dist/types/util.d.ts.map +1 -0
  179. package/package.json +100 -0
package/README.md ADDED
@@ -0,0 +1,711 @@
1
+ # Levr SDK
2
+
3
+ <div align="center">
4
+
5
+ [![npm latest package][npm-latest-image]][npm-url]
6
+ [![Build Status][ci-image]][ci-url]
7
+ [![License][license-image]][license-url]
8
+ [![npm downloads][npm-downloads-image]][npm-url]
9
+ [![Follow on Twitter][twitter-image]][twitter-url]
10
+
11
+ </div>
12
+
13
+ TypeScript SDK for interacting with Levr protocol - a decentralized governance, staking, and liquidity management system built on Uniswap v4.
14
+
15
+ ## Features
16
+
17
+ - 🎯 **Type-Safe** - Full TypeScript support with comprehensive types
18
+ - 🔄 **Centralized Refetch** - 100% coverage with smart cross-domain awareness
19
+ - ⚡ **Zero Duplication** - Optimized query management via React Context
20
+ - 🪝 **React Hooks** - Easy integration with React applications
21
+ - 🔌 **Server & Client** - Works in both server and client environments
22
+ - 📦 **Tree-Shakeable** - Import only what you need
23
+
24
+ ## Installation
25
+
26
+ ```bash
27
+ npm install levr-sdk
28
+ # or
29
+ bun add levr-sdk
30
+ # or
31
+ yarn add levr-sdk
32
+ ```
33
+
34
+ ## Quick Start
35
+
36
+ ### Client-Side (React) Usage
37
+
38
+ For React applications, use the centralized provider pattern:
39
+
40
+ ```typescript
41
+ // 1. Wrap your app with LevrProvider
42
+ import { LevrProvider } from 'levr-sdk/client'
43
+
44
+ export function App() {
45
+ return (
46
+ <QueryClientProvider client={queryClient}>
47
+ <WagmiConfig config={wagmiConfig}>
48
+ <LevrProvider>
49
+ <YourApp />
50
+ </LevrProvider>
51
+ </WagmiConfig>
52
+ </QueryClientProvider>
53
+ )
54
+ }
55
+
56
+ // 2. Set the active token in your pages
57
+ import { useSetClankerToken, useProject } from 'levr-sdk/client'
58
+
59
+ export function ProjectPage({ clankerToken }: { clankerToken: `0x${string}` }) {
60
+ const setClankerToken = useSetClankerToken()
61
+ const { data: project, isLoading } = useProject()
62
+
63
+ useEffect(() => {
64
+ setClankerToken(clankerToken) // Updates global context
65
+ }, [clankerToken, setClankerToken])
66
+
67
+ if (isLoading) return <div>Loading...</div>
68
+ if (!project) return <div>Project not found</div>
69
+
70
+ return (
71
+ <div>
72
+ <h1>{project.token.name}</h1>
73
+ <StakeComponent />
74
+ <SwapComponent />
75
+ <GovernanceComponent />
76
+ </div>
77
+ )
78
+ }
79
+
80
+ // 3. Use hooks in child components - they automatically share queries!
81
+ import { useStake, useBalance } from 'levr-sdk/client'
82
+
83
+ function StakeComponent() {
84
+ const { data: balances } = useBalance()
85
+ const {
86
+ stake,
87
+ stakedBalance,
88
+ needsApproval,
89
+ } = useStake({
90
+ onStakeSuccess: () => {
91
+ toast.success('Staked successfully!')
92
+ // All related data automatically refetches
93
+ },
94
+ })
95
+
96
+ return (
97
+ <div>
98
+ <p>Balance: {balances?.token?.formatted}</p>
99
+ <p>Staked: {stakedBalance?.formatted}</p>
100
+ <button onClick={() => stake.mutate(amount)}>
101
+ Stake
102
+ </button>
103
+ </div>
104
+ )
105
+ }
106
+ ```
107
+
108
+ ### Server-Side Usage
109
+
110
+ For server-side operations or scripts:
111
+
112
+ ```typescript
113
+ import { project, balance, Stake, Governance } from 'levr-sdk'
114
+ import { createPublicClient, createWalletClient, http } from 'viem'
115
+ import { base } from 'viem/chains'
116
+
117
+ // Initialize clients
118
+ const publicClient = createPublicClient({
119
+ chain: base,
120
+ transport: http(),
121
+ })
122
+
123
+ const walletClient = createWalletClient({
124
+ chain: base,
125
+ transport: http(),
126
+ account: privateKeyToAccount('0x...'),
127
+ })
128
+
129
+ // Get project data
130
+ const projectData = await project({
131
+ publicClient,
132
+ factoryAddress: '0x...',
133
+ chainId: base.id,
134
+ clankerToken: '0x...',
135
+ })
136
+
137
+ // Get balances
138
+ const balances = await balance({
139
+ publicClient,
140
+ address: '0x...',
141
+ tokens: [
142
+ { address: projectData.token.address, decimals: 18, key: 'token' },
143
+ { address: '0x...', decimals: 18, key: 'weth' },
144
+ ],
145
+ })
146
+
147
+ // Stake tokens
148
+ const stake = new Stake({
149
+ wallet: walletClient,
150
+ publicClient,
151
+ stakingAddress: projectData.staking,
152
+ tokenAddress: projectData.token.address,
153
+ tokenDecimals: 18,
154
+ trustedForwarder: projectData.forwarder,
155
+ })
156
+
157
+ // Approve and stake
158
+ await stake.approve(1000)
159
+ const receipt = await stake.stake(1000)
160
+
161
+ // Governance operations
162
+ const governance = new Governance({
163
+ wallet: walletClient,
164
+ publicClient,
165
+ governorAddress: projectData.governor,
166
+ tokenDecimals: 18,
167
+ clankerToken: projectData.token.address,
168
+ })
169
+
170
+ // Propose a transfer
171
+ const { receipt, proposalId } = await governance.proposeTransfer(
172
+ '0x...', // recipient
173
+ parseUnits('1000', 18), // amount
174
+ 'Fund development' // description
175
+ )
176
+ ```
177
+
178
+ ## Available Hooks (Client)
179
+
180
+ ### Simple Query Hooks
181
+
182
+ Direct context accessors for read-only data:
183
+
184
+ ```typescript
185
+ import {
186
+ useProject, // Project data (token, contracts, pool info)
187
+ useBalance, // Token balances (token, WETH, ETH)
188
+ useProposals, // Proposals list
189
+ useClankerToken, // Token metadata (admin, image, etc.)
190
+ } from 'levr-sdk/client'
191
+
192
+ const { data: project } = useProject()
193
+ const { data: balances } = useBalance()
194
+ const { data: proposals } = useProposals()
195
+ const { data: tokenData } = useClankerToken()
196
+ ```
197
+
198
+ ### Mutation Hooks
199
+
200
+ Hooks with both queries and mutations:
201
+
202
+ ```typescript
203
+ import {
204
+ useStake, // Staking operations
205
+ useSwap, // Swap operations
206
+ useGovernance, // Governance operations
207
+ useFeeReceivers, // Fee receiver management
208
+ } from 'levr-sdk/client'
209
+ ```
210
+
211
+ #### `useStake()`
212
+
213
+ ```typescript
214
+ const {
215
+ // Mutations
216
+ approve,
217
+ stake,
218
+ unstake,
219
+ claim,
220
+ accrueRewards,
221
+ accrueAllRewards,
222
+
223
+ // Queries
224
+ allowance,
225
+ poolData,
226
+ userData,
227
+ balances,
228
+ wethRewardRate,
229
+ aprBpsWeth,
230
+
231
+ // Convenience accessors
232
+ stakedBalance,
233
+ totalStaked,
234
+ tokenBalance,
235
+ needsApproval,
236
+
237
+ // Loading states
238
+ isLoadingPoolData,
239
+ isLoadingUserData,
240
+ } = useStake({
241
+ onStakeSuccess: (receipt) => console.log('Staked!', receipt),
242
+ onUnstakeSuccess: (receipt) => console.log('Unstaked!', receipt),
243
+ onClaimSuccess: (receipt) => console.log('Claimed!', receipt),
244
+ })
245
+
246
+ // Use mutations
247
+ stake.mutate(1000) // Automatically refetches balances, staking data, project
248
+ ```
249
+
250
+ #### `useSwap()`
251
+
252
+ ```typescript
253
+ const {
254
+ // Mutations
255
+ swap,
256
+
257
+ // Queries
258
+ quote,
259
+ balances,
260
+ poolKey,
261
+
262
+ // Convenience
263
+ tokenBalance,
264
+ wethBalance,
265
+ buildSwapConfig,
266
+ } = useSwap({
267
+ quoteParams: {
268
+ zeroForOne: true, // true = token -> WETH, false = WETH -> token
269
+ amountIn: '100',
270
+ amountInDecimals: 18,
271
+ amountOutDecimals: 18,
272
+ },
273
+ onSwapSuccess: (receipt) => console.log('Swapped!', receipt),
274
+ })
275
+
276
+ // Build swap config (poolKey from context)
277
+ const config = buildSwapConfig({
278
+ zeroForOne: true,
279
+ amountIn: 100,
280
+ amountInDecimals: 18,
281
+ minAmountOut: '95',
282
+ })
283
+ ```
284
+
285
+ #### `useGovernance()`
286
+
287
+ ```typescript
288
+ const {
289
+ // Mutations
290
+ proposeTransfer,
291
+ proposeBoost,
292
+ vote,
293
+ executeProposal,
294
+ claimAirdrop,
295
+
296
+ // Queries
297
+ currentCycleId,
298
+ addresses,
299
+ airdropStatus,
300
+ proposal,
301
+
302
+ // Convenience accessors
303
+ treasuryAddress,
304
+ isAirdropAvailable,
305
+
306
+ // Loading states
307
+ isProposing,
308
+ isVoting,
309
+ isExecuting,
310
+ } = useGovernance({
311
+ governorAddress: project.governor,
312
+ clankerToken: project.token.address,
313
+ onVoteSuccess: (receipt) => console.log('Voted!', receipt),
314
+ onExecuteProposalSuccess: (receipt) => console.log('Executed!', receipt),
315
+ })
316
+ ```
317
+
318
+ #### `useFeeReceivers()`
319
+
320
+ ```typescript
321
+ const {
322
+ query, // Fee receivers data
323
+ mutate, // Update mutation
324
+ } = useFeeReceivers({
325
+ onSuccess: (hash) => console.log('Updated fee receiver', hash),
326
+ })
327
+
328
+ // Use mutation
329
+ mutate.mutate({
330
+ clankerToken: '0x...',
331
+ rewardIndex: 0,
332
+ newRecipient: '0x...',
333
+ })
334
+ ```
335
+
336
+ ### Utility Hooks
337
+
338
+ ```typescript
339
+ import {
340
+ useSetClankerToken, // Update global token context
341
+ useLevrRefetch, // Manual refetch control
342
+ useClanker, // Clanker SDK instance
343
+ } from 'levr-sdk/client'
344
+
345
+ // Update active token
346
+ const setClankerToken = useSetClankerToken()
347
+ setClankerToken('0x...')
348
+
349
+ // Manual refetch control
350
+ const refetch = useLevrRefetch()
351
+ await refetch.all() // Refetch everything
352
+ await refetch.staking() // Refetch staking data
353
+ await refetch.afterStake() // Smart cross-domain refetch after stake
354
+
355
+ // Get Clanker SDK instance
356
+ const clanker = useClanker()
357
+ ```
358
+
359
+ ## Centralized Refetch Coverage
360
+
361
+ The SDK provides **100% refetch coverage** with smart cross-domain awareness:
362
+
363
+ | Action | Auto-Refetches |
364
+ | ------------------------ | ----------------------------------------------------------------- |
365
+ | **Stake/Unstake/Claim** | Balances, All Staking Data, Project (treasury), WETH Rewards |
366
+ | **Swap** | Balances, Project (pool data) |
367
+ | **Propose/Vote/Execute** | Governance, Proposals, Project (treasury), Staking (voting power) |
368
+ | **Wallet/Chain Change** | All Queries |
369
+
370
+ All mutations automatically trigger appropriate refetches - no manual coordination needed!
371
+
372
+ ## API Reference
373
+
374
+ ### Server-Side APIs
375
+
376
+ #### `project()`
377
+
378
+ Get project data including token, contracts, and pool information:
379
+
380
+ ```typescript
381
+ import { project } from 'levr-sdk'
382
+
383
+ const projectData = await project({
384
+ publicClient,
385
+ factoryAddress: '0x...',
386
+ chainId: 8453, // Base
387
+ clankerToken: '0x...',
388
+ })
389
+ ```
390
+
391
+ #### `balance()`
392
+
393
+ Get token balances for multiple tokens:
394
+
395
+ ```typescript
396
+ import { balance } from 'levr-sdk'
397
+
398
+ const balances = await balance({
399
+ publicClient,
400
+ address: '0x...',
401
+ tokens: [
402
+ { address: '0x...', decimals: 18, key: 'token' },
403
+ { address: '0x...', decimals: 18, key: 'weth' },
404
+ { address: zeroAddress, decimals: 18, key: 'eth' }, // Native ETH
405
+ ],
406
+ })
407
+
408
+ console.log(balances.token?.formatted) // "1000.0"
409
+ console.log(balances.weth?.formatted) // "5.5"
410
+ console.log(balances.eth?.formatted) // "0.1"
411
+ ```
412
+
413
+ #### `Stake` Class
414
+
415
+ Manage staking operations:
416
+
417
+ ```typescript
418
+ import { Stake } from 'levr-sdk'
419
+
420
+ const stake = new Stake({
421
+ wallet: walletClient,
422
+ publicClient,
423
+ stakingAddress: '0x...',
424
+ tokenAddress: '0x...',
425
+ tokenDecimals: 18,
426
+ trustedForwarder: '0x...',
427
+ })
428
+
429
+ // Get staking data
430
+ const poolData = await stake.getPoolData()
431
+ const userData = await stake.getUserData()
432
+ const allowance = await stake.getAllowance()
433
+
434
+ // Perform operations
435
+ await stake.approve(amount)
436
+ await stake.stake(amount)
437
+ await stake.unstake({ amount, to: '0x...' })
438
+ await stake.claimRewards()
439
+ await stake.accrueRewards(tokenAddress)
440
+ ```
441
+
442
+ #### `Governance` Class
443
+
444
+ Manage governance operations:
445
+
446
+ ```typescript
447
+ import { Governance } from 'levr-sdk'
448
+
449
+ const governance = new Governance({
450
+ wallet: walletClient,
451
+ publicClient,
452
+ governorAddress: '0x...',
453
+ tokenDecimals: 18,
454
+ clankerToken: '0x...',
455
+ })
456
+
457
+ // Get governance data
458
+ const cycleId = await governance.getCurrentCycleId()
459
+ const treasury = await governance.getTreasury()
460
+ const airdropStatus = await governance.getAirdropStatus()
461
+
462
+ // Propose actions
463
+ const { receipt, proposalId } = await governance.proposeTransfer(
464
+ '0x...', // recipient
465
+ parseUnits('1000', 18), // amount
466
+ 'Fund development' // description
467
+ )
468
+
469
+ // Vote on proposals
470
+ await governance.vote(proposalId, true) // true = support
471
+
472
+ // Execute proposals
473
+ await governance.executeProposal(proposalId)
474
+ ```
475
+
476
+ #### `swapV4()` and `quoteV4()`
477
+
478
+ Uniswap v4 swap operations:
479
+
480
+ ```typescript
481
+ import { swapV4, quoteV4 } from 'levr-sdk'
482
+
483
+ // Get swap quote
484
+ const quote = await quoteV4({
485
+ publicClient,
486
+ chainId: 8453,
487
+ poolKey: {
488
+ currency0: '0x...',
489
+ currency1: '0x...',
490
+ fee: 500,
491
+ tickSpacing: 10,
492
+ hooks: '0x...',
493
+ },
494
+ zeroForOne: true,
495
+ amountIn: parseUnits('100', 18),
496
+ })
497
+
498
+ console.log(formatUnits(quote.amountOut, 18)) // "95.5"
499
+
500
+ // Execute swap
501
+ const receipt = await swapV4({
502
+ publicClient,
503
+ wallet: walletClient,
504
+ chainId: 8453,
505
+ poolKey,
506
+ zeroForOne: true,
507
+ amountIn: parseUnits('100', 18),
508
+ amountOutMinimum: parseUnits('95', 18),
509
+ })
510
+ ```
511
+
512
+ ## Architecture: Centralized Provider Pattern
513
+
514
+ The SDK uses a centralized provider pattern that eliminates query duplication and provides 100% refetch coverage:
515
+
516
+ ```
517
+ ┌─────────────────────────────────────────────────┐
518
+ │ LevrProvider (Global) │
519
+ │ │
520
+ │ ┌───────────────────────────────────────────┐ │
521
+ │ │ Centralized Queries (created once) │ │
522
+ │ │ • Project data │ │
523
+ │ │ • Token balances (token + WETH + ETH) │ │
524
+ │ │ • Staking (all queries) │ │
525
+ │ │ • Governance (global queries) │ │
526
+ │ │ • Proposals │ │
527
+ │ │ • Fee receivers │ │
528
+ │ └───────────────────────────────────────────┘ │
529
+ │ │
530
+ │ ┌───────────────────────────────────────────┐ │
531
+ │ │ Smart Refetch Methods │ │
532
+ │ │ • afterStake() → Balances, Staking, etc. │ │
533
+ │ │ • afterSwap() → Balances, Project │ │
534
+ │ │ • afterGovernance() → Gov, Proposals, etc.│ │
535
+ │ └───────────────────────────────────────────┘ │
536
+ └─────────────────────────────────────────────────┘
537
+ ↓ Context shared via hooks
538
+ ┌─────────────────────────────────────────────────┐
539
+ │ Components consume without duplication │
540
+ │ • useProject() → Shared query │
541
+ │ • useBalance() → Shared query │
542
+ │ • useStake() → Shared queries + mutations │
543
+ └─────────────────────────────────────────────────┘
544
+ ```
545
+
546
+ ### Benefits
547
+
548
+ ✅ **Zero Duplication** - Each query created once, shared across all components
549
+ ✅ **100% Refetch Coverage** - Smart cross-domain refetches after mutations
550
+ ✅ **Better Performance** - Fewer network requests, better caching
551
+ ✅ **Type Safety** - Full TypeScript throughout
552
+ ✅ **Easy to Use** - Simple hook API, automatic coordination
553
+
554
+ ## Advanced Usage
555
+
556
+ ### Dynamic Token Updates
557
+
558
+ ```typescript
559
+ import { useSetClankerToken } from 'levr-sdk/client'
560
+
561
+ function TokenSwitcher() {
562
+ const setClankerToken = useSetClankerToken()
563
+
564
+ const switchToToken = (tokenAddress: `0x${string}`) => {
565
+ setClankerToken(tokenAddress)
566
+ // All queries automatically update!
567
+ }
568
+
569
+ return (
570
+ <select onChange={(e) => switchToToken(e.target.value as `0x${string}`)}>
571
+ <option value="0x...">Token A</option>
572
+ <option value="0x...">Token B</option>
573
+ </select>
574
+ )
575
+ }
576
+ ```
577
+
578
+ ### Manual Refetch Control
579
+
580
+ ```typescript
581
+ import { useLevrRefetch } from 'levr-sdk/client'
582
+
583
+ function RefreshButton() {
584
+ const refetch = useLevrRefetch()
585
+
586
+ return (
587
+ <div>
588
+ <button onClick={() => refetch.all()}>Refresh All</button>
589
+ <button onClick={() => refetch.staking()}>Refresh Staking</button>
590
+ <button onClick={() => refetch.governance()}>Refresh Governance</button>
591
+ </div>
592
+ )
593
+ }
594
+ ```
595
+
596
+ ### Deploying New Tokens
597
+
598
+ ```typescript
599
+ import { useDeploy } from 'levr-sdk/client'
600
+
601
+ function DeployToken() {
602
+ const deploy = useDeploy({
603
+ onSuccess: ({ receipt, address }) => {
604
+ console.log('Deployed to:', address)
605
+ },
606
+ })
607
+
608
+ const handleDeploy = () => {
609
+ deploy.mutate({
610
+ name: 'My Token',
611
+ ticker: 'TKN',
612
+ imageUrl: 'ipfs://...',
613
+ description: 'Token description',
614
+ // ... other params
615
+ })
616
+ }
617
+
618
+ return <button onClick={handleDeploy}>Deploy</button>
619
+ }
620
+ ```
621
+
622
+ ## Query Keys
623
+
624
+ All query keys are centralized and exported:
625
+
626
+ ```typescript
627
+ import { queryKeys } from 'levr-sdk/client'
628
+
629
+ // Use in custom queries or invalidations
630
+ queryClient.invalidateQueries({
631
+ queryKey: queryKeys.project(factoryAddress, clankerToken, chainId),
632
+ })
633
+ ```
634
+
635
+ ## TypeScript Support
636
+
637
+ Full TypeScript support with comprehensive types:
638
+
639
+ ```typescript
640
+ import type {
641
+ Project,
642
+ PoolKey,
643
+ ProposalsResult,
644
+ BalanceResult,
645
+ ClaimParams,
646
+ ProposeTransferConfig,
647
+ // ... many more
648
+ } from 'levr-sdk'
649
+ ```
650
+
651
+ ## Development
652
+
653
+ ```bash
654
+ # Install dependencies
655
+ bun install
656
+
657
+ # Type check
658
+ bun run type-check
659
+
660
+ # Run tests
661
+ bun test
662
+
663
+ # Build
664
+ bun run build
665
+ ```
666
+
667
+ ## Architecture
668
+
669
+ ```
670
+ levr-sdk/
671
+ ├── src/
672
+ │ ├── index.ts # Server-safe exports
673
+ │ ├── project.ts # Project queries
674
+ │ ├── balance.ts # Balance queries
675
+ │ ├── stake.ts # Stake class
676
+ │ ├── governance.ts # Governance class
677
+ │ ├── swap-v4.ts # Swap functions
678
+ │ ├── quote-v4.ts # Quote functions
679
+ │ └── client/
680
+ │ ├── index.ts # Client-only exports
681
+ │ ├── levr-provider.tsx # Centralized provider
682
+ │ ├── query-keys.ts # Query key registry
683
+ │ └── hook/
684
+ │ ├── index.ts # Public hook exports
685
+ │ ├── use-project.ts
686
+ │ ├── use-balance.ts
687
+ │ ├── use-stake.ts
688
+ │ ├── use-swap.ts
689
+ │ ├── use-governance.ts
690
+ │ └── ... (other hooks)
691
+ ```
692
+
693
+ ## License
694
+
695
+ Apache v2 - see [LICENSE.md](./LICENSE.md) for details.
696
+
697
+ ## Links
698
+
699
+ - [Documentation](https://github.com/quantidexyz/levr)
700
+ - [Twitter](https://twitter.com/levrworld)
701
+ - [npm](https://npmjs.org/package/levr-sdk)
702
+
703
+ [ci-image]: https://badgen.net/github/checks/quantidexyz/levr/main?label=ci
704
+ [ci-url]: https://github.com/quantidexyz/levr/actions/workflows/ci.yaml
705
+ [npm-url]: https://npmjs.org/package/levr-sdk
706
+ [twitter-url]: https://twitter.com/levrworld
707
+ [twitter-image]: https://img.shields.io/twitter/follow/levrworld.svg?label=follow+levr
708
+ [license-image]: https://img.shields.io/badge/License-Apache%20v2-blue
709
+ [license-url]: ./LICENSE.md
710
+ [npm-latest-image]: https://img.shields.io/npm/v/levr-sdk/latest.svg
711
+ [npm-downloads-image]: https://img.shields.io/npm/dm/levr-sdk.svg