@gvnrdao/dh-sdk 0.0.320 → 0.0.323

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.
@@ -48,6 +48,8 @@ export interface ContractAddresses {
48
48
  agentDelegationRegistry?: string;
49
49
  /** DHAgentDelegate; EIP-7702 execution adapter (Gate 2) the borrower EOA delegates to. Sepolia only. */
50
50
  dhAgentDelegate?: string;
51
+ /** AgentModuleFactory; CREATE2 factory a multi-sig Safe uses to deploy its own AgentModule in the delegation ceremony. Sepolia only. */
52
+ agentModuleFactory?: string;
51
53
  mockUsdcToken?: string;
52
54
  mockUsdcOwner?: string;
53
55
  mockUsdtToken?: string;
@@ -148,6 +148,98 @@ export declare class DiamondHandsSDK {
148
148
  * No-op in standalone mode (no server session to prime).
149
149
  */
150
150
  primeServerSession(payload: DhServerLoginPayload): Promise<void>;
151
+ /**
152
+ * Build the Safe-delegation ceremony for a multi-sig Safe (Phase 1 of
153
+ * multi-sig support): asks lit-ops-server to mint (or recover) the Safe's
154
+ * agent PKP and returns the exact call batch the Safe's owners must execute
155
+ * (AgentModuleFactory.deploy → safe.enableModule → registerAgent), derived
156
+ * from live chain state so a half-done ceremony resumes.
157
+ *
158
+ * Service-mode only — the server holds the Chipotle account that mints the
159
+ * PKP and it gates the route to current Safe owners. `knownAgentAddress` is
160
+ * the caller-persisted agent from an earlier prepare whose ceremony has not
161
+ * landed yet; echoing it back prevents a duplicate mint after a server
162
+ * restart.
163
+ */
164
+ prepareSafeAgentModule(request: {
165
+ safeAddress: string;
166
+ knownAgentAddress?: string;
167
+ }): Promise<{
168
+ status: "ready" | "already-delegated";
169
+ agentAddress: string;
170
+ moduleAddress: string;
171
+ validUntil: number | null;
172
+ calls: {
173
+ to: string;
174
+ data: string;
175
+ value: string;
176
+ }[];
177
+ }>;
178
+ /**
179
+ * Shared transport for `/agent-module/{authorize,execute}`.
180
+ *
181
+ * Both routes run the agent PKP's key inside a Lit Action, gated on the
182
+ * caller's session being a CURRENT Safe owner (M-8c). Service-mode only, for
183
+ * the same reason as {@link prepareSafeAgentModule}: the key lives in the
184
+ * server's Chipotle account and has no standalone equivalent.
185
+ */
186
+ private postAgentModuleRoute;
187
+ /**
188
+ * The agent signs the borrower authorization envelope for `op` on `positionId`.
189
+ *
190
+ * The returned `{ timestamp, signature }` feeds the SDK's PRECOMPUTED
191
+ * authorization path (`generateExtendAuthorization` and siblings) — the same
192
+ * path Safe/EIP-1271 borrowers already use. It is NOT a generic message
193
+ * signer: the Lit Action REBUILDS the envelope from these fields rather than
194
+ * signing anything the caller supplies, which is what stops a delegated agent
195
+ * key being turned into an arbitrary oracle.
196
+ *
197
+ * `timestamp` must be quantum-aligned by the caller
198
+ * (`calculateNextQuantumTimestamp()`) and must be the SAME value later passed
199
+ * to the protocol call, or the validator recovers a different signer.
200
+ */
201
+ agentModuleAuthorize(request: {
202
+ safeAddress: string;
203
+ positionId: string;
204
+ op: "mint" | "repay" | "renew" | "withdraw";
205
+ timestamp: number;
206
+ amount?: string;
207
+ selectedTerm?: number;
208
+ }): Promise<{
209
+ module: string;
210
+ agent: string;
211
+ authorization: {
212
+ timestamp: number;
213
+ signature: string;
214
+ signer: string;
215
+ };
216
+ }>;
217
+ /**
218
+ * The agent signs `module.execute(target, innerData)` as a raw EIP-1559
219
+ * transaction. Returns the SIGNED transaction — the caller broadcasts it, so
220
+ * the tx hash and receipt come from the caller's own provider.
221
+ *
222
+ * `tx` fields are caller-supplied because the Lit Action runs on many nodes
223
+ * and reconciles results: anything fetched in-action (nonce, gas) would
224
+ * differ per node and fail consensus.
225
+ */
226
+ agentModuleExecute(request: {
227
+ safeAddress: string;
228
+ positionId: string;
229
+ op: "mint" | "repay" | "renew" | "withdraw";
230
+ target: string;
231
+ innerData: string;
232
+ tx: {
233
+ nonce: number;
234
+ gasLimit: string;
235
+ maxFeePerGas: string;
236
+ maxPriorityFeePerGas: string;
237
+ };
238
+ }): Promise<{
239
+ module: string;
240
+ agent: string;
241
+ signedTransaction: string;
242
+ }>;
151
243
  /**
152
244
  * Audit H-9: invalidate the LoanQuery cache so subsequent reads return
153
245
  * the post-write state. We clear the entire loan-query cache (not just
@@ -509,6 +601,11 @@ export declare class DiamondHandsSDK {
509
601
  * The service path's post-broadcast CRIT-2 re-verification exists to catch
510
602
  * a LYING SERVER; here the broadcast happens locally from the signatures we
511
603
  * just obtained, so the esplora-returned txid is already first-hand.
604
+ *
605
+ * Multi-UTXO consolidation in standalone mode requires the caller to supply
606
+ * `request.utxos` explicitly — `fetchConfirmedVaultUtxos` is service-mode
607
+ * only, so there is no automatic gather here; without the set, a multi-UTXO
608
+ * vault fails in the signer with its "Insufficient UTXO value" error.
512
609
  */
513
610
  private executeBTCWithdrawalStandalonePhase2;
514
611
  executeBTCWithdrawal(request: {
@@ -903,6 +1000,25 @@ export declare class DiamondHandsSDK {
903
1000
  * and catching — `ALL_DEPLOYMENTS` is published on the `@gvnrdao/dh-sdk/deployments` subpath.
904
1001
  */
905
1002
  private agentDelegationRegistryOrThrow;
1003
+ /**
1004
+ * `LoanGrant` fields that EVERY deployed registry version returns.
1005
+ *
1006
+ * Deliberately omits `minWithdrawRatioBps` — see {@link readLoanGrant}.
1007
+ */
1008
+ private static readonly LOAN_GRANT_PREFIX_IFACE;
1009
+ /**
1010
+ * Read a position's grant, decoding only the struct prefix that every deployed registry
1011
+ * version shares.
1012
+ *
1013
+ * `LoanGrant` gained a fourth member (`minWithdrawRatioBps`) in registry v2.1.0, and the
1014
+ * typechain bindings are generated from that source — but Sepolia (`0x6AE7fc6b…`) and mainnet
1015
+ * (`0x54853b7E…`) both run v2.0.0, whose `getLoanGrant` returns three words. Decoding that
1016
+ * with the generated four-field decoder fails `BAD_DATA` on every live chain, which is what
1017
+ * took the Agents tab down. The first three members are identical in both layouts, and ethers
1018
+ * ignores the trailing static word on a v2.1.0 registry, so this decoder is correct against
1019
+ * both. Nothing in this SDK reads `minWithdrawRatioBps`: WITHDRAW is not a scope it grants.
1020
+ */
1021
+ private readLoanGrant;
906
1022
  /**
907
1023
  * Read a position's auto-renew delegation state (used to drive the Enable/Disable toggle).
908
1024
  * Pure view — no signer required.
@@ -916,6 +1032,49 @@ export declare class DiamondHandsSDK {
916
1032
  reason: number;
917
1033
  } | null;
918
1034
  }>;
1035
+ /**
1036
+ * Read every delegation scope a position has granted, plus the mint floor and the protocol
1037
+ * minimum the UI must clamp its editor to. Pure view — no signer required.
1038
+ *
1039
+ * Superset of `getAutoRenewStatus`, which predates the multi-scope UI and is kept for
1040
+ * callers that only care about renew.
1041
+ */
1042
+ getDelegationStatus(positionId: string, user?: string): Promise<{
1043
+ renewEnabled: boolean;
1044
+ repayEnabled: boolean;
1045
+ mintEnabled: boolean;
1046
+ /** Grant's post-mint CR floor in bps; 0 when MINT is not granted. */
1047
+ minCollateralRatioBps: number;
1048
+ /** What `canMint` actually enforces: `max(grant floor, protocol min)`. 0 when not granted. */
1049
+ effectiveMintFloorBps: number;
1050
+ /** Governance floor-of-floors — the lowest value the user may set (15000 = 150%). */
1051
+ protocolMinFloorBps: number;
1052
+ borrower: string;
1053
+ agentActive: boolean | null;
1054
+ /** Agent expiry (unix seconds) — the ONLY time bound on every grant. Null without `user`. */
1055
+ agentValidUntil: number | null;
1056
+ }>;
1057
+ /** Governance floor-of-floors for agent mints (bps). The UI's minimum for the floor editor. */
1058
+ getAgentMintFloorMinBps(): Promise<number>;
1059
+ /**
1060
+ * Shared enable-path preamble for EVERY scope: resolve the registry, ensure the borrower has
1061
+ * an active agent (minting + registering a per-user PKP on first use), and make that agent the
1062
+ * position's Gate-1 delegate. Returns the signer-connected registry and the agent address.
1063
+ *
1064
+ * Every `enableAuto*` runs this: the registry reverts `NoActiveAgent` without an agent, and
1065
+ * `lit-ops-server.isPositionDelegate` 403s the agent on the execute routes without Gate 1 —
1066
+ * so a scope enabled without this preamble would look on but never execute.
1067
+ */
1068
+ private prepareAgentDelegation;
1069
+ /**
1070
+ * Shared disable-path epilogue: drop the position's Gate-1 delegate, but ONLY once no scope
1071
+ * remains. Scopes compose, so clearing Gate 1 on every disable would silently break the
1072
+ * surviving ones server-side (the agent would 403 on the execute routes while its remaining
1073
+ * grant still reads as enabled on-chain).
1074
+ *
1075
+ * Also refuses to clobber a delegate registered for anything other than this user's agent.
1076
+ */
1077
+ private clearGate1IfNoScopesRemain;
919
1078
  /**
920
1079
  * Enable auto-renew delegation for a position. Orchestrates the first-time setup: if the
921
1080
  * borrower has no active agent, mints a fresh per-user agent PKP (via lit-ops-server) and
@@ -938,6 +1097,54 @@ export declare class DiamondHandsSDK {
938
1097
  hash: string;
939
1098
  blockNumber: number;
940
1099
  }>;
1100
+ /**
1101
+ * Enable auto-repay delegation: the agent may repay this position's debt on the borrower's
1102
+ * behalf. Deliberately uncapped in the registry — repay only ever burns the borrower's own
1103
+ * debt from the borrower's own funds, and the ERC-20 allowance to PositionManager (never
1104
+ * granted to the agent) is the natural bound. Borrower-signed.
1105
+ */
1106
+ enableAutoRepay(positionId: string, options?: {
1107
+ agentValiditySeconds?: number;
1108
+ }): Promise<{
1109
+ hash: string;
1110
+ blockNumber: number;
1111
+ agentAddress?: string;
1112
+ }>;
1113
+ /** Disable auto-repay delegation for a position. Borrower-signed. */
1114
+ disableAutoRepay(positionId: string): Promise<{
1115
+ hash: string;
1116
+ blockNumber: number;
1117
+ }>;
1118
+ /**
1119
+ * Enable auto-mint delegation with a post-mint collateral-ratio floor (bps) the mint validator
1120
+ * enforces. `minCollateralRatioBps` must be at or above the governance minimum
1121
+ * (`getAgentMintFloorMinBps()`, 15000 = 150%) — checked here so the caller gets a readable
1122
+ * error instead of a `FloorBelowProtocolMin` revert after signing. Borrower-signed.
1123
+ */
1124
+ enableAutoMint(positionId: string, minCollateralRatioBps: number, options?: {
1125
+ agentValiditySeconds?: number;
1126
+ }): Promise<{
1127
+ hash: string;
1128
+ blockNumber: number;
1129
+ agentAddress?: string;
1130
+ }>;
1131
+ /** Disable auto-mint delegation for a position (also zeroes its mint floor). Borrower-signed. */
1132
+ disableAutoMint(positionId: string): Promise<{
1133
+ hash: string;
1134
+ blockNumber: number;
1135
+ }>;
1136
+ /**
1137
+ * Change an existing mint grant's collateral floor in place — no disable/re-enable dance.
1138
+ * MINT must already be granted; the new floor must clear the governance minimum. Note the
1139
+ * borrower may move it in either direction (above the minimum); only `REGISTRAR_ROLE` is
1140
+ * restricted to raising. Borrower-signed.
1141
+ */
1142
+ setMintCollateralFloor(positionId: string, newFloorBps: number): Promise<{
1143
+ hash: string;
1144
+ blockNumber: number;
1145
+ }>;
1146
+ /** Pre-flight the registry's `FloorBelowProtocolMin` guard with a message a user can act on. */
1147
+ private assertMintFloorAtOrAboveProtocolMin;
941
1148
  /**
942
1149
  * Get Bitcoin balance for an address
943
1150
  *
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Narrow entry point for Safe agent-delegation reads.
3
+ *
4
+ * A SUBPATH rather than a main-index re-export, for two reasons the frontend
5
+ * learned the hard way:
6
+ *
7
+ * - the app shadows the bare `@gvnrdao/dh-sdk` specifier with a hand-written
8
+ * ambient module (`types/@gvnrdao__dh-sdk.d.ts`), so anything imported from
9
+ * there is UNCHECKED against the real package — a call could take wrong
10
+ * arguments and still compile. Subpaths escape the shim and get the
11
+ * package's own types;
12
+ * - the main index pulls the whole SDK (and `@gvnrdao/dh-lit-actions`) for what
13
+ * is a handful of `eth_call`s.
14
+ */
15
+ export { getSafeAgentDelegation, buildSafeAgentDelegationDisableCalls, type SafeAgentDelegation, type SafeAgentDelegationDisablePlan, type SafeDelegationCall, type SafeDelegationStatus, } from "./utils/safe-agent-delegation.utils";