pepay-streams-sdk 0.1.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.
- package/README.md +405 -0
- package/dist/api/index.d.mts +321 -0
- package/dist/api/index.d.ts +321 -0
- package/dist/api/index.js +312 -0
- package/dist/api/index.js.map +1 -0
- package/dist/api/index.mjs +306 -0
- package/dist/api/index.mjs.map +1 -0
- package/dist/automation/index.d.mts +140 -0
- package/dist/automation/index.d.ts +140 -0
- package/dist/automation/index.js +331 -0
- package/dist/automation/index.js.map +1 -0
- package/dist/automation/index.mjs +326 -0
- package/dist/automation/index.mjs.map +1 -0
- package/dist/campaigns/index.d.mts +286 -0
- package/dist/campaigns/index.d.ts +286 -0
- package/dist/campaigns/index.js +652 -0
- package/dist/campaigns/index.js.map +1 -0
- package/dist/campaigns/index.mjs +645 -0
- package/dist/campaigns/index.mjs.map +1 -0
- package/dist/claims/index.d.mts +190 -0
- package/dist/claims/index.d.ts +190 -0
- package/dist/claims/index.js +414 -0
- package/dist/claims/index.js.map +1 -0
- package/dist/claims/index.mjs +409 -0
- package/dist/claims/index.mjs.map +1 -0
- package/dist/index-BTG0TRJt.d.mts +555 -0
- package/dist/index-BTG0TRJt.d.ts +555 -0
- package/dist/index.d.mts +170 -0
- package/dist/index.d.ts +170 -0
- package/dist/index.js +2926 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +2888 -0
- package/dist/index.mjs.map +1 -0
- package/dist/marketplace/index.d.mts +225 -0
- package/dist/marketplace/index.d.ts +225 -0
- package/dist/marketplace/index.js +529 -0
- package/dist/marketplace/index.js.map +1 -0
- package/dist/marketplace/index.mjs +524 -0
- package/dist/marketplace/index.mjs.map +1 -0
- package/dist/react/index.d.mts +185 -0
- package/dist/react/index.d.ts +185 -0
- package/dist/react/index.js +340 -0
- package/dist/react/index.js.map +1 -0
- package/dist/react/index.mjs +333 -0
- package/dist/react/index.mjs.map +1 -0
- package/dist/staking/index.d.mts +158 -0
- package/dist/staking/index.d.ts +158 -0
- package/dist/staking/index.js +359 -0
- package/dist/staking/index.js.map +1 -0
- package/dist/staking/index.mjs +354 -0
- package/dist/staking/index.mjs.map +1 -0
- package/package.json +106 -0
- package/src/api/index.ts +577 -0
- package/src/automation/index.ts +436 -0
- package/src/campaigns/index.ts +835 -0
- package/src/claims/index.ts +530 -0
- package/src/client.ts +518 -0
- package/src/index.ts +101 -0
- package/src/marketplace/index.ts +730 -0
- package/src/react/index.ts +498 -0
- package/src/staking/index.ts +449 -0
- package/src/types/index.ts +631 -0
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
// src/react/index.ts
|
|
2
|
+
function getConfigFromEnv() {
|
|
3
|
+
if (typeof process === "undefined") {
|
|
4
|
+
return {};
|
|
5
|
+
}
|
|
6
|
+
const config = {
|
|
7
|
+
chainId: Number(
|
|
8
|
+
process.env.NEXT_PUBLIC_CHAIN_ID ?? process.env.CHAIN_ID ?? "1"
|
|
9
|
+
)
|
|
10
|
+
};
|
|
11
|
+
const rpcUrl = process.env.NEXT_PUBLIC_RPC_URL ?? process.env.RPC_URL;
|
|
12
|
+
if (rpcUrl) {
|
|
13
|
+
config.rpcUrl = rpcUrl;
|
|
14
|
+
}
|
|
15
|
+
const diamondAddress = process.env.NEXT_PUBLIC_DIAMOND_ADDRESS ?? process.env.DIAMOND_ADDRESS;
|
|
16
|
+
if (diamondAddress) {
|
|
17
|
+
config.diamondAddress = diamondAddress;
|
|
18
|
+
}
|
|
19
|
+
const apiBaseUrl = process.env.NEXT_PUBLIC_API_URL ?? process.env.API_URL;
|
|
20
|
+
if (apiBaseUrl) {
|
|
21
|
+
config.apiBaseUrl = apiBaseUrl;
|
|
22
|
+
}
|
|
23
|
+
return config;
|
|
24
|
+
}
|
|
25
|
+
var CONTEXT_EXAMPLE = `
|
|
26
|
+
// Example usage with wagmi and React
|
|
27
|
+
|
|
28
|
+
import { createContext, useContext, useState, useEffect, ReactNode } from 'react';
|
|
29
|
+
import { PepayStreamsClient, PepayStreamsClientWithSigner, PepayStreamsConfig } from '@pepay-streams/sdk';
|
|
30
|
+
import { useWalletClient, usePublicClient, useAccount, useChainId } from 'wagmi';
|
|
31
|
+
|
|
32
|
+
interface PepayStreamsContextValue {
|
|
33
|
+
client: PepayStreamsClient | PepayStreamsClientWithSigner | null;
|
|
34
|
+
isConnected: boolean;
|
|
35
|
+
isLoading: boolean;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const PepayStreamsContext = createContext<PepayStreamsContextValue>({
|
|
39
|
+
client: null,
|
|
40
|
+
isConnected: false,
|
|
41
|
+
isLoading: true,
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
export function PepayStreamsProvider({
|
|
45
|
+
children,
|
|
46
|
+
config,
|
|
47
|
+
}: {
|
|
48
|
+
children: ReactNode;
|
|
49
|
+
config: PepayStreamsConfig;
|
|
50
|
+
}) {
|
|
51
|
+
const { isConnected } = useAccount();
|
|
52
|
+
const chainId = useChainId();
|
|
53
|
+
const { data: walletClient, isLoading: walletLoading } = useWalletClient();
|
|
54
|
+
const [client, setClient] = useState<PepayStreamsClient | null>(null);
|
|
55
|
+
|
|
56
|
+
useEffect(() => {
|
|
57
|
+
const newClient = new PepayStreamsClient({
|
|
58
|
+
...config,
|
|
59
|
+
chainId,
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
if (walletClient && isConnected) {
|
|
63
|
+
setClient(newClient.withSigner(walletClient));
|
|
64
|
+
} else {
|
|
65
|
+
setClient(newClient);
|
|
66
|
+
}
|
|
67
|
+
}, [walletClient, isConnected, chainId, config]);
|
|
68
|
+
|
|
69
|
+
return (
|
|
70
|
+
<PepayStreamsContext.Provider
|
|
71
|
+
value={{
|
|
72
|
+
client,
|
|
73
|
+
isConnected,
|
|
74
|
+
isLoading: walletLoading,
|
|
75
|
+
}}
|
|
76
|
+
>
|
|
77
|
+
{children}
|
|
78
|
+
</PepayStreamsContext.Provider>
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export function usePepayStreams() {
|
|
83
|
+
return useContext(PepayStreamsContext);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Usage in components:
|
|
87
|
+
function ClaimButton({ campaignId }: { campaignId: bigint }) {
|
|
88
|
+
const { client, isConnected } = usePepayStreams();
|
|
89
|
+
const [loading, setLoading] = useState(false);
|
|
90
|
+
|
|
91
|
+
const handleClaim = async () => {
|
|
92
|
+
if (!client || !isConnected) return;
|
|
93
|
+
|
|
94
|
+
setLoading(true);
|
|
95
|
+
try {
|
|
96
|
+
const result = await client.claims.claim({ campaignId });
|
|
97
|
+
await result.wait();
|
|
98
|
+
console.log('Claimed!');
|
|
99
|
+
} catch (error) {
|
|
100
|
+
console.error('Claim failed:', error);
|
|
101
|
+
} finally {
|
|
102
|
+
setLoading(false);
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
return (
|
|
107
|
+
<button onClick={handleClaim} disabled={!isConnected || loading}>
|
|
108
|
+
{loading ? 'Claiming...' : 'Claim'}
|
|
109
|
+
</button>
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
`;
|
|
113
|
+
var queryKeys = {
|
|
114
|
+
// Campaigns
|
|
115
|
+
campaigns: (params) => ["pepay", "campaigns", params],
|
|
116
|
+
campaign: (id) => ["pepay", "campaign", String(id)],
|
|
117
|
+
campaignRecipients: (id, page) => ["pepay", "campaign", String(id), "recipients", page],
|
|
118
|
+
campaignActivity: (id, page) => ["pepay", "campaign", String(id), "activity", page],
|
|
119
|
+
// Claims
|
|
120
|
+
dueAmount: (campaignId, address) => ["pepay", "dueAmount", String(campaignId), address],
|
|
121
|
+
recipientStatus: (campaignId, address) => ["pepay", "recipientStatus", String(campaignId), address],
|
|
122
|
+
// Staking
|
|
123
|
+
stakingPools: (params) => ["pepay", "staking", "pools", params],
|
|
124
|
+
stakingPool: (id) => ["pepay", "staking", "pool", String(id)],
|
|
125
|
+
userStake: (poolId, address) => ["pepay", "staking", "userStake", String(poolId), address],
|
|
126
|
+
pendingRewards: (poolId, address) => ["pepay", "staking", "pendingRewards", String(poolId), address],
|
|
127
|
+
// Marketplace
|
|
128
|
+
orders: (params) => ["pepay", "marketplace", "orders", params],
|
|
129
|
+
order: (id) => ["pepay", "marketplace", "order", String(id)],
|
|
130
|
+
orderQuote: (id) => ["pepay", "marketplace", "order", String(id), "quote"],
|
|
131
|
+
// Wallet
|
|
132
|
+
walletActivity: (address) => ["pepay", "wallet", address, "activity"],
|
|
133
|
+
walletPositions: (address) => ["pepay", "wallet", address, "positions"],
|
|
134
|
+
walletClaims: (address, page) => ["pepay", "wallet", address, "claims", page],
|
|
135
|
+
// Tokens
|
|
136
|
+
tokenBalance: (token, address) => ["pepay", "token", token, "balance", address],
|
|
137
|
+
tokenAllowance: (token, owner, spender) => ["pepay", "token", token, "allowance", owner, spender],
|
|
138
|
+
tokenInfo: (token) => ["pepay", "token", token, "info"],
|
|
139
|
+
// Automation
|
|
140
|
+
autoWithdrawStatus: (campaignId) => ["pepay", "automation", "autoWithdraw", String(campaignId)],
|
|
141
|
+
autoReleaseStatus: (campaignId) => ["pepay", "automation", "autoRelease", String(campaignId)]
|
|
142
|
+
};
|
|
143
|
+
var mutationKeys = {
|
|
144
|
+
claim: (campaignId) => ["pepay", "mutation", "claim", String(campaignId)],
|
|
145
|
+
claimBatch: () => ["pepay", "mutation", "claimBatch"],
|
|
146
|
+
stake: (poolId) => ["pepay", "mutation", "stake", String(poolId)],
|
|
147
|
+
unstake: (poolId) => ["pepay", "mutation", "unstake", String(poolId)],
|
|
148
|
+
fillOrder: (orderId) => ["pepay", "mutation", "fillOrder", String(orderId)],
|
|
149
|
+
cancelOrder: (orderId) => ["pepay", "mutation", "cancelOrder", String(orderId)],
|
|
150
|
+
approve: (token) => ["pepay", "mutation", "approve", token]
|
|
151
|
+
};
|
|
152
|
+
var HOOK_EXAMPLES = `
|
|
153
|
+
// Custom hooks for common operations
|
|
154
|
+
|
|
155
|
+
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
|
|
156
|
+
import { usePepayStreams, queryKeys, mutationKeys } from '@pepay-streams/sdk/react';
|
|
157
|
+
import { parseEther } from 'viem';
|
|
158
|
+
|
|
159
|
+
// Hook: Get campaign with due amount
|
|
160
|
+
export function useCampaignWithDue(campaignId: bigint, recipientAddress: Address) {
|
|
161
|
+
const { client } = usePepayStreams();
|
|
162
|
+
|
|
163
|
+
const campaign = useQuery({
|
|
164
|
+
queryKey: queryKeys.campaign(campaignId),
|
|
165
|
+
queryFn: () => client!.campaigns.getCampaign(campaignId),
|
|
166
|
+
enabled: !!client,
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
const dueAmount = useQuery({
|
|
170
|
+
queryKey: queryKeys.dueAmount(campaignId, recipientAddress),
|
|
171
|
+
queryFn: () => client!.claims.getDueAmount(campaignId, recipientAddress),
|
|
172
|
+
enabled: !!client && !!recipientAddress,
|
|
173
|
+
refetchInterval: 30000, // Refresh every 30s
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
return {
|
|
177
|
+
campaign: campaign.data,
|
|
178
|
+
dueAmount: dueAmount.data,
|
|
179
|
+
isLoading: campaign.isLoading || dueAmount.isLoading,
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// Hook: Claim mutation with optimistic updates
|
|
184
|
+
export function useClaim() {
|
|
185
|
+
const { client } = usePepayStreams();
|
|
186
|
+
const queryClient = useQueryClient();
|
|
187
|
+
|
|
188
|
+
return useMutation({
|
|
189
|
+
mutationFn: async ({ campaignId }: { campaignId: bigint }) => {
|
|
190
|
+
const result = await client!.claims.claim({ campaignId });
|
|
191
|
+
return result.wait();
|
|
192
|
+
},
|
|
193
|
+
onSuccess: (_, { campaignId }) => {
|
|
194
|
+
// Invalidate related queries
|
|
195
|
+
queryClient.invalidateQueries({ queryKey: queryKeys.campaign(campaignId) });
|
|
196
|
+
queryClient.invalidateQueries({ queryKey: ['pepay', 'dueAmount', String(campaignId)] });
|
|
197
|
+
},
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// Hook: Stake with approval check
|
|
202
|
+
export function useStake() {
|
|
203
|
+
const { client } = usePepayStreams();
|
|
204
|
+
const queryClient = useQueryClient();
|
|
205
|
+
|
|
206
|
+
return useMutation({
|
|
207
|
+
mutationFn: async ({
|
|
208
|
+
poolId,
|
|
209
|
+
amount,
|
|
210
|
+
stakeToken,
|
|
211
|
+
}: {
|
|
212
|
+
poolId: bigint;
|
|
213
|
+
amount: bigint;
|
|
214
|
+
stakeToken: Address;
|
|
215
|
+
}) => {
|
|
216
|
+
// Check and approve if needed
|
|
217
|
+
const approval = await (client as PepayStreamsClientWithSigner).ensureAllowance(stakeToken, amount);
|
|
218
|
+
if (approval) {
|
|
219
|
+
await approval.wait();
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// Stake
|
|
223
|
+
const result = await client!.staking.stake(poolId, amount);
|
|
224
|
+
return result.wait();
|
|
225
|
+
},
|
|
226
|
+
onSuccess: (_, { poolId }) => {
|
|
227
|
+
queryClient.invalidateQueries({ queryKey: queryKeys.stakingPool(poolId) });
|
|
228
|
+
queryClient.invalidateQueries({ queryKey: ['pepay', 'staking', 'userStake', String(poolId)] });
|
|
229
|
+
},
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// Hook: Fill order with price display
|
|
234
|
+
export function useOrderWithQuote(orderId: bigint) {
|
|
235
|
+
const { client } = usePepayStreams();
|
|
236
|
+
|
|
237
|
+
const order = useQuery({
|
|
238
|
+
queryKey: queryKeys.order(orderId),
|
|
239
|
+
queryFn: () => client!.marketplace.getOrder(orderId),
|
|
240
|
+
enabled: !!client,
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
const quote = useQuery({
|
|
244
|
+
queryKey: queryKeys.orderQuote(orderId),
|
|
245
|
+
queryFn: () => client!.marketplace.getQuote(orderId),
|
|
246
|
+
enabled: !!client && order.data?.status === 'open',
|
|
247
|
+
refetchInterval: 10000, // Refresh quote every 10s
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
return {
|
|
251
|
+
order: order.data,
|
|
252
|
+
quote: quote.data,
|
|
253
|
+
isLoading: order.isLoading || quote.isLoading,
|
|
254
|
+
canFill: quote.data?.isValid ?? false,
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
`;
|
|
258
|
+
var formatters = {
|
|
259
|
+
/**
|
|
260
|
+
* Format token amount with decimals
|
|
261
|
+
*/
|
|
262
|
+
formatTokenAmount(amount, decimals = 18, maxDecimals = 4) {
|
|
263
|
+
const divisor = BigInt(10 ** decimals);
|
|
264
|
+
const integerPart = amount / divisor;
|
|
265
|
+
const fractionalPart = amount % divisor;
|
|
266
|
+
const fractionalStr = fractionalPart.toString().padStart(decimals, "0");
|
|
267
|
+
const trimmedFractional = fractionalStr.slice(0, maxDecimals).replace(/0+$/, "");
|
|
268
|
+
if (trimmedFractional) {
|
|
269
|
+
return `${integerPart}.${trimmedFractional}`;
|
|
270
|
+
}
|
|
271
|
+
return integerPart.toString();
|
|
272
|
+
},
|
|
273
|
+
/**
|
|
274
|
+
* Format USD amount
|
|
275
|
+
*/
|
|
276
|
+
formatUsd(amount) {
|
|
277
|
+
const num = typeof amount === "string" ? parseFloat(amount) : amount;
|
|
278
|
+
return new Intl.NumberFormat("en-US", {
|
|
279
|
+
style: "currency",
|
|
280
|
+
currency: "USD",
|
|
281
|
+
minimumFractionDigits: 2,
|
|
282
|
+
maximumFractionDigits: 2
|
|
283
|
+
}).format(num);
|
|
284
|
+
},
|
|
285
|
+
/**
|
|
286
|
+
* Format percentage
|
|
287
|
+
*/
|
|
288
|
+
formatPercent(value, decimals = 2) {
|
|
289
|
+
return `${value.toFixed(decimals)}%`;
|
|
290
|
+
},
|
|
291
|
+
/**
|
|
292
|
+
* Format timestamp to date string
|
|
293
|
+
*/
|
|
294
|
+
formatDate(timestamp) {
|
|
295
|
+
return new Date(timestamp * 1e3).toLocaleDateString();
|
|
296
|
+
},
|
|
297
|
+
/**
|
|
298
|
+
* Format timestamp to relative time
|
|
299
|
+
*/
|
|
300
|
+
formatRelativeTime(timestamp) {
|
|
301
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
302
|
+
const diff = timestamp - now;
|
|
303
|
+
if (diff < 0) {
|
|
304
|
+
const absDiff = Math.abs(diff);
|
|
305
|
+
if (absDiff < 60) return "just now";
|
|
306
|
+
if (absDiff < 3600) return `${Math.floor(absDiff / 60)}m ago`;
|
|
307
|
+
if (absDiff < 86400) return `${Math.floor(absDiff / 3600)}h ago`;
|
|
308
|
+
return `${Math.floor(absDiff / 86400)}d ago`;
|
|
309
|
+
}
|
|
310
|
+
if (diff < 60) return "in < 1m";
|
|
311
|
+
if (diff < 3600) return `in ${Math.floor(diff / 60)}m`;
|
|
312
|
+
if (diff < 86400) return `in ${Math.floor(diff / 3600)}h`;
|
|
313
|
+
return `in ${Math.floor(diff / 86400)}d`;
|
|
314
|
+
},
|
|
315
|
+
/**
|
|
316
|
+
* Format vesting progress
|
|
317
|
+
*/
|
|
318
|
+
formatVestingProgress(claimed, allocated) {
|
|
319
|
+
if (allocated === 0n) return "0%";
|
|
320
|
+
const progress = Number(claimed * 100n / allocated);
|
|
321
|
+
return `${progress.toFixed(1)}%`;
|
|
322
|
+
},
|
|
323
|
+
/**
|
|
324
|
+
* Shorten address for display
|
|
325
|
+
*/
|
|
326
|
+
shortenAddress(address, chars = 4) {
|
|
327
|
+
return `${address.slice(0, chars + 2)}...${address.slice(-chars)}`;
|
|
328
|
+
}
|
|
329
|
+
};
|
|
330
|
+
|
|
331
|
+
export { CONTEXT_EXAMPLE, HOOK_EXAMPLES, formatters, getConfigFromEnv, mutationKeys, queryKeys };
|
|
332
|
+
//# sourceMappingURL=index.mjs.map
|
|
333
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/react/index.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["/**\r\n * React Integration Helpers\r\n *\r\n * Provides React-friendly patterns for using the SDK:\r\n * - Context provider\r\n * - Hooks for common operations\r\n * - Type-safe query helpers\r\n */\r\n\r\n// Note: This module provides patterns and helpers, not actual React hooks,\r\n// since we want to avoid React as a hard dependency.\r\n\r\nimport type { Address } from 'viem';\r\nimport type { PepayStreamsConfig } from '../types';\r\nimport { PepayStreamsClient, PepayStreamsClientWithSigner } from '../client';\r\n\r\n/**\r\n * SDK context value type for React context\r\n */\r\nexport interface PepayStreamsContextValue {\r\n /** SDK client instance */\r\n client: PepayStreamsClient | PepayStreamsClientWithSigner | null;\r\n /** Whether the client has a signer */\r\n isConnected: boolean;\r\n /** Connected wallet address */\r\n address: Address | null;\r\n /** Chain ID */\r\n chainId: number;\r\n /** Diamond contract address */\r\n diamondAddress: Address;\r\n}\r\n\r\n/**\r\n * Configuration for creating SDK context\r\n */\r\nexport interface CreateContextConfig extends PepayStreamsConfig {\r\n /** Auto-connect on mount */\r\n autoConnect?: boolean;\r\n}\r\n\r\n/**\r\n * Helper to create SDK client configuration from environment\r\n */\r\nexport function getConfigFromEnv(): Partial<PepayStreamsConfig> {\r\n if (typeof process === 'undefined') {\r\n return {};\r\n }\r\n\r\n const config: Partial<PepayStreamsConfig> = {\r\n chainId: Number(\r\n process.env.NEXT_PUBLIC_CHAIN_ID ?? process.env.CHAIN_ID ?? '1'\r\n ),\r\n };\r\n\r\n const rpcUrl = process.env.NEXT_PUBLIC_RPC_URL ?? process.env.RPC_URL;\r\n if (rpcUrl) {\r\n config.rpcUrl = rpcUrl;\r\n }\r\n\r\n const diamondAddress = process.env.NEXT_PUBLIC_DIAMOND_ADDRESS ??\r\n process.env.DIAMOND_ADDRESS;\r\n if (diamondAddress) {\r\n config.diamondAddress = diamondAddress as Address;\r\n }\r\n\r\n const apiBaseUrl = process.env.NEXT_PUBLIC_API_URL ?? process.env.API_URL;\r\n if (apiBaseUrl) {\r\n config.apiBaseUrl = apiBaseUrl;\r\n }\r\n\r\n return config;\r\n}\r\n\r\n/**\r\n * Example React context creation pattern\r\n *\r\n * @example\r\n * ```tsx\r\n * // contexts/PepayStreams.tsx\r\n * import { createContext, useContext, useState, useEffect } from 'react';\r\n * import { PepayStreamsClient, PepayStreamsClientWithSigner } from '@pepay-streams/sdk';\r\n * import { useWalletClient, usePublicClient, useAccount } from 'wagmi';\r\n *\r\n * const PepayStreamsContext = createContext<PepayStreamsContextValue | null>(null);\r\n *\r\n * export function PepayStreamsProvider({ children, config }) {\r\n * const { address, isConnected } = useAccount();\r\n * const publicClient = usePublicClient();\r\n * const { data: walletClient } = useWalletClient();\r\n * const [client, setClient] = useState<PepayStreamsClient | null>(null);\r\n *\r\n * useEffect(() => {\r\n * if (!publicClient) return;\r\n *\r\n * if (walletClient && isConnected) {\r\n * setClient(new PepayStreamsClient(config).withSigner(walletClient));\r\n * } else {\r\n * setClient(new PepayStreamsClient(config));\r\n * }\r\n * }, [publicClient, walletClient, isConnected]);\r\n *\r\n * return (\r\n * <PepayStreamsContext.Provider value={{ client, isConnected, address, ... }}>\r\n * {children}\r\n * </PepayStreamsContext.Provider>\r\n * );\r\n * }\r\n *\r\n * export function usePepayStreams() {\r\n * const context = useContext(PepayStreamsContext);\r\n * if (!context) throw new Error('Must be used within PepayStreamsProvider');\r\n * return context;\r\n * }\r\n * ```\r\n */\r\nexport const CONTEXT_EXAMPLE = `\r\n// Example usage with wagmi and React\r\n\r\nimport { createContext, useContext, useState, useEffect, ReactNode } from 'react';\r\nimport { PepayStreamsClient, PepayStreamsClientWithSigner, PepayStreamsConfig } from '@pepay-streams/sdk';\r\nimport { useWalletClient, usePublicClient, useAccount, useChainId } from 'wagmi';\r\n\r\ninterface PepayStreamsContextValue {\r\n client: PepayStreamsClient | PepayStreamsClientWithSigner | null;\r\n isConnected: boolean;\r\n isLoading: boolean;\r\n}\r\n\r\nconst PepayStreamsContext = createContext<PepayStreamsContextValue>({\r\n client: null,\r\n isConnected: false,\r\n isLoading: true,\r\n});\r\n\r\nexport function PepayStreamsProvider({\r\n children,\r\n config,\r\n}: {\r\n children: ReactNode;\r\n config: PepayStreamsConfig;\r\n}) {\r\n const { isConnected } = useAccount();\r\n const chainId = useChainId();\r\n const { data: walletClient, isLoading: walletLoading } = useWalletClient();\r\n const [client, setClient] = useState<PepayStreamsClient | null>(null);\r\n\r\n useEffect(() => {\r\n const newClient = new PepayStreamsClient({\r\n ...config,\r\n chainId,\r\n });\r\n\r\n if (walletClient && isConnected) {\r\n setClient(newClient.withSigner(walletClient));\r\n } else {\r\n setClient(newClient);\r\n }\r\n }, [walletClient, isConnected, chainId, config]);\r\n\r\n return (\r\n <PepayStreamsContext.Provider\r\n value={{\r\n client,\r\n isConnected,\r\n isLoading: walletLoading,\r\n }}\r\n >\r\n {children}\r\n </PepayStreamsContext.Provider>\r\n );\r\n}\r\n\r\nexport function usePepayStreams() {\r\n return useContext(PepayStreamsContext);\r\n}\r\n\r\n// Usage in components:\r\nfunction ClaimButton({ campaignId }: { campaignId: bigint }) {\r\n const { client, isConnected } = usePepayStreams();\r\n const [loading, setLoading] = useState(false);\r\n\r\n const handleClaim = async () => {\r\n if (!client || !isConnected) return;\r\n\r\n setLoading(true);\r\n try {\r\n const result = await client.claims.claim({ campaignId });\r\n await result.wait();\r\n console.log('Claimed!');\r\n } catch (error) {\r\n console.error('Claim failed:', error);\r\n } finally {\r\n setLoading(false);\r\n }\r\n };\r\n\r\n return (\r\n <button onClick={handleClaim} disabled={!isConnected || loading}>\r\n {loading ? 'Claiming...' : 'Claim'}\r\n </button>\r\n );\r\n}\r\n`;\r\n\r\n/**\r\n * Query key factories for react-query integration\r\n *\r\n * @example\r\n * ```tsx\r\n * import { useQuery } from '@tanstack/react-query';\r\n * import { queryKeys, usePepayStreams } from '@pepay-streams/sdk/react';\r\n *\r\n * function CampaignDetails({ id }) {\r\n * const { client } = usePepayStreams();\r\n *\r\n * const { data: campaign, isLoading } = useQuery({\r\n * queryKey: queryKeys.campaign(id),\r\n * queryFn: () => client.campaigns.getCampaign(BigInt(id)),\r\n * enabled: !!client,\r\n * });\r\n *\r\n * if (isLoading) return <div>Loading...</div>;\r\n * return <div>{campaign?.name}</div>;\r\n * }\r\n * ```\r\n */\r\nexport const queryKeys = {\r\n // Campaigns\r\n campaigns: (params?: Record<string, unknown>) =>\r\n ['pepay', 'campaigns', params] as const,\r\n campaign: (id: string | bigint) => ['pepay', 'campaign', String(id)] as const,\r\n campaignRecipients: (id: string | bigint, page?: number) =>\r\n ['pepay', 'campaign', String(id), 'recipients', page] as const,\r\n campaignActivity: (id: string | bigint, page?: number) =>\r\n ['pepay', 'campaign', String(id), 'activity', page] as const,\r\n\r\n // Claims\r\n dueAmount: (campaignId: bigint, address: Address) =>\r\n ['pepay', 'dueAmount', String(campaignId), address] as const,\r\n recipientStatus: (campaignId: bigint, address: Address) =>\r\n ['pepay', 'recipientStatus', String(campaignId), address] as const,\r\n\r\n // Staking\r\n stakingPools: (params?: Record<string, unknown>) =>\r\n ['pepay', 'staking', 'pools', params] as const,\r\n stakingPool: (id: string | bigint) =>\r\n ['pepay', 'staking', 'pool', String(id)] as const,\r\n userStake: (poolId: bigint, address: Address) =>\r\n ['pepay', 'staking', 'userStake', String(poolId), address] as const,\r\n pendingRewards: (poolId: bigint, address: Address) =>\r\n ['pepay', 'staking', 'pendingRewards', String(poolId), address] as const,\r\n\r\n // Marketplace\r\n orders: (params?: Record<string, unknown>) =>\r\n ['pepay', 'marketplace', 'orders', params] as const,\r\n order: (id: string | bigint) =>\r\n ['pepay', 'marketplace', 'order', String(id)] as const,\r\n orderQuote: (id: string | bigint) =>\r\n ['pepay', 'marketplace', 'order', String(id), 'quote'] as const,\r\n\r\n // Wallet\r\n walletActivity: (address: Address) =>\r\n ['pepay', 'wallet', address, 'activity'] as const,\r\n walletPositions: (address: Address) =>\r\n ['pepay', 'wallet', address, 'positions'] as const,\r\n walletClaims: (address: Address, page?: number) =>\r\n ['pepay', 'wallet', address, 'claims', page] as const,\r\n\r\n // Tokens\r\n tokenBalance: (token: Address, address: Address) =>\r\n ['pepay', 'token', token, 'balance', address] as const,\r\n tokenAllowance: (token: Address, owner: Address, spender: Address) =>\r\n ['pepay', 'token', token, 'allowance', owner, spender] as const,\r\n tokenInfo: (token: Address) => ['pepay', 'token', token, 'info'] as const,\r\n\r\n // Automation\r\n autoWithdrawStatus: (campaignId: bigint) =>\r\n ['pepay', 'automation', 'autoWithdraw', String(campaignId)] as const,\r\n autoReleaseStatus: (campaignId: bigint) =>\r\n ['pepay', 'automation', 'autoRelease', String(campaignId)] as const,\r\n};\r\n\r\n/**\r\n * Mutation key factories for react-query\r\n */\r\nexport const mutationKeys = {\r\n claim: (campaignId: bigint) =>\r\n ['pepay', 'mutation', 'claim', String(campaignId)] as const,\r\n claimBatch: () => ['pepay', 'mutation', 'claimBatch'] as const,\r\n stake: (poolId: bigint) =>\r\n ['pepay', 'mutation', 'stake', String(poolId)] as const,\r\n unstake: (poolId: bigint) =>\r\n ['pepay', 'mutation', 'unstake', String(poolId)] as const,\r\n fillOrder: (orderId: bigint) =>\r\n ['pepay', 'mutation', 'fillOrder', String(orderId)] as const,\r\n cancelOrder: (orderId: bigint) =>\r\n ['pepay', 'mutation', 'cancelOrder', String(orderId)] as const,\r\n approve: (token: Address) =>\r\n ['pepay', 'mutation', 'approve', token] as const,\r\n};\r\n\r\n/**\r\n * Example hook patterns for common operations\r\n */\r\nexport const HOOK_EXAMPLES = `\r\n// Custom hooks for common operations\r\n\r\nimport { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';\r\nimport { usePepayStreams, queryKeys, mutationKeys } from '@pepay-streams/sdk/react';\r\nimport { parseEther } from 'viem';\r\n\r\n// Hook: Get campaign with due amount\r\nexport function useCampaignWithDue(campaignId: bigint, recipientAddress: Address) {\r\n const { client } = usePepayStreams();\r\n\r\n const campaign = useQuery({\r\n queryKey: queryKeys.campaign(campaignId),\r\n queryFn: () => client!.campaigns.getCampaign(campaignId),\r\n enabled: !!client,\r\n });\r\n\r\n const dueAmount = useQuery({\r\n queryKey: queryKeys.dueAmount(campaignId, recipientAddress),\r\n queryFn: () => client!.claims.getDueAmount(campaignId, recipientAddress),\r\n enabled: !!client && !!recipientAddress,\r\n refetchInterval: 30000, // Refresh every 30s\r\n });\r\n\r\n return {\r\n campaign: campaign.data,\r\n dueAmount: dueAmount.data,\r\n isLoading: campaign.isLoading || dueAmount.isLoading,\r\n };\r\n}\r\n\r\n// Hook: Claim mutation with optimistic updates\r\nexport function useClaim() {\r\n const { client } = usePepayStreams();\r\n const queryClient = useQueryClient();\r\n\r\n return useMutation({\r\n mutationFn: async ({ campaignId }: { campaignId: bigint }) => {\r\n const result = await client!.claims.claim({ campaignId });\r\n return result.wait();\r\n },\r\n onSuccess: (_, { campaignId }) => {\r\n // Invalidate related queries\r\n queryClient.invalidateQueries({ queryKey: queryKeys.campaign(campaignId) });\r\n queryClient.invalidateQueries({ queryKey: ['pepay', 'dueAmount', String(campaignId)] });\r\n },\r\n });\r\n}\r\n\r\n// Hook: Stake with approval check\r\nexport function useStake() {\r\n const { client } = usePepayStreams();\r\n const queryClient = useQueryClient();\r\n\r\n return useMutation({\r\n mutationFn: async ({\r\n poolId,\r\n amount,\r\n stakeToken,\r\n }: {\r\n poolId: bigint;\r\n amount: bigint;\r\n stakeToken: Address;\r\n }) => {\r\n // Check and approve if needed\r\n const approval = await (client as PepayStreamsClientWithSigner).ensureAllowance(stakeToken, amount);\r\n if (approval) {\r\n await approval.wait();\r\n }\r\n\r\n // Stake\r\n const result = await client!.staking.stake(poolId, amount);\r\n return result.wait();\r\n },\r\n onSuccess: (_, { poolId }) => {\r\n queryClient.invalidateQueries({ queryKey: queryKeys.stakingPool(poolId) });\r\n queryClient.invalidateQueries({ queryKey: ['pepay', 'staking', 'userStake', String(poolId)] });\r\n },\r\n });\r\n}\r\n\r\n// Hook: Fill order with price display\r\nexport function useOrderWithQuote(orderId: bigint) {\r\n const { client } = usePepayStreams();\r\n\r\n const order = useQuery({\r\n queryKey: queryKeys.order(orderId),\r\n queryFn: () => client!.marketplace.getOrder(orderId),\r\n enabled: !!client,\r\n });\r\n\r\n const quote = useQuery({\r\n queryKey: queryKeys.orderQuote(orderId),\r\n queryFn: () => client!.marketplace.getQuote(orderId),\r\n enabled: !!client && order.data?.status === 'open',\r\n refetchInterval: 10000, // Refresh quote every 10s\r\n });\r\n\r\n return {\r\n order: order.data,\r\n quote: quote.data,\r\n isLoading: order.isLoading || quote.isLoading,\r\n canFill: quote.data?.isValid ?? false,\r\n };\r\n}\r\n`;\r\n\r\n/**\r\n * Format helpers for display\r\n */\r\nexport const formatters = {\r\n /**\r\n * Format token amount with decimals\r\n */\r\n formatTokenAmount(amount: bigint, decimals = 18, maxDecimals = 4): string {\r\n const divisor = BigInt(10 ** decimals);\r\n const integerPart = amount / divisor;\r\n const fractionalPart = amount % divisor;\r\n\r\n const fractionalStr = fractionalPart.toString().padStart(decimals, '0');\r\n const trimmedFractional = fractionalStr.slice(0, maxDecimals).replace(/0+$/, '');\r\n\r\n if (trimmedFractional) {\r\n return `${integerPart}.${trimmedFractional}`;\r\n }\r\n return integerPart.toString();\r\n },\r\n\r\n /**\r\n * Format USD amount\r\n */\r\n formatUsd(amount: number | string): string {\r\n const num = typeof amount === 'string' ? parseFloat(amount) : amount;\r\n return new Intl.NumberFormat('en-US', {\r\n style: 'currency',\r\n currency: 'USD',\r\n minimumFractionDigits: 2,\r\n maximumFractionDigits: 2,\r\n }).format(num);\r\n },\r\n\r\n /**\r\n * Format percentage\r\n */\r\n formatPercent(value: number, decimals = 2): string {\r\n return `${value.toFixed(decimals)}%`;\r\n },\r\n\r\n /**\r\n * Format timestamp to date string\r\n */\r\n formatDate(timestamp: number): string {\r\n return new Date(timestamp * 1000).toLocaleDateString();\r\n },\r\n\r\n /**\r\n * Format timestamp to relative time\r\n */\r\n formatRelativeTime(timestamp: number): string {\r\n const now = Math.floor(Date.now() / 1000);\r\n const diff = timestamp - now;\r\n\r\n if (diff < 0) {\r\n const absDiff = Math.abs(diff);\r\n if (absDiff < 60) return 'just now';\r\n if (absDiff < 3600) return `${Math.floor(absDiff / 60)}m ago`;\r\n if (absDiff < 86400) return `${Math.floor(absDiff / 3600)}h ago`;\r\n return `${Math.floor(absDiff / 86400)}d ago`;\r\n }\r\n\r\n if (diff < 60) return 'in < 1m';\r\n if (diff < 3600) return `in ${Math.floor(diff / 60)}m`;\r\n if (diff < 86400) return `in ${Math.floor(diff / 3600)}h`;\r\n return `in ${Math.floor(diff / 86400)}d`;\r\n },\r\n\r\n /**\r\n * Format vesting progress\r\n */\r\n formatVestingProgress(claimed: bigint, allocated: bigint): string {\r\n if (allocated === 0n) return '0%';\r\n const progress = Number((claimed * 100n) / allocated);\r\n return `${progress.toFixed(1)}%`;\r\n },\r\n\r\n /**\r\n * Shorten address for display\r\n */\r\n shortenAddress(address: Address, chars = 4): string {\r\n return `${address.slice(0, chars + 2)}...${address.slice(-chars)}`;\r\n },\r\n};\r\n\r\n// Types are already exported as interfaces above\r\n"]}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import { PublicClient, WalletClient, Address } from 'viem';
|
|
2
|
+
import { T as TransactionResult, c as PoolInfo, U as UserStake } from '../index-BTG0TRJt.mjs';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Staking Module
|
|
6
|
+
*
|
|
7
|
+
* Provides methods for staking operations:
|
|
8
|
+
* - Stake tokens
|
|
9
|
+
* - Unstake tokens
|
|
10
|
+
* - Claim rewards
|
|
11
|
+
* - Pool queries
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Staking module for fixed-duration staking pools
|
|
16
|
+
*/
|
|
17
|
+
declare class StakingModule {
|
|
18
|
+
private readonly publicClient;
|
|
19
|
+
private readonly walletClient;
|
|
20
|
+
private readonly diamondAddress;
|
|
21
|
+
constructor(publicClient: PublicClient, walletClient: WalletClient | undefined, diamondAddress: Address);
|
|
22
|
+
/**
|
|
23
|
+
* Stake tokens in a pool
|
|
24
|
+
*
|
|
25
|
+
* Must approve the Diamond contract first.
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```typescript
|
|
29
|
+
* await sdk.approve(stakeToken, amount);
|
|
30
|
+
* const result = await sdk.staking.stake(poolId, amount);
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
stake(poolId: bigint, amount: bigint): Promise<TransactionResult>;
|
|
34
|
+
/**
|
|
35
|
+
* Increase stake in an existing deposit
|
|
36
|
+
*/
|
|
37
|
+
increaseStake(poolId: bigint, amount: bigint): Promise<TransactionResult>;
|
|
38
|
+
/**
|
|
39
|
+
* Unstake all tokens from a pool
|
|
40
|
+
*
|
|
41
|
+
* Automatically claims pending rewards.
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* ```typescript
|
|
45
|
+
* const result = await sdk.staking.unstake(poolId);
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
unstake(poolId: bigint): Promise<TransactionResult>;
|
|
49
|
+
/**
|
|
50
|
+
* Partial unstake - withdraw some tokens but keep position open
|
|
51
|
+
*/
|
|
52
|
+
partialUnstake(poolId: bigint, amount: bigint): Promise<TransactionResult>;
|
|
53
|
+
/**
|
|
54
|
+
* Emergency unstake - forfeit rewards but get principal back
|
|
55
|
+
*
|
|
56
|
+
* Use when pool has issues or you need immediate exit.
|
|
57
|
+
*/
|
|
58
|
+
emergencyUnstake(poolId: bigint): Promise<TransactionResult>;
|
|
59
|
+
/**
|
|
60
|
+
* Get pool information
|
|
61
|
+
*
|
|
62
|
+
* @example
|
|
63
|
+
* ```typescript
|
|
64
|
+
* const pool = await sdk.staking.getPool(1n);
|
|
65
|
+
* console.log('Total staked:', formatEther(pool.totalStaked));
|
|
66
|
+
* ```
|
|
67
|
+
*/
|
|
68
|
+
getPool(poolId: bigint): Promise<PoolInfo>;
|
|
69
|
+
/**
|
|
70
|
+
* Get total number of staking pools
|
|
71
|
+
*/
|
|
72
|
+
getPoolCount(): Promise<bigint>;
|
|
73
|
+
/**
|
|
74
|
+
* Get pool stats (runtime state)
|
|
75
|
+
*/
|
|
76
|
+
getPoolStats(poolId: bigint): Promise<{
|
|
77
|
+
statusBits: number;
|
|
78
|
+
rewardRemaining: bigint;
|
|
79
|
+
totalStaked: bigint;
|
|
80
|
+
endAt: number;
|
|
81
|
+
finalized: boolean;
|
|
82
|
+
rewardRatePerSecond: bigint;
|
|
83
|
+
}>;
|
|
84
|
+
/**
|
|
85
|
+
* Get user's deposit info for a pool
|
|
86
|
+
*
|
|
87
|
+
* @example
|
|
88
|
+
* ```typescript
|
|
89
|
+
* const stake = await sdk.staking.getUserDeposit(poolId, address);
|
|
90
|
+
* console.log('Staked:', formatEther(stake.amount));
|
|
91
|
+
* ```
|
|
92
|
+
*/
|
|
93
|
+
getUserDeposit(poolId: bigint, user: Address): Promise<{
|
|
94
|
+
amount: bigint;
|
|
95
|
+
startAt: number;
|
|
96
|
+
rewardDebtRay: bigint;
|
|
97
|
+
claimedReward: bigint;
|
|
98
|
+
claimedAt: number;
|
|
99
|
+
active: boolean;
|
|
100
|
+
}>;
|
|
101
|
+
/**
|
|
102
|
+
* Get comprehensive deposit status for a user
|
|
103
|
+
*/
|
|
104
|
+
getDepositStatus(poolId: bigint, user: Address): Promise<{
|
|
105
|
+
active: boolean;
|
|
106
|
+
stakedAmount: bigint;
|
|
107
|
+
pendingRewards: bigint;
|
|
108
|
+
canUnstakeNow: boolean;
|
|
109
|
+
secondsUntilUnstake: number;
|
|
110
|
+
totalClaimed: bigint;
|
|
111
|
+
}>;
|
|
112
|
+
/**
|
|
113
|
+
* Get pending rewards for a user in a pool
|
|
114
|
+
*/
|
|
115
|
+
getPendingRewards(poolId: bigint, user: Address): Promise<bigint>;
|
|
116
|
+
/**
|
|
117
|
+
* Check if user can unstake from a pool
|
|
118
|
+
*/
|
|
119
|
+
canUnstake(poolId: bigint, user: Address): Promise<boolean>;
|
|
120
|
+
/**
|
|
121
|
+
* Get time until user can unstake
|
|
122
|
+
*/
|
|
123
|
+
secondsUntilUnstakeable(poolId: bigint, user: Address): Promise<bigint>;
|
|
124
|
+
/**
|
|
125
|
+
* Get user's stake info for a pool (convenience wrapper)
|
|
126
|
+
*
|
|
127
|
+
* @example
|
|
128
|
+
* ```typescript
|
|
129
|
+
* const stake = await sdk.staking.getUserStake(poolId, address);
|
|
130
|
+
* console.log('Staked:', formatEther(stake.amount));
|
|
131
|
+
* console.log('Pending rewards:', formatEther(stake.pendingRewards));
|
|
132
|
+
* ```
|
|
133
|
+
*/
|
|
134
|
+
getUserStake(poolId: bigint, user: Address): Promise<UserStake>;
|
|
135
|
+
/**
|
|
136
|
+
* Get APY preview for a pool
|
|
137
|
+
*/
|
|
138
|
+
getApyPreview(poolId: bigint): Promise<{
|
|
139
|
+
ratePerSecond: bigint;
|
|
140
|
+
totalStaked: bigint;
|
|
141
|
+
}>;
|
|
142
|
+
/**
|
|
143
|
+
* Calculate APY for a pool
|
|
144
|
+
*
|
|
145
|
+
* @example
|
|
146
|
+
* ```typescript
|
|
147
|
+
* const pool = await sdk.staking.getPool(poolId);
|
|
148
|
+
* const apy = sdk.staking.calculateApy(pool);
|
|
149
|
+
* console.log('APY:', apy.toFixed(2), '%');
|
|
150
|
+
* ```
|
|
151
|
+
*/
|
|
152
|
+
calculateApy(pool: PoolInfo): number;
|
|
153
|
+
private requireWallet;
|
|
154
|
+
private parsePoolInfo;
|
|
155
|
+
private createTransactionResult;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
export { StakingModule, StakingModule as default };
|