@gvnrdao/dh-lit-actions 0.0.61 → 0.0.68
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/package.json +3 -3
- package/pkg-dist/pkg-src/constants/chunks/lit-actions-registry.d.ts.map +1 -0
- package/pkg-dist/{constants → pkg-src/constants}/chunks/lit-actions-registry.js +16 -16
- package/pkg-dist/pkg-src/constants/chunks/lit-actions-registry.js.map +1 -0
- package/pkg-dist/pkg-src/constants/chunks/package-registry.d.ts.map +1 -0
- package/pkg-dist/pkg-src/constants/chunks/package-registry.js.map +1 -0
- package/pkg-dist/pkg-src/constants/index.d.ts.map +1 -0
- package/pkg-dist/pkg-src/constants/index.js.map +1 -0
- package/pkg-dist/pkg-src/executors/chunks/vault-snapshot-executor.d.ts +40 -0
- package/pkg-dist/pkg-src/executors/chunks/vault-snapshot-executor.d.ts.map +1 -0
- package/pkg-dist/pkg-src/executors/chunks/vault-snapshot-executor.js +102 -0
- package/pkg-dist/pkg-src/executors/chunks/vault-snapshot-executor.js.map +1 -0
- package/pkg-dist/pkg-src/executors/index.d.ts +43 -0
- package/pkg-dist/pkg-src/executors/index.d.ts.map +1 -0
- package/pkg-dist/pkg-src/executors/index.js +48 -0
- package/pkg-dist/pkg-src/executors/index.js.map +1 -0
- package/pkg-dist/{index.d.ts → pkg-src/index.d.ts} +1 -2
- package/pkg-dist/pkg-src/index.d.ts.map +1 -0
- package/pkg-dist/{index.js → pkg-src/index.js} +1 -4
- package/pkg-dist/pkg-src/index.js.map +1 -0
- package/pkg-dist/pkg-src/interfaces/chunks/diamond-hands-lit-actions.i.d.ts.map +1 -0
- package/pkg-dist/pkg-src/interfaces/chunks/diamond-hands-lit-actions.i.js.map +1 -0
- package/pkg-dist/pkg-src/interfaces/chunks/lit-action-config.i.d.ts.map +1 -0
- package/pkg-dist/pkg-src/interfaces/chunks/lit-action-config.i.js.map +1 -0
- package/pkg-dist/pkg-src/interfaces/chunks/lit-action-name.i.d.ts.map +1 -0
- package/pkg-dist/pkg-src/interfaces/chunks/lit-action-name.i.js.map +1 -0
- package/pkg-dist/pkg-src/interfaces/chunks/lit-action-registry.i.d.ts.map +1 -0
- package/pkg-dist/pkg-src/interfaces/chunks/lit-action-registry.i.js.map +1 -0
- package/pkg-dist/pkg-src/interfaces/chunks/pkp-info.i.d.ts.map +1 -0
- package/pkg-dist/pkg-src/interfaces/chunks/pkp-info.i.js.map +1 -0
- package/pkg-dist/pkg-src/interfaces/index.d.ts.map +1 -0
- package/pkg-dist/pkg-src/interfaces/index.js.map +1 -0
- package/pkg-dist/pkg-src/utils/chunks/cid-utils.d.ts.map +1 -0
- package/pkg-dist/pkg-src/utils/chunks/cid-utils.js.map +1 -0
- package/pkg-dist/pkg-src/utils/chunks/connection-helpers.d.ts.map +1 -0
- package/pkg-dist/pkg-src/utils/chunks/connection-helpers.js.map +1 -0
- package/pkg-dist/pkg-src/utils/chunks/debug-logger.d.ts.map +1 -0
- package/pkg-dist/pkg-src/utils/chunks/debug-logger.js.map +1 -0
- package/pkg-dist/pkg-src/utils/chunks/error-classification.d.ts.map +1 -0
- package/pkg-dist/pkg-src/utils/chunks/error-classification.js.map +1 -0
- package/pkg-dist/pkg-src/utils/chunks/lit-action-helpers.d.ts.map +1 -0
- package/pkg-dist/pkg-src/utils/chunks/lit-action-helpers.js.map +1 -0
- package/pkg-dist/pkg-src/utils/chunks/pkp-setup.d.ts.map +1 -0
- package/pkg-dist/pkg-src/utils/chunks/pkp-setup.js.map +1 -0
- package/pkg-dist/pkg-src/utils/chunks/session-signature-cache.d.ts.map +1 -0
- package/pkg-dist/pkg-src/utils/chunks/session-signature-cache.js.map +1 -0
- package/pkg-dist/pkg-src/utils/index.d.ts.map +1 -0
- package/pkg-dist/pkg-src/utils/index.js.map +1 -0
- package/pkg-dist/src/constants/chunks/bitcoin-network-config.d.ts +130 -0
- package/pkg-dist/src/constants/chunks/bitcoin-network-config.d.ts.map +1 -0
- package/pkg-dist/src/constants/chunks/bitcoin-network-config.js +244 -0
- package/pkg-dist/src/constants/chunks/bitcoin-network-config.js.map +1 -0
- package/pkg-dist/src/constants/chunks/bitcoin.d.ts +42 -0
- package/pkg-dist/src/constants/chunks/bitcoin.d.ts.map +1 -0
- package/pkg-dist/src/constants/chunks/bitcoin.js +45 -0
- package/pkg-dist/src/constants/chunks/bitcoin.js.map +1 -0
- package/pkg-dist/src/constants/chunks/decimals.d.ts +44 -0
- package/pkg-dist/src/constants/chunks/decimals.d.ts.map +1 -0
- package/pkg-dist/src/constants/chunks/decimals.js +47 -0
- package/pkg-dist/src/constants/chunks/decimals.js.map +1 -0
- package/pkg-dist/src/constants/chunks/liquidation.d.ts +51 -0
- package/pkg-dist/src/constants/chunks/liquidation.d.ts.map +1 -0
- package/pkg-dist/src/constants/chunks/liquidation.js +54 -0
- package/pkg-dist/src/constants/chunks/liquidation.js.map +1 -0
- package/pkg-dist/src/constants/chunks/loan-status.d.ts +57 -0
- package/pkg-dist/src/constants/chunks/loan-status.d.ts.map +1 -0
- package/pkg-dist/src/constants/chunks/loan-status.js +95 -0
- package/pkg-dist/src/constants/chunks/loan-status.js.map +1 -0
- package/pkg-dist/src/constants/chunks/price-oracle.d.ts +46 -0
- package/pkg-dist/src/constants/chunks/price-oracle.d.ts.map +1 -0
- package/pkg-dist/src/constants/chunks/price-oracle.js +49 -0
- package/pkg-dist/src/constants/chunks/price-oracle.js.map +1 -0
- package/pkg-dist/src/constants/chunks/quantum-time.d.ts +63 -0
- package/pkg-dist/src/constants/chunks/quantum-time.d.ts.map +1 -0
- package/pkg-dist/src/constants/chunks/quantum-time.js +66 -0
- package/pkg-dist/src/constants/chunks/quantum-time.js.map +1 -0
- package/pkg-dist/src/constants/index.d.ts +16 -0
- package/pkg-dist/src/constants/index.d.ts.map +1 -0
- package/pkg-dist/src/constants/index.js +57 -0
- package/pkg-dist/src/constants/index.js.map +1 -0
- package/pkg-dist/src/interfaces/chunks/authorization.i.d.ts +19 -0
- package/pkg-dist/src/interfaces/chunks/authorization.i.d.ts.map +1 -0
- package/pkg-dist/src/interfaces/chunks/authorization.i.js +3 -0
- package/pkg-dist/src/interfaces/chunks/authorization.i.js.map +1 -0
- package/pkg-dist/src/interfaces/chunks/bitcoin-data-provider.i.d.ts +60 -0
- package/pkg-dist/src/interfaces/chunks/bitcoin-data-provider.i.d.ts.map +1 -0
- package/pkg-dist/src/interfaces/chunks/bitcoin-data-provider.i.js +3 -0
- package/pkg-dist/src/interfaces/chunks/bitcoin-data-provider.i.js.map +1 -0
- package/pkg-dist/src/interfaces/chunks/circuit-breaker.i.d.ts +18 -0
- package/pkg-dist/src/interfaces/chunks/circuit-breaker.i.d.ts.map +1 -0
- package/pkg-dist/src/interfaces/chunks/circuit-breaker.i.js +8 -0
- package/pkg-dist/src/interfaces/chunks/circuit-breaker.i.js.map +1 -0
- package/pkg-dist/src/interfaces/chunks/mint-authorization.i.d.ts +24 -0
- package/pkg-dist/src/interfaces/chunks/mint-authorization.i.d.ts.map +1 -0
- package/pkg-dist/src/interfaces/chunks/mint-authorization.i.js +5 -0
- package/pkg-dist/src/interfaces/chunks/mint-authorization.i.js.map +1 -0
- package/pkg-dist/src/interfaces/chunks/owner-authorization.d.ts +60 -0
- package/pkg-dist/src/interfaces/chunks/owner-authorization.d.ts.map +1 -0
- package/pkg-dist/src/interfaces/chunks/owner-authorization.js +8 -0
- package/pkg-dist/src/interfaces/chunks/owner-authorization.js.map +1 -0
- package/pkg-dist/src/interfaces/chunks/price-oracle.i.d.ts +26 -0
- package/pkg-dist/src/interfaces/chunks/price-oracle.i.d.ts.map +1 -0
- package/pkg-dist/src/interfaces/chunks/price-oracle.i.js +3 -0
- package/pkg-dist/src/interfaces/chunks/price-oracle.i.js.map +1 -0
- package/pkg-dist/src/interfaces/chunks/vault-balance-module.i.d.ts +23 -0
- package/pkg-dist/src/interfaces/chunks/vault-balance-module.i.d.ts.map +1 -0
- package/pkg-dist/src/interfaces/chunks/vault-balance-module.i.js +3 -0
- package/pkg-dist/src/interfaces/chunks/vault-balance-module.i.js.map +1 -0
- package/pkg-dist/src/interfaces/chunks/vault-balance.i.d.ts +63 -0
- package/pkg-dist/src/interfaces/chunks/vault-balance.i.d.ts.map +1 -0
- package/pkg-dist/src/interfaces/chunks/vault-balance.i.js +3 -0
- package/pkg-dist/src/interfaces/chunks/vault-balance.i.js.map +1 -0
- package/pkg-dist/src/interfaces/chunks/vault-snapshot.i.d.ts +51 -0
- package/pkg-dist/src/interfaces/chunks/vault-snapshot.i.d.ts.map +1 -0
- package/pkg-dist/src/interfaces/chunks/vault-snapshot.i.js +3 -0
- package/pkg-dist/src/interfaces/chunks/vault-snapshot.i.js.map +1 -0
- package/pkg-dist/src/interfaces/index.d.ts +15 -0
- package/pkg-dist/src/interfaces/index.d.ts.map +1 -0
- package/pkg-dist/src/interfaces/index.js +30 -0
- package/pkg-dist/src/interfaces/index.js.map +1 -0
- package/pkg-dist/src/modules/authorization.module.d.ts +160 -0
- package/pkg-dist/src/modules/authorization.module.d.ts.map +1 -0
- package/pkg-dist/src/modules/authorization.module.js +317 -0
- package/pkg-dist/src/modules/authorization.module.js.map +1 -0
- package/pkg-dist/src/modules/bitcoin-data-provider.module.d.ts +91 -0
- package/pkg-dist/src/modules/bitcoin-data-provider.module.d.ts.map +1 -0
- package/pkg-dist/src/modules/bitcoin-data-provider.module.js +261 -0
- package/pkg-dist/src/modules/bitcoin-data-provider.module.js.map +1 -0
- package/pkg-dist/src/modules/business-rules-math.module.d.ts +155 -0
- package/pkg-dist/src/modules/business-rules-math.module.d.ts.map +1 -0
- package/pkg-dist/src/modules/business-rules-math.module.js +309 -0
- package/pkg-dist/src/modules/business-rules-math.module.js.map +1 -0
- package/pkg-dist/src/modules/price-oracle.module.d.ts +29 -0
- package/pkg-dist/src/modules/price-oracle.module.d.ts.map +1 -0
- package/pkg-dist/src/modules/price-oracle.module.js +223 -0
- package/pkg-dist/src/modules/price-oracle.module.js.map +1 -0
- package/pkg-dist/src/modules/protocol-parameters.module.d.ts +58 -0
- package/pkg-dist/src/modules/protocol-parameters.module.d.ts.map +1 -0
- package/pkg-dist/src/modules/protocol-parameters.module.js +125 -0
- package/pkg-dist/src/modules/protocol-parameters.module.js.map +1 -0
- package/pkg-dist/src/modules/quantum-time.module.d.ts +149 -0
- package/pkg-dist/src/modules/quantum-time.module.d.ts.map +1 -0
- package/pkg-dist/src/modules/quantum-time.module.js +240 -0
- package/pkg-dist/src/modules/quantum-time.module.js.map +1 -0
- package/pkg-dist/src/modules/vault-balance.module.d.ts +172 -0
- package/pkg-dist/src/modules/vault-balance.module.d.ts.map +1 -0
- package/pkg-dist/src/modules/vault-balance.module.js +318 -0
- package/pkg-dist/src/modules/vault-balance.module.js.map +1 -0
- package/pkg-dist/src/modules/vault-snapshot.d.ts +168 -0
- package/pkg-dist/src/modules/vault-snapshot.d.ts.map +1 -0
- package/pkg-dist/src/modules/vault-snapshot.js +370 -0
- package/pkg-dist/src/modules/vault-snapshot.js.map +1 -0
- package/pkg-dist/constants/chunks/contract-deployments.d.ts +0 -65
- package/pkg-dist/constants/chunks/contract-deployments.d.ts.map +0 -1
- package/pkg-dist/constants/chunks/contract-deployments.js +0 -181
- package/pkg-dist/constants/chunks/contract-deployments.js.map +0 -1
- package/pkg-dist/constants/chunks/lit-actions-registry.d.ts.map +0 -1
- package/pkg-dist/constants/chunks/lit-actions-registry.js.map +0 -1
- package/pkg-dist/constants/chunks/package-registry.d.ts.map +0 -1
- package/pkg-dist/constants/chunks/package-registry.js.map +0 -1
- package/pkg-dist/constants/index.d.ts.map +0 -1
- package/pkg-dist/constants/index.js.map +0 -1
- package/pkg-dist/index.d.ts.map +0 -1
- package/pkg-dist/index.js.map +0 -1
- package/pkg-dist/interfaces/chunks/diamond-hands-lit-actions.i.d.ts.map +0 -1
- package/pkg-dist/interfaces/chunks/diamond-hands-lit-actions.i.js.map +0 -1
- package/pkg-dist/interfaces/chunks/lit-action-config.i.d.ts.map +0 -1
- package/pkg-dist/interfaces/chunks/lit-action-config.i.js.map +0 -1
- package/pkg-dist/interfaces/chunks/lit-action-name.i.d.ts.map +0 -1
- package/pkg-dist/interfaces/chunks/lit-action-name.i.js.map +0 -1
- package/pkg-dist/interfaces/chunks/lit-action-registry.i.d.ts.map +0 -1
- package/pkg-dist/interfaces/chunks/lit-action-registry.i.js.map +0 -1
- package/pkg-dist/interfaces/chunks/pkp-info.i.d.ts.map +0 -1
- package/pkg-dist/interfaces/chunks/pkp-info.i.js.map +0 -1
- package/pkg-dist/interfaces/deployments.d.ts +0 -117
- package/pkg-dist/interfaces/deployments.d.ts.map +0 -1
- package/pkg-dist/interfaces/deployments.js +0 -7
- package/pkg-dist/interfaces/deployments.js.map +0 -1
- package/pkg-dist/interfaces/index.d.ts.map +0 -1
- package/pkg-dist/interfaces/index.js.map +0 -1
- package/pkg-dist/utils/chunks/cid-utils.d.ts.map +0 -1
- package/pkg-dist/utils/chunks/cid-utils.js.map +0 -1
- package/pkg-dist/utils/chunks/connection-helpers.d.ts.map +0 -1
- package/pkg-dist/utils/chunks/connection-helpers.js.map +0 -1
- package/pkg-dist/utils/chunks/debug-logger.d.ts.map +0 -1
- package/pkg-dist/utils/chunks/debug-logger.js.map +0 -1
- package/pkg-dist/utils/chunks/error-classification.d.ts.map +0 -1
- package/pkg-dist/utils/chunks/error-classification.js.map +0 -1
- package/pkg-dist/utils/chunks/lit-action-helpers.d.ts.map +0 -1
- package/pkg-dist/utils/chunks/lit-action-helpers.js.map +0 -1
- package/pkg-dist/utils/chunks/pkp-setup.d.ts.map +0 -1
- package/pkg-dist/utils/chunks/pkp-setup.js.map +0 -1
- package/pkg-dist/utils/chunks/session-signature-cache.d.ts.map +0 -1
- package/pkg-dist/utils/chunks/session-signature-cache.js.map +0 -1
- package/pkg-dist/utils/index.d.ts.map +0 -1
- package/pkg-dist/utils/index.js.map +0 -1
- /package/pkg-dist/{constants → pkg-src/constants}/chunks/lit-actions-registry.d.ts +0 -0
- /package/pkg-dist/{constants → pkg-src/constants}/chunks/package-registry.d.ts +0 -0
- /package/pkg-dist/{constants → pkg-src/constants}/chunks/package-registry.js +0 -0
- /package/pkg-dist/{constants → pkg-src/constants}/index.d.ts +0 -0
- /package/pkg-dist/{constants → pkg-src/constants}/index.js +0 -0
- /package/pkg-dist/{interfaces → pkg-src/interfaces}/chunks/diamond-hands-lit-actions.i.d.ts +0 -0
- /package/pkg-dist/{interfaces → pkg-src/interfaces}/chunks/diamond-hands-lit-actions.i.js +0 -0
- /package/pkg-dist/{interfaces → pkg-src/interfaces}/chunks/lit-action-config.i.d.ts +0 -0
- /package/pkg-dist/{interfaces → pkg-src/interfaces}/chunks/lit-action-config.i.js +0 -0
- /package/pkg-dist/{interfaces → pkg-src/interfaces}/chunks/lit-action-name.i.d.ts +0 -0
- /package/pkg-dist/{interfaces → pkg-src/interfaces}/chunks/lit-action-name.i.js +0 -0
- /package/pkg-dist/{interfaces → pkg-src/interfaces}/chunks/lit-action-registry.i.d.ts +0 -0
- /package/pkg-dist/{interfaces → pkg-src/interfaces}/chunks/lit-action-registry.i.js +0 -0
- /package/pkg-dist/{interfaces → pkg-src/interfaces}/chunks/pkp-info.i.d.ts +0 -0
- /package/pkg-dist/{interfaces → pkg-src/interfaces}/chunks/pkp-info.i.js +0 -0
- /package/pkg-dist/{interfaces → pkg-src/interfaces}/index.d.ts +0 -0
- /package/pkg-dist/{interfaces → pkg-src/interfaces}/index.js +0 -0
- /package/pkg-dist/{utils → pkg-src/utils}/chunks/cid-utils.d.ts +0 -0
- /package/pkg-dist/{utils → pkg-src/utils}/chunks/cid-utils.js +0 -0
- /package/pkg-dist/{utils → pkg-src/utils}/chunks/connection-helpers.d.ts +0 -0
- /package/pkg-dist/{utils → pkg-src/utils}/chunks/connection-helpers.js +0 -0
- /package/pkg-dist/{utils → pkg-src/utils}/chunks/debug-logger.d.ts +0 -0
- /package/pkg-dist/{utils → pkg-src/utils}/chunks/debug-logger.js +0 -0
- /package/pkg-dist/{utils → pkg-src/utils}/chunks/error-classification.d.ts +0 -0
- /package/pkg-dist/{utils → pkg-src/utils}/chunks/error-classification.js +0 -0
- /package/pkg-dist/{utils → pkg-src/utils}/chunks/lit-action-helpers.d.ts +0 -0
- /package/pkg-dist/{utils → pkg-src/utils}/chunks/lit-action-helpers.js +0 -0
- /package/pkg-dist/{utils → pkg-src/utils}/chunks/pkp-setup.d.ts +0 -0
- /package/pkg-dist/{utils → pkg-src/utils}/chunks/pkp-setup.js +0 -0
- /package/pkg-dist/{utils → pkg-src/utils}/chunks/session-signature-cache.d.ts +0 -0
- /package/pkg-dist/{utils → pkg-src/utils}/chunks/session-signature-cache.js +0 -0
- /package/pkg-dist/{utils → pkg-src/utils}/index.d.ts +0 -0
- /package/pkg-dist/{utils → pkg-src/utils}/index.js +0 -0
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Business Rules Math Module
|
|
4
|
+
*
|
|
5
|
+
* Pure calculation functions for Diamond Hands Protocol business logic.
|
|
6
|
+
* These functions contain no side effects - they only perform calculations.
|
|
7
|
+
*
|
|
8
|
+
* Used by vault-snapshot and other modules for consistent math across the system.
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.calculateTermStartFromExpiry = calculateTermStartFromExpiry;
|
|
12
|
+
exports.calculateTermStatus = calculateTermStatus;
|
|
13
|
+
exports.calculateLiquidationThreshold = calculateLiquidationThreshold;
|
|
14
|
+
exports.calculateCollateralMetrics = calculateCollateralMetrics;
|
|
15
|
+
exports.hasSufficientCollateralForDebt = hasSufficientCollateralForDebt;
|
|
16
|
+
exports.calculateFeeBps = calculateFeeBps;
|
|
17
|
+
exports.calculateBtcValueUsd = calculateBtcValueUsd;
|
|
18
|
+
exports.calculateCollateralRatioBps = calculateCollateralRatioBps;
|
|
19
|
+
exports.isCollateralSufficient = isCollateralSufficient;
|
|
20
|
+
exports.bpsToPercent = bpsToPercent;
|
|
21
|
+
const constants_1 = require("../constants");
|
|
22
|
+
/**
|
|
23
|
+
* Calculate term start timestamp from expiry timestamp and term length
|
|
24
|
+
*
|
|
25
|
+
* Contract stores expiryAt but not termStartTimestamp.
|
|
26
|
+
* We derive it: termStart = expiry - (termLength * 30 days)
|
|
27
|
+
*
|
|
28
|
+
* Uses constants to avoid magic numbers and ensure accuracy.
|
|
29
|
+
*
|
|
30
|
+
* @param expiryTimestamp - Unix timestamp when term expires (0 if no term)
|
|
31
|
+
* @param termLengthMonths - Term length in months
|
|
32
|
+
* @returns Unix timestamp when term started (0 if no term)
|
|
33
|
+
*/
|
|
34
|
+
function calculateTermStartFromExpiry(expiryTimestamp, termLengthMonths) {
|
|
35
|
+
// No term started if expiryAt is 0
|
|
36
|
+
if (expiryTimestamp === 0) {
|
|
37
|
+
return 0;
|
|
38
|
+
}
|
|
39
|
+
// Constants for time calculations
|
|
40
|
+
const SECONDS_PER_DAY = 86400;
|
|
41
|
+
const DAYS_PER_MONTH = 30;
|
|
42
|
+
// Calculate term start
|
|
43
|
+
// termStart = expiry - (months * 30 days/month * 86400 seconds/day)
|
|
44
|
+
const termDurationSeconds = termLengthMonths * DAYS_PER_MONTH * SECONDS_PER_DAY;
|
|
45
|
+
return expiryTimestamp - termDurationSeconds;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Calculate term status from timestamps
|
|
49
|
+
*
|
|
50
|
+
* Determines:
|
|
51
|
+
* - How long into the term we are
|
|
52
|
+
* - Whether term is expired
|
|
53
|
+
* - Days until expiry or days into grace period
|
|
54
|
+
*
|
|
55
|
+
* @param termStartTimestamp - Unix timestamp when term started (0 if not started)
|
|
56
|
+
* @param selectedTermMonths - Term length in months
|
|
57
|
+
* @returns Complete term status metrics
|
|
58
|
+
*/
|
|
59
|
+
function calculateTermStatus(termStartTimestamp, selectedTermMonths) {
|
|
60
|
+
// If no term started yet (no debt), return zeros
|
|
61
|
+
if (termStartTimestamp === 0) {
|
|
62
|
+
return {
|
|
63
|
+
termDurationDays: 0,
|
|
64
|
+
termLengthDays: selectedTermMonths * 30,
|
|
65
|
+
isExpired: false,
|
|
66
|
+
daysUntilExpiry: selectedTermMonths * 30,
|
|
67
|
+
daysIntoGracePeriod: 0,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
const now = Math.floor(Date.now() / 1000);
|
|
71
|
+
const termLengthDays = selectedTermMonths * 30;
|
|
72
|
+
const termDurationSeconds = now - termStartTimestamp;
|
|
73
|
+
const termDurationDays = Math.floor(termDurationSeconds / 86400);
|
|
74
|
+
const isExpired = termDurationDays > termLengthDays;
|
|
75
|
+
const daysUntilExpiry = Math.max(0, termLengthDays - termDurationDays);
|
|
76
|
+
const daysIntoGracePeriod = Math.max(0, termDurationDays - termLengthDays);
|
|
77
|
+
return {
|
|
78
|
+
termDurationDays,
|
|
79
|
+
termLengthDays,
|
|
80
|
+
isExpired,
|
|
81
|
+
daysUntilExpiry,
|
|
82
|
+
daysIntoGracePeriod,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Calculate current liquidation threshold with grace period escalation
|
|
87
|
+
*
|
|
88
|
+
* Active loan: 130% (13000 bps)
|
|
89
|
+
* Expired:
|
|
90
|
+
* Day 0: 110% (11000 bps)
|
|
91
|
+
* Day 30: 200% (20000 bps)
|
|
92
|
+
* Quadratic escalation between
|
|
93
|
+
*
|
|
94
|
+
* Uses integer-only math for deterministic results across all platforms.
|
|
95
|
+
*
|
|
96
|
+
* @param isExpired - Whether loan is expired
|
|
97
|
+
* @param daysIntoGracePeriod - Days past expiry (0 if not expired)
|
|
98
|
+
* @returns Liquidation threshold in basis points
|
|
99
|
+
*/
|
|
100
|
+
function calculateLiquidationThreshold(isExpired, daysIntoGracePeriod) {
|
|
101
|
+
// Active loan: Use protocol constant
|
|
102
|
+
if (!isExpired) {
|
|
103
|
+
return constants_1.ACTIVE_LOAN_LIQUIDATION_THRESHOLD_BPS;
|
|
104
|
+
}
|
|
105
|
+
// Expired: escalate from MIN to MAX over grace period using protocol constants
|
|
106
|
+
// Cap at grace period days
|
|
107
|
+
const day = Math.min(daysIntoGracePeriod, constants_1.GRACE_PERIOD_DAYS);
|
|
108
|
+
// Quadratic curve using ONLY integer math for determinism:
|
|
109
|
+
// threshold = MIN + ((day^2 / GRACE_PERIOD_DAYS^2) * (MAX - MIN))
|
|
110
|
+
//
|
|
111
|
+
// This avoids floating point entirely while maintaining quadratic curve
|
|
112
|
+
const daySquared = day * day;
|
|
113
|
+
const escalation = (daySquared *
|
|
114
|
+
(constants_1.EXPIRED_LOAN_MAX_LIQUIDATION_THRESHOLD_BPS -
|
|
115
|
+
constants_1.EXPIRED_LOAN_MIN_LIQUIDATION_THRESHOLD_BPS)) /
|
|
116
|
+
(constants_1.GRACE_PERIOD_DAYS * constants_1.GRACE_PERIOD_DAYS);
|
|
117
|
+
const threshold = constants_1.EXPIRED_LOAN_MIN_LIQUIDATION_THRESHOLD_BPS + escalation;
|
|
118
|
+
return threshold;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Calculate collateral metrics from BTC balance and debt
|
|
122
|
+
*
|
|
123
|
+
* Converts BTC balance to USD value and calculates collateral ratio.
|
|
124
|
+
* Uses BigInt for all calculations to avoid JavaScript number precision issues.
|
|
125
|
+
*
|
|
126
|
+
* @param availableBTCSats - Available BTC balance in satoshis
|
|
127
|
+
* @param btcPriceUsd - BTC price with 8 decimals (e.g., 10000000000000 = $100,000)
|
|
128
|
+
* @param ucdDebt - UCD debt in wei (18 decimals)
|
|
129
|
+
* @returns Collateral value in USD and ratio in basis points
|
|
130
|
+
*/
|
|
131
|
+
function calculateCollateralMetrics(availableBTCSats, btcPriceUsd, ucdDebt) {
|
|
132
|
+
// Convert available BTC to USD value using BigInt math
|
|
133
|
+
// btcPriceUsd has 8 decimals: $100,000 = 10000000000000n
|
|
134
|
+
// availableBTCSats is in satoshis: 1 BTC = 100_000_000n sats
|
|
135
|
+
// ucdDebt has 18 decimals (ERC20 wei)
|
|
136
|
+
//
|
|
137
|
+
// Formula: (sats * priceWith8Decimals) / (SATOSHIS_PER_BITCOIN * PRICE_ORACLE_DECIMALS)
|
|
138
|
+
// This gives us USD value with 0 decimals (whole dollars)
|
|
139
|
+
// Calculate collateral value in USD (no decimals) - ALWAYS calculate, even with no debt
|
|
140
|
+
const collateralValueUsd = (availableBTCSats * btcPriceUsd) /
|
|
141
|
+
(constants_1.SATOSHIS_PER_BITCOIN * constants_1.PRICE_ORACLE_DECIMALS);
|
|
142
|
+
// If no debt, return max safe collateral ratio
|
|
143
|
+
if (ucdDebt === 0n) {
|
|
144
|
+
return {
|
|
145
|
+
collateralValueUsd,
|
|
146
|
+
collateralRatioBps: Number.MAX_SAFE_INTEGER,
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
// Calculate collateral ratio in basis points
|
|
150
|
+
// Ratio = (collateral / debt) * 10000
|
|
151
|
+
// Example: $20,000 collateral / $10,000 debt = 2.0 = 20000 bps (200%)
|
|
152
|
+
//
|
|
153
|
+
// CRITICAL: We must preserve precision by doing multiplication BEFORE division
|
|
154
|
+
// Use debt in wei (18 decimals) directly, adjust for collateral being in whole dollars
|
|
155
|
+
//
|
|
156
|
+
// Formula: (collateralUSD * UCD_TOKEN_DECIMALS * 10000) / ucdDebt
|
|
157
|
+
const ratioBigInt = (collateralValueUsd * constants_1.UCD_TOKEN_DECIMALS * 10000n) / ucdDebt;
|
|
158
|
+
// Convert to number - safe because ratio will be small (typically 10000-30000)
|
|
159
|
+
const collateralRatioBps = Number(ratioBigInt);
|
|
160
|
+
return {
|
|
161
|
+
collateralValueUsd,
|
|
162
|
+
collateralRatioBps,
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Check if adding additional debt would maintain required collateral ratio
|
|
167
|
+
*
|
|
168
|
+
* Used by minting authorization to validate new mints.
|
|
169
|
+
*
|
|
170
|
+
* @param collateralValueUsd - Current collateral value in USD (whole dollars)
|
|
171
|
+
* @param currentDebt - Current UCD debt in wei (18 decimals)
|
|
172
|
+
* @param additionalDebt - Additional UCD debt to add in wei (18 decimals)
|
|
173
|
+
* @param requiredRatioBps - Required collateral ratio in basis points (e.g., 13000 for 130%)
|
|
174
|
+
* @returns True if sufficient collateral exists after adding debt
|
|
175
|
+
*/
|
|
176
|
+
function hasSufficientCollateralForDebt(collateralValueUsd, currentDebt, additionalDebt, requiredRatioBps) {
|
|
177
|
+
// Calculate new total debt
|
|
178
|
+
const newTotalDebt = currentDebt + additionalDebt;
|
|
179
|
+
// If no debt after addition, always sufficient
|
|
180
|
+
if (newTotalDebt === 0n) {
|
|
181
|
+
return true;
|
|
182
|
+
}
|
|
183
|
+
// Calculate new collateral ratio using precise BigInt math
|
|
184
|
+
// Must multiply BEFORE dividing to preserve precision (same as calculateCollateralMetrics)
|
|
185
|
+
const newCollateralRatioBps = Number((collateralValueUsd * constants_1.UCD_TOKEN_DECIMALS * 10000n) / newTotalDebt);
|
|
186
|
+
return newCollateralRatioBps >= requiredRatioBps;
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Calculate fee from amount using basis points
|
|
190
|
+
*
|
|
191
|
+
* Bulletproof fee calculation with validation.
|
|
192
|
+
* Multiply before divide to maintain precision.
|
|
193
|
+
*
|
|
194
|
+
* @param amount - Principal amount (in wei or sats)
|
|
195
|
+
* @param feeBps - Fee in basis points (e.g., 50 = 0.5%)
|
|
196
|
+
* @returns Fee amount in same units as input
|
|
197
|
+
*
|
|
198
|
+
* @example
|
|
199
|
+
* calculateFeeBps(1000000000000000000n, 50) // 0.5% of 1 ETH
|
|
200
|
+
* // Returns: 5000000000000000n (0.005 ETH)
|
|
201
|
+
*/
|
|
202
|
+
function calculateFeeBps(amount, feeBps) {
|
|
203
|
+
if (amount < 0n) {
|
|
204
|
+
throw new Error("Amount cannot be negative");
|
|
205
|
+
}
|
|
206
|
+
if (feeBps < 0 || feeBps > 10000) {
|
|
207
|
+
throw new Error("Fee basis points must be between 0 and 10000 (0% to 100%)");
|
|
208
|
+
}
|
|
209
|
+
// Multiply first to preserve precision, then divide
|
|
210
|
+
const fee = (amount * BigInt(feeBps)) / 10000n;
|
|
211
|
+
return fee;
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Calculate USD value of BTC amount
|
|
215
|
+
*
|
|
216
|
+
* Converts satoshis to USD using price with 8 decimals.
|
|
217
|
+
* Result maintains 8 decimal precision.
|
|
218
|
+
*
|
|
219
|
+
* @param btcSats - Bitcoin amount in satoshis
|
|
220
|
+
* @param btcPriceUsd8Decimals - BTC price with 8 decimals (e.g., 9800000000000n = $98,000)
|
|
221
|
+
* @returns USD value with 8 decimals
|
|
222
|
+
*
|
|
223
|
+
* @example
|
|
224
|
+
* calculateBtcValueUsd(100000000n, 9800000000000n) // 1 BTC at $98,000
|
|
225
|
+
* // Returns: 9800000000000n ($98,000 with 8 decimals)
|
|
226
|
+
*/
|
|
227
|
+
function calculateBtcValueUsd(btcSats, btcPriceUsd8Decimals) {
|
|
228
|
+
if (btcSats < 0n) {
|
|
229
|
+
throw new Error("BTC amount cannot be negative");
|
|
230
|
+
}
|
|
231
|
+
if (btcPriceUsd8Decimals <= 0n) {
|
|
232
|
+
throw new Error("BTC price must be positive");
|
|
233
|
+
}
|
|
234
|
+
// btcSats: satoshis (no decimals)
|
|
235
|
+
// btcPriceUsd8Decimals: price with 8 decimals
|
|
236
|
+
// Formula: (sats * priceWith8Decimals) / SATOSHIS_PER_BITCOIN
|
|
237
|
+
// Result: USD value with 8 decimals
|
|
238
|
+
const valueUsd = (btcSats * btcPriceUsd8Decimals) / constants_1.SATOSHIS_PER_BITCOIN;
|
|
239
|
+
return valueUsd;
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Calculate collateral ratio in basis points (with 8-decimal collateral and 18-decimal debt)
|
|
243
|
+
*
|
|
244
|
+
* Used for UCD mint validation where collateral is in USD (8 decimals)
|
|
245
|
+
* and debt is in UCD wei (18 decimals).
|
|
246
|
+
*
|
|
247
|
+
* @param collateralValueUsd8Decimals - Collateral value in USD with 8 decimals
|
|
248
|
+
* @param debtUsd18Decimals - Debt amount in USD with 18 decimals (UCD wei)
|
|
249
|
+
* @returns Collateral ratio in basis points (e.g., 20000 = 200%)
|
|
250
|
+
*
|
|
251
|
+
* @example
|
|
252
|
+
* calculateCollateralRatioBps(9800000000000n, 4000000000000000000000n)
|
|
253
|
+
* // $98,000 collateral / $4,000 debt = 24.5 = 2450% = 24500 bps
|
|
254
|
+
* // Returns: 24500
|
|
255
|
+
*/
|
|
256
|
+
function calculateCollateralRatioBps(collateralValueUsd8Decimals, debtUsd18Decimals) {
|
|
257
|
+
if (collateralValueUsd8Decimals < 0n) {
|
|
258
|
+
throw new Error("Collateral value cannot be negative");
|
|
259
|
+
}
|
|
260
|
+
if (debtUsd18Decimals <= 0n) {
|
|
261
|
+
throw new Error("Debt must be positive to calculate ratio");
|
|
262
|
+
}
|
|
263
|
+
// Scale collateral from 8 decimals to 18 decimals: multiply by 10^10
|
|
264
|
+
const scaledCollateral = collateralValueUsd8Decimals * 10000000000n;
|
|
265
|
+
// Ratio in basis points = (collateral / debt) * 10000
|
|
266
|
+
// Multiply first to preserve precision
|
|
267
|
+
const ratioBps = (scaledCollateral * 10000n) / debtUsd18Decimals;
|
|
268
|
+
// Convert to number for comparison
|
|
269
|
+
const ratioBpsNumber = Number(ratioBps);
|
|
270
|
+
// Sanity check: ratio should be reasonable (0% to 10,000,000%)
|
|
271
|
+
if (ratioBpsNumber < 0 || ratioBpsNumber > 100000000) {
|
|
272
|
+
throw new Error(`Collateral ratio out of bounds: ${ratioBpsNumber} bps (${ratioBpsNumber / 100}%)`);
|
|
273
|
+
}
|
|
274
|
+
return ratioBpsNumber;
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Check if collateral ratio meets minimum requirement
|
|
278
|
+
*
|
|
279
|
+
* @param collateralValueUsd8Decimals - Collateral value in USD with 8 decimals
|
|
280
|
+
* @param debtUsd18Decimals - Debt amount in USD with 18 decimals
|
|
281
|
+
* @param minimumRatioBps - Minimum required ratio in basis points (e.g., 20000 = 200%)
|
|
282
|
+
* @returns True if collateral is sufficient
|
|
283
|
+
*
|
|
284
|
+
* @example
|
|
285
|
+
* isCollateralSufficient(20000000000000n, 10000000000000000000000n, 20000)
|
|
286
|
+
* // $200,000 collateral / $10,000 debt = 2000% >= 200%
|
|
287
|
+
* // Returns: true
|
|
288
|
+
*/
|
|
289
|
+
function isCollateralSufficient(collateralValueUsd8Decimals, debtUsd18Decimals, minimumRatioBps) {
|
|
290
|
+
if (minimumRatioBps < 0 || minimumRatioBps > 1000000) {
|
|
291
|
+
throw new Error("Minimum ratio must be between 0 and 1000000 bps (0% to 10000%)");
|
|
292
|
+
}
|
|
293
|
+
const actualRatioBps = calculateCollateralRatioBps(collateralValueUsd8Decimals, debtUsd18Decimals);
|
|
294
|
+
return actualRatioBps >= minimumRatioBps;
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* Convert basis points to percentage (for display)
|
|
298
|
+
*
|
|
299
|
+
* @param basisPoints - Value in basis points
|
|
300
|
+
* @returns Percentage as number (e.g., 20000 bps => 200)
|
|
301
|
+
*
|
|
302
|
+
* @example
|
|
303
|
+
* bpsToPercent(20000) // Returns: 200
|
|
304
|
+
* bpsToPercent(50) // Returns: 0.5
|
|
305
|
+
*/
|
|
306
|
+
function bpsToPercent(basisPoints) {
|
|
307
|
+
return basisPoints / 100;
|
|
308
|
+
}
|
|
309
|
+
//# sourceMappingURL=business-rules-math.module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"business-rules-math.module.js","sourceRoot":"","sources":["../../../src/modules/business-rules-math.module.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { IPriceOracle, PriceSourceConfig } from "../interfaces/chunks/price-oracle.i";
|
|
2
|
+
export declare class PriceOracleModule implements IPriceOracle {
|
|
3
|
+
private sources;
|
|
4
|
+
constructor(sources?: PriceSourceConfig[]);
|
|
5
|
+
private getDefaultSources;
|
|
6
|
+
/**
|
|
7
|
+
* Get BTC price in USD with 8 decimals
|
|
8
|
+
* Fetches from real price sources in priority order
|
|
9
|
+
*/
|
|
10
|
+
getBTCPrice(): Promise<bigint>;
|
|
11
|
+
/**
|
|
12
|
+
* Consensus across multiple sources with outlier detection
|
|
13
|
+
* Returns median price from valid sources after filtering outliers
|
|
14
|
+
*
|
|
15
|
+
* Master's Wisdom: Two-Path Validation
|
|
16
|
+
* 1. If ONE source is outlier (>2% from median) → FILTER it, continue with remaining
|
|
17
|
+
* 2. If ALL sources too dispersed (>5% spread) → REJECT all, throw error
|
|
18
|
+
*
|
|
19
|
+
* Logic Flow:
|
|
20
|
+
* 1. Calculate initial median from all sources
|
|
21
|
+
* 2. Filter individual outliers (>2% from median)
|
|
22
|
+
* 3. If outliers found: remove them, require minimum 2 sources remaining
|
|
23
|
+
* 4. Recalculate median from valid sources only
|
|
24
|
+
* 5. Check if remaining sources are too dispersed (max/min ratio > 1.05)
|
|
25
|
+
* 6. Return final median or throw appropriate error
|
|
26
|
+
*/
|
|
27
|
+
getBTCPriceConsensus(): Promise<bigint>;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=price-oracle.module.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"price-oracle.module.d.ts","sourceRoot":"","sources":["../../../src/modules/price-oracle.module.ts"],"names":[],"mappings":"AACA,OAAO,EACL,YAAY,EACZ,iBAAiB,EAClB,MAAM,qCAAqC,CAAC;AAM7C,qBAAa,iBAAkB,YAAW,YAAY;IACpD,OAAO,CAAC,OAAO,CAAsB;gBAEzB,OAAO,CAAC,EAAE,iBAAiB,EAAE;IAKzC,OAAO,CAAC,iBAAiB;IAqGzB;;;OAGG;IACG,WAAW,IAAI,OAAO,CAAC,MAAM,CAAC;IAyCpC;;;;;;;;;;;;;;;OAeG;IACG,oBAAoB,IAAI,OAAO,CAAC,MAAM,CAAC;CA+G9C"}
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PriceOracleModule = void 0;
|
|
4
|
+
const constants_1 = require("../constants");
|
|
5
|
+
class PriceOracleModule {
|
|
6
|
+
constructor(sources) {
|
|
7
|
+
this.sources = sources || this.getDefaultSources();
|
|
8
|
+
this.sources.sort((a, b) => a.priority - b.priority);
|
|
9
|
+
}
|
|
10
|
+
getDefaultSources() {
|
|
11
|
+
const DEFAULT_HEADERS = {
|
|
12
|
+
// LIT runtime rejects custom User-Agent headers (gRPC invalid_argument)
|
|
13
|
+
Accept: "application/json",
|
|
14
|
+
};
|
|
15
|
+
const fetchJson = async (url) => {
|
|
16
|
+
const controller = new AbortController();
|
|
17
|
+
// Reduced from 8000ms to 5000ms to fail faster and avoid LIT Protocol 30s timeout
|
|
18
|
+
// When CoinGecko fails, we need to quickly try Binance to stay under 30s limit
|
|
19
|
+
const timeoutMs = 5000;
|
|
20
|
+
const id = setTimeout(() => controller.abort(), timeoutMs);
|
|
21
|
+
try {
|
|
22
|
+
const res = await fetch(url, {
|
|
23
|
+
headers: DEFAULT_HEADERS,
|
|
24
|
+
signal: controller.signal,
|
|
25
|
+
});
|
|
26
|
+
if (!res.ok) {
|
|
27
|
+
throw new Error(`HTTP ${res.status} ${res.statusText}`);
|
|
28
|
+
}
|
|
29
|
+
return await res.json();
|
|
30
|
+
}
|
|
31
|
+
finally {
|
|
32
|
+
clearTimeout(id);
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
return [
|
|
36
|
+
{
|
|
37
|
+
name: "CoinGecko",
|
|
38
|
+
fetchPrice: async () => {
|
|
39
|
+
// Each node fetches the price
|
|
40
|
+
const url = new URL("https://api.coingecko.com/api/v3/simple/price");
|
|
41
|
+
url.searchParams.set("ids", "bitcoin");
|
|
42
|
+
url.searchParams.set("vs_currencies", "usd");
|
|
43
|
+
const data = await fetchJson(url.toString());
|
|
44
|
+
const price = Number(data?.bitcoin?.usd);
|
|
45
|
+
if (!Number.isFinite(price) || price <= 0) {
|
|
46
|
+
throw new Error("Invalid CoinGecko price payload");
|
|
47
|
+
}
|
|
48
|
+
// Master's wisdom: Use broadcastAndCollect to ensure consensus across all LIT nodes
|
|
49
|
+
// Each node broadcasts its fetched price, then all receive all prices
|
|
50
|
+
const allPrices = await Lit.Actions.broadcastAndCollect({
|
|
51
|
+
name: "coinGeckoPrice",
|
|
52
|
+
value: price.toString(),
|
|
53
|
+
});
|
|
54
|
+
const prices = allPrices.map((p) => parseFloat(p));
|
|
55
|
+
prices.sort((a, b) => a - b);
|
|
56
|
+
return prices[Math.floor(prices.length / 2)];
|
|
57
|
+
},
|
|
58
|
+
priority: 1,
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
name: "Binance",
|
|
62
|
+
fetchPrice: async () => {
|
|
63
|
+
// Each node fetches the price
|
|
64
|
+
const url = new URL("https://api.binance.com/api/v3/ticker/price");
|
|
65
|
+
url.searchParams.set("symbol", "BTCUSDT");
|
|
66
|
+
const data = await fetchJson(url.toString());
|
|
67
|
+
const price = Number(data?.price);
|
|
68
|
+
if (!Number.isFinite(price) || price <= 0) {
|
|
69
|
+
throw new Error("Invalid Binance price payload");
|
|
70
|
+
}
|
|
71
|
+
// Master's wisdom: Use broadcastAndCollect to ensure consensus across all LIT nodes
|
|
72
|
+
const allPrices = await Lit.Actions.broadcastAndCollect({
|
|
73
|
+
name: "binancePrice",
|
|
74
|
+
value: price.toString(),
|
|
75
|
+
});
|
|
76
|
+
const prices = allPrices.map((p) => parseFloat(p));
|
|
77
|
+
prices.sort((a, b) => a - b);
|
|
78
|
+
return prices[Math.floor(prices.length / 2)];
|
|
79
|
+
},
|
|
80
|
+
priority: 2,
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
name: "Coinbase",
|
|
84
|
+
fetchPrice: async () => {
|
|
85
|
+
// Each node fetches the price
|
|
86
|
+
const data = await fetchJson("https://api.coinbase.com/v2/prices/BTC-USD/spot");
|
|
87
|
+
const price = Number(data?.data?.amount);
|
|
88
|
+
if (!Number.isFinite(price) || price <= 0) {
|
|
89
|
+
throw new Error("Invalid Coinbase price payload");
|
|
90
|
+
}
|
|
91
|
+
// Master's wisdom: Use broadcastAndCollect to ensure consensus across all LIT nodes
|
|
92
|
+
const allPrices = await Lit.Actions.broadcastAndCollect({
|
|
93
|
+
name: "coinbasePrice",
|
|
94
|
+
value: price.toString(),
|
|
95
|
+
});
|
|
96
|
+
const prices = allPrices.map((p) => parseFloat(p));
|
|
97
|
+
prices.sort((a, b) => a - b);
|
|
98
|
+
return prices[Math.floor(prices.length / 2)];
|
|
99
|
+
},
|
|
100
|
+
priority: 3,
|
|
101
|
+
},
|
|
102
|
+
];
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Get BTC price in USD with 8 decimals
|
|
106
|
+
* Fetches from real price sources in priority order
|
|
107
|
+
*/
|
|
108
|
+
async getBTCPrice() {
|
|
109
|
+
console.log(`[Price Oracle] Fetching BTC price from external sources...`);
|
|
110
|
+
// Try sources in priority order
|
|
111
|
+
for (const source of this.sources) {
|
|
112
|
+
try {
|
|
113
|
+
console.log(`[Price Oracle] Trying ${source.name}...`);
|
|
114
|
+
const priceUSD = await source.fetchPrice();
|
|
115
|
+
console.log(`[Price Oracle] ✅ ${source.name}: $${priceUSD.toLocaleString()}`);
|
|
116
|
+
// Convert to 8 decimals as bigint - DETERMINISTIC METHOD
|
|
117
|
+
// CRITICAL: Avoid floating-point multiplication which is non-deterministic
|
|
118
|
+
// across different JavaScript engines/architectures
|
|
119
|
+
//
|
|
120
|
+
// Instead of: BigInt(Math.floor(priceUSD * 100_000_000))
|
|
121
|
+
// Which could give different results on different nodes due to FP precision
|
|
122
|
+
//
|
|
123
|
+
// Solution: Convert to integer cents first, then scale using BigInt-only math
|
|
124
|
+
// Example: $105,447.25 → 10544725 cents → 10544725000000n (8 decimals)
|
|
125
|
+
const priceCents = Math.round(priceUSD * 100); // Convert to cents (integer)
|
|
126
|
+
const priceWith8Decimals = BigInt(priceCents) * 1000000n; // Scale to 8 decimals using BigInt
|
|
127
|
+
console.log(`[Price Oracle] Price with 8 decimals: ${priceWith8Decimals}`);
|
|
128
|
+
return priceWith8Decimals;
|
|
129
|
+
}
|
|
130
|
+
catch (error) {
|
|
131
|
+
console.warn(`[Price Oracle] ⚠️ ${source.name} failed: ${error.message}`);
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
throw new Error("All price sources failed");
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Consensus across multiple sources with outlier detection
|
|
139
|
+
* Returns median price from valid sources after filtering outliers
|
|
140
|
+
*
|
|
141
|
+
* Master's Wisdom: Two-Path Validation
|
|
142
|
+
* 1. If ONE source is outlier (>2% from median) → FILTER it, continue with remaining
|
|
143
|
+
* 2. If ALL sources too dispersed (>5% spread) → REJECT all, throw error
|
|
144
|
+
*
|
|
145
|
+
* Logic Flow:
|
|
146
|
+
* 1. Calculate initial median from all sources
|
|
147
|
+
* 2. Filter individual outliers (>2% from median)
|
|
148
|
+
* 3. If outliers found: remove them, require minimum 2 sources remaining
|
|
149
|
+
* 4. Recalculate median from valid sources only
|
|
150
|
+
* 5. Check if remaining sources are too dispersed (max/min ratio > 1.05)
|
|
151
|
+
* 6. Return final median or throw appropriate error
|
|
152
|
+
*/
|
|
153
|
+
async getBTCPriceConsensus() {
|
|
154
|
+
console.log(`[Price Oracle] Fetching BTC price with consensus...`);
|
|
155
|
+
// Use configured tolerances
|
|
156
|
+
const OUTLIER_DEVIATION = constants_1.PRICE_ORACLE_OUTLIER_DEVIATION_THRESHOLD; // 2%
|
|
157
|
+
const DISPERSION_THRESHOLD = constants_1.PRICE_ORACLE_DISPERSION_THRESHOLD; // 5%
|
|
158
|
+
const results = await Promise.allSettled(this.sources.map(async (source) => {
|
|
159
|
+
const price = await source.fetchPrice();
|
|
160
|
+
return { source: source.name, price };
|
|
161
|
+
}));
|
|
162
|
+
const successful = results
|
|
163
|
+
.filter((r) => r.status === "fulfilled")
|
|
164
|
+
.map((r) => r.value);
|
|
165
|
+
if (successful.length === 0) {
|
|
166
|
+
throw new Error("No price sources returned data");
|
|
167
|
+
}
|
|
168
|
+
console.log(`[Price Oracle] Got prices from ${successful.length}/${this.sources.length} sources:`);
|
|
169
|
+
successful.forEach((s) => {
|
|
170
|
+
console.log(` ${s.source}: $${s.price.toLocaleString()}`);
|
|
171
|
+
});
|
|
172
|
+
// Calculate initial median
|
|
173
|
+
const prices = successful.map((s) => s.price);
|
|
174
|
+
prices.sort((a, b) => a - b);
|
|
175
|
+
const initialMedian = prices[Math.floor(prices.length / 2)];
|
|
176
|
+
// Check price dispersion FIRST (max/min ratio)
|
|
177
|
+
// If ALL sources are moderately dispersed, reject before filtering
|
|
178
|
+
const minPrice = prices[0];
|
|
179
|
+
const maxPrice = prices[prices.length - 1];
|
|
180
|
+
const dispersionRatio = maxPrice / minPrice;
|
|
181
|
+
// Filter outliers (more than PRICE_ORACLE_OUTLIER_DEVIATION_THRESHOLD away from median)
|
|
182
|
+
const validPrices = successful.filter((s) => {
|
|
183
|
+
const deviation = Math.abs(s.price - initialMedian) / initialMedian;
|
|
184
|
+
return deviation <= OUTLIER_DEVIATION;
|
|
185
|
+
});
|
|
186
|
+
// If dispersion is high BUT no clear outliers, fail with "too dispersed"
|
|
187
|
+
if (dispersionRatio > 1 + DISPERSION_THRESHOLD &&
|
|
188
|
+
validPrices.length === successful.length) {
|
|
189
|
+
// All prices within outlier threshold but spread too wide
|
|
190
|
+
throw new Error(`Price consensus failed: sources too dispersed (${((dispersionRatio - 1) *
|
|
191
|
+
100).toFixed(1)}% spread)`);
|
|
192
|
+
}
|
|
193
|
+
// Check if we filtered any outliers
|
|
194
|
+
if (validPrices.length < successful.length) {
|
|
195
|
+
const outliers = successful.filter((s) => !validPrices.find((v) => v.source === s.source));
|
|
196
|
+
console.log(`[Price Oracle] ⚠️ Detected ${outliers.length} outlier(s):`);
|
|
197
|
+
outliers.forEach((o) => {
|
|
198
|
+
const deviation = Math.abs(o.price - initialMedian) / initialMedian;
|
|
199
|
+
console.log(` ${o.source}: $${o.price.toLocaleString()} (${(deviation * 100).toFixed(1)}% deviation)`);
|
|
200
|
+
});
|
|
201
|
+
// Check if we have enough valid sources remaining
|
|
202
|
+
if (validPrices.length < 2) {
|
|
203
|
+
throw new Error("Price consensus failed: insufficient valid sources after outlier removal");
|
|
204
|
+
}
|
|
205
|
+
console.log(`[Price Oracle] ✅ Outliers filtered, continuing with ${validPrices.length} valid sources`);
|
|
206
|
+
// Recalculate median with valid prices only
|
|
207
|
+
const validPricesOnly = validPrices.map((v) => v.price);
|
|
208
|
+
validPricesOnly.sort((a, b) => a - b);
|
|
209
|
+
const finalMedian = validPricesOnly[Math.floor(validPricesOnly.length / 2)];
|
|
210
|
+
console.log(`[Price Oracle] ✅ Consensus price (median): $${finalMedian.toLocaleString()}`);
|
|
211
|
+
// Convert to 8 decimals as bigint - DETERMINISTIC METHOD
|
|
212
|
+
const priceCents = Math.round(finalMedian * 100);
|
|
213
|
+
return BigInt(priceCents) * 1000000n;
|
|
214
|
+
}
|
|
215
|
+
// No outliers detected - use initial median
|
|
216
|
+
console.log(`[Price Oracle] ✅ Consensus price (median): $${initialMedian.toLocaleString()}`);
|
|
217
|
+
// Convert to 8 decimals as bigint - DETERMINISTIC METHOD
|
|
218
|
+
const priceCents = Math.round(initialMedian * 100);
|
|
219
|
+
return BigInt(priceCents) * 1000000n;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
exports.PriceOracleModule = PriceOracleModule;
|
|
223
|
+
//# sourceMappingURL=price-oracle.module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"price-oracle.module.js","sourceRoot":"","sources":["../../../src/modules/price-oracle.module.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Protocol Parameters Module
|
|
3
|
+
*
|
|
4
|
+
* Fetches protocol parameters directly from smart contracts.
|
|
5
|
+
* This ensures LIT actions always use current values set by protocol governance.
|
|
6
|
+
*
|
|
7
|
+
* Parameters fetched:
|
|
8
|
+
* - Liquidation threshold (from LoanOperationsManager)
|
|
9
|
+
* - Term-specific fees (from TermManager)
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Configuration for protocol parameters module
|
|
13
|
+
*/
|
|
14
|
+
export interface ProtocolParametersConfig {
|
|
15
|
+
termManagerAddress: string;
|
|
16
|
+
loanOpsManagerAddress: string;
|
|
17
|
+
chain: string;
|
|
18
|
+
chainId: number;
|
|
19
|
+
rpcUrl?: string;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Term fees structure
|
|
23
|
+
*/
|
|
24
|
+
export interface TermFees {
|
|
25
|
+
originationFeeBps: number;
|
|
26
|
+
extensionFeeBps: number;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Protocol Parameters Module
|
|
30
|
+
*
|
|
31
|
+
* Fetches governance-controlled parameters from smart contracts
|
|
32
|
+
*/
|
|
33
|
+
export declare class ProtocolParametersModule {
|
|
34
|
+
private termManagerAddress;
|
|
35
|
+
private loanOpsManagerAddress;
|
|
36
|
+
private chain;
|
|
37
|
+
private chainId;
|
|
38
|
+
private rpcUrl?;
|
|
39
|
+
constructor(config: ProtocolParametersConfig);
|
|
40
|
+
/**
|
|
41
|
+
* Get liquidation threshold from LoanOperationsManager
|
|
42
|
+
*
|
|
43
|
+
* @returns Liquidation threshold in basis points
|
|
44
|
+
*/
|
|
45
|
+
getLiquidationThreshold(): Promise<number>;
|
|
46
|
+
/**
|
|
47
|
+
* Get term-specific fees from TermManager
|
|
48
|
+
*
|
|
49
|
+
* @param termMonths Loan term in months
|
|
50
|
+
* @returns Term fees (origination and extension) in basis points
|
|
51
|
+
*/
|
|
52
|
+
getTermFees(termMonths: number): Promise<TermFees>;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Factory function to create protocol parameters module
|
|
56
|
+
*/
|
|
57
|
+
export declare function createProtocolParametersModule(config: ProtocolParametersConfig): ProtocolParametersModule;
|
|
58
|
+
//# sourceMappingURL=protocol-parameters.module.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"protocol-parameters.module.d.ts","sourceRoot":"","sources":["../../../src/modules/protocol-parameters.module.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,kBAAkB,EAAE,MAAM,CAAC;IAC3B,qBAAqB,EAAE,MAAM,CAAC;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,eAAe,EAAE,MAAM,CAAC;CACzB;AAED;;;;GAIG;AACH,qBAAa,wBAAwB;IACnC,OAAO,CAAC,kBAAkB,CAAS;IACnC,OAAO,CAAC,qBAAqB,CAAS;IACtC,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,MAAM,CAAC,CAAS;gBAEZ,MAAM,EAAE,wBAAwB;IAQ5C;;;;OAIG;IACG,uBAAuB,IAAI,OAAO,CAAC,MAAM,CAAC;IAyChD;;;;;OAKG;IACG,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;CAsDzD;AAED;;GAEG;AACH,wBAAgB,8BAA8B,CAC5C,MAAM,EAAE,wBAAwB,GAC/B,wBAAwB,CAE1B"}
|