@gvnrdao/dh-sdk 0.0.317 → 0.0.319

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.
@@ -96,18 +96,6 @@ export interface IUCDController extends BaseContract {
96
96
  ucdToken(): Promise<string>;
97
97
  adminModule(): Promise<string>;
98
98
  }
99
- /**
100
- * Price Feed Consumer Contract Interface
101
- */
102
- export interface IPriceFeedConsumer extends BaseContract {
103
- updatePrice(): Promise<ContractTransactionResponse>;
104
- getCurrentPrice(): Promise<bigint>;
105
- getPriceAge(): Promise<bigint>;
106
- isPriceStale(): Promise<boolean>;
107
- validatePriceFeed(): Promise<boolean>;
108
- getLatestBTCPrice(): Promise<bigint>;
109
- decimals(): Promise<number>;
110
- }
111
99
  /**
112
100
  * Term Manager Contract Interface
113
101
  * Based on contracts/src/interfaces/ITermManager.sol
@@ -15,7 +15,7 @@ import type { ContractAddresses } from "../../interfaces/chunks/config.i";
15
15
  import { type DeploymentContracts } from "../../constants/chunks/deployment-addresses";
16
16
  import { Result } from "../../types/result";
17
17
  import { SDKError } from "../../utils/error-handler";
18
- import type { PositionManager, ILoanOperationsManager, IUCDController, IPriceFeedConsumer, ITermManager, CircuitBreakerModule, ILiquidationManager } from "../../interfaces/chunks/contract-types.i";
18
+ import type { PositionManager, ILoanOperationsManager, IUCDController, ITermManager, CircuitBreakerModule, ILiquidationManager } from "../../interfaces/chunks/contract-types.i";
19
19
  /**
20
20
  * Type alias for ethers v6 provider (used throughout SDK)
21
21
  */
@@ -52,7 +52,6 @@ export interface ManagedContracts {
52
52
  positionManager: PositionManager;
53
53
  loanOperationsManager: ILoanOperationsManager;
54
54
  ucdController: IUCDController;
55
- priceFeed: IPriceFeedConsumer;
56
55
  termManager: ITermManager;
57
56
  circuitBreaker: CircuitBreakerModule;
58
57
  liquidationManager: ILiquidationManager;
@@ -94,10 +93,6 @@ export declare class ContractManager {
94
93
  * Get UCD Controller contract
95
94
  */
96
95
  getUCDController(): Result<IUCDController, SDKError>;
97
- /**
98
- * Get Price Feed contract
99
- */
100
- getPriceFeed(): Result<IPriceFeedConsumer, SDKError>;
101
96
  /**
102
97
  * Get Term Manager contract
103
98
  */
@@ -887,8 +887,22 @@ export declare class DiamondHandsSDK {
887
887
  * @param options - Override timeout/interval for this call
888
888
  * @throws if timeout is reached before subgraph catches up
889
889
  */
890
- /** Guard: the AgentDelegationRegistry MVP is deployed on Sepolia only. */
891
- private assertAgentDelegationSepolia;
890
+ /**
891
+ * Guard: resolve the AgentDelegationRegistry for the configured network.
892
+ *
893
+ * Deployment presence IS the availability test — there is deliberately no chainId
894
+ * allow-list here. The registry is deployed per network (Sepolia 2026-07, mainnet
895
+ * 2026-08 agent-stack release) and `getNetworkConfig` populates the address from the
896
+ * generated deployment table, so a chain without a deployment resolves to `""` and
897
+ * fails closed below. Adding a chain therefore needs no SDK code change — which is
898
+ * exactly how the previous hardcoded `chainId !== 11155111` gate went stale and kept
899
+ * the mainnet toggle dark after the registry shipped.
900
+ *
901
+ * Callers that need the availability answer WITHOUT throwing (e.g. to decide whether to
902
+ * render a toggle at all) should ask the deployment table directly rather than calling this
903
+ * and catching — `ALL_DEPLOYMENTS` is published on the `@gvnrdao/dh-sdk/deployments` subpath.
904
+ */
905
+ private agentDelegationRegistryOrThrow;
892
906
  /**
893
907
  * Read a position's auto-renew delegation state (used to drive the Enable/Disable toggle).
894
908
  * Pure view — no signer required.
@@ -12,12 +12,27 @@
12
12
  * and cannot carry the additional storage + setter without going over.
13
13
  */
14
14
  import { type Signer, type Provider, type TransactionResponse } from "ethers";
15
- /** Registry v2.0.0 `delegateStatus` deny reasons. */
15
+ /**
16
+ * Registry v2.0.0 `delegateStatus` deny reasons.
17
+ *
18
+ * Mirrors `PositionDelegateRegistry.DenyReason` exactly, by ordinal — `getDelegateStatus` casts the
19
+ * raw uint8 straight to this enum, so a missing member surfaces as an unmapped value rather than an
20
+ * error. Keep the two in lockstep, and only ever APPEND: the contract appends too, so that the
21
+ * existing ABI values never shift.
22
+ */
16
23
  export declare enum DelegateDenyReason {
17
24
  NONE = 0,
18
25
  PAUSED = 1,
19
26
  NO_DELEGATE = 2,
20
- NOT_DELEGATE = 3
27
+ NOT_DELEGATE = 3,
28
+ /**
29
+ * The delegate address was permanently burned protocol-wide by `revokeDelegate`
30
+ * (REGISTRAR_ROLE). Checked ahead of the per-position match, so a burned key reports BURNED on
31
+ * every position rather than NOT_DELEGATE on the one it was revoked from. The burn is global and
32
+ * irreversible — recovery is rotating to a fresh address, which AgentDelegationRegistry's AR-1
33
+ * non-reuse rule forces anyway.
34
+ */
35
+ BURNED = 4
21
36
  }
22
37
  /**
23
38
  * Register (or revoke) the off-chain authorization delegate for a position.
@@ -44,8 +44,12 @@ export interface ServerSessionStore {
44
44
  * so a custom store written before this existed still satisfies the interface;
45
45
  * without it the session simply mints a fresh envelope each attempt, which is
46
46
  * the pre-existing behavior and only costs a multi-owner Safe a restart.
47
+ *
48
+ * `maxAgeSeconds` is supplied by the caller, which knows the signer kind and
49
+ * therefore which of the server's two first-use windows applies. A store that
50
+ * ignores it keeps the old single-TTL behavior.
47
51
  */
48
- loadPending?(key: string): PendingLoginEnvelope | null;
52
+ loadPending?(key: string, maxAgeSeconds?: number): PendingLoginEnvelope | null;
49
53
  savePending?(key: string, envelope: PendingLoginEnvelope): void;
50
54
  clearPending?(key: string): void;
51
55
  }
@@ -69,12 +73,26 @@ export interface PendingLoginEnvelope {
69
73
  nonce: string;
70
74
  }
71
75
  /**
72
- * How long an unsigned envelope stays reusable. Must stay UNDER the server's
73
- * contract-wallet first-use skew (`CONTRACT_ISSUED_AT_SKEW_SECONDS`, 10 min):
74
- * beyond it the first use is rejected as stale, so reuse would guarantee failure
75
- * instead of preventing a re-sign.
76
+ * How long an unsigned envelope stays reusable FOR A CONTRACT WALLET. Must stay
77
+ * UNDER the server's contract-wallet first-use skew
78
+ * (`CONTRACT_ISSUED_AT_SKEW_SECONDS`, 10 min): beyond it the first use is
79
+ * rejected as stale, so reuse would guarantee failure instead of preventing a
80
+ * re-sign.
76
81
  */
77
82
  export declare const PENDING_ENVELOPE_TTL_SECONDS: number;
83
+ /**
84
+ * The same, for an EOA — which the server gives only `ISSUED_AT_SKEW_SECONDS`
85
+ * (120s) to make its FIRST use.
86
+ *
87
+ * Between 120s and 8 minutes a reused EOA envelope is still "live" locally and
88
+ * certain to be refused by the server, so the contract-wallet TTL is not a safe
89
+ * over-estimate for a key-holding wallet — it is a window in which every retry
90
+ * re-signs a message that cannot be accepted. 60s leaves a full minute of the
91
+ * server's window for the prompt and the round trip, and an EOA gives up
92
+ * nothing by re-minting: it signs in one click, so it has no equivalent of the
93
+ * cross-session ceremony this reuse exists for.
94
+ */
95
+ export declare const EOA_PENDING_ENVELOPE_TTL_SECONDS = 60;
78
96
  /** Storage key for the pending envelope matching a session key. */
79
97
  export declare function pendingEnvelopeKey(sessionKey: string): string;
80
98
  export declare function isPendingEnvelopeShape(value: any): value is PendingLoginEnvelope;
@@ -82,7 +100,7 @@ export declare class LocalStorageSessionStore implements ServerSessionStore {
82
100
  load(key: string): PersistedServerSession | null;
83
101
  save(key: string, session: PersistedServerSession): void;
84
102
  clear(key: string): void;
85
- loadPending(key: string): PendingLoginEnvelope | null;
103
+ loadPending(key: string, maxAgeSeconds?: number): PendingLoginEnvelope | null;
86
104
  savePending(key: string, envelope: PendingLoginEnvelope): void;
87
105
  clearPending(key: string): void;
88
106
  }
@@ -92,7 +110,7 @@ export declare class MemorySessionStore implements ServerSessionStore {
92
110
  load(key: string): PersistedServerSession | null;
93
111
  save(key: string, session: PersistedServerSession): void;
94
112
  clear(key: string): void;
95
- loadPending(key: string): PendingLoginEnvelope | null;
113
+ loadPending(key: string, maxAgeSeconds?: number): PendingLoginEnvelope | null;
96
114
  savePending(key: string, envelope: PendingLoginEnvelope): void;
97
115
  clearPending(key: string): void;
98
116
  }
@@ -62,10 +62,15 @@ export interface ServerSessionOptions {
62
62
  /** Override for tests. */
63
63
  fetchImpl?: typeof fetch;
64
64
  }
65
- /** Login failure carrying the HTTP status so callers can tell rejection from outage. */
65
+ /**
66
+ * Login failure carrying the HTTP status — and the server's machine-readable
67
+ * `reason` where it sent one — so callers can tell rejection from outage, and
68
+ * one kind of rejection from another.
69
+ */
66
70
  export declare class ServerLoginError extends Error {
67
71
  readonly status: number;
68
- constructor(message: string, status: number);
72
+ readonly reason?: string | undefined;
73
+ constructor(message: string, status: number, reason?: string | undefined);
69
74
  }
70
75
  export declare class ServerSession {
71
76
  private readonly signer;
@@ -97,6 +102,12 @@ export declare class ServerSession {
97
102
  * `clear()` can drop the persisted token without an async address lookup.
98
103
  */
99
104
  private lastStoreKey;
105
+ /**
106
+ * Whether the signer is a smart-contract wallet, memoized after the first
107
+ * `eth_getCode`. Decides which of the server's two first-use windows bounds
108
+ * envelope reuse; a signer cannot change kind for the life of the session.
109
+ */
110
+ private contractSigner;
100
111
  constructor(opts: ServerSessionOptions);
101
112
  /**
102
113
  * Returns a JWT good for at least `REFRESH_LEEWAY_SECONDS` more seconds.
@@ -160,6 +171,20 @@ export declare class ServerSession {
160
171
  * and the store are skipped if a `clearPersisted()` landed meanwhile.
161
172
  */
162
173
  private tryResolveSilently;
174
+ /**
175
+ * How long a pending envelope for THIS signer may be reused, in seconds.
176
+ *
177
+ * The server grants an EOA 120s to make an envelope's first use and a contract
178
+ * wallet 600s, so one local TTL is necessarily wrong for one of them. Deployed
179
+ * code has bytecode; an EOA does not — one `eth_getCode`, memoized, settles it.
180
+ *
181
+ * Reports the CONTRACT window when it cannot tell, which is the behavior that
182
+ * shipped before the split. The asymmetry is intended: guessing "EOA" for a
183
+ * Safe hands it a new message and orphans the owner signatures already
184
+ * collected, while guessing "contract" for an EOA now costs one rejected
185
+ * attempt, because a rejection clears the envelope.
186
+ */
187
+ private pendingEnvelopeTtl;
163
188
  private getOrRefresh;
164
189
  private login;
165
190
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gvnrdao/dh-sdk",
3
- "version": "0.0.317",
3
+ "version": "0.0.319",
4
4
  "description": "TypeScript SDK for Diamond Hands Protocol - Bitcoin-backed lending with LIT Protocol PKPs",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -82,8 +82,8 @@
82
82
  },
83
83
  "sideEffects": false,
84
84
  "dependencies": {
85
- "@gvnrdao/dh-lit-actions": "^0.0.318",
86
- "@gvnrdao/dh-lit-ops": "^0.0.309",
85
+ "@gvnrdao/dh-lit-actions": "^0.0.319",
86
+ "@gvnrdao/dh-lit-ops": "^0.0.310",
87
87
  "@noble/hashes": "^1.5.0",
88
88
  "axios": "^1.17.0",
89
89
  "bech32": "^2.0.0",