@gvnrdao/dh-sdk 0.0.236 → 0.0.244
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/dist/constants/chunks/deployment-addresses.d.ts +2 -0
- package/dist/constants/chunks/network-configs.d.ts +2 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +20482 -31339
- package/dist/index.mjs +20288 -31147
- package/dist/interfaces/chunks/config.i.d.ts +20 -10
- package/dist/interfaces/chunks/contract-interactions.i.d.ts +2 -2
- package/dist/interfaces/chunks/contract-types.i.d.ts +95 -91
- package/dist/interfaces/chunks/loan-operations.i.d.ts +2 -3
- package/dist/modules/bitcoin/bitcoin-operations.module.d.ts +37 -0
- package/dist/modules/cache/cache-manager.module.d.ts +8 -0
- package/dist/modules/contract/contract-manager.module.d.ts +5 -5
- package/dist/modules/diamond-hands-sdk.d.ts +103 -7
- package/dist/modules/loan/loan-creator.module.d.ts +1 -1
- package/dist/modules/loan/loan-query.module.d.ts +3 -3
- package/dist/modules/pkp/pkp-manager.module.d.ts +6 -2
- package/dist/protocol/protocol-pause.d.ts +2 -2
- package/dist/utils/address-conversion.utils.d.ts +39 -0
- package/dist/utils/bitcoin-provider.utils.d.ts +36 -0
- package/dist/utils/btc-withdrawal-message.d.ts +60 -0
- package/dist/utils/chunks/bitcoin-utils.d.ts +10 -0
- package/dist/utils/chunks/eip1559-broadcast.utils.d.ts +8 -9
- package/dist/utils/eip712-login.d.ts +27 -0
- package/dist/utils/extend-authorization.utils.d.ts +2 -2
- package/dist/utils/mint-authorization.utils.d.ts +9 -8
- package/dist/utils/position-delegate.utils.d.ts +41 -0
- package/dist/utils/server-session.d.ts +44 -0
- package/dist/utils/signature-tempering.utils.d.ts +6 -3
- package/package.json +5 -7
- package/dist/utils/bitcoin-signature.d.ts +0 -20
|
@@ -70,8 +70,72 @@ export declare class DiamondHandsSDK {
|
|
|
70
70
|
private readonly bitcoinOperations;
|
|
71
71
|
private readonly mockTokenManager?;
|
|
72
72
|
private readonly graphClient;
|
|
73
|
+
/**
|
|
74
|
+
* Session helper for the lit-ops-server. Set in service mode; undefined
|
|
75
|
+
* in standalone mode (no server to authenticate against). Use
|
|
76
|
+
* `this.getAuthHeader()` which centralizes the undefined check.
|
|
77
|
+
*/
|
|
78
|
+
private readonly serverSession?;
|
|
73
79
|
private isInitialized;
|
|
74
80
|
private isDisposed;
|
|
81
|
+
/**
|
|
82
|
+
* Audit H-13: per-position write serialization. Tracks positions with an
|
|
83
|
+
* in-flight state-mutating call so a concurrent mint / payment / extend /
|
|
84
|
+
* withdraw / liquidation for the same position fast-fails locally instead
|
|
85
|
+
* of paying a full Lit-Action round-trip + gas only to revert on-chain
|
|
86
|
+
* via the M-4 flash-loan protection's `lastInteractionBlockByPosition`
|
|
87
|
+
* guard. Stored as a Set — no Promise needed since callers don't await
|
|
88
|
+
* on each other; they get an immediate refusal and can retry once their
|
|
89
|
+
* sibling call has completed.
|
|
90
|
+
*/
|
|
91
|
+
private readonly inFlightWrites;
|
|
92
|
+
/**
|
|
93
|
+
* Acquire the per-position write lock. Returns `null` on success, or a
|
|
94
|
+
* structured failure when another write is already in flight. The caller
|
|
95
|
+
* must `cast` the failure to the method's specific result type — every
|
|
96
|
+
* write-method result includes a `{ success: false; error: string }`
|
|
97
|
+
* branch so the cast is safe.
|
|
98
|
+
*/
|
|
99
|
+
private tryAcquireWriteLock;
|
|
100
|
+
/** Release the per-position write lock. Safe to call when not held. */
|
|
101
|
+
private releaseWriteLock;
|
|
102
|
+
/**
|
|
103
|
+
* Build the `Authorization: Bearer <jwt>` header for a request to
|
|
104
|
+
* lit-ops-server. Returns an empty object in standalone mode (no server
|
|
105
|
+
* to authenticate to) or when the session helper has not been wired —
|
|
106
|
+
* in which case the server's `requireSessionToken` middleware will
|
|
107
|
+
* reject the call with 401, which is the correct outcome.
|
|
108
|
+
*/
|
|
109
|
+
private getAuthHeader;
|
|
110
|
+
/**
|
|
111
|
+
* Audit H-9: invalidate the LoanQuery cache so subsequent reads return
|
|
112
|
+
* the post-write state. We clear the entire loan-query cache (not just
|
|
113
|
+
* the entry for this position) because the cache keys by `pkpId` and we
|
|
114
|
+
* don't always have it in scope at the release site — a position-keyed
|
|
115
|
+
* helper would require a pre-write lookup that defeats the cache. The
|
|
116
|
+
* blast radius is bounded: the cache is per-process and a fresh fetch
|
|
117
|
+
* is cheap relative to a Lit Action call.
|
|
118
|
+
*
|
|
119
|
+
* `includePkpCache: true` is passed by liquidation to also drop the
|
|
120
|
+
* 24-hour PKP-data cache entry — the Lit auth-context attached to a
|
|
121
|
+
* PKP changes when ownership transfers, so the cached `ethAddress`
|
|
122
|
+
* (used for capacity-credit delegation) must be re-derived.
|
|
123
|
+
*/
|
|
124
|
+
private invalidateCachesForPosition;
|
|
125
|
+
/**
|
|
126
|
+
* Audit H-11: pre-flight check for `PositionManager.getProtocolPauseStatus()`.
|
|
127
|
+
*
|
|
128
|
+
* Returns `{ ok: true }` if none of the supplied pause keys are set, or
|
|
129
|
+
* `{ ok: false, error }` if the protocol is paused for this operation
|
|
130
|
+
* type. Caller returns the structured failure to the user before paying
|
|
131
|
+
* for a LIT Action round-trip + gas that the on-chain function would
|
|
132
|
+
* later revert.
|
|
133
|
+
*
|
|
134
|
+
* Best-effort: if no EVM provider is available (e.g., service-mode setup
|
|
135
|
+
* without `ethRpcUrl`) or the read itself fails, we return `{ ok: true }`
|
|
136
|
+
* with a debug log — the on-chain call remains the final authority.
|
|
137
|
+
*/
|
|
138
|
+
private preflightProtocolPause;
|
|
75
139
|
/**
|
|
76
140
|
* Private constructor - use DiamondHandsSDK.create() instead
|
|
77
141
|
*
|
|
@@ -328,7 +392,7 @@ export declare class DiamondHandsSDK {
|
|
|
328
392
|
* @param customBitcoinRpcUrl - Optional custom Bitcoin RPC URL (for local testing)
|
|
329
393
|
* @returns Withdrawal result with transaction details
|
|
330
394
|
*/
|
|
331
|
-
withdrawBTC(positionId: string, withdrawalAddress: string, withdrawalAmount: number
|
|
395
|
+
withdrawBTC(positionId: string, withdrawalAddress: string, withdrawalAmount: number): Promise<BTCWithdrawalResult>;
|
|
332
396
|
/**
|
|
333
397
|
* Execute Bitcoin withdrawal (Phase 2)
|
|
334
398
|
*
|
|
@@ -341,10 +405,15 @@ export declare class DiamondHandsSDK {
|
|
|
341
405
|
executeBTCWithdrawal(request: {
|
|
342
406
|
positionId: string;
|
|
343
407
|
utxoIdentifier: string;
|
|
408
|
+
utxoSatoshis: number;
|
|
344
409
|
networkFee: number;
|
|
345
410
|
destination: string;
|
|
346
|
-
|
|
347
|
-
|
|
411
|
+
/**
|
|
412
|
+
* User-authorized withdrawal amount in satoshis (Phase 1 `withdrawalAmount`).
|
|
413
|
+
* Bound into the Phase-2 signature alongside `destination` so the Lit
|
|
414
|
+
* Action can cross-check against the on-chain authorizer record.
|
|
415
|
+
*/
|
|
416
|
+
targetAmount: number;
|
|
348
417
|
}): Promise<{
|
|
349
418
|
success: boolean;
|
|
350
419
|
txid?: string;
|
|
@@ -364,7 +433,7 @@ export declare class DiamondHandsSDK {
|
|
|
364
433
|
* @param rpcUrl - Optional RPC URL override for LIT Action (for local testing)
|
|
365
434
|
* @returns Array of execution results for each pending transfer
|
|
366
435
|
*/
|
|
367
|
-
executePendingBtcTransfers(positionId: string, networkFee: number
|
|
436
|
+
executePendingBtcTransfers(positionId: string, networkFee: number): Promise<Array<{
|
|
368
437
|
success: boolean;
|
|
369
438
|
utxoIdentifier?: string;
|
|
370
439
|
txid?: string;
|
|
@@ -423,7 +492,7 @@ export declare class DiamondHandsSDK {
|
|
|
423
492
|
* @param customBitcoinRpcUrl - Optional custom Bitcoin RPC URL (for local testing)
|
|
424
493
|
* @returns Complete withdrawal result with both authorization and execution details
|
|
425
494
|
*/
|
|
426
|
-
withdrawBTCAndExecute(positionId: string, withdrawalAddress: string, withdrawalAmount: number, networkFee: number
|
|
495
|
+
withdrawBTCAndExecute(positionId: string, withdrawalAddress: string, withdrawalAmount: number, networkFee: number): Promise<{
|
|
427
496
|
success: boolean;
|
|
428
497
|
authorization?: BTCWithdrawalResult;
|
|
429
498
|
transfers?: Array<{
|
|
@@ -463,7 +532,7 @@ export declare class DiamondHandsSDK {
|
|
|
463
532
|
getLoansByBorrower(borrower: string, pagination?: {
|
|
464
533
|
page: number;
|
|
465
534
|
pageSize: number;
|
|
466
|
-
}): Promise<Result<import("../interfaces/chunks/loan-operations.i").PaginatedLoansResponse, SDKError>>;
|
|
535
|
+
}, orderBy?: "createdAt" | "lastUpdatedAt" | "ucdDebt", orderDirection?: "asc" | "desc"): Promise<Result<import("../interfaces/chunks/loan-operations.i").PaginatedLoansResponse, SDKError>>;
|
|
467
536
|
/**
|
|
468
537
|
* Get all active loans
|
|
469
538
|
*
|
|
@@ -524,6 +593,13 @@ export declare class DiamondHandsSDK {
|
|
|
524
593
|
* @returns the current Bitcoin price in USD
|
|
525
594
|
*/
|
|
526
595
|
getBitcoinPrice(): Promise<{
|
|
596
|
+
price: number;
|
|
597
|
+
priceE8: string;
|
|
598
|
+
timestamp: number;
|
|
599
|
+
source: string;
|
|
600
|
+
signature?: undefined;
|
|
601
|
+
signer?: undefined;
|
|
602
|
+
} | {
|
|
527
603
|
price: number;
|
|
528
604
|
priceE8: string;
|
|
529
605
|
timestamp: number;
|
|
@@ -571,6 +647,23 @@ export declare class DiamondHandsSDK {
|
|
|
571
647
|
* ```
|
|
572
648
|
*/
|
|
573
649
|
getTermsWithFees(): Promise<Result<TermsWithFeesResult, SDKError>>;
|
|
650
|
+
getProtocolConfig(): Promise<Result<{
|
|
651
|
+
liquidationThreshold: string;
|
|
652
|
+
minimumLoanValueUcd: string;
|
|
653
|
+
minimumLoanValueWei: string;
|
|
654
|
+
maxSingleLoanValueUcd: string;
|
|
655
|
+
maxSingleLoanValueWei: string;
|
|
656
|
+
}, SDKError>>;
|
|
657
|
+
getGasBalance(address: string): Promise<Result<{
|
|
658
|
+
balanceWei: string;
|
|
659
|
+
balanceEth: string;
|
|
660
|
+
}, SDKError>>;
|
|
661
|
+
getVaultBalance(positionId: string): Promise<Result<{
|
|
662
|
+
vaultAddress: string;
|
|
663
|
+
balanceSats: string;
|
|
664
|
+
balanceBtc: string;
|
|
665
|
+
btcPrice: string;
|
|
666
|
+
}, SDKError>>;
|
|
574
667
|
/**
|
|
575
668
|
* Mint mock BTC tokens (test networks only)
|
|
576
669
|
*
|
|
@@ -612,7 +705,10 @@ export declare class DiamondHandsSDK {
|
|
|
612
705
|
*/
|
|
613
706
|
private isProductionNetwork;
|
|
614
707
|
/**
|
|
615
|
-
* Get Bitcoin network based on chain
|
|
708
|
+
* Get Bitcoin network based on chain.
|
|
709
|
+
*
|
|
710
|
+
* Provider URLs are now sourced from the on-chain registry, so the network
|
|
711
|
+
* is derived purely from `this.config.chain`.
|
|
616
712
|
*/
|
|
617
713
|
private getBitcoinNetwork;
|
|
618
714
|
/**
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
*
|
|
11
11
|
* Flow: PKP Creation → Authorization → Contract Call → Verification
|
|
12
12
|
*/
|
|
13
|
-
import type
|
|
13
|
+
import { type Wallet } from "ethers";
|
|
14
14
|
import { Result } from "../../types/result";
|
|
15
15
|
import { SDKError } from "../../utils/error-handler";
|
|
16
16
|
import type { PKPManager } from "../pkp/pkp-manager.module";
|
|
@@ -16,7 +16,7 @@ import type { Cache } from "../cache/cache-manager.module";
|
|
|
16
16
|
import type { LoanData, LoanDataDetail, PaginatedLoansResponse } from "../../interfaces/chunks/loan-operations.i";
|
|
17
17
|
import type { LoanEvents, LoanEventsFilter } from "../../types/event-types";
|
|
18
18
|
import { DiamondHandsGraphClient } from "@graphs/diamond-hands";
|
|
19
|
-
import type
|
|
19
|
+
import { type Provider } from "ethers";
|
|
20
20
|
/**
|
|
21
21
|
* Loan query filters
|
|
22
22
|
*/
|
|
@@ -52,7 +52,7 @@ export interface LoanQueryConfig {
|
|
|
52
52
|
/** Bitcoin operations for balance enrichment */
|
|
53
53
|
bitcoinOperations: BitcoinOperations;
|
|
54
54
|
/** Ethereum provider for PKP public key retrieval */
|
|
55
|
-
provider?:
|
|
55
|
+
provider?: Provider;
|
|
56
56
|
/** PositionManagerCoreModule address — used as fallback vault address source for Chipotle loans */
|
|
57
57
|
positionManagerCoreAddress?: string;
|
|
58
58
|
/** Cache for loan query results (keyed by PKP ID) */
|
|
@@ -132,7 +132,7 @@ export declare class LoanQuery {
|
|
|
132
132
|
* @param pagination - Pagination parameters
|
|
133
133
|
* @returns Paginated loans for borrower
|
|
134
134
|
*/
|
|
135
|
-
getLoansByBorrower(borrower: string, pagination?: PaginationParams): Promise<Result<PaginatedLoansResponse, SDKError>>;
|
|
135
|
+
getLoansByBorrower(borrower: string, pagination?: PaginationParams, orderBy?: "createdAt" | "lastUpdatedAt" | "ucdDebt", orderDirection?: "asc" | "desc"): Promise<Result<PaginatedLoansResponse, SDKError>>;
|
|
136
136
|
/**
|
|
137
137
|
* Get active loans (status = 0)
|
|
138
138
|
*
|
|
@@ -27,8 +27,12 @@ export interface PKPManagerConfig {
|
|
|
27
27
|
litNetwork: string;
|
|
28
28
|
/** Service mode: endpoint for lit-ops-server */
|
|
29
29
|
serviceEndpoint?: string;
|
|
30
|
-
/**
|
|
31
|
-
|
|
30
|
+
/**
|
|
31
|
+
* Service mode: returns `Authorization`-style headers for each request.
|
|
32
|
+
* Called once per request so the underlying session can refresh as
|
|
33
|
+
* needed. Empty object disables the header (server will 401).
|
|
34
|
+
*/
|
|
35
|
+
getAuthHeader?: () => Promise<Record<string, string>>;
|
|
32
36
|
/** Direct mode: wallet for PKP operations */
|
|
33
37
|
litOpsWallet?: Wallet;
|
|
34
38
|
/** Optional cache for PKP data */
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Helpers for `PositionManager.getProtocolPauseStatus()` (Lit Actions / client fast-fail).
|
|
3
3
|
*/
|
|
4
|
-
import {
|
|
4
|
+
import { type Provider } from 'ethers';
|
|
5
5
|
export type ProtocolPauseStatus = {
|
|
6
6
|
positionManagerPaused: boolean;
|
|
7
7
|
positionManagerLiquidationsPaused: boolean;
|
|
@@ -14,6 +14,6 @@ export type ProtocolPauseStatus = {
|
|
|
14
14
|
ucdTokenPaused: boolean;
|
|
15
15
|
simplePsmPaused: boolean;
|
|
16
16
|
};
|
|
17
|
-
export declare function fetchProtocolPauseStatus(provider:
|
|
17
|
+
export declare function fetchProtocolPauseStatus(provider: Provider, positionManagerAddress: string): Promise<ProtocolPauseStatus>;
|
|
18
18
|
export type ProtocolPauseKey = keyof ProtocolPauseStatus;
|
|
19
19
|
export declare function assertProtocolNotPaused(status: ProtocolPauseStatus, requiredKeys: readonly ProtocolPauseKey[]): void;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Address Conversion Utilities
|
|
3
|
+
* Provides safe address conversion and validation with clear error messages
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Safely convert a string to bytes32 with clear error handling
|
|
7
|
+
* @param value String value to convert
|
|
8
|
+
* @param fieldName Name of the field for error messages
|
|
9
|
+
* @returns bytes32 string
|
|
10
|
+
* @throws Clear error message if conversion fails
|
|
11
|
+
*/
|
|
12
|
+
export declare function safeHexZeroPad(value: string, fieldName?: string): string;
|
|
13
|
+
/**
|
|
14
|
+
* Safely get Bitcoin addresses from PKP with retry and clear error handling
|
|
15
|
+
* @param pkpId PKP ID to derive addresses from
|
|
16
|
+
* @param maxRetries Maximum number of retries (default: 3)
|
|
17
|
+
* @returns Bitcoin addresses for all networks
|
|
18
|
+
* @throws Clear error message if derivation fails
|
|
19
|
+
*/
|
|
20
|
+
export declare function safeGetBitcoinAddressesFromPkp(pkpId: string, maxRetries?: number): Promise<{
|
|
21
|
+
mainnet: string;
|
|
22
|
+
testnet: string;
|
|
23
|
+
regtest: string;
|
|
24
|
+
}>;
|
|
25
|
+
/**
|
|
26
|
+
* Safely validate and format a Bitcoin address
|
|
27
|
+
* @param address Bitcoin address to validate
|
|
28
|
+
* @param network Network type for validation
|
|
29
|
+
* @returns Validated address
|
|
30
|
+
* @throws Clear error message if validation fails
|
|
31
|
+
*/
|
|
32
|
+
export declare function safeValidateBitcoinAddress(address: string, network?: 'mainnet' | 'testnet' | 'regtest'): string;
|
|
33
|
+
/**
|
|
34
|
+
* Safely parse and validate a position ID
|
|
35
|
+
* @param positionId Position ID to validate
|
|
36
|
+
* @returns Validated position ID
|
|
37
|
+
* @throws Clear error message if validation fails
|
|
38
|
+
*/
|
|
39
|
+
export declare function safeValidatePositionId(positionId: string): string;
|
|
@@ -45,4 +45,40 @@ export declare class BitcoinProvider {
|
|
|
45
45
|
* Check if an address has received at least a specific amount
|
|
46
46
|
*/
|
|
47
47
|
hasReceivedAmount(address: string, expectedAmount: bigint): Promise<boolean>;
|
|
48
|
+
/**
|
|
49
|
+
* Fetch a Bitcoin transaction by txid.
|
|
50
|
+
*
|
|
51
|
+
* Audit CRIT-2: used to verify that a Phase-2 BTC withdrawal the server
|
|
52
|
+
* claimed broadcast actually exists and matches the user's authorization.
|
|
53
|
+
* Returns `null` if no provider has the tx yet — the caller may retry to
|
|
54
|
+
* allow for propagation/indexing delay.
|
|
55
|
+
*
|
|
56
|
+
* Esplora response shape: `{ txid, vin: [{txid, vout, ...}], vout: [{value, scriptpubkey_address, ...}], status: {confirmed, ...} }`
|
|
57
|
+
*/
|
|
58
|
+
getTransaction(txid: string): Promise<BitcoinTransactionInfo | null>;
|
|
59
|
+
/**
|
|
60
|
+
* Try each candidate path on the provider. Returns `null` on 404 (tx not
|
|
61
|
+
* yet visible) but throws on other errors so the outer loop can move to
|
|
62
|
+
* the next provider.
|
|
63
|
+
*/
|
|
64
|
+
private fetchTxFromProvider;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Normalized Bitcoin transaction information returned by `getTransaction`.
|
|
68
|
+
* Only the fields used by post-broadcast verification are populated; we
|
|
69
|
+
* deliberately do NOT echo full witness / scriptpubkey data to keep the
|
|
70
|
+
* surface small.
|
|
71
|
+
*/
|
|
72
|
+
export interface BitcoinTransactionInfo {
|
|
73
|
+
txid: string;
|
|
74
|
+
vin: Array<{
|
|
75
|
+
txid: string;
|
|
76
|
+
vout: number;
|
|
77
|
+
}>;
|
|
78
|
+
vout: Array<{
|
|
79
|
+
value: number;
|
|
80
|
+
address?: string;
|
|
81
|
+
}>;
|
|
82
|
+
/** True if the tx is in a block, false if still in mempool, undefined unknown. */
|
|
83
|
+
confirmed?: boolean;
|
|
48
84
|
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Helpers for building the EIP-191 `execute-btc-withdrawal` envelope that the
|
|
3
|
+
* `btc-transaction-signer` LIT Action verifies.
|
|
4
|
+
*
|
|
5
|
+
* Pulled out of the CLI's executePendingWithdrawal util so the SDK and CLI
|
|
6
|
+
* use the same logic and signing rules.
|
|
7
|
+
*/
|
|
8
|
+
import { type Signer } from "ethers";
|
|
9
|
+
export interface BtcExecuteSignParams {
|
|
10
|
+
positionId: string;
|
|
11
|
+
txid: string;
|
|
12
|
+
vout: number;
|
|
13
|
+
networkFee: number;
|
|
14
|
+
chainId: number;
|
|
15
|
+
signer: Signer;
|
|
16
|
+
}
|
|
17
|
+
export interface BtcExecuteSignedEnvelope {
|
|
18
|
+
positionId: string;
|
|
19
|
+
txid: string;
|
|
20
|
+
vout: number;
|
|
21
|
+
satoshis: number;
|
|
22
|
+
/** Bitcoin destination address bound into the signature. */
|
|
23
|
+
targetAddress: string;
|
|
24
|
+
/** Authorized withdrawal amount (sats) bound into the signature. */
|
|
25
|
+
targetAmount: number;
|
|
26
|
+
networkFee: number;
|
|
27
|
+
chainId: number;
|
|
28
|
+
/** Quantum-aligned timestamp (start of a 60s quantum). */
|
|
29
|
+
timestamp: number;
|
|
30
|
+
/** EIP-191 signature over the message hash. */
|
|
31
|
+
userSignature: string;
|
|
32
|
+
/** Address recovered from the signer (borrower). */
|
|
33
|
+
borrowerAddress: string;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Build the quantum-aligned timestamp + EIP-191 signature the
|
|
37
|
+
* `/api/lit/pending-withdrawals/execute` endpoint expects.
|
|
38
|
+
*
|
|
39
|
+
* Audit CRIT-1: the signed message now binds `targetAddress` and `targetAmount`
|
|
40
|
+
* in addition to the UTXO identifier. The previous shape bound only the UTXO,
|
|
41
|
+
* delegating destination/amount enforcement to the Lit Action's on-chain
|
|
42
|
+
* `getAuthorizedSpends` lookup. That single defense was reliable in practice
|
|
43
|
+
* but the user-signed message is now self-describing — the Lit Action
|
|
44
|
+
* cross-checks the user-signed values against the on-chain authorizer record
|
|
45
|
+
* and refuses any disagreement, so a bug or future loosening of one side does
|
|
46
|
+
* not silently redirect funds.
|
|
47
|
+
*
|
|
48
|
+
* Caller passes the UTXO satoshis (from Phase 1 result) AND the user-authorized
|
|
49
|
+
* destination + amount; this helper returns everything the server needs to
|
|
50
|
+
* delegate to the BTC signer LIT Action.
|
|
51
|
+
*
|
|
52
|
+
* Wire-compat: this is a coordinated breaking change — the new SDK signatures
|
|
53
|
+
* are not accepted by an older btc-transaction-signer Lit Action, and the new
|
|
54
|
+
* Lit Action does not accept older SDK signatures. Deploy together.
|
|
55
|
+
*/
|
|
56
|
+
export declare function buildBtcExecuteEnvelope(params: BtcExecuteSignParams & {
|
|
57
|
+
satoshis: number;
|
|
58
|
+
targetAddress: string;
|
|
59
|
+
targetAmount: number;
|
|
60
|
+
}): Promise<BtcExecuteSignedEnvelope>;
|
|
@@ -51,6 +51,16 @@ export declare function getBitcoinAddressFromPkp(pkpPublicKey: string, network?:
|
|
|
51
51
|
*/
|
|
52
52
|
export declare function getBitcoinAddressesFromPkp(pkpPublicKey: string): Promise<BitcoinAddresses>;
|
|
53
53
|
export declare class BitcoinUtils {
|
|
54
|
+
/**
|
|
55
|
+
* Validate a Bitcoin address across mainnet / testnet / regtest with full
|
|
56
|
+
* checksum verification.
|
|
57
|
+
*
|
|
58
|
+
* Audit H-12: the previous implementation was a permissive regex with no
|
|
59
|
+
* checksum check — garbage like `bc1qqqqqqqqqq` passed. The new
|
|
60
|
+
* implementation uses the `bech32` and `bs58check` packages (both already
|
|
61
|
+
* in deps) to validate the actual checksum, and rejects unknown HRPs /
|
|
62
|
+
* version bytes / witness program lengths.
|
|
63
|
+
*/
|
|
54
64
|
static validateAddress(address: string): boolean;
|
|
55
65
|
static formatTransaction(hash: string, amount: string, recipient: string): {
|
|
56
66
|
hash: string;
|
|
@@ -2,23 +2,22 @@
|
|
|
2
2
|
* EIP-1559 transaction broadcast helpers for paths that need explicit gas limits
|
|
3
3
|
* (e.g. large mintUCD) without manual signDigest / eth_sendRawTransaction.
|
|
4
4
|
*/
|
|
5
|
-
import {
|
|
6
|
-
import type { BigNumber, providers, Signer } from "ethers";
|
|
5
|
+
import { type Provider, type Signer, type TransactionResponse } from "ethers";
|
|
7
6
|
/** Observed mintUCD + LIT validation can exceed 7M gas; cap avoids block limit issues. */
|
|
8
|
-
export declare const MINT_UCD_GAS_CEILING:
|
|
7
|
+
export declare const MINT_UCD_GAS_CEILING: bigint;
|
|
9
8
|
/** Headroom on eth_estimateGas (25%). */
|
|
10
9
|
export declare const MINT_UCD_ESTIMATE_MARGIN_BPS = 2500;
|
|
11
10
|
/**
|
|
12
11
|
* Returns gas limit with margin, capped, or null if estimateGas reverts/fails.
|
|
13
12
|
*/
|
|
14
|
-
export declare function estimateContractCallGasWithMargin(provider:
|
|
15
|
-
export declare function resolveEip1559FeeFields(provider:
|
|
16
|
-
maxFeePerGas:
|
|
17
|
-
maxPriorityFeePerGas:
|
|
13
|
+
export declare function estimateContractCallGasWithMargin(provider: Provider, from: string, to: string, data: string, marginBps: number, ceiling: bigint): Promise<bigint | null>;
|
|
14
|
+
export declare function resolveEip1559FeeFields(provider: Provider): Promise<{
|
|
15
|
+
maxFeePerGas: bigint;
|
|
16
|
+
maxPriorityFeePerGas: bigint;
|
|
18
17
|
}>;
|
|
19
18
|
export declare function sendEip1559Transaction(params: {
|
|
20
19
|
signer: Signer;
|
|
21
20
|
to: string;
|
|
22
21
|
data: string;
|
|
23
|
-
gasLimit:
|
|
24
|
-
}): Promise<
|
|
22
|
+
gasLimit: bigint;
|
|
23
|
+
}): Promise<TransactionResponse>;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Build + sign the `DhServerLogin` EIP-712 envelope the lit-ops-server's
|
|
3
|
+
* `POST /api/auth/login` route expects. Used by both the CLI helper and
|
|
4
|
+
* frontends that consume the SDK directly.
|
|
5
|
+
*/
|
|
6
|
+
import { Signer, TypedDataField } from "ethers";
|
|
7
|
+
export interface DhServerLoginMessage {
|
|
8
|
+
address: string;
|
|
9
|
+
issuedAt: number;
|
|
10
|
+
nonce: string;
|
|
11
|
+
}
|
|
12
|
+
export interface DhServerLoginPayload {
|
|
13
|
+
chainId: number;
|
|
14
|
+
message: DhServerLoginMessage;
|
|
15
|
+
signature: string;
|
|
16
|
+
}
|
|
17
|
+
export declare function buildLoginDomain(chainId: number): {
|
|
18
|
+
name: string;
|
|
19
|
+
version: string;
|
|
20
|
+
chainId: number;
|
|
21
|
+
};
|
|
22
|
+
export declare const LOGIN_TYPES: Record<string, TypedDataField[]>;
|
|
23
|
+
/**
|
|
24
|
+
* Sign a fresh login envelope. Caller POSTs the returned `payload` to the
|
|
25
|
+
* server's `/api/auth/login` route.
|
|
26
|
+
*/
|
|
27
|
+
export declare function buildSignedLoginPayload(signer: Signer, chainId: number): Promise<DhServerLoginPayload>;
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Generates authorization signatures for extend position requests
|
|
5
5
|
* that can be verified by the extend-position-validator LIT Action.
|
|
6
6
|
*/
|
|
7
|
-
import {
|
|
7
|
+
import { type Wallet } from "ethers";
|
|
8
8
|
/**
|
|
9
9
|
* Extend Owner Authorization Interface (matches lit-actions)
|
|
10
10
|
*/
|
|
@@ -55,7 +55,7 @@ export declare function buildExtendAuthorizationHash(positionId: string, newTerm
|
|
|
55
55
|
* @param signerOrPrecomputed - Either an ethers Wallet (EOA) or { timestamp, signature } for smart contract wallets
|
|
56
56
|
* @returns Authorization object with signature
|
|
57
57
|
*/
|
|
58
|
-
export declare function generateExtendAuthorization(positionId: string, newTerm: number, chainId: number, signerOrPrecomputed:
|
|
58
|
+
export declare function generateExtendAuthorization(positionId: string, newTerm: number, chainId: number, signerOrPrecomputed: Wallet | {
|
|
59
59
|
timestamp: number;
|
|
60
60
|
signature: string;
|
|
61
61
|
}): Promise<ExtendOwnerAuthorization>;
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* that can be verified by the ucd-mint-validator LIT Action.
|
|
6
6
|
* Also includes withdrawal authorization utilities.
|
|
7
7
|
*/
|
|
8
|
-
import {
|
|
8
|
+
import { type Provider, type Signer } from "ethers";
|
|
9
9
|
/**
|
|
10
10
|
* Owner Authorization Interface (matches lit-actions)
|
|
11
11
|
*/
|
|
@@ -58,7 +58,7 @@ export declare function buildMintAuthorizationHash(positionId: string, amount: b
|
|
|
58
58
|
* @param signerOrPrecomputed - Either an ethers Signer (EOA) or { timestamp, signature } for smart contract wallets
|
|
59
59
|
* @returns Authorization object with signature
|
|
60
60
|
*/
|
|
61
|
-
export declare function generateMintAuthorization(positionId: string, amount: bigint, chainId: number, signerOrPrecomputed:
|
|
61
|
+
export declare function generateMintAuthorization(positionId: string, amount: bigint, chainId: number, signerOrPrecomputed: Signer | {
|
|
62
62
|
timestamp: number;
|
|
63
63
|
signature: string;
|
|
64
64
|
}): Promise<MintOwnerAuthorization>;
|
|
@@ -113,7 +113,7 @@ export interface BalanceConfirmationAuthorization {
|
|
|
113
113
|
* - Signer address is recovered from signature by LIT Action
|
|
114
114
|
* - LIT Action validates recovered address === position owner
|
|
115
115
|
*/
|
|
116
|
-
export declare function generatePaymentAuthorization(positionId: string, amount: bigint, chainId: number, signer:
|
|
116
|
+
export declare function generatePaymentAuthorization(positionId: string, amount: bigint, chainId: number, signer: Signer): Promise<PaymentOwnerAuthorization>;
|
|
117
117
|
/**
|
|
118
118
|
* Generate extend position authorization signature
|
|
119
119
|
*
|
|
@@ -131,7 +131,7 @@ export declare function generatePaymentAuthorization(positionId: string, amount:
|
|
|
131
131
|
* - Signer address is recovered from signature by LIT Action
|
|
132
132
|
* - LIT Action validates recovered address === position owner
|
|
133
133
|
*/
|
|
134
|
-
export declare function generateExtendAuthorization(positionId: string, selectedTerm: number, chainId: number, signer:
|
|
134
|
+
export declare function generateExtendAuthorization(positionId: string, selectedTerm: number, chainId: number, signer: Signer): Promise<ExtendOwnerAuthorization>;
|
|
135
135
|
/**
|
|
136
136
|
* Optional Chipotle service fallback for `getPKPPublicKeyFromTokenId`.
|
|
137
137
|
*
|
|
@@ -143,7 +143,8 @@ export declare function generateExtendAuthorization(positionId: string, selected
|
|
|
143
143
|
*/
|
|
144
144
|
export interface ChipotleServiceFallback {
|
|
145
145
|
serviceEndpoint: string;
|
|
146
|
-
|
|
146
|
+
/** Returns `Authorization`-style headers for the lit-ops-server request. */
|
|
147
|
+
getAuthHeader?: () => Promise<Record<string, string>>;
|
|
147
148
|
borrowerAddress?: string;
|
|
148
149
|
timeoutMs?: number;
|
|
149
150
|
debug?: boolean;
|
|
@@ -165,7 +166,7 @@ export interface ChipotleServiceFallback {
|
|
|
165
166
|
* @param chipotleFallback - Service-mode fallback used when pkpTokenId is a Chipotle id
|
|
166
167
|
* @returns PKP public key as hex string with '0x' prefix
|
|
167
168
|
*/
|
|
168
|
-
export declare function getPKPPublicKeyFromTokenId(pkpTokenId: string, provider?:
|
|
169
|
+
export declare function getPKPPublicKeyFromTokenId(pkpTokenId: string, provider?: Provider, pkpNftContractAddress?: string, chipotleFallback?: ChipotleServiceFallback): Promise<string>;
|
|
169
170
|
/**
|
|
170
171
|
* Withdraw Owner Authorization Interface (matches lit-actions)
|
|
171
172
|
*/
|
|
@@ -218,7 +219,7 @@ export declare function buildWithdrawAuthorizationHash(positionId: string, amoun
|
|
|
218
219
|
* @returns Authorization object with signature
|
|
219
220
|
*/
|
|
220
221
|
export declare function generateWithdrawAuthorization(positionId: string, amount: bigint, // satoshis
|
|
221
|
-
chainId: number, signerOrPrecomputed:
|
|
222
|
+
chainId: number, signerOrPrecomputed: Signer | {
|
|
222
223
|
timestamp: number;
|
|
223
224
|
signature: string;
|
|
224
225
|
}, destinationAddress: string): Promise<WithdrawOwnerAuthorization>;
|
|
@@ -244,4 +245,4 @@ chainId: number, signerOrPrecomputed: ethers5.Signer | {
|
|
|
244
245
|
* @param signer - Ethereum signer to sign with (the caller)
|
|
245
246
|
* @returns Authorization object with signature
|
|
246
247
|
*/
|
|
247
|
-
export declare function generateBalanceConfirmationAuthorization(positionId: string, chainId: number, signer:
|
|
248
|
+
export declare function generateBalanceConfirmationAuthorization(positionId: string, chainId: number, signer: Signer): Promise<BalanceConfirmationAuthorization>;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Position Delegate Utilities
|
|
3
|
+
*
|
|
4
|
+
* Helpers for registering an off-chain authorization delegate on a position.
|
|
5
|
+
* The delegate lets a Safe-as-borrower delegate LIT Action auth signing to a
|
|
6
|
+
* hot agent EOA without making that EOA a Safe owner. The delegate is read by
|
|
7
|
+
* the LIT Action authorization verifier as a third recovery arm after the
|
|
8
|
+
* EOA `position.borrower` check and the EIP-1271 smart-account fallback.
|
|
9
|
+
*
|
|
10
|
+
* State lives on `PositionDelegateRegistry` (a standalone contract), not on
|
|
11
|
+
* PositionManager — PositionManager is at the 24 KiB Spurious Dragon limit
|
|
12
|
+
* and cannot carry the additional storage + setter without going over.
|
|
13
|
+
*/
|
|
14
|
+
import { type Signer, type Provider, type TransactionResponse } from "ethers";
|
|
15
|
+
/**
|
|
16
|
+
* Register (or revoke) the off-chain authorization delegate for a position.
|
|
17
|
+
*
|
|
18
|
+
* Must be called by the position's current `borrower` — for Safe-as-borrower
|
|
19
|
+
* setups, that means the call must go through `safe.execTransaction(...)` or
|
|
20
|
+
* `agentModule.execute(...)` so that `msg.sender` at the registry equals the
|
|
21
|
+
* Safe. Pass `ethers.constants.AddressZero` as `delegate` to revoke.
|
|
22
|
+
*
|
|
23
|
+
* @param positionId Position identifier (bytes32).
|
|
24
|
+
* @param delegate New delegate EOA, or zero address to clear.
|
|
25
|
+
* @param signer Ethers signer that will be `msg.sender` at the registry.
|
|
26
|
+
* @param registryAddress Deployed `PositionDelegateRegistry` address for the chain.
|
|
27
|
+
* @returns The submitted transaction response.
|
|
28
|
+
*/
|
|
29
|
+
export declare function setPositionDelegate(positionId: string, delegate: string, signer: Signer, registryAddress: string): Promise<TransactionResponse>;
|
|
30
|
+
/**
|
|
31
|
+
* Read the currently registered delegate for a position.
|
|
32
|
+
*
|
|
33
|
+
* Returns the zero address when no delegate has been registered. Pure view;
|
|
34
|
+
* any provider works (signer not required).
|
|
35
|
+
*
|
|
36
|
+
* @param positionId Position identifier (bytes32).
|
|
37
|
+
* @param provider Ethers provider or signer.
|
|
38
|
+
* @param registryAddress Deployed `PositionDelegateRegistry` address.
|
|
39
|
+
* @returns The delegate EOA, or zero address if none.
|
|
40
|
+
*/
|
|
41
|
+
export declare function getPositionDelegate(positionId: string, provider: Provider | Signer, registryAddress: string): Promise<string>;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In-memory session JWT manager for lit-ops-server.
|
|
3
|
+
*
|
|
4
|
+
* The server's `POST /api/auth/login` route accepts an EIP-712-signed
|
|
5
|
+
* `DhServerLogin` envelope and returns an HS256 JWT with a 15-minute TTL.
|
|
6
|
+
* This helper:
|
|
7
|
+
*
|
|
8
|
+
* - caches the JWT until ~30s before expiry,
|
|
9
|
+
* - coalesces concurrent callers behind a single in-flight Promise so we
|
|
10
|
+
* don't spam `/api/auth/login` on parallel SDK calls,
|
|
11
|
+
* - exposes `getValidToken()` returning the live token and
|
|
12
|
+
* `getAuthHeader()` returning a ready-to-spread `{ Authorization: ... }`
|
|
13
|
+
* object.
|
|
14
|
+
*
|
|
15
|
+
* Browser-safe — no filesystem touches. The CLI mirrors this shape but
|
|
16
|
+
* persists to `~/.diamond-hands/session.json` for cross-invocation reuse.
|
|
17
|
+
*/
|
|
18
|
+
import type { Signer } from "ethers";
|
|
19
|
+
export interface ServerSessionOptions {
|
|
20
|
+
signer: Signer;
|
|
21
|
+
serviceEndpoint: string;
|
|
22
|
+
chainId: number;
|
|
23
|
+
/** Override for tests. */
|
|
24
|
+
now?: () => number;
|
|
25
|
+
/** Override for tests. */
|
|
26
|
+
fetchImpl?: typeof fetch;
|
|
27
|
+
}
|
|
28
|
+
export declare class ServerSession {
|
|
29
|
+
private readonly signer;
|
|
30
|
+
private readonly serviceEndpoint;
|
|
31
|
+
private readonly chainId;
|
|
32
|
+
private readonly now;
|
|
33
|
+
private readonly fetchImpl;
|
|
34
|
+
private cached;
|
|
35
|
+
private inFlight;
|
|
36
|
+
constructor(opts: ServerSessionOptions);
|
|
37
|
+
/** Returns a JWT good for at least `REFRESH_LEEWAY_SECONDS` more seconds. */
|
|
38
|
+
getValidToken(): Promise<string>;
|
|
39
|
+
/** Convenience for fetch: spread directly into `headers`. */
|
|
40
|
+
getAuthHeader(): Promise<Record<string, string>>;
|
|
41
|
+
/** Drop the cached token (e.g. on 401 from server). Next call re-logs in. */
|
|
42
|
+
clear(): void;
|
|
43
|
+
private getOrRefresh;
|
|
44
|
+
}
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Signature Tempering Utility
|
|
3
3
|
*
|
|
4
|
-
* Security testing tool to intentionally corrupt signatures
|
|
5
|
-
*
|
|
4
|
+
* Security testing tool to intentionally corrupt signatures so tests can prove
|
|
5
|
+
* the on-chain validator rejects invalid signatures.
|
|
6
6
|
*
|
|
7
|
-
* WARNING:
|
|
7
|
+
* WARNING: TESTING ONLY. `maybeTemperSignature` refuses to corrupt signatures
|
|
8
|
+
* when `NODE_ENV === "production"`, regardless of the config flag. The previous
|
|
9
|
+
* behavior (any caller could flip `temperSignaturesTest: true` to corrupt every
|
|
10
|
+
* signature) was an audit finding — the function is now defense-in-depth.
|
|
8
11
|
*/
|
|
9
12
|
/**
|
|
10
13
|
* Tempers a signature by modifying the 3rd character with a random valid hex character
|