@hermetica/sdk 1.0.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 ADDED
@@ -0,0 +1,294 @@
1
+ # @hermetica/transactions
2
+
3
+ A TypeScript library for creating and managing stake, unstake, and claim transactions on the Hermetica protocol. This library supports both Stacks and Bitcoin blockchains.
4
+
5
+ ## Features
6
+
7
+ - Generate transaction hex for staking, unstaking, and claiming rewards
8
+ - Support for both Stacks and Bitcoin blockchains
9
+ - USDh/sUSDh supported on Stacks and Bitcoin; hBTC supported on Stacks only
10
+ - Claims data retrieval for both chains
11
+ - sUSDh and hBTC rate, price, and APY information retrieval
12
+ - Configurable API host and affiliate code support
13
+
14
+ ## Installation
15
+
16
+ ```bash
17
+ npm install @hermetica/transactions
18
+ ```
19
+
20
+ ## Configuration
21
+
22
+ The library can be configured with the following options:
23
+
24
+ ```typescript
25
+ const config = {
26
+ // Optional: Custom API host (defaults to https://app.hermetica.fi)
27
+ HOST: string;
28
+ // Optional: Your Hermetica affiliate code
29
+ AFFILIATE_CODE: string;
30
+ };
31
+ ```
32
+
33
+ ## Usage
34
+
35
+ ### Initialization
36
+
37
+ ```typescript
38
+ import { TransactionBuilder } from '@hermetica/transactions';
39
+
40
+ const transactionBuilder = new TransactionBuilder({
41
+ HOST: 'CUSTOM_HERMETICA_API', // optional
42
+ AFFILIATE_CODE: 'YOUR_AFFILIATE_CODE' // optional
43
+ });
44
+ ```
45
+
46
+ ### Generating Transactions
47
+
48
+ #### For Stacks (USDh or hBTC)
49
+
50
+ ```typescript
51
+ const stakeResult = await transactionBuilder.generateTransactionHex({
52
+ amount: '94.2', // Amount to stake
53
+ type: 'stake', // 'stake' | 'unstake' | 'withdraw'
54
+ chain: 'stacks',
55
+ protocol: 'USDh', // 'USDh' | 'hBTC'
56
+ public_key: '923xcv2...' // Your Stacks public key
57
+ });
58
+
59
+ // Response format
60
+ {
61
+ status: 'success' | 'failed';
62
+ message: string;
63
+ data: {
64
+ tx_hex: string; // The transaction hex to be signed
65
+ type: 'stake' | 'unstake' | 'withdraw';
66
+ chain: 'stacks';
67
+ }
68
+ }
69
+ ```
70
+
71
+ #### Multisig Transactions (Stacks only)
72
+
73
+ For multisig wallets (e.g., Asigna), pass comma-separated public keys and the signing threshold:
74
+
75
+ ```typescript
76
+ const stakeResult = await transactionBuilder.generateTransactionHex({
77
+ amount: '100',
78
+ type: 'stake',
79
+ chain: 'stacks',
80
+ protocol: 'USDh',
81
+ public_key: 'pubKey1,pubKey2,pubKey3', // Comma-separated signer public keys
82
+ threshold: 2 // 2-of-3 multisig (required signatures)
83
+ });
84
+ ```
85
+
86
+ | Parameter | Type | Required | Description |
87
+ | ------------ | -------- | -------- | ------------------------------------------------------------------------------------------------ |
88
+ | `public_key` | `string` | Yes | Single key for standard wallets, or comma-separated keys for multisig |
89
+ | `threshold` | `number` | No | Number of required signatures. Defaults to 1. Only used when `public_key` contains multiple keys |
90
+
91
+ > **Note:** Multisig is only supported on **Stacks**. Bitcoin USDh/sUSDh transactions do not support multisig.
92
+
93
+ #### For Bitcoin (USDh only)
94
+
95
+ ```typescript
96
+ const stakeResult = await transactionBuilder.generateTransactionHex({
97
+ amount: '94.2', // Amount to stake in BTC
98
+ type: 'stake', // 'stake' | 'unstake' | 'withdraw'
99
+ chain: 'bitcoin',
100
+ protocol: 'USDh', // Only USDh is supported on Bitcoin
101
+ addresses: {
102
+ payment_btc_address: {
103
+ address: '38byQL...', // Your Bitcoin payment address
104
+ pubKey: '0000231...', // Public key for the payment address
105
+ type: 'p2sh' // Address type: p2wpkh, p2sh, etc.
106
+ },
107
+ taproot_btc_address: {
108
+ address: 'bc1pkd...', // Your Taproot address
109
+ pubKey: '023xc0...', // Public key for the Taproot address
110
+ type: 'p2tr'
111
+ }
112
+ },
113
+ satvBFee: 5 // Optional: Fee rate in sat/vB (defaults to highest from mempool)
114
+ });
115
+
116
+ // Response format
117
+ {
118
+ status: 'success' | 'failed';
119
+ message: string;
120
+ data: {
121
+ tx_hex: string; // The transaction hex to be signed
122
+ type: 'stake' | 'unstake' | 'withdraw';
123
+ chain: 'bitcoin';
124
+ inputs_to_sign?: {
125
+ [address: string]: number[]; // Input indices that need to be signed
126
+ }
127
+ }
128
+ }
129
+ ```
130
+
131
+ ### Retrieving Claims Data
132
+
133
+ #### For Stacks (USDh or hBTC)
134
+
135
+ ```typescript
136
+ const withdrawalsData = await transactionBuilder.getWithdrawalsData({
137
+ chain: 'stacks',
138
+ protocol: 'USDh', // 'USDh' | 'hBTC'
139
+ public_key: '923xcv2...' // Your Stacks public key
140
+ });
141
+
142
+ // Response formats
143
+ {
144
+ total_to_claim: number; // Total amount of tokens currently available to claim
145
+ next_amount_to_unlock: number; // Amount of tokens that will be unlocked in the next unlock period
146
+ next_claim_timestamp: number; // The timestamp in ms at which the next amount will become claimable
147
+ last_claim_timestamp: number; // The timestamp in ms at which the last unstake request will be fully unlocked
148
+ }
149
+ ```
150
+
151
+ #### For Bitcoin (USDh only)
152
+
153
+ ```typescript
154
+ const withdrawalsData = await transactionBuilder.getWithdrawalsData({
155
+ chain: 'bitcoin',
156
+ protocol: 'USDh', // Only USDh is supported on Bitcoin
157
+ addresses: {
158
+ payment_btc_address: {
159
+ address: '38byQL...',
160
+ pubKey: '0000231...',
161
+ type: 'p2sh'
162
+ },
163
+ taproot_btc_address: {
164
+ address: 'bc1pkd...',
165
+ pubKey: '023xc0...',
166
+ type: 'p2tr'
167
+ }
168
+ }
169
+ });
170
+
171
+ // Response format
172
+ {
173
+ total_to_claim: number; // Total amount of tokens currently available to claim
174
+ next_amount_to_unlock: number; // Amount of tokens that will be unlocked in the next unlock period
175
+ next_claim_timestamp: number; // The timestamp in ms at which the next amount will become claimable
176
+ last_claim_timestamp: number; // The timestamp in ms at which the last unstake request will be fully unlocked
177
+ }
178
+ ```
179
+
180
+ The claims data response provides information about:
181
+
182
+ - Currently claimable amounts
183
+ - Future unlock amounts
184
+ - Timestamps for tracking unlock periods
185
+ - This information is useful for displaying countdown timers, progress bars, or other UI elements related to the staking lifecycle
186
+
187
+ ### Retrieving hBTC Rate
188
+
189
+ Get the current hBTC share price rate:
190
+
191
+ ```typescript
192
+ const hbtcRate = await transactionBuilder.gethBTCRate();
193
+
194
+ // Returns: number — The hBTC share price rate
195
+ ```
196
+
197
+ ### Retrieving hBTC Price
198
+
199
+ Get the current hBTC price in USD:
200
+
201
+ ```typescript
202
+ const hbtcPrice = await transactionBuilder.gethBTCPrice();
203
+
204
+ // Returns: number — The hBTC price in USD
205
+ ```
206
+
207
+ ### Retrieving hBTC APY
208
+
209
+ Get the current hBTC APY (Annual Percentage Yield):
210
+
211
+ ```typescript
212
+ const hbtcApy = await transactionBuilder.gethBTCApy({
213
+ range: '7d' // Optional: Time range for APY calculation ('7d', '30d' or '365d')
214
+ });
215
+
216
+ // Returns: number — The current hBTC APY percentage
217
+ ```
218
+
219
+ ### Retrieving hBTC Remaining Capacity
220
+
221
+ Get the remaining BTC deposit capacity for the hBTC vault:
222
+
223
+ ```typescript
224
+ const remainingCapacity = await transactionBuilder.gethBTCRemainingCapacity();
225
+
226
+ // Returns: number — The remaining BTC room available for deposits into the hBTC vault
227
+ ```
228
+
229
+ ### Retrieving sUSDh Rate
230
+
231
+ Get the current sUSDh rate:
232
+
233
+ ```typescript
234
+ const susdhRate = await transactionBuilder.getsUSDhRate();
235
+
236
+ // Returns: number — The rate of USDh per sUSDh
237
+ ```
238
+
239
+ ### Retrieving sUSDh APY
240
+
241
+ Get the current sUSDh APY (Annual Percentage Yield):
242
+
243
+ ```typescript
244
+ const susdhApy = await transactionBuilder.getsUSDhApy({
245
+ range: '7d' // Optional: Time range for APY calculation ('7d', '30d' or '365d')
246
+ });
247
+
248
+ // Returns: number — The current sUSDh APY percentage
249
+ ```
250
+
251
+ The APY functions support different time ranges to get historical or current yield data.
252
+
253
+ ## Supported Blockchains
254
+
255
+ - **Stacks**: Full support for USDh and hBTC staking, unstaking, and claiming rewards
256
+ - **Bitcoin**: Support for USDh staking, unstaking, and claiming rewards with:
257
+ - Payment address (p2sh, p2wpkh)
258
+ - Taproot address (p2tr)
259
+
260
+ > **Note:** hBTC transactions are only supported on Stacks. Bitcoin chain support is limited to USDh/sUSDh.
261
+ >
262
+ > **Note:** Multisig transactions are only supported on **Stacks**. Bitcoin USDh/sUSDh transactions do not support multisig.
263
+
264
+ ## Transaction Types
265
+
266
+ - **stake**: Lock your tokens in the protocol to start earning rewards
267
+ - **unstake**: Initiate the withdrawal process for your staked tokens (requires waiting period)
268
+ - **withdraw**: Collect your available rewards and/or unlocked tokens after the waiting period
269
+
270
+ ## Error Handling
271
+
272
+ The library throws errors in the following cases:
273
+
274
+ - Invalid configuration
275
+ - Insufficient funds
276
+ - Invalid address format
277
+ - Network errors
278
+ - Invalid transaction parameters
279
+
280
+ Example error handling:
281
+
282
+ ```typescript
283
+ try {
284
+ const result = await transactionBuilder.generateTransactionHex({
285
+ // ... transaction parameters
286
+ });
287
+ } catch (error) {
288
+ console.error('Transaction generation failed:', error.message);
289
+ }
290
+ ```
291
+
292
+ ## License
293
+
294
+ GPL-3.0
@@ -0,0 +1,15 @@
1
+ import type { TransactionResult, TransactionBuilderConfig, BitcoinTransactionParams, StacksTransactionParams, ClaimsData, GetApyParams } from './types';
2
+ export declare class TransactionBuilder {
3
+ private config;
4
+ private axiosInstance;
5
+ constructor({ HOST, AFFILIATE_CODE }: TransactionBuilderConfig);
6
+ generateTransactionHex(params: BitcoinTransactionParams | StacksTransactionParams): Promise<TransactionResult>;
7
+ getWithdrawalsData(params: BitcoinTransactionParams | StacksTransactionParams): Promise<ClaimsData>;
8
+ private parseNumericResponse;
9
+ getsUSDhRate(): Promise<number>;
10
+ gethBTCRate(): Promise<number>;
11
+ gethBTCPrice(): Promise<number>;
12
+ getsUSDhApy(params?: GetApyParams): Promise<number>;
13
+ gethBTCApy(params?: GetApyParams): Promise<number>;
14
+ gethBTCRemainingCapacity(): Promise<number>;
15
+ }
package/dist/index.js ADDED
@@ -0,0 +1,86 @@
1
+ import axios from 'axios';
2
+ // Main class
3
+ export class TransactionBuilder {
4
+ constructor({ HOST, AFFILIATE_CODE }) {
5
+ this.config = {
6
+ HOST: HOST || 'https://app.hermetica.fi',
7
+ AFFILIATE_CODE: AFFILIATE_CODE || undefined
8
+ };
9
+ this.axiosInstance = axios.create({
10
+ baseURL: this.config.HOST,
11
+ headers: {
12
+ 'Content-Type': 'application/json'
13
+ }
14
+ });
15
+ }
16
+ async generateTransactionHex(params) {
17
+ const { amount, chain, type, protocol } = params;
18
+ const requestBody = {
19
+ token_symbol: protocol,
20
+ amount,
21
+ chain,
22
+ affiliate_code: this.config.AFFILIATE_CODE,
23
+ ...(chain === 'bitcoin'
24
+ ? {
25
+ addresses: params?.addresses,
26
+ satvb_fee: params?.satvBFee
27
+ }
28
+ : {
29
+ public_key: params?.public_key,
30
+ threshold: params?.threshold
31
+ })
32
+ };
33
+ const response = await this.axiosInstance.post(`/api/v2/transactions/${type}`, requestBody);
34
+ return response.data;
35
+ }
36
+ async getWithdrawalsData(params) {
37
+ const { chain, protocol } = params;
38
+ const requestBody = {
39
+ chain,
40
+ public_key: params?.public_key,
41
+ addresses: params?.addresses,
42
+ token_symbol: protocol
43
+ };
44
+ const response = await this.axiosInstance.post(`/api/v2/transactions/claims_data`, requestBody);
45
+ return response.data;
46
+ }
47
+ parseNumericResponse(value, endpoint) {
48
+ const parsed = Number(value);
49
+ if (isNaN(parsed)) {
50
+ throw new Error(`Invalid numeric response from ${endpoint}: ${value}`);
51
+ }
52
+ return parsed;
53
+ }
54
+ async getsUSDhRate() {
55
+ const response = await this.axiosInstance.get(`/api/v2c/info/susdh_rate`);
56
+ return this.parseNumericResponse(response.data.rate, '/api/v2c/info/susdh_rate');
57
+ }
58
+ async gethBTCRate() {
59
+ const response = await this.axiosInstance.get(`/api/v2c/info/hbtc_rate`);
60
+ return this.parseNumericResponse(response.data.rate, '/api/v2c/info/hbtc_rate');
61
+ }
62
+ async gethBTCPrice() {
63
+ const response = await this.axiosInstance.get(`/api/v2/hbtc/price`);
64
+ return this.parseNumericResponse(response.data.price, '/api/v2/hbtc/price');
65
+ }
66
+ async getsUSDhApy(params) {
67
+ const response = await this.axiosInstance.get(`/api/v2/info/apy/susdh`, {
68
+ params: {
69
+ range: params?.range || '7d'
70
+ }
71
+ });
72
+ return this.parseNumericResponse(response.data.apy, '/api/v2/info/apy/susdh');
73
+ }
74
+ async gethBTCApy(params) {
75
+ const response = await this.axiosInstance.get(`/api/v2/info/apy/hbtc`, {
76
+ params: {
77
+ range: params?.range || '7d'
78
+ }
79
+ });
80
+ return this.parseNumericResponse(response.data.apy, '/api/v2/info/apy/hbtc');
81
+ }
82
+ async gethBTCRemainingCapacity() {
83
+ const response = await this.axiosInstance.get(`/api/v2/hbtc/vault-capacity`);
84
+ return this.parseNumericResponse(response.data.vault_capacity, '/api/v2/hbtc/vault-capacity');
85
+ }
86
+ }
@@ -0,0 +1,64 @@
1
+ export type TransactionType = 'stake' | 'unstake' | 'withdraw';
2
+ export type BlockchainType = 'stacks' | 'bitcoin';
3
+ export interface AddressData {
4
+ address: string;
5
+ pubKey: string;
6
+ type?: string;
7
+ threshold?: number;
8
+ }
9
+ export interface BtcAddresses {
10
+ payment_btc_address: AddressData;
11
+ taproot_btc_address: AddressData;
12
+ }
13
+ export interface BaseTransactionParams {
14
+ amount: string;
15
+ type: TransactionType;
16
+ chain: BlockchainType;
17
+ protocol: 'USDh' | 'hBTC';
18
+ }
19
+ export interface BitcoinTransactionParams extends BaseTransactionParams {
20
+ chain: 'bitcoin';
21
+ addresses: BtcAddresses;
22
+ satvBFee?: number;
23
+ }
24
+ export interface StacksTransactionParams extends BaseTransactionParams {
25
+ chain: 'stacks';
26
+ public_key: string;
27
+ threshold?: number;
28
+ }
29
+ export interface GetApyParams {
30
+ range?: '7d' | '30d' | '365d';
31
+ }
32
+ export type TransactionParams = BitcoinTransactionParams | StacksTransactionParams;
33
+ export interface TransactionResult {
34
+ status: 'success' | 'failed';
35
+ message: string;
36
+ data: {
37
+ tx_hex: string;
38
+ type: TransactionType;
39
+ chain: BlockchainType;
40
+ inputs_to_sign?: {
41
+ [address: string]: number[];
42
+ };
43
+ };
44
+ }
45
+ export interface TransactionBuilderConfig {
46
+ HOST?: string;
47
+ AFFILIATE_CODE?: string;
48
+ }
49
+ export interface ClaimsData {
50
+ total_to_claim: number;
51
+ next_amount_to_unlock: number;
52
+ next_claim_timestamp: number;
53
+ last_claim_timestamp: number;
54
+ }
55
+ export interface RateData {
56
+ rate: number;
57
+ }
58
+ export interface sUSdhApyData {
59
+ apy: string;
60
+ }
61
+ export interface hBTCApyData {
62
+ apy: string;
63
+ last_update: number;
64
+ }
@@ -0,0 +1 @@
1
+ export {};
package/package.json ADDED
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "@hermetica/sdk",
3
+ "version": "1.0.0",
4
+ "description": "Hermetica Transactions Library",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "files": [
8
+ "dist"
9
+ ],
10
+ "scripts": {
11
+ "build": "tsc",
12
+ "prepare": "npm run build",
13
+ "test": "jest",
14
+ "test:info": "npx tsx tests/test-info.ts",
15
+ "test:transactions": "npx tsx tests/test-transactions.ts",
16
+ "test:live": "npx tsx tests/test-info.ts && npx tsx tests/test-transactions.ts",
17
+ "test:live:local": "npx tsx tests/test-info.ts --local && npx tsx tests/test-transactions.ts --local",
18
+ "publish": "./publish.sh"
19
+ },
20
+ "publishConfig": {
21
+ "access": "public"
22
+ },
23
+ "dependencies": {
24
+ "axios": "^1.9.0"
25
+ },
26
+ "devDependencies": {
27
+ "typescript": "^5.2.2",
28
+ "@types/node": "^20.11.22"
29
+ }
30
+ }