timefi-sdk 0.1.3 → 0.2.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 +70 -24
- package/dist/client.d.ts +33 -0
- package/dist/constants.d.ts +51 -0
- package/dist/format.d.ts +6 -0
- package/dist/index.cjs +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.mjs +283 -0
- package/dist/protocol.d.ts +75 -0
- package/dist/utils.d.ts +60 -0
- package/package.json +23 -9
- package/dist/index.esm.js +0 -131
- package/dist/index.js +0 -1
package/README.md
CHANGED
|
@@ -3,58 +3,104 @@
|
|
|
3
3
|
The official JavaScript SDK for interacting with the **TimeFi Protocol** on the Stacks blockchain.
|
|
4
4
|
|
|
5
5
|
[](https://www.npmjs.com/package/timefi-sdk)
|
|
6
|
+
[](https://www.npmjs.com/package/timefi-sdk)
|
|
6
7
|
[](https://opensource.org/licenses/MIT)
|
|
7
8
|
|
|
8
|
-
##
|
|
9
|
+
## Features
|
|
9
10
|
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
11
|
+
- Protocol Client: Easy-to-use `TimeFiClient` for read and write interactions.
|
|
12
|
+
- On-chain Data: Fetch TVL, vault status, and lock durations directly from smart contracts.
|
|
13
|
+
- Formatting Utilities: Standardized formatting for STX (microSTX to STX), addresses, dates, and timestamps.
|
|
14
|
+
- Shared Helpers: Utility helpers and protocol models from the old `timefi-utils` and `timefi-types` packages are now included directly in `timefi-sdk`.
|
|
15
|
+
- Mainnet/Testnet Support: Unified interface for both networks.
|
|
14
16
|
|
|
15
|
-
##
|
|
17
|
+
## Installation
|
|
16
18
|
|
|
17
19
|
```bash
|
|
18
20
|
npm install timefi-sdk
|
|
19
|
-
|
|
20
|
-
### Running Tests
|
|
21
|
-
|
|
22
|
-
```bash
|
|
23
|
-
npm test
|
|
24
21
|
```
|
|
25
|
-
|
|
22
|
+
|
|
23
|
+
## Quick Start
|
|
26
24
|
|
|
27
25
|
### Fetch Protocol Stats
|
|
28
26
|
|
|
29
27
|
```javascript
|
|
30
28
|
import { TimeFiClient, formatSTX } from 'timefi-sdk';
|
|
31
29
|
|
|
32
|
-
// Initialize for Stacks Mainnet
|
|
33
30
|
const client = new TimeFiClient('mainnet');
|
|
34
|
-
|
|
35
|
-
// Get Total Value Locked
|
|
36
31
|
const tvl = await client.getTVL();
|
|
32
|
+
|
|
37
33
|
console.log(`Current TVL: ${formatSTX(tvl)} STX`);
|
|
38
34
|
```
|
|
39
35
|
|
|
36
|
+
### Build a Create-Vault Transaction
|
|
37
|
+
|
|
38
|
+
```javascript
|
|
39
|
+
import { TimeFiClient } from 'timefi-sdk';
|
|
40
|
+
|
|
41
|
+
const client = new TimeFiClient('mainnet');
|
|
42
|
+
|
|
43
|
+
const txOptions = client.getCreateVaultOptions('1.25', 4320);
|
|
44
|
+
```
|
|
45
|
+
|
|
40
46
|
### Format a Stacks Address
|
|
41
47
|
|
|
42
48
|
```javascript
|
|
43
49
|
import { formatAddress } from 'timefi-sdk';
|
|
44
50
|
|
|
45
|
-
const shortAddress = formatAddress('
|
|
46
|
-
console.log(shortAddress);
|
|
51
|
+
const shortAddress = formatAddress('SP3F1234567890ABCDEFG1234567890XYZ123');
|
|
52
|
+
console.log(shortAddress);
|
|
47
53
|
```
|
|
48
54
|
|
|
49
|
-
|
|
55
|
+
### Use Integrated Utilities and Protocol Helpers
|
|
56
|
+
|
|
57
|
+
```javascript
|
|
58
|
+
import {
|
|
59
|
+
calculateTimeRemaining,
|
|
60
|
+
getProtocolConfig,
|
|
61
|
+
validateAddress,
|
|
62
|
+
} from 'timefi-sdk';
|
|
63
|
+
|
|
64
|
+
const config = getProtocolConfig();
|
|
65
|
+
const remaining = calculateTimeRemaining(Date.now() + 60_000);
|
|
66
|
+
const isValid = validateAddress('SP3FKNEZ86RG5RT7SZ5FBRGH85FZNG94ZH1MCGG6N');
|
|
67
|
+
```
|
|
50
68
|
|
|
51
|
-
|
|
69
|
+
## Running Tests
|
|
52
70
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
- `CONTRACT_ADDRESS`: The main TimeFi Protocol contract address on Stacks.
|
|
71
|
+
```bash
|
|
72
|
+
npm test
|
|
73
|
+
```
|
|
57
74
|
|
|
58
|
-
##
|
|
75
|
+
## Documentation
|
|
76
|
+
|
|
77
|
+
The SDK exports:
|
|
78
|
+
|
|
79
|
+
- `TimeFiClient`
|
|
80
|
+
- `formatSTX(microStx)`
|
|
81
|
+
- `formatAddress(address)`
|
|
82
|
+
- `formatTimestamp(timestamp)`
|
|
83
|
+
- `calculateTimeRemaining(endTime)`
|
|
84
|
+
- `validateAddress(address)`
|
|
85
|
+
- `validateAddressResult(address)`
|
|
86
|
+
- `formatAmount(amount, decimals?)`
|
|
87
|
+
- `parseAmount(amount)`
|
|
88
|
+
- `generateId()`
|
|
89
|
+
- `sleep(ms)`
|
|
90
|
+
- `retry(fn, maxRetries?, delay?)`
|
|
91
|
+
- `initializeProtocol(options?)`
|
|
92
|
+
- `getProtocolVersion()`
|
|
93
|
+
- `getProtocolConfig()`
|
|
94
|
+
- `normalizeVault(vault)`
|
|
95
|
+
- `normalizeTransaction(transaction)`
|
|
96
|
+
- `formatNumber(value)`
|
|
97
|
+
- `formatPercent(value)`
|
|
98
|
+
- `formatDate(value)`
|
|
99
|
+
- `formatRelativeTime(value)`
|
|
100
|
+
- `CONTRACT_ADDRESS`
|
|
101
|
+
- `CONTRACT_NAMES`
|
|
102
|
+
- `LOCK_PERIODS`
|
|
103
|
+
|
|
104
|
+
## License
|
|
59
105
|
|
|
60
106
|
MIT © [AdekunleBamz](https://github.com/AdekunleBamz)
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export class TimeFiClient {
|
|
2
|
+
constructor(networkType?: string);
|
|
3
|
+
networkType: string;
|
|
4
|
+
network: StacksMainnet | StacksTestnet;
|
|
5
|
+
contractAddress: string;
|
|
6
|
+
callReadOnly(functionName: any, functionArgs: any[], senderAddress: any): Promise<any>;
|
|
7
|
+
getVault(vaultId: any): Promise<any>;
|
|
8
|
+
getTimeRemaining(vaultId: any): Promise<any>;
|
|
9
|
+
canWithdraw(vaultId: any): Promise<any>;
|
|
10
|
+
getTVL(): Promise<any>;
|
|
11
|
+
getCreateVaultOptions(amountSTX: any, lockDurationBlocks: any): {
|
|
12
|
+
contractAddress: string;
|
|
13
|
+
contractName: string;
|
|
14
|
+
functionName: string;
|
|
15
|
+
functionArgs: import("@stacks/transactions").UIntCV[];
|
|
16
|
+
network: StacksMainnet | StacksTestnet;
|
|
17
|
+
anchorMode: AnchorMode;
|
|
18
|
+
postConditionMode: PostConditionMode;
|
|
19
|
+
};
|
|
20
|
+
getWithdrawOptions(vaultId: any): {
|
|
21
|
+
contractAddress: string;
|
|
22
|
+
contractName: string;
|
|
23
|
+
functionName: string;
|
|
24
|
+
functionArgs: import("@stacks/transactions").UIntCV[];
|
|
25
|
+
network: StacksMainnet | StacksTestnet;
|
|
26
|
+
anchorMode: AnchorMode;
|
|
27
|
+
postConditionMode: PostConditionMode;
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
import { StacksMainnet } from '@stacks/network';
|
|
31
|
+
import { StacksTestnet } from '@stacks/network';
|
|
32
|
+
import { AnchorMode } from '@stacks/transactions';
|
|
33
|
+
import { PostConditionMode } from '@stacks/transactions';
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Protocol Constants
|
|
3
|
+
*/
|
|
4
|
+
export const CONTRACT_ADDRESS: "SP3FKNEZ86RG5RT7SZ5FBRGH85FZNG94ZH1MCGG6N";
|
|
5
|
+
export namespace CONTRACT_NAMES {
|
|
6
|
+
let VAULT: string;
|
|
7
|
+
let REWARDS: string;
|
|
8
|
+
let GOVERNANCE: string;
|
|
9
|
+
let EMERGENCY: string;
|
|
10
|
+
}
|
|
11
|
+
export namespace LOCK_PERIODS {
|
|
12
|
+
namespace MONTH_1 {
|
|
13
|
+
let label: string;
|
|
14
|
+
let blocks: number;
|
|
15
|
+
let apy: number;
|
|
16
|
+
}
|
|
17
|
+
namespace MONTH_3 {
|
|
18
|
+
let label_1: string;
|
|
19
|
+
export { label_1 as label };
|
|
20
|
+
let blocks_1: number;
|
|
21
|
+
export { blocks_1 as blocks };
|
|
22
|
+
let apy_1: number;
|
|
23
|
+
export { apy_1 as apy };
|
|
24
|
+
}
|
|
25
|
+
namespace MONTH_6 {
|
|
26
|
+
let label_2: string;
|
|
27
|
+
export { label_2 as label };
|
|
28
|
+
let blocks_2: number;
|
|
29
|
+
export { blocks_2 as blocks };
|
|
30
|
+
let apy_2: number;
|
|
31
|
+
export { apy_2 as apy };
|
|
32
|
+
}
|
|
33
|
+
namespace MONTH_9 {
|
|
34
|
+
let label_3: string;
|
|
35
|
+
export { label_3 as label };
|
|
36
|
+
let blocks_3: number;
|
|
37
|
+
export { blocks_3 as blocks };
|
|
38
|
+
let apy_3: number;
|
|
39
|
+
export { apy_3 as apy };
|
|
40
|
+
}
|
|
41
|
+
namespace YEAR_1 {
|
|
42
|
+
let label_4: string;
|
|
43
|
+
export { label_4 as label };
|
|
44
|
+
let blocks_4: number;
|
|
45
|
+
export { blocks_4 as blocks };
|
|
46
|
+
let apy_4: number;
|
|
47
|
+
export { apy_4 as apy };
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
export const MIN_DEPOSIT: 0.01;
|
|
51
|
+
export const MAX_DEPOSIT: 1000000;
|
package/dist/format.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export function formatSTX(microStx: any): string;
|
|
2
|
+
export function formatAddress(address: any, prefix?: number, suffix?: number): any;
|
|
3
|
+
export function formatNumber(val: any): string;
|
|
4
|
+
export function formatPercent(val: any, decimals?: number): string;
|
|
5
|
+
export function formatDate(date: any): string;
|
|
6
|
+
export function formatRelativeTime(date: any): string;
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("@stacks/transactions"),f=require("@stacks/network"),d="SP3FKNEZ86RG5RT7SZ5FBRGH85FZNG94ZH1MCGG6N",u={VAULT:"timefi-vault-v-A2",REWARDS:"timefi-rewards-v-A2",GOVERNANCE:"timefi-governance-v-A2",EMERGENCY:"timefi-emergency-v-A2"},p={MONTH_1:{label:"1 Month",blocks:4320,apy:1},MONTH_3:{label:"3 Months",blocks:12960,apy:3},MONTH_6:{label:"6 Months",blocks:25920,apy:6},MONTH_9:{label:"9 Months",blocks:38880,apy:9},YEAR_1:{label:"1 Year",blocks:52560,apy:12}},y=.01,M=1e6,V=e=>{if(e==null)return"0.000000";try{const t=typeof e=="object"&&e!==null&&"value"in e?e.value:e,r=Number(t);return isNaN(r)?"0.000000":(r/1e6).toLocaleString(void 0,{minimumFractionDigits:0,maximumFractionDigits:6})}catch(t){return console.error("Error formatting STX:",t),"0.000000"}},E=(e,t=4,r=4)=>e?e.length<=t+r?e:`${e.slice(0,t+2)}...${e.slice(-r)}`:"",P=e=>{if(e==null)return"0";const t=Number(e);return isNaN(t)?"0":t.toLocaleString()},R=(e,t=2)=>{if(e==null)return"0%";const r=Number(e);return isNaN(r)?"0%":(r*100).toFixed(t)+"%"},m=e=>{if(!e)return"--";const t=new Date(e);return isNaN(t.getTime())?"--":t.toLocaleDateString(void 0,{year:"numeric",month:"short",day:"numeric"})},_=e=>{if(!e)return"--";const t=new Date,r=new Date(e),n=Math.floor((t-r)/1e3);if(n<-1){const i=Math.abs(n);return i<60?"in a few seconds":i<3600?`in ${Math.floor(i/60)}m`:i<86400?`in ${Math.floor(i/3600)}h`:`in ${Math.floor(i/86400)}d`}return n<5?"just now":n<60?`${n}s ago`:n<3600?`${Math.floor(n/60)}m ago`:n<86400?`${Math.floor(n/3600)}h ago`:n<604800?`${Math.floor(n/86400)}d ago`:m(e)},D=/^S[PTMN][A-Z0-9]{38,40}$/i;function v(e){const t=Number(e);return!Number.isInteger(t)||t<0?6:t}function k(e){const t=e instanceof Date?e:new Date(e);return Number.isNaN(t.getTime())?"Invalid Date":t.toLocaleString()}function I(e){const t=e instanceof Date?e.getTime():Number(e),r=Number.isFinite(t)?t-Date.now():0;if(r<=0)return{days:0,hours:0,minutes:0,seconds:0,total:0};const n=Math.floor(r/(1e3*60*60*24)),i=Math.floor(r%(1e3*60*60*24)/(1e3*60*60)),l=Math.floor(r%(1e3*60*60)/(1e3*60)),C=Math.floor(r%(1e3*60)/1e3);return{days:n,hours:i,minutes:l,seconds:C,total:r}}function g(e){if(typeof e!="string")return{valid:!1,error:"Address must be a string."};const t=e.trim().toUpperCase();return t?D.test(t)?{valid:!0,address:t}:{valid:!1,address:t,error:"Address must be a valid Stacks address."}:{valid:!1,error:"Address is required."}}function F(e){return g(e).valid}function L(e,t=6){const r=Number(e),n=v(t);return Number.isFinite(r)?r.toFixed(n):0 .toFixed(n)}function j(e){const t=Number.parseFloat(String(e).replace(/,/g,"").trim());return Number.isFinite(t)?t:0}function U(){return`${Date.now()}-${Math.random().toString(36).slice(2,11)}`}function T(e){const t=Number.isFinite(e)&&e>0?e:0;return new Promise(r=>setTimeout(r,t))}async function z(e,t=3,r=1e3){const n=Number.isInteger(t)&&t>0?t:1;for(let i=0;i<n;i+=1)try{return await e()}catch(l){if(i===n-1)throw l;await T(r)}throw new Error("Retry exhausted without executing the operation.")}const A="1.0.0",h=Object.freeze({timeLock:!0,vaults:!0,governance:!1,rewards:!1}),b=Object.freeze(["active","locked","withdrawn","failed"]),N=Object.freeze(["deposit","withdraw","create","fee"]),S=Object.freeze(["pending","confirmed","failed"]);function s(e,t=0){const r=Number(e);return Number.isFinite(r)?r:t}function $(e){return b.includes(e)?e:"active"}function G(e){return N.includes(e)?e:"deposit"}function X(e){return S.includes(e)?e:"pending"}function O(e={}){const t={...h,...e.features||{}};return{network:e.network||"mainnet",version:e.version||A,features:t,initialized:e.initialized??!0}}let c=O();function H(e={}){return c=O(e),w()}function q(){return c.version}function w(){return{...c,features:{...c.features}}}function Y(e={}){return{id:e.id?String(e.id):"",owner:e.owner?String(e.owner):"",amount:s(e.amount),lockTime:s(e.lockTime),unlockTime:s(e.unlockTime),status:$(e.status),fees:s(e.fees)}}function Z(e={}){return{hash:e.hash?String(e.hash):"",type:G(e.type),amount:s(e.amount),from:e.from?String(e.from):"",to:e.to?String(e.to):"",timestamp:s(e.timestamp),status:X(e.status)}}function a(e,t){if(!Number.isInteger(e)||e<=0)throw new Error(`${t} must be a positive integer.`)}function K(e){if(e==null)throw new Error("amountSTX is required");const t=String(e).trim();if(!/^\d+(\.\d+)?$/.test(t))throw new Error("amountSTX must be a valid positive number.");const[r,n=""]=t.split(".");if(n.length>6)throw new Error("amountSTX supports at most 6 decimal places.");const i=BigInt(r)*1000000n+BigInt((n+"000000").slice(0,6));if(i<=0n)throw new Error("amountSTX must be greater than 0.");return i}class B{constructor(t="mainnet"){if(!["mainnet","testnet"].includes(t))throw new Error(`Invalid networkType "${t}". Use "mainnet" or "testnet".`);this.networkType=t,this.network=t==="mainnet"?new f.StacksMainnet:new f.StacksTestnet,this.contractAddress=d}async callReadOnly(t,r=[],n){const i=await o.callReadOnlyFunction({contractAddress:this.contractAddress,contractName:u.VAULT,functionName:t,functionArgs:r,network:this.network,senderAddress:n||this.contractAddress});return i.type===7||i.type===8?o.cvToValue(i.value):o.cvToValue(i)}async getVault(t){return a(t,"vaultId"),this.callReadOnly("get-vault",[o.uintCV(t)])}async getTimeRemaining(t){return a(t,"vaultId"),this.callReadOnly("get-time-remaining",[o.uintCV(t)])}async canWithdraw(t){return a(t,"vaultId"),this.callReadOnly("can-withdraw",[o.uintCV(t)])}async getTVL(){return this.callReadOnly("get-tvl",[])}getCreateVaultOptions(t,r){return a(r,"lockDurationBlocks"),{contractAddress:this.contractAddress,contractName:u.VAULT,functionName:"create-vault",functionArgs:[o.uintCV(K(t)),o.uintCV(r)],network:this.network,anchorMode:o.AnchorMode.Any,postConditionMode:o.PostConditionMode.Allow}}getWithdrawOptions(t){return a(t,"vaultId"),{contractAddress:this.contractAddress,contractName:u.VAULT,functionName:"request-withdraw",functionArgs:[o.uintCV(t)],network:this.network,anchorMode:o.AnchorMode.Any,postConditionMode:o.PostConditionMode.Allow}}}Object.defineProperty(exports,"AnchorMode",{enumerable:!0,get:()=>o.AnchorMode});Object.defineProperty(exports,"PostConditionMode",{enumerable:!0,get:()=>o.PostConditionMode});Object.defineProperty(exports,"bufferCV",{enumerable:!0,get:()=>o.bufferCV});Object.defineProperty(exports,"noneCV",{enumerable:!0,get:()=>o.noneCV});Object.defineProperty(exports,"principalCV",{enumerable:!0,get:()=>o.principalCV});Object.defineProperty(exports,"responseErrorCV",{enumerable:!0,get:()=>o.responseErrorCV});Object.defineProperty(exports,"responseOkCV",{enumerable:!0,get:()=>o.responseOkCV});Object.defineProperty(exports,"someCV",{enumerable:!0,get:()=>o.someCV});Object.defineProperty(exports,"stringAsciiCV",{enumerable:!0,get:()=>o.stringAsciiCV});Object.defineProperty(exports,"stringUtf8CV",{enumerable:!0,get:()=>o.stringUtf8CV});Object.defineProperty(exports,"uintCV",{enumerable:!0,get:()=>o.uintCV});exports.CONTRACT_ADDRESS=d;exports.CONTRACT_NAMES=u;exports.DEFAULT_PROTOCOL_FEATURES=h;exports.LOCK_PERIODS=p;exports.MAX_DEPOSIT=M;exports.MIN_DEPOSIT=y;exports.PROTOCOL_VERSION=A;exports.TRANSACTION_STATUSES=S;exports.TRANSACTION_TYPES=N;exports.TimeFiClient=B;exports.VAULT_STATUSES=b;exports.calculateTimeRemaining=I;exports.formatAddress=E;exports.formatAmount=L;exports.formatDate=m;exports.formatNumber=P;exports.formatPercent=R;exports.formatRelativeTime=_;exports.formatSTX=V;exports.formatTimestamp=k;exports.generateId=U;exports.getProtocolConfig=w;exports.getProtocolVersion=q;exports.initializeProtocol=H;exports.normalizeTransaction=Z;exports.normalizeVault=Y;exports.parseAmount=j;exports.retry=z;exports.sleep=T;exports.validateAddress=F;exports.validateAddressResult=g;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export * from "./constants.js";
|
|
2
|
+
export * from "./format.js";
|
|
3
|
+
export * from "./utils.js";
|
|
4
|
+
export * from "./protocol.js";
|
|
5
|
+
export * from "./client.js";
|
|
6
|
+
export { uintCV, principalCV, bufferCV, stringAsciiCV, stringUtf8CV, noneCV, someCV, responseOkCV, responseErrorCV, AnchorMode, PostConditionMode } from "@stacks/transactions";
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
import { callReadOnlyFunction as w, cvToValue as f, uintCV as i, PostConditionMode as d, AnchorMode as m } from "@stacks/transactions";
|
|
2
|
+
import { AnchorMode as it, PostConditionMode as st, bufferCV as at, noneCV as ut, principalCV as ct, responseErrorCV as lt, responseOkCV as ft, someCV as dt, stringAsciiCV as mt, stringUtf8CV as ht, uintCV as gt } from "@stacks/transactions";
|
|
3
|
+
import { StacksMainnet as A, StacksTestnet as N } from "@stacks/network";
|
|
4
|
+
const T = "SP3FKNEZ86RG5RT7SZ5FBRGH85FZNG94ZH1MCGG6N", l = {
|
|
5
|
+
VAULT: "timefi-vault-v-A2",
|
|
6
|
+
REWARDS: "timefi-rewards-v-A2",
|
|
7
|
+
GOVERNANCE: "timefi-governance-v-A2",
|
|
8
|
+
EMERGENCY: "timefi-emergency-v-A2"
|
|
9
|
+
}, L = {
|
|
10
|
+
MONTH_1: { label: "1 Month", blocks: 4320, apy: 1 },
|
|
11
|
+
MONTH_3: { label: "3 Months", blocks: 12960, apy: 3 },
|
|
12
|
+
MONTH_6: { label: "6 Months", blocks: 25920, apy: 6 },
|
|
13
|
+
MONTH_9: { label: "9 Months", blocks: 38880, apy: 9 },
|
|
14
|
+
YEAR_1: { label: "1 Year", blocks: 52560, apy: 12 }
|
|
15
|
+
}, $ = 0.01, z = 1e6, U = (t) => {
|
|
16
|
+
if (t == null) return "0.000000";
|
|
17
|
+
try {
|
|
18
|
+
const e = typeof t == "object" && t !== null && "value" in t ? t.value : t, n = Number(e);
|
|
19
|
+
return isNaN(n) ? "0.000000" : (n / 1e6).toLocaleString(void 0, {
|
|
20
|
+
minimumFractionDigits: 0,
|
|
21
|
+
maximumFractionDigits: 6
|
|
22
|
+
});
|
|
23
|
+
} catch (e) {
|
|
24
|
+
return console.error("Error formatting STX:", e), "0.000000";
|
|
25
|
+
}
|
|
26
|
+
}, G = (t, e = 4, n = 4) => t ? t.length <= e + n ? t : `${t.slice(0, e + 2)}...${t.slice(-n)}` : "", j = (t) => {
|
|
27
|
+
if (t == null) return "0";
|
|
28
|
+
const e = Number(t);
|
|
29
|
+
return isNaN(e) ? "0" : e.toLocaleString();
|
|
30
|
+
}, H = (t, e = 2) => {
|
|
31
|
+
if (t == null) return "0%";
|
|
32
|
+
const n = Number(t);
|
|
33
|
+
return isNaN(n) ? "0%" : (n * 100).toFixed(e) + "%";
|
|
34
|
+
}, b = (t) => {
|
|
35
|
+
if (!t) return "--";
|
|
36
|
+
const e = new Date(t);
|
|
37
|
+
return isNaN(e.getTime()) ? "--" : e.toLocaleDateString(void 0, {
|
|
38
|
+
year: "numeric",
|
|
39
|
+
month: "short",
|
|
40
|
+
day: "numeric"
|
|
41
|
+
});
|
|
42
|
+
}, X = (t) => {
|
|
43
|
+
if (!t) return "--";
|
|
44
|
+
const e = /* @__PURE__ */ new Date(), n = new Date(t), r = Math.floor((e - n) / 1e3);
|
|
45
|
+
if (r < -1) {
|
|
46
|
+
const o = Math.abs(r);
|
|
47
|
+
return o < 60 ? "in a few seconds" : o < 3600 ? `in ${Math.floor(o / 60)}m` : o < 86400 ? `in ${Math.floor(o / 3600)}h` : `in ${Math.floor(o / 86400)}d`;
|
|
48
|
+
}
|
|
49
|
+
return r < 5 ? "just now" : r < 60 ? `${r}s ago` : r < 3600 ? `${Math.floor(r / 60)}m ago` : r < 86400 ? `${Math.floor(r / 3600)}h ago` : r < 604800 ? `${Math.floor(r / 86400)}d ago` : b(t);
|
|
50
|
+
}, S = /^S[PTMN][A-Z0-9]{38,40}$/i;
|
|
51
|
+
function p(t) {
|
|
52
|
+
const e = Number(t);
|
|
53
|
+
return !Number.isInteger(e) || e < 0 ? 6 : e;
|
|
54
|
+
}
|
|
55
|
+
function Z(t) {
|
|
56
|
+
const e = t instanceof Date ? t : new Date(t);
|
|
57
|
+
return Number.isNaN(e.getTime()) ? "Invalid Date" : e.toLocaleString();
|
|
58
|
+
}
|
|
59
|
+
function Y(t) {
|
|
60
|
+
const e = t instanceof Date ? t.getTime() : Number(t), n = Number.isFinite(e) ? e - Date.now() : 0;
|
|
61
|
+
if (n <= 0)
|
|
62
|
+
return { days: 0, hours: 0, minutes: 0, seconds: 0, total: 0 };
|
|
63
|
+
const r = Math.floor(n / (1e3 * 60 * 60 * 24)), o = Math.floor(n % (1e3 * 60 * 60 * 24) / (1e3 * 60 * 60)), c = Math.floor(n % (1e3 * 60 * 60) / (1e3 * 60)), g = Math.floor(n % (1e3 * 60) / 1e3);
|
|
64
|
+
return { days: r, hours: o, minutes: c, seconds: g, total: n };
|
|
65
|
+
}
|
|
66
|
+
function M(t) {
|
|
67
|
+
if (typeof t != "string")
|
|
68
|
+
return { valid: !1, error: "Address must be a string." };
|
|
69
|
+
const e = t.trim().toUpperCase();
|
|
70
|
+
return e ? S.test(e) ? { valid: !0, address: e } : { valid: !1, address: e, error: "Address must be a valid Stacks address." } : { valid: !1, error: "Address is required." };
|
|
71
|
+
}
|
|
72
|
+
function q(t) {
|
|
73
|
+
return M(t).valid;
|
|
74
|
+
}
|
|
75
|
+
function B(t, e = 6) {
|
|
76
|
+
const n = Number(t), r = p(e);
|
|
77
|
+
return Number.isFinite(n) ? n.toFixed(r) : 0 .toFixed(r);
|
|
78
|
+
}
|
|
79
|
+
function K(t) {
|
|
80
|
+
const e = Number.parseFloat(String(t).replace(/,/g, "").trim());
|
|
81
|
+
return Number.isFinite(e) ? e : 0;
|
|
82
|
+
}
|
|
83
|
+
function W() {
|
|
84
|
+
return `${Date.now()}-${Math.random().toString(36).slice(2, 11)}`;
|
|
85
|
+
}
|
|
86
|
+
function y(t) {
|
|
87
|
+
const e = Number.isFinite(t) && t > 0 ? t : 0;
|
|
88
|
+
return new Promise((n) => setTimeout(n, e));
|
|
89
|
+
}
|
|
90
|
+
async function x(t, e = 3, n = 1e3) {
|
|
91
|
+
const r = Number.isInteger(e) && e > 0 ? e : 1;
|
|
92
|
+
for (let o = 0; o < r; o += 1)
|
|
93
|
+
try {
|
|
94
|
+
return await t();
|
|
95
|
+
} catch (c) {
|
|
96
|
+
if (o === r - 1)
|
|
97
|
+
throw c;
|
|
98
|
+
await y(n);
|
|
99
|
+
}
|
|
100
|
+
throw new Error("Retry exhausted without executing the operation.");
|
|
101
|
+
}
|
|
102
|
+
const C = "1.0.0", O = Object.freeze({
|
|
103
|
+
timeLock: !0,
|
|
104
|
+
vaults: !0,
|
|
105
|
+
governance: !1,
|
|
106
|
+
rewards: !1
|
|
107
|
+
}), E = Object.freeze(["active", "locked", "withdrawn", "failed"]), R = Object.freeze(["deposit", "withdraw", "create", "fee"]), V = Object.freeze(["pending", "confirmed", "failed"]);
|
|
108
|
+
function s(t, e = 0) {
|
|
109
|
+
const n = Number(t);
|
|
110
|
+
return Number.isFinite(n) ? n : e;
|
|
111
|
+
}
|
|
112
|
+
function D(t) {
|
|
113
|
+
return E.includes(t) ? t : "active";
|
|
114
|
+
}
|
|
115
|
+
function k(t) {
|
|
116
|
+
return R.includes(t) ? t : "deposit";
|
|
117
|
+
}
|
|
118
|
+
function v(t) {
|
|
119
|
+
return V.includes(t) ? t : "pending";
|
|
120
|
+
}
|
|
121
|
+
function h(t = {}) {
|
|
122
|
+
const e = {
|
|
123
|
+
...O,
|
|
124
|
+
...t.features || {}
|
|
125
|
+
};
|
|
126
|
+
return {
|
|
127
|
+
network: t.network || "mainnet",
|
|
128
|
+
version: t.version || C,
|
|
129
|
+
features: e,
|
|
130
|
+
initialized: t.initialized ?? !0
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
let u = h();
|
|
134
|
+
function J(t = {}) {
|
|
135
|
+
return u = h(t), _();
|
|
136
|
+
}
|
|
137
|
+
function Q() {
|
|
138
|
+
return u.version;
|
|
139
|
+
}
|
|
140
|
+
function _() {
|
|
141
|
+
return {
|
|
142
|
+
...u,
|
|
143
|
+
features: { ...u.features }
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
function tt(t = {}) {
|
|
147
|
+
return {
|
|
148
|
+
id: t.id ? String(t.id) : "",
|
|
149
|
+
owner: t.owner ? String(t.owner) : "",
|
|
150
|
+
amount: s(t.amount),
|
|
151
|
+
lockTime: s(t.lockTime),
|
|
152
|
+
unlockTime: s(t.unlockTime),
|
|
153
|
+
status: D(t.status),
|
|
154
|
+
fees: s(t.fees)
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
function et(t = {}) {
|
|
158
|
+
return {
|
|
159
|
+
hash: t.hash ? String(t.hash) : "",
|
|
160
|
+
type: k(t.type),
|
|
161
|
+
amount: s(t.amount),
|
|
162
|
+
from: t.from ? String(t.from) : "",
|
|
163
|
+
to: t.to ? String(t.to) : "",
|
|
164
|
+
timestamp: s(t.timestamp),
|
|
165
|
+
status: v(t.status)
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
function a(t, e) {
|
|
169
|
+
if (!Number.isInteger(t) || t <= 0)
|
|
170
|
+
throw new Error(`${e} must be a positive integer.`);
|
|
171
|
+
}
|
|
172
|
+
function F(t) {
|
|
173
|
+
if (t == null)
|
|
174
|
+
throw new Error("amountSTX is required");
|
|
175
|
+
const e = String(t).trim();
|
|
176
|
+
if (!/^\d+(\.\d+)?$/.test(e))
|
|
177
|
+
throw new Error("amountSTX must be a valid positive number.");
|
|
178
|
+
const [n, r = ""] = e.split(".");
|
|
179
|
+
if (r.length > 6)
|
|
180
|
+
throw new Error("amountSTX supports at most 6 decimal places.");
|
|
181
|
+
const o = BigInt(n) * 1000000n + BigInt((r + "000000").slice(0, 6));
|
|
182
|
+
if (o <= 0n)
|
|
183
|
+
throw new Error("amountSTX must be greater than 0.");
|
|
184
|
+
return o;
|
|
185
|
+
}
|
|
186
|
+
class nt {
|
|
187
|
+
constructor(e = "mainnet") {
|
|
188
|
+
if (!["mainnet", "testnet"].includes(e))
|
|
189
|
+
throw new Error(`Invalid networkType "${e}". Use "mainnet" or "testnet".`);
|
|
190
|
+
this.networkType = e, this.network = e === "mainnet" ? new A() : new N(), this.contractAddress = T;
|
|
191
|
+
}
|
|
192
|
+
// --- Read-only Methods ---
|
|
193
|
+
async callReadOnly(e, n = [], r) {
|
|
194
|
+
const o = await w({
|
|
195
|
+
contractAddress: this.contractAddress,
|
|
196
|
+
contractName: l.VAULT,
|
|
197
|
+
functionName: e,
|
|
198
|
+
functionArgs: n,
|
|
199
|
+
network: this.network,
|
|
200
|
+
senderAddress: r || this.contractAddress
|
|
201
|
+
});
|
|
202
|
+
return o.type === 7 || o.type === 8 ? f(o.value) : f(o);
|
|
203
|
+
}
|
|
204
|
+
async getVault(e) {
|
|
205
|
+
return a(e, "vaultId"), this.callReadOnly("get-vault", [i(e)]);
|
|
206
|
+
}
|
|
207
|
+
async getTimeRemaining(e) {
|
|
208
|
+
return a(e, "vaultId"), this.callReadOnly("get-time-remaining", [i(e)]);
|
|
209
|
+
}
|
|
210
|
+
async canWithdraw(e) {
|
|
211
|
+
return a(e, "vaultId"), this.callReadOnly("can-withdraw", [i(e)]);
|
|
212
|
+
}
|
|
213
|
+
async getTVL() {
|
|
214
|
+
return this.callReadOnly("get-tvl", []);
|
|
215
|
+
}
|
|
216
|
+
// --- Transaction Signing Options Helpers ---
|
|
217
|
+
getCreateVaultOptions(e, n) {
|
|
218
|
+
return a(n, "lockDurationBlocks"), {
|
|
219
|
+
contractAddress: this.contractAddress,
|
|
220
|
+
contractName: l.VAULT,
|
|
221
|
+
functionName: "create-vault",
|
|
222
|
+
functionArgs: [i(F(e)), i(n)],
|
|
223
|
+
network: this.network,
|
|
224
|
+
anchorMode: m.Any,
|
|
225
|
+
postConditionMode: d.Allow
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
getWithdrawOptions(e) {
|
|
229
|
+
return a(e, "vaultId"), {
|
|
230
|
+
contractAddress: this.contractAddress,
|
|
231
|
+
contractName: l.VAULT,
|
|
232
|
+
functionName: "request-withdraw",
|
|
233
|
+
functionArgs: [i(e)],
|
|
234
|
+
network: this.network,
|
|
235
|
+
anchorMode: m.Any,
|
|
236
|
+
postConditionMode: d.Allow
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
export {
|
|
241
|
+
it as AnchorMode,
|
|
242
|
+
T as CONTRACT_ADDRESS,
|
|
243
|
+
l as CONTRACT_NAMES,
|
|
244
|
+
O as DEFAULT_PROTOCOL_FEATURES,
|
|
245
|
+
L as LOCK_PERIODS,
|
|
246
|
+
z as MAX_DEPOSIT,
|
|
247
|
+
$ as MIN_DEPOSIT,
|
|
248
|
+
C as PROTOCOL_VERSION,
|
|
249
|
+
st as PostConditionMode,
|
|
250
|
+
V as TRANSACTION_STATUSES,
|
|
251
|
+
R as TRANSACTION_TYPES,
|
|
252
|
+
nt as TimeFiClient,
|
|
253
|
+
E as VAULT_STATUSES,
|
|
254
|
+
at as bufferCV,
|
|
255
|
+
Y as calculateTimeRemaining,
|
|
256
|
+
G as formatAddress,
|
|
257
|
+
B as formatAmount,
|
|
258
|
+
b as formatDate,
|
|
259
|
+
j as formatNumber,
|
|
260
|
+
H as formatPercent,
|
|
261
|
+
X as formatRelativeTime,
|
|
262
|
+
U as formatSTX,
|
|
263
|
+
Z as formatTimestamp,
|
|
264
|
+
W as generateId,
|
|
265
|
+
_ as getProtocolConfig,
|
|
266
|
+
Q as getProtocolVersion,
|
|
267
|
+
J as initializeProtocol,
|
|
268
|
+
ut as noneCV,
|
|
269
|
+
et as normalizeTransaction,
|
|
270
|
+
tt as normalizeVault,
|
|
271
|
+
K as parseAmount,
|
|
272
|
+
ct as principalCV,
|
|
273
|
+
lt as responseErrorCV,
|
|
274
|
+
ft as responseOkCV,
|
|
275
|
+
x as retry,
|
|
276
|
+
y as sleep,
|
|
277
|
+
dt as someCV,
|
|
278
|
+
mt as stringAsciiCV,
|
|
279
|
+
ht as stringUtf8CV,
|
|
280
|
+
gt as uintCV,
|
|
281
|
+
q as validateAddress,
|
|
282
|
+
M as validateAddressResult
|
|
283
|
+
};
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @param {Partial<ProtocolConfig>} [options={}]
|
|
3
|
+
* @returns {ProtocolConfig}
|
|
4
|
+
*/
|
|
5
|
+
export function initializeProtocol(options?: Partial<ProtocolConfig>): ProtocolConfig;
|
|
6
|
+
/**
|
|
7
|
+
* @returns {string}
|
|
8
|
+
*/
|
|
9
|
+
export function getProtocolVersion(): string;
|
|
10
|
+
/**
|
|
11
|
+
* @returns {ProtocolConfig}
|
|
12
|
+
*/
|
|
13
|
+
export function getProtocolConfig(): ProtocolConfig;
|
|
14
|
+
/**
|
|
15
|
+
* @param {Partial<Vault>} [vault={}]
|
|
16
|
+
* @returns {Vault}
|
|
17
|
+
*/
|
|
18
|
+
export function normalizeVault(vault?: Partial<Vault>): Vault;
|
|
19
|
+
/**
|
|
20
|
+
* @param {Partial<Transaction>} [transaction={}]
|
|
21
|
+
* @returns {Transaction}
|
|
22
|
+
*/
|
|
23
|
+
export function normalizeTransaction(transaction?: Partial<Transaction>): Transaction;
|
|
24
|
+
/**
|
|
25
|
+
* Protocol metadata and typed helpers for the TimeFi ecosystem.
|
|
26
|
+
*/
|
|
27
|
+
/** @typedef {{ timeLock: boolean, vaults: boolean, governance: boolean, rewards: boolean }} ProtocolFeatures */
|
|
28
|
+
/** @typedef {{ network: string, version: string, features: ProtocolFeatures, initialized?: boolean }} ProtocolConfig */
|
|
29
|
+
/** @typedef {'active' | 'locked' | 'withdrawn' | 'failed'} VaultStatus */
|
|
30
|
+
/** @typedef {{ id: string, owner: string, amount: number, lockTime: number, unlockTime: number, status: VaultStatus, fees: number }} Vault */
|
|
31
|
+
/** @typedef {'deposit' | 'withdraw' | 'create' | 'fee'} TransactionType */
|
|
32
|
+
/** @typedef {'pending' | 'confirmed' | 'failed'} TransactionStatus */
|
|
33
|
+
/** @typedef {{ hash: string, type: TransactionType, amount: number, from: string, to: string, timestamp: number, status: TransactionStatus }} Transaction */
|
|
34
|
+
export const PROTOCOL_VERSION: "1.0.0";
|
|
35
|
+
/** @type {Readonly<ProtocolFeatures>} */
|
|
36
|
+
export const DEFAULT_PROTOCOL_FEATURES: Readonly<ProtocolFeatures>;
|
|
37
|
+
/** @type {Readonly<VaultStatus[]>} */
|
|
38
|
+
export const VAULT_STATUSES: Readonly<VaultStatus[]>;
|
|
39
|
+
/** @type {Readonly<TransactionType[]>} */
|
|
40
|
+
export const TRANSACTION_TYPES: Readonly<TransactionType[]>;
|
|
41
|
+
/** @type {Readonly<TransactionStatus[]>} */
|
|
42
|
+
export const TRANSACTION_STATUSES: Readonly<TransactionStatus[]>;
|
|
43
|
+
export type ProtocolFeatures = {
|
|
44
|
+
timeLock: boolean;
|
|
45
|
+
vaults: boolean;
|
|
46
|
+
governance: boolean;
|
|
47
|
+
rewards: boolean;
|
|
48
|
+
};
|
|
49
|
+
export type ProtocolConfig = {
|
|
50
|
+
network: string;
|
|
51
|
+
version: string;
|
|
52
|
+
features: ProtocolFeatures;
|
|
53
|
+
initialized?: boolean;
|
|
54
|
+
};
|
|
55
|
+
export type VaultStatus = "active" | "locked" | "withdrawn" | "failed";
|
|
56
|
+
export type Vault = {
|
|
57
|
+
id: string;
|
|
58
|
+
owner: string;
|
|
59
|
+
amount: number;
|
|
60
|
+
lockTime: number;
|
|
61
|
+
unlockTime: number;
|
|
62
|
+
status: VaultStatus;
|
|
63
|
+
fees: number;
|
|
64
|
+
};
|
|
65
|
+
export type TransactionType = "deposit" | "withdraw" | "create" | "fee";
|
|
66
|
+
export type TransactionStatus = "pending" | "confirmed" | "failed";
|
|
67
|
+
export type Transaction = {
|
|
68
|
+
hash: string;
|
|
69
|
+
type: TransactionType;
|
|
70
|
+
amount: number;
|
|
71
|
+
from: string;
|
|
72
|
+
to: string;
|
|
73
|
+
timestamp: number;
|
|
74
|
+
status: TransactionStatus;
|
|
75
|
+
};
|
package/dist/utils.d.ts
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @param {number | string | Date} timestamp
|
|
3
|
+
* @returns {string}
|
|
4
|
+
*/
|
|
5
|
+
export function formatTimestamp(timestamp: number | string | Date): string;
|
|
6
|
+
/**
|
|
7
|
+
* @param {number | string | Date} endTime
|
|
8
|
+
* @returns {TimeRemaining}
|
|
9
|
+
*/
|
|
10
|
+
export function calculateTimeRemaining(endTime: number | string | Date): TimeRemaining;
|
|
11
|
+
/**
|
|
12
|
+
* @param {string} address
|
|
13
|
+
* @returns {ValidationResult}
|
|
14
|
+
*/
|
|
15
|
+
export function validateAddressResult(address: string): ValidationResult;
|
|
16
|
+
/**
|
|
17
|
+
* @param {string} address
|
|
18
|
+
* @returns {boolean}
|
|
19
|
+
*/
|
|
20
|
+
export function validateAddress(address: string): boolean;
|
|
21
|
+
/**
|
|
22
|
+
* @param {number | string} amount
|
|
23
|
+
* @param {number} [decimals=6]
|
|
24
|
+
* @returns {string}
|
|
25
|
+
*/
|
|
26
|
+
export function formatAmount(amount: number | string, decimals?: number): string;
|
|
27
|
+
/**
|
|
28
|
+
* @param {string | number} amountStr
|
|
29
|
+
* @returns {number}
|
|
30
|
+
*/
|
|
31
|
+
export function parseAmount(amountStr: string | number): number;
|
|
32
|
+
/**
|
|
33
|
+
* @returns {string}
|
|
34
|
+
*/
|
|
35
|
+
export function generateId(): string;
|
|
36
|
+
/**
|
|
37
|
+
* @param {number} ms
|
|
38
|
+
* @returns {Promise<void>}
|
|
39
|
+
*/
|
|
40
|
+
export function sleep(ms: number): Promise<void>;
|
|
41
|
+
/**
|
|
42
|
+
* @template T
|
|
43
|
+
* @param {() => Promise<T>} fn
|
|
44
|
+
* @param {number} [maxRetries=3]
|
|
45
|
+
* @param {number} [delay=1000]
|
|
46
|
+
* @returns {Promise<T>}
|
|
47
|
+
*/
|
|
48
|
+
export function retry<T>(fn: () => Promise<T>, maxRetries?: number, delay?: number): Promise<T>;
|
|
49
|
+
export type TimeRemaining = {
|
|
50
|
+
days: number;
|
|
51
|
+
hours: number;
|
|
52
|
+
minutes: number;
|
|
53
|
+
seconds: number;
|
|
54
|
+
total: number;
|
|
55
|
+
};
|
|
56
|
+
export type ValidationResult = {
|
|
57
|
+
valid: boolean;
|
|
58
|
+
address?: string;
|
|
59
|
+
error?: string;
|
|
60
|
+
};
|
package/package.json
CHANGED
|
@@ -1,19 +1,28 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "timefi-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Official JavaScript SDK for TimeFi Protocol - Time-locked vaults on Stacks blockchain",
|
|
5
|
-
"main": "dist/index.
|
|
6
|
-
"module": "dist/index.
|
|
5
|
+
"main": "dist/index.cjs",
|
|
6
|
+
"module": "dist/index.mjs",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.mjs",
|
|
12
|
+
"require": "./dist/index.cjs"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
8
15
|
"files": [
|
|
9
16
|
"dist",
|
|
10
17
|
"README.md",
|
|
11
18
|
"LICENSE"
|
|
12
19
|
],
|
|
13
20
|
"scripts": {
|
|
14
|
-
"
|
|
15
|
-
"
|
|
16
|
-
"
|
|
21
|
+
"clean": "rimraf dist",
|
|
22
|
+
"build": "npm run clean && vite build && npm run build:types",
|
|
23
|
+
"build:types": "tsc -p tsconfig.types.json",
|
|
24
|
+
"test": "vitest run",
|
|
25
|
+
"prepublishOnly": "npm run build && npm run test"
|
|
17
26
|
},
|
|
18
27
|
"keywords": [
|
|
19
28
|
"stacks",
|
|
@@ -41,12 +50,17 @@
|
|
|
41
50
|
"publishConfig": {
|
|
42
51
|
"access": "public"
|
|
43
52
|
},
|
|
53
|
+
"engines": {
|
|
54
|
+
"node": ">=18"
|
|
55
|
+
},
|
|
44
56
|
"dependencies": {
|
|
45
57
|
"@stacks/transactions": "^6.0.0",
|
|
46
58
|
"@stacks/network": "^6.0.0"
|
|
47
59
|
},
|
|
48
60
|
"devDependencies": {
|
|
49
|
-
"
|
|
61
|
+
"rimraf": "^6.1.0",
|
|
62
|
+
"typescript": "^5.9.2",
|
|
63
|
+
"vite": "^5.0.0",
|
|
64
|
+
"vitest": "^4.0.8"
|
|
50
65
|
}
|
|
51
|
-
|
|
52
|
-
}
|
|
66
|
+
}
|
package/dist/index.esm.js
DELETED
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
import { callReadOnlyFunction as l, cvToValue as a, uintCV as i, PostConditionMode as c, AnchorMode as u } from "@stacks/transactions";
|
|
2
|
-
import { AnchorMode as b, PostConditionMode as D, bufferCV as k, noneCV as _, principalCV as S, responseErrorCV as L, responseOkCV as $, someCV as F, stringAsciiCV as v, stringUtf8CV as G, uintCV as P } from "@stacks/transactions";
|
|
3
|
-
import { StacksMainnet as f, StacksTestnet as d } from "@stacks/network";
|
|
4
|
-
const h = "SP3FKNEZ86RG5RT7SZ5FBRGH85FZNG94ZH1MCGG6N", s = {
|
|
5
|
-
VAULT: "timefi-vault-v-A2",
|
|
6
|
-
REWARDS: "timefi-rewards-v-A2",
|
|
7
|
-
GOVERNANCE: "timefi-governance-v-A2",
|
|
8
|
-
EMERGENCY: "timefi-emergency-v-A2"
|
|
9
|
-
}, N = {
|
|
10
|
-
MONTH_1: { label: "1 Month", blocks: 4320, apy: 1 },
|
|
11
|
-
MONTH_3: { label: "3 Months", blocks: 12960, apy: 3 },
|
|
12
|
-
MONTH_6: { label: "6 Months", blocks: 25920, apy: 6 },
|
|
13
|
-
MONTH_9: { label: "9 Months", blocks: 38880, apy: 9 },
|
|
14
|
-
YEAR_1: { label: "1 Year", blocks: 52560, apy: 12 }
|
|
15
|
-
}, M = 0.01, g = 1e6, y = (t) => {
|
|
16
|
-
if (t == null) return "0.000000";
|
|
17
|
-
try {
|
|
18
|
-
const n = typeof t == "object" && t !== null && "value" in t ? t.value : t, e = Number(n);
|
|
19
|
-
return isNaN(e) ? "0.000000" : (e / 1e6).toLocaleString(void 0, {
|
|
20
|
-
minimumFractionDigits: 0,
|
|
21
|
-
maximumFractionDigits: 6
|
|
22
|
-
});
|
|
23
|
-
} catch (n) {
|
|
24
|
-
return console.error("Error formatting STX:", n), "0.000000";
|
|
25
|
-
}
|
|
26
|
-
}, C = (t, n = 4, e = 4) => t ? t.length <= n + e ? t : `${t.slice(0, n + 2)}...${t.slice(-e)}` : "", T = (t) => {
|
|
27
|
-
if (t == null) return "0";
|
|
28
|
-
const n = Number(t);
|
|
29
|
-
return isNaN(n) ? "0" : n.toLocaleString();
|
|
30
|
-
}, p = (t, n = 2) => {
|
|
31
|
-
if (t == null) return "0%";
|
|
32
|
-
const e = Number(t);
|
|
33
|
-
return isNaN(e) ? "0%" : (e * 100).toFixed(n) + "%";
|
|
34
|
-
}, m = (t) => {
|
|
35
|
-
if (!t) return "--";
|
|
36
|
-
const n = new Date(t);
|
|
37
|
-
return isNaN(n.getTime()) ? "--" : n.toLocaleDateString(void 0, {
|
|
38
|
-
year: "numeric",
|
|
39
|
-
month: "short",
|
|
40
|
-
day: "numeric"
|
|
41
|
-
});
|
|
42
|
-
}, O = (t) => {
|
|
43
|
-
if (!t) return "--";
|
|
44
|
-
const n = /* @__PURE__ */ new Date(), e = new Date(t), r = Math.floor((n - e) / 1e3);
|
|
45
|
-
if (r < -1) {
|
|
46
|
-
const o = Math.abs(r);
|
|
47
|
-
return o < 60 ? "in a few seconds" : o < 3600 ? `in ${Math.floor(o / 60)}m` : o < 86400 ? `in ${Math.floor(o / 3600)}h` : `in ${Math.floor(o / 86400)}d`;
|
|
48
|
-
}
|
|
49
|
-
return r < 5 ? "just now" : r < 60 ? `${r}s ago` : r < 3600 ? `${Math.floor(r / 60)}m ago` : r < 86400 ? `${Math.floor(r / 3600)}h ago` : r < 604800 ? `${Math.floor(r / 86400)}d ago` : m(t);
|
|
50
|
-
};
|
|
51
|
-
class R {
|
|
52
|
-
constructor(n = "mainnet") {
|
|
53
|
-
this.network = n === "mainnet" ? new f() : new d(), this.contractAddress = h;
|
|
54
|
-
}
|
|
55
|
-
// --- Read-only Methods ---
|
|
56
|
-
async callReadOnly(n, e = [], r) {
|
|
57
|
-
const o = await l({
|
|
58
|
-
contractAddress: this.contractAddress,
|
|
59
|
-
contractName: s.VAULT,
|
|
60
|
-
functionName: n,
|
|
61
|
-
functionArgs: e,
|
|
62
|
-
network: this.network,
|
|
63
|
-
senderAddress: r || this.contractAddress
|
|
64
|
-
});
|
|
65
|
-
return o.type === 7 || o.type === 8 ? a(o.value) : a(o);
|
|
66
|
-
}
|
|
67
|
-
async getVault(n) {
|
|
68
|
-
if (n == null) throw new Error("vaultId is required");
|
|
69
|
-
return this.callReadOnly("get-vault", [i(n)]);
|
|
70
|
-
}
|
|
71
|
-
async getTimeRemaining(n) {
|
|
72
|
-
if (n == null) throw new Error("vaultId is required");
|
|
73
|
-
return this.callReadOnly("get-time-remaining", [i(n)]);
|
|
74
|
-
}
|
|
75
|
-
async canWithdraw(n) {
|
|
76
|
-
if (n == null) throw new Error("vaultId is required");
|
|
77
|
-
return this.callReadOnly("can-withdraw", [i(n)]);
|
|
78
|
-
}
|
|
79
|
-
async getTVL() {
|
|
80
|
-
return this.callReadOnly("get-tvl", []);
|
|
81
|
-
}
|
|
82
|
-
// --- Transaction Signing Options Helpers ---
|
|
83
|
-
getCreateVaultOptions(n, e) {
|
|
84
|
-
return {
|
|
85
|
-
contractAddress: this.contractAddress,
|
|
86
|
-
contractName: s.VAULT,
|
|
87
|
-
functionName: "create-vault",
|
|
88
|
-
functionArgs: [i(n * 1e6), i(e)],
|
|
89
|
-
network: this.network,
|
|
90
|
-
anchorMode: u.Any,
|
|
91
|
-
postConditionMode: c.Deny
|
|
92
|
-
};
|
|
93
|
-
}
|
|
94
|
-
getWithdrawOptions(n) {
|
|
95
|
-
if (n == null) throw new Error("vaultId is required");
|
|
96
|
-
return {
|
|
97
|
-
contractAddress: this.contractAddress,
|
|
98
|
-
contractName: s.VAULT,
|
|
99
|
-
functionName: "request-withdraw",
|
|
100
|
-
functionArgs: [i(n)],
|
|
101
|
-
network: this.network,
|
|
102
|
-
anchorMode: u.Any,
|
|
103
|
-
postConditionMode: c.Deny
|
|
104
|
-
};
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
export {
|
|
108
|
-
b as AnchorMode,
|
|
109
|
-
h as CONTRACT_ADDRESS,
|
|
110
|
-
s as CONTRACT_NAMES,
|
|
111
|
-
N as LOCK_PERIODS,
|
|
112
|
-
g as MAX_DEPOSIT,
|
|
113
|
-
M as MIN_DEPOSIT,
|
|
114
|
-
D as PostConditionMode,
|
|
115
|
-
R as TimeFiClient,
|
|
116
|
-
k as bufferCV,
|
|
117
|
-
C as formatAddress,
|
|
118
|
-
m as formatDate,
|
|
119
|
-
T as formatNumber,
|
|
120
|
-
p as formatPercent,
|
|
121
|
-
O as formatRelativeTime,
|
|
122
|
-
y as formatSTX,
|
|
123
|
-
_ as noneCV,
|
|
124
|
-
S as principalCV,
|
|
125
|
-
L as responseErrorCV,
|
|
126
|
-
$ as responseOkCV,
|
|
127
|
-
F as someCV,
|
|
128
|
-
v as stringAsciiCV,
|
|
129
|
-
G as stringUtf8CV,
|
|
130
|
-
P as uintCV
|
|
131
|
-
};
|
package/dist/index.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const n=require("@stacks/transactions"),s=require("@stacks/network"),u="SP3FKNEZ86RG5RT7SZ5FBRGH85FZNG94ZH1MCGG6N",a={VAULT:"timefi-vault-v-A2",REWARDS:"timefi-rewards-v-A2",GOVERNANCE:"timefi-governance-v-A2",EMERGENCY:"timefi-emergency-v-A2"},l={MONTH_1:{label:"1 Month",blocks:4320,apy:1},MONTH_3:{label:"3 Months",blocks:12960,apy:3},MONTH_6:{label:"6 Months",blocks:25920,apy:6},MONTH_9:{label:"9 Months",blocks:38880,apy:9},YEAR_1:{label:"1 Year",blocks:52560,apy:12}},f=.01,d=1e6,m=t=>{if(t==null)return"0.000000";try{const e=typeof t=="object"&&t!==null&&"value"in t?t.value:t,r=Number(e);return isNaN(r)?"0.000000":(r/1e6).toLocaleString(void 0,{minimumFractionDigits:0,maximumFractionDigits:6})}catch(e){return console.error("Error formatting STX:",e),"0.000000"}},C=(t,e=4,r=4)=>t?t.length<=e+r?t:`${t.slice(0,e+2)}...${t.slice(-r)}`:"",h=t=>{if(t==null)return"0";const e=Number(t);return isNaN(e)?"0":e.toLocaleString()},b=(t,e=2)=>{if(t==null)return"0%";const r=Number(t);return isNaN(r)?"0%":(r*100).toFixed(e)+"%"},c=t=>{if(!t)return"--";const e=new Date(t);return isNaN(e.getTime())?"--":e.toLocaleDateString(void 0,{year:"numeric",month:"short",day:"numeric"})},g=t=>{if(!t)return"--";const e=new Date,r=new Date(t),o=Math.floor((e-r)/1e3);if(o<-1){const i=Math.abs(o);return i<60?"in a few seconds":i<3600?`in ${Math.floor(i/60)}m`:i<86400?`in ${Math.floor(i/3600)}h`:`in ${Math.floor(i/86400)}d`}return o<5?"just now":o<60?`${o}s ago`:o<3600?`${Math.floor(o/60)}m ago`:o<86400?`${Math.floor(o/3600)}h ago`:o<604800?`${Math.floor(o/86400)}d ago`:c(t)};class A{constructor(e="mainnet"){this.network=e==="mainnet"?new s.StacksMainnet:new s.StacksTestnet,this.contractAddress=u}async callReadOnly(e,r=[],o){const i=await n.callReadOnlyFunction({contractAddress:this.contractAddress,contractName:a.VAULT,functionName:e,functionArgs:r,network:this.network,senderAddress:o||this.contractAddress});return i.type===7||i.type===8?n.cvToValue(i.value):n.cvToValue(i)}async getVault(e){if(e==null)throw new Error("vaultId is required");return this.callReadOnly("get-vault",[n.uintCV(e)])}async getTimeRemaining(e){if(e==null)throw new Error("vaultId is required");return this.callReadOnly("get-time-remaining",[n.uintCV(e)])}async canWithdraw(e){if(e==null)throw new Error("vaultId is required");return this.callReadOnly("can-withdraw",[n.uintCV(e)])}async getTVL(){return this.callReadOnly("get-tvl",[])}getCreateVaultOptions(e,r){return{contractAddress:this.contractAddress,contractName:a.VAULT,functionName:"create-vault",functionArgs:[n.uintCV(e*1e6),n.uintCV(r)],network:this.network,anchorMode:n.AnchorMode.Any,postConditionMode:n.PostConditionMode.Deny}}getWithdrawOptions(e){if(e==null)throw new Error("vaultId is required");return{contractAddress:this.contractAddress,contractName:a.VAULT,functionName:"request-withdraw",functionArgs:[n.uintCV(e)],network:this.network,anchorMode:n.AnchorMode.Any,postConditionMode:n.PostConditionMode.Deny}}}Object.defineProperty(exports,"AnchorMode",{enumerable:!0,get:()=>n.AnchorMode});Object.defineProperty(exports,"PostConditionMode",{enumerable:!0,get:()=>n.PostConditionMode});Object.defineProperty(exports,"bufferCV",{enumerable:!0,get:()=>n.bufferCV});Object.defineProperty(exports,"noneCV",{enumerable:!0,get:()=>n.noneCV});Object.defineProperty(exports,"principalCV",{enumerable:!0,get:()=>n.principalCV});Object.defineProperty(exports,"responseErrorCV",{enumerable:!0,get:()=>n.responseErrorCV});Object.defineProperty(exports,"responseOkCV",{enumerable:!0,get:()=>n.responseOkCV});Object.defineProperty(exports,"someCV",{enumerable:!0,get:()=>n.someCV});Object.defineProperty(exports,"stringAsciiCV",{enumerable:!0,get:()=>n.stringAsciiCV});Object.defineProperty(exports,"stringUtf8CV",{enumerable:!0,get:()=>n.stringUtf8CV});Object.defineProperty(exports,"uintCV",{enumerable:!0,get:()=>n.uintCV});exports.CONTRACT_ADDRESS=u;exports.CONTRACT_NAMES=a;exports.LOCK_PERIODS=l;exports.MAX_DEPOSIT=d;exports.MIN_DEPOSIT=f;exports.TimeFiClient=A;exports.formatAddress=C;exports.formatDate=c;exports.formatNumber=h;exports.formatPercent=b;exports.formatRelativeTime=g;exports.formatSTX=m;
|