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,158 @@
|
|
|
1
|
+
import { PublicClient, WalletClient, Address } from 'viem';
|
|
2
|
+
import { T as TransactionResult, c as PoolInfo, U as UserStake } from '../index-BTG0TRJt.js';
|
|
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 };
|
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var diamond = require('@pepay-streams/abi/diamond');
|
|
6
|
+
|
|
7
|
+
// src/staking/index.ts
|
|
8
|
+
var StakingModule = class {
|
|
9
|
+
constructor(publicClient, walletClient, diamondAddress) {
|
|
10
|
+
this.publicClient = publicClient;
|
|
11
|
+
this.walletClient = walletClient;
|
|
12
|
+
this.diamondAddress = diamondAddress;
|
|
13
|
+
}
|
|
14
|
+
// ============================================================================
|
|
15
|
+
// Staking Operations
|
|
16
|
+
// ============================================================================
|
|
17
|
+
/**
|
|
18
|
+
* Stake tokens in a pool
|
|
19
|
+
*
|
|
20
|
+
* Must approve the Diamond contract first.
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```typescript
|
|
24
|
+
* await sdk.approve(stakeToken, amount);
|
|
25
|
+
* const result = await sdk.staking.stake(poolId, amount);
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
async stake(poolId, amount) {
|
|
29
|
+
const wallet = this.requireWallet();
|
|
30
|
+
const hash = await wallet.writeContract({
|
|
31
|
+
chain: wallet.chain,
|
|
32
|
+
account: wallet.account,
|
|
33
|
+
address: this.diamondAddress,
|
|
34
|
+
abi: diamond.DIAMOND_ABI,
|
|
35
|
+
functionName: "stake",
|
|
36
|
+
args: [poolId, amount]
|
|
37
|
+
});
|
|
38
|
+
return this.createTransactionResult(hash);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Increase stake in an existing deposit
|
|
42
|
+
*/
|
|
43
|
+
async increaseStake(poolId, amount) {
|
|
44
|
+
const wallet = this.requireWallet();
|
|
45
|
+
const hash = await wallet.writeContract({
|
|
46
|
+
chain: wallet.chain,
|
|
47
|
+
account: wallet.account,
|
|
48
|
+
address: this.diamondAddress,
|
|
49
|
+
abi: diamond.DIAMOND_ABI,
|
|
50
|
+
functionName: "increaseStake",
|
|
51
|
+
args: [poolId, amount]
|
|
52
|
+
});
|
|
53
|
+
return this.createTransactionResult(hash);
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Unstake all tokens from a pool
|
|
57
|
+
*
|
|
58
|
+
* Automatically claims pending rewards.
|
|
59
|
+
*
|
|
60
|
+
* @example
|
|
61
|
+
* ```typescript
|
|
62
|
+
* const result = await sdk.staking.unstake(poolId);
|
|
63
|
+
* ```
|
|
64
|
+
*/
|
|
65
|
+
async unstake(poolId) {
|
|
66
|
+
const wallet = this.requireWallet();
|
|
67
|
+
const hash = await wallet.writeContract({
|
|
68
|
+
chain: wallet.chain,
|
|
69
|
+
account: wallet.account,
|
|
70
|
+
address: this.diamondAddress,
|
|
71
|
+
abi: diamond.DIAMOND_ABI,
|
|
72
|
+
functionName: "unstake",
|
|
73
|
+
args: [poolId]
|
|
74
|
+
});
|
|
75
|
+
return this.createTransactionResult(hash);
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Partial unstake - withdraw some tokens but keep position open
|
|
79
|
+
*/
|
|
80
|
+
async partialUnstake(poolId, amount) {
|
|
81
|
+
const wallet = this.requireWallet();
|
|
82
|
+
const hash = await wallet.writeContract({
|
|
83
|
+
chain: wallet.chain,
|
|
84
|
+
account: wallet.account,
|
|
85
|
+
address: this.diamondAddress,
|
|
86
|
+
abi: diamond.DIAMOND_ABI,
|
|
87
|
+
functionName: "partialUnstake",
|
|
88
|
+
args: [poolId, amount]
|
|
89
|
+
});
|
|
90
|
+
return this.createTransactionResult(hash);
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Emergency unstake - forfeit rewards but get principal back
|
|
94
|
+
*
|
|
95
|
+
* Use when pool has issues or you need immediate exit.
|
|
96
|
+
*/
|
|
97
|
+
async emergencyUnstake(poolId) {
|
|
98
|
+
const wallet = this.requireWallet();
|
|
99
|
+
const hash = await wallet.writeContract({
|
|
100
|
+
chain: wallet.chain,
|
|
101
|
+
account: wallet.account,
|
|
102
|
+
address: this.diamondAddress,
|
|
103
|
+
abi: diamond.DIAMOND_ABI,
|
|
104
|
+
functionName: "emergencyUnstake",
|
|
105
|
+
args: [poolId]
|
|
106
|
+
});
|
|
107
|
+
return this.createTransactionResult(hash);
|
|
108
|
+
}
|
|
109
|
+
// ============================================================================
|
|
110
|
+
// Pool Queries
|
|
111
|
+
// ============================================================================
|
|
112
|
+
/**
|
|
113
|
+
* Get pool information
|
|
114
|
+
*
|
|
115
|
+
* @example
|
|
116
|
+
* ```typescript
|
|
117
|
+
* const pool = await sdk.staking.getPool(1n);
|
|
118
|
+
* console.log('Total staked:', formatEther(pool.totalStaked));
|
|
119
|
+
* ```
|
|
120
|
+
*/
|
|
121
|
+
async getPool(poolId) {
|
|
122
|
+
const result = await this.publicClient.readContract({
|
|
123
|
+
address: this.diamondAddress,
|
|
124
|
+
abi: diamond.DIAMOND_ABI,
|
|
125
|
+
functionName: "pools",
|
|
126
|
+
args: [poolId]
|
|
127
|
+
});
|
|
128
|
+
return this.parsePoolInfo(poolId, result);
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Get total number of staking pools
|
|
132
|
+
*/
|
|
133
|
+
async getPoolCount() {
|
|
134
|
+
const result = await this.publicClient.readContract({
|
|
135
|
+
address: this.diamondAddress,
|
|
136
|
+
abi: diamond.DIAMOND_ABI,
|
|
137
|
+
functionName: "poolCount",
|
|
138
|
+
args: []
|
|
139
|
+
});
|
|
140
|
+
return result;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Get pool stats (runtime state)
|
|
144
|
+
*/
|
|
145
|
+
async getPoolStats(poolId) {
|
|
146
|
+
const result = await this.publicClient.readContract({
|
|
147
|
+
address: this.diamondAddress,
|
|
148
|
+
abi: diamond.DIAMOND_ABI,
|
|
149
|
+
functionName: "poolStats",
|
|
150
|
+
args: [poolId]
|
|
151
|
+
});
|
|
152
|
+
return {
|
|
153
|
+
statusBits: result[0],
|
|
154
|
+
rewardRemaining: result[1],
|
|
155
|
+
totalStaked: result[2],
|
|
156
|
+
endAt: Number(result[4]),
|
|
157
|
+
finalized: result[6],
|
|
158
|
+
rewardRatePerSecond: result[9]
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
// ============================================================================
|
|
162
|
+
// User Stake Queries
|
|
163
|
+
// ============================================================================
|
|
164
|
+
/**
|
|
165
|
+
* Get user's deposit info for a pool
|
|
166
|
+
*
|
|
167
|
+
* @example
|
|
168
|
+
* ```typescript
|
|
169
|
+
* const stake = await sdk.staking.getUserDeposit(poolId, address);
|
|
170
|
+
* console.log('Staked:', formatEther(stake.amount));
|
|
171
|
+
* ```
|
|
172
|
+
*/
|
|
173
|
+
async getUserDeposit(poolId, user) {
|
|
174
|
+
const result = await this.publicClient.readContract({
|
|
175
|
+
address: this.diamondAddress,
|
|
176
|
+
abi: diamond.DIAMOND_ABI,
|
|
177
|
+
functionName: "deposits",
|
|
178
|
+
args: [poolId, user]
|
|
179
|
+
});
|
|
180
|
+
return {
|
|
181
|
+
amount: result.amount,
|
|
182
|
+
startAt: Number(result.startAt),
|
|
183
|
+
rewardDebtRay: result.rewardDebtRay,
|
|
184
|
+
claimedReward: result.claimedReward,
|
|
185
|
+
claimedAt: Number(result.claimedAt),
|
|
186
|
+
active: result.active
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Get comprehensive deposit status for a user
|
|
191
|
+
*/
|
|
192
|
+
async getDepositStatus(poolId, user) {
|
|
193
|
+
const result = await this.publicClient.readContract({
|
|
194
|
+
address: this.diamondAddress,
|
|
195
|
+
abi: diamond.DIAMOND_ABI,
|
|
196
|
+
functionName: "depositStatus",
|
|
197
|
+
args: [poolId, user]
|
|
198
|
+
});
|
|
199
|
+
return {
|
|
200
|
+
active: result[0],
|
|
201
|
+
stakedAmount: result[1],
|
|
202
|
+
pendingRewards: result[2],
|
|
203
|
+
canUnstakeNow: result[3],
|
|
204
|
+
secondsUntilUnstake: Number(result[4]),
|
|
205
|
+
totalClaimed: result[5]
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Get pending rewards for a user in a pool
|
|
210
|
+
*/
|
|
211
|
+
async getPendingRewards(poolId, user) {
|
|
212
|
+
const result = await this.publicClient.readContract({
|
|
213
|
+
address: this.diamondAddress,
|
|
214
|
+
abi: diamond.DIAMOND_ABI,
|
|
215
|
+
functionName: "pendingReward",
|
|
216
|
+
args: [poolId, user]
|
|
217
|
+
});
|
|
218
|
+
return result;
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Check if user can unstake from a pool
|
|
222
|
+
*/
|
|
223
|
+
async canUnstake(poolId, user) {
|
|
224
|
+
const result = await this.publicClient.readContract({
|
|
225
|
+
address: this.diamondAddress,
|
|
226
|
+
abi: diamond.DIAMOND_ABI,
|
|
227
|
+
functionName: "canUnstake",
|
|
228
|
+
args: [poolId, user]
|
|
229
|
+
});
|
|
230
|
+
return result;
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Get time until user can unstake
|
|
234
|
+
*/
|
|
235
|
+
async secondsUntilUnstakeable(poolId, user) {
|
|
236
|
+
const result = await this.publicClient.readContract({
|
|
237
|
+
address: this.diamondAddress,
|
|
238
|
+
abi: diamond.DIAMOND_ABI,
|
|
239
|
+
functionName: "secondsUntilUnstakeable",
|
|
240
|
+
args: [poolId, user]
|
|
241
|
+
});
|
|
242
|
+
return result;
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Get user's stake info for a pool (convenience wrapper)
|
|
246
|
+
*
|
|
247
|
+
* @example
|
|
248
|
+
* ```typescript
|
|
249
|
+
* const stake = await sdk.staking.getUserStake(poolId, address);
|
|
250
|
+
* console.log('Staked:', formatEther(stake.amount));
|
|
251
|
+
* console.log('Pending rewards:', formatEther(stake.pendingRewards));
|
|
252
|
+
* ```
|
|
253
|
+
*/
|
|
254
|
+
async getUserStake(poolId, user) {
|
|
255
|
+
const [deposit, pendingRewards] = await Promise.all([
|
|
256
|
+
this.getUserDeposit(poolId, user),
|
|
257
|
+
this.getPendingRewards(poolId, user)
|
|
258
|
+
]);
|
|
259
|
+
return {
|
|
260
|
+
amount: deposit.amount,
|
|
261
|
+
pendingRewards,
|
|
262
|
+
lastClaimTime: deposit.claimedAt,
|
|
263
|
+
stakeTime: deposit.startAt
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
// ============================================================================
|
|
267
|
+
// Utility Functions
|
|
268
|
+
// ============================================================================
|
|
269
|
+
/**
|
|
270
|
+
* Get APY preview for a pool
|
|
271
|
+
*/
|
|
272
|
+
async getApyPreview(poolId) {
|
|
273
|
+
const result = await this.publicClient.readContract({
|
|
274
|
+
address: this.diamondAddress,
|
|
275
|
+
abi: diamond.DIAMOND_ABI,
|
|
276
|
+
functionName: "apyPreview",
|
|
277
|
+
args: [poolId]
|
|
278
|
+
});
|
|
279
|
+
return {
|
|
280
|
+
ratePerSecond: result[0],
|
|
281
|
+
totalStaked: result[1]
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* Calculate APY for a pool
|
|
286
|
+
*
|
|
287
|
+
* @example
|
|
288
|
+
* ```typescript
|
|
289
|
+
* const pool = await sdk.staking.getPool(poolId);
|
|
290
|
+
* const apy = sdk.staking.calculateApy(pool);
|
|
291
|
+
* console.log('APY:', apy.toFixed(2), '%');
|
|
292
|
+
* ```
|
|
293
|
+
*/
|
|
294
|
+
calculateApy(pool) {
|
|
295
|
+
if (pool.totalStaked === 0n) {
|
|
296
|
+
return 0;
|
|
297
|
+
}
|
|
298
|
+
const durationInYears = (pool.endTime - pool.startTime) / (365 * 24 * 60 * 60);
|
|
299
|
+
const rewardRate = Number(pool.rewardBudget) / Number(pool.totalStaked);
|
|
300
|
+
return rewardRate / durationInYears * 100;
|
|
301
|
+
}
|
|
302
|
+
// ============================================================================
|
|
303
|
+
// Helpers
|
|
304
|
+
// ============================================================================
|
|
305
|
+
requireWallet() {
|
|
306
|
+
if (!this.walletClient) {
|
|
307
|
+
throw new Error(
|
|
308
|
+
"Wallet client required for write operations. Initialize SDK with a signer."
|
|
309
|
+
);
|
|
310
|
+
}
|
|
311
|
+
return this.walletClient;
|
|
312
|
+
}
|
|
313
|
+
parsePoolInfo(id, data) {
|
|
314
|
+
return {
|
|
315
|
+
id,
|
|
316
|
+
stakeToken: data.stake,
|
|
317
|
+
rewardToken: data.reward,
|
|
318
|
+
creator: data.creator,
|
|
319
|
+
totalStaked: data.totalStaked,
|
|
320
|
+
rewardBudget: data.rewardRemaining,
|
|
321
|
+
// Current remaining
|
|
322
|
+
rewardsDistributed: 0n,
|
|
323
|
+
// Not directly available
|
|
324
|
+
startTime: 0,
|
|
325
|
+
// Not in pool struct
|
|
326
|
+
endTime: Number(data.endAt),
|
|
327
|
+
minStake: 0n,
|
|
328
|
+
// Not in pool struct
|
|
329
|
+
maxStake: data.cap,
|
|
330
|
+
stakerCount: 0,
|
|
331
|
+
// Not in pool struct
|
|
332
|
+
isActive: !(data.statusBits > 0),
|
|
333
|
+
isFinalized: data.finalized
|
|
334
|
+
};
|
|
335
|
+
}
|
|
336
|
+
createTransactionResult(hash) {
|
|
337
|
+
return {
|
|
338
|
+
hash,
|
|
339
|
+
wait: async () => {
|
|
340
|
+
const receipt = await this.publicClient.waitForTransactionReceipt({
|
|
341
|
+
hash
|
|
342
|
+
});
|
|
343
|
+
return {
|
|
344
|
+
blockNumber: receipt.blockNumber,
|
|
345
|
+
transactionHash: receipt.transactionHash,
|
|
346
|
+
gasUsed: receipt.gasUsed,
|
|
347
|
+
status: receipt.status,
|
|
348
|
+
logs: receipt.logs
|
|
349
|
+
};
|
|
350
|
+
}
|
|
351
|
+
};
|
|
352
|
+
}
|
|
353
|
+
};
|
|
354
|
+
var staking_default = StakingModule;
|
|
355
|
+
|
|
356
|
+
exports.StakingModule = StakingModule;
|
|
357
|
+
exports.default = staking_default;
|
|
358
|
+
//# sourceMappingURL=index.js.map
|
|
359
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/staking/index.ts"],"names":["DIAMOND_ABI"],"mappings":"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","file":"index.js","sourcesContent":["/**\r\n * Staking Module\r\n *\r\n * Provides methods for staking operations:\r\n * - Stake tokens\r\n * - Unstake tokens\r\n * - Claim rewards\r\n * - Pool queries\r\n */\r\nimport {\r\n type PublicClient,\r\n type WalletClient,\r\n type Address,\r\n type Hash,\r\n} from 'viem';\r\nimport { DIAMOND_ABI } from '@pepay-streams/abi/diamond';\r\nimport type {\r\n PoolInfo,\r\n UserStake,\r\n TransactionResult,\r\n} from '../types';\r\n\r\n/**\r\n * Staking module for fixed-duration staking pools\r\n */\r\nexport class StakingModule {\r\n constructor(\r\n private readonly publicClient: PublicClient,\r\n private readonly walletClient: WalletClient | undefined,\r\n private readonly diamondAddress: Address\r\n ) {}\r\n\r\n // ============================================================================\r\n // Staking Operations\r\n // ============================================================================\r\n\r\n /**\r\n * Stake tokens in a pool\r\n *\r\n * Must approve the Diamond contract first.\r\n *\r\n * @example\r\n * ```typescript\r\n * await sdk.approve(stakeToken, amount);\r\n * const result = await sdk.staking.stake(poolId, amount);\r\n * ```\r\n */\r\n async stake(poolId: bigint, amount: bigint): Promise<TransactionResult> {\r\n const wallet = this.requireWallet();\r\n\r\n const hash = await wallet.writeContract({\r\n chain: wallet.chain,\r\n account: wallet.account!,\r\n address: this.diamondAddress,\r\n abi: DIAMOND_ABI,\r\n functionName: 'stake',\r\n args: [poolId, amount],\r\n });\r\n\r\n return this.createTransactionResult(hash);\r\n }\r\n\r\n /**\r\n * Increase stake in an existing deposit\r\n */\r\n async increaseStake(\r\n poolId: bigint,\r\n amount: bigint\r\n ): Promise<TransactionResult> {\r\n const wallet = this.requireWallet();\r\n\r\n const hash = await wallet.writeContract({\r\n chain: wallet.chain,\r\n account: wallet.account!,\r\n address: this.diamondAddress,\r\n abi: DIAMOND_ABI,\r\n functionName: 'increaseStake',\r\n args: [poolId, amount],\r\n });\r\n\r\n return this.createTransactionResult(hash);\r\n }\r\n\r\n /**\r\n * Unstake all tokens from a pool\r\n *\r\n * Automatically claims pending rewards.\r\n *\r\n * @example\r\n * ```typescript\r\n * const result = await sdk.staking.unstake(poolId);\r\n * ```\r\n */\r\n async unstake(poolId: bigint): Promise<TransactionResult> {\r\n const wallet = this.requireWallet();\r\n\r\n const hash = await wallet.writeContract({\r\n chain: wallet.chain,\r\n account: wallet.account!,\r\n address: this.diamondAddress,\r\n abi: DIAMOND_ABI,\r\n functionName: 'unstake',\r\n args: [poolId],\r\n });\r\n\r\n return this.createTransactionResult(hash);\r\n }\r\n\r\n /**\r\n * Partial unstake - withdraw some tokens but keep position open\r\n */\r\n async partialUnstake(\r\n poolId: bigint,\r\n amount: bigint\r\n ): Promise<TransactionResult> {\r\n const wallet = this.requireWallet();\r\n\r\n const hash = await wallet.writeContract({\r\n chain: wallet.chain,\r\n account: wallet.account!,\r\n address: this.diamondAddress,\r\n abi: DIAMOND_ABI,\r\n functionName: 'partialUnstake',\r\n args: [poolId, amount],\r\n });\r\n\r\n return this.createTransactionResult(hash);\r\n }\r\n\r\n /**\r\n * Emergency unstake - forfeit rewards but get principal back\r\n *\r\n * Use when pool has issues or you need immediate exit.\r\n */\r\n async emergencyUnstake(poolId: bigint): Promise<TransactionResult> {\r\n const wallet = this.requireWallet();\r\n\r\n const hash = await wallet.writeContract({\r\n chain: wallet.chain,\r\n account: wallet.account!,\r\n address: this.diamondAddress,\r\n abi: DIAMOND_ABI,\r\n functionName: 'emergencyUnstake',\r\n args: [poolId],\r\n });\r\n\r\n return this.createTransactionResult(hash);\r\n }\r\n\r\n // ============================================================================\r\n // Pool Queries\r\n // ============================================================================\r\n\r\n /**\r\n * Get pool information\r\n *\r\n * @example\r\n * ```typescript\r\n * const pool = await sdk.staking.getPool(1n);\r\n * console.log('Total staked:', formatEther(pool.totalStaked));\r\n * ```\r\n */\r\n async getPool(poolId: bigint): Promise<PoolInfo> {\r\n const result = await this.publicClient.readContract({\r\n address: this.diamondAddress,\r\n abi: DIAMOND_ABI,\r\n functionName: 'pools',\r\n args: [poolId],\r\n });\r\n\r\n return this.parsePoolInfo(poolId, result as Record<string, unknown>);\r\n }\r\n\r\n /**\r\n * Get total number of staking pools\r\n */\r\n async getPoolCount(): Promise<bigint> {\r\n const result = await this.publicClient.readContract({\r\n address: this.diamondAddress,\r\n abi: DIAMOND_ABI,\r\n functionName: 'poolCount',\r\n args: [],\r\n });\r\n\r\n return result as bigint;\r\n }\r\n\r\n /**\r\n * Get pool stats (runtime state)\r\n */\r\n async getPoolStats(poolId: bigint): Promise<{\r\n statusBits: number;\r\n rewardRemaining: bigint;\r\n totalStaked: bigint;\r\n endAt: number;\r\n finalized: boolean;\r\n rewardRatePerSecond: bigint;\r\n }> {\r\n const result = await this.publicClient.readContract({\r\n address: this.diamondAddress,\r\n abi: DIAMOND_ABI,\r\n functionName: 'poolStats',\r\n args: [poolId],\r\n }) as [number, bigint, bigint, bigint, bigint, bigint, boolean, bigint, bigint, bigint];\r\n\r\n return {\r\n statusBits: result[0],\r\n rewardRemaining: result[1],\r\n totalStaked: result[2],\r\n endAt: Number(result[4]),\r\n finalized: result[6],\r\n rewardRatePerSecond: result[9],\r\n };\r\n }\r\n\r\n // ============================================================================\r\n // User Stake Queries\r\n // ============================================================================\r\n\r\n /**\r\n * Get user's deposit info for a pool\r\n *\r\n * @example\r\n * ```typescript\r\n * const stake = await sdk.staking.getUserDeposit(poolId, address);\r\n * console.log('Staked:', formatEther(stake.amount));\r\n * ```\r\n */\r\n async getUserDeposit(poolId: bigint, user: Address): Promise<{\r\n amount: bigint;\r\n startAt: number;\r\n rewardDebtRay: bigint;\r\n claimedReward: bigint;\r\n claimedAt: number;\r\n active: boolean;\r\n }> {\r\n const result = await this.publicClient.readContract({\r\n address: this.diamondAddress,\r\n abi: DIAMOND_ABI,\r\n functionName: 'deposits',\r\n args: [poolId, user],\r\n }) as { amount: bigint; startAt: bigint; rewardDebtRay: bigint; claimedReward: bigint; claimedAt: bigint; active: boolean };\r\n\r\n return {\r\n amount: result.amount,\r\n startAt: Number(result.startAt),\r\n rewardDebtRay: result.rewardDebtRay,\r\n claimedReward: result.claimedReward,\r\n claimedAt: Number(result.claimedAt),\r\n active: result.active,\r\n };\r\n }\r\n\r\n /**\r\n * Get comprehensive deposit status for a user\r\n */\r\n async getDepositStatus(poolId: bigint, user: Address): Promise<{\r\n active: boolean;\r\n stakedAmount: bigint;\r\n pendingRewards: bigint;\r\n canUnstakeNow: boolean;\r\n secondsUntilUnstake: number;\r\n totalClaimed: bigint;\r\n }> {\r\n const result = await this.publicClient.readContract({\r\n address: this.diamondAddress,\r\n abi: DIAMOND_ABI,\r\n functionName: 'depositStatus',\r\n args: [poolId, user],\r\n }) as [boolean, bigint, bigint, boolean, bigint, bigint];\r\n\r\n return {\r\n active: result[0],\r\n stakedAmount: result[1],\r\n pendingRewards: result[2],\r\n canUnstakeNow: result[3],\r\n secondsUntilUnstake: Number(result[4]),\r\n totalClaimed: result[5],\r\n };\r\n }\r\n\r\n /**\r\n * Get pending rewards for a user in a pool\r\n */\r\n async getPendingRewards(poolId: bigint, user: Address): Promise<bigint> {\r\n const result = await this.publicClient.readContract({\r\n address: this.diamondAddress,\r\n abi: DIAMOND_ABI,\r\n functionName: 'pendingReward',\r\n args: [poolId, user],\r\n });\r\n\r\n return result as bigint;\r\n }\r\n\r\n /**\r\n * Check if user can unstake from a pool\r\n */\r\n async canUnstake(poolId: bigint, user: Address): Promise<boolean> {\r\n const result = await this.publicClient.readContract({\r\n address: this.diamondAddress,\r\n abi: DIAMOND_ABI,\r\n functionName: 'canUnstake',\r\n args: [poolId, user],\r\n });\r\n\r\n return result as boolean;\r\n }\r\n\r\n /**\r\n * Get time until user can unstake\r\n */\r\n async secondsUntilUnstakeable(\r\n poolId: bigint,\r\n user: Address\r\n ): Promise<bigint> {\r\n const result = await this.publicClient.readContract({\r\n address: this.diamondAddress,\r\n abi: DIAMOND_ABI,\r\n functionName: 'secondsUntilUnstakeable',\r\n args: [poolId, user],\r\n });\r\n\r\n return result as bigint;\r\n }\r\n\r\n /**\r\n * Get user's stake info for a pool (convenience wrapper)\r\n *\r\n * @example\r\n * ```typescript\r\n * const stake = await sdk.staking.getUserStake(poolId, address);\r\n * console.log('Staked:', formatEther(stake.amount));\r\n * console.log('Pending rewards:', formatEther(stake.pendingRewards));\r\n * ```\r\n */\r\n async getUserStake(poolId: bigint, user: Address): Promise<UserStake> {\r\n const [deposit, pendingRewards] = await Promise.all([\r\n this.getUserDeposit(poolId, user),\r\n this.getPendingRewards(poolId, user),\r\n ]);\r\n\r\n return {\r\n amount: deposit.amount,\r\n pendingRewards,\r\n lastClaimTime: deposit.claimedAt,\r\n stakeTime: deposit.startAt,\r\n };\r\n }\r\n\r\n // ============================================================================\r\n // Utility Functions\r\n // ============================================================================\r\n\r\n /**\r\n * Get APY preview for a pool\r\n */\r\n async getApyPreview(poolId: bigint): Promise<{\r\n ratePerSecond: bigint;\r\n totalStaked: bigint;\r\n }> {\r\n const result = await this.publicClient.readContract({\r\n address: this.diamondAddress,\r\n abi: DIAMOND_ABI,\r\n functionName: 'apyPreview',\r\n args: [poolId],\r\n }) as [bigint, bigint];\r\n\r\n return {\r\n ratePerSecond: result[0],\r\n totalStaked: result[1],\r\n };\r\n }\r\n\r\n /**\r\n * Calculate APY for a pool\r\n *\r\n * @example\r\n * ```typescript\r\n * const pool = await sdk.staking.getPool(poolId);\r\n * const apy = sdk.staking.calculateApy(pool);\r\n * console.log('APY:', apy.toFixed(2), '%');\r\n * ```\r\n */\r\n calculateApy(pool: PoolInfo): number {\r\n if (pool.totalStaked === 0n) {\r\n return 0;\r\n }\r\n\r\n const durationInYears =\r\n (pool.endTime - pool.startTime) / (365 * 24 * 60 * 60);\r\n const rewardRate =\r\n Number(pool.rewardBudget) / Number(pool.totalStaked);\r\n\r\n return (rewardRate / durationInYears) * 100;\r\n }\r\n\r\n // ============================================================================\r\n // Helpers\r\n // ============================================================================\r\n\r\n private requireWallet(): WalletClient {\r\n if (!this.walletClient) {\r\n throw new Error(\r\n 'Wallet client required for write operations. Initialize SDK with a signer.'\r\n );\r\n }\r\n return this.walletClient;\r\n }\r\n\r\n private parsePoolInfo(id: bigint, data: Record<string, unknown>): PoolInfo {\r\n return {\r\n id,\r\n stakeToken: data.stake as Address,\r\n rewardToken: data.reward as Address,\r\n creator: data.creator as Address,\r\n totalStaked: data.totalStaked as bigint,\r\n rewardBudget: data.rewardRemaining as bigint, // Current remaining\r\n rewardsDistributed: 0n, // Not directly available\r\n startTime: 0, // Not in pool struct\r\n endTime: Number(data.endAt as bigint),\r\n minStake: 0n, // Not in pool struct\r\n maxStake: data.cap as bigint,\r\n stakerCount: 0, // Not in pool struct\r\n isActive: !((data.statusBits as number) > 0),\r\n isFinalized: data.finalized as boolean,\r\n };\r\n }\r\n\r\n private createTransactionResult(hash: Hash): TransactionResult {\r\n return {\r\n hash,\r\n wait: async () => {\r\n const receipt = await this.publicClient.waitForTransactionReceipt({\r\n hash,\r\n });\r\n return {\r\n blockNumber: receipt.blockNumber,\r\n transactionHash: receipt.transactionHash,\r\n gasUsed: receipt.gasUsed,\r\n status: receipt.status,\r\n logs: receipt.logs,\r\n };\r\n },\r\n };\r\n }\r\n}\r\n\r\nexport default StakingModule;\r\n"]}
|