@gvnrdao/dh-lit-ops 0.0.33 ā 0.0.39
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/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/interfaces/chunks/authentication.d.ts +1 -0
- package/dist/interfaces/chunks/authentication.d.ts.map +1 -1
- package/dist/interfaces/chunks/lit-action-config.d.ts +2 -0
- package/dist/interfaces/chunks/lit-action-config.d.ts.map +1 -1
- package/dist/interfaces/chunks/lit-action-execution.d.ts +2 -0
- package/dist/interfaces/chunks/lit-action-execution.d.ts.map +1 -1
- package/dist/modules/action-executor.module.d.ts.map +1 -1
- package/dist/modules/action-executor.module.js +70 -16
- package/dist/modules/action-executor.module.js.map +1 -1
- package/dist/modules/auth-manager.module.d.ts.map +1 -1
- package/dist/modules/auth-manager.module.js +52 -32
- package/dist/modules/auth-manager.module.js.map +1 -1
- package/dist/modules/capacity-master.module.d.ts +1 -1
- package/dist/modules/capacity-master.module.d.ts.map +1 -1
- package/dist/modules/capacity-master.module.js +78 -23
- package/dist/modules/capacity-master.module.js.map +1 -1
- package/dist/modules/lit-ops.module.d.ts +34 -7
- package/dist/modules/lit-ops.module.d.ts.map +1 -1
- package/dist/modules/lit-ops.module.js +269 -84
- package/dist/modules/lit-ops.module.js.map +1 -1
- package/dist/modules/pkp-macros.module.d.ts +7 -3
- package/dist/modules/pkp-macros.module.d.ts.map +1 -1
- package/dist/modules/pkp-macros.module.js +57 -17
- package/dist/modules/pkp-macros.module.js.map +1 -1
- package/dist/modules/session-signature-manager.module.d.ts +1 -0
- package/dist/modules/session-signature-manager.module.d.ts.map +1 -1
- package/dist/modules/session-signature-manager.module.js +24 -17
- package/dist/modules/session-signature-manager.module.js.map +1 -1
- package/dist/utils/connection-helpers.d.ts.map +1 -1
- package/dist/utils/connection-helpers.js +8 -4
- package/dist/utils/connection-helpers.js.map +1 -1
- package/package.json +2 -2
|
@@ -289,7 +289,8 @@ class LitOps {
|
|
|
289
289
|
/**
|
|
290
290
|
* Execute a LIT Action from CID
|
|
291
291
|
*/
|
|
292
|
-
async executeActionFromCID(cid, pkpPublicKey, params, signer, pkpTokenId // Optional PKP token ID for session signature scoping
|
|
292
|
+
async executeActionFromCID(cid, pkpPublicKey, params, signer, pkpTokenId, // Optional PKP token ID for session signature scoping
|
|
293
|
+
pkpEthAddress // Optional PKP Ethereum address for capacity credit delegation
|
|
293
294
|
) {
|
|
294
295
|
const litClient = await this.clientManager.getClient({
|
|
295
296
|
litNetwork: this.config.network,
|
|
@@ -301,6 +302,7 @@ class LitOps {
|
|
|
301
302
|
params,
|
|
302
303
|
signer,
|
|
303
304
|
pkpTokenId, // Pass through pkpTokenId for session signature scoping
|
|
305
|
+
pkpEthAddress, // Pass through pkpEthAddress for capacity delegation
|
|
304
306
|
};
|
|
305
307
|
return this.actionExecutor.executeAction(request, litClient);
|
|
306
308
|
}
|
|
@@ -505,15 +507,18 @@ class LitOps {
|
|
|
505
507
|
* @param signer - The wallet to use for PKP creation and transactions
|
|
506
508
|
* @returns Complete PKP data including tokenId, publicKey, ethAddress, etc.
|
|
507
509
|
*/
|
|
508
|
-
async createProductionPKP(
|
|
510
|
+
async createProductionPKP(litActionCids, signer) {
|
|
511
|
+
// Normalize to array
|
|
512
|
+
const cids = Array.isArray(litActionCids) ? litActionCids : [litActionCids];
|
|
509
513
|
if (this.config.debug) {
|
|
510
514
|
console.log("\nšļø LitOps.createProductionPKP called");
|
|
511
|
-
console.log(` LIT Action
|
|
515
|
+
console.log(` LIT Action CIDs (${cids.length}):`);
|
|
516
|
+
cids.forEach((cid, idx) => console.log(` ${idx + 1}. ${cid}`));
|
|
512
517
|
console.log(` Network: ${this.config.network}`);
|
|
513
518
|
}
|
|
514
|
-
// Create PKP with authorization and burn for immutability
|
|
519
|
+
// Create PKP with authorization of ALL actions and burn for immutability
|
|
515
520
|
const pkpResult = await this.pkpMacroUtils.quickCreatePkpAuthorizeDhActionAndBurn(signer, {
|
|
516
|
-
litActionCid:
|
|
521
|
+
litActionCid: cids, // Pass array to authorize all actions before burn
|
|
517
522
|
});
|
|
518
523
|
if (this.config.debug) {
|
|
519
524
|
console.log(" ā
Production PKP created successfully!");
|
|
@@ -594,6 +599,14 @@ class LitOps {
|
|
|
594
599
|
* @returns PKP validation result with signature verification
|
|
595
600
|
*/
|
|
596
601
|
async validatePKPSecurity(targetPkpTokenId, expectedCid, signerPkp, signer) {
|
|
602
|
+
console.log(`š LIT-OPS TRACE: validatePKPSecurity ENTRY`);
|
|
603
|
+
console.log(` - targetPkpTokenId: "${targetPkpTokenId}"`);
|
|
604
|
+
console.log(` - targetPkpTokenId type: ${typeof targetPkpTokenId}`);
|
|
605
|
+
console.log(` - targetPkpTokenId length: ${targetPkpTokenId.length}`);
|
|
606
|
+
console.log(` - targetPkpTokenId startsWith '0x': ${targetPkpTokenId.startsWith('0x')}`);
|
|
607
|
+
console.log(` - expectedCid (WILL BE PASSED TO LIT ACTION): "${expectedCid}"`);
|
|
608
|
+
console.log(` - signerPkp.tokenId: "${signerPkp.tokenId}"`);
|
|
609
|
+
console.log(` - signerPkp.ethAddress: "${signerPkp.ethAddress}"`);
|
|
597
610
|
if (this.config.debug) {
|
|
598
611
|
console.log("\nš LitOps.validatePKPSecurity");
|
|
599
612
|
console.log(` Target PKP: ${targetPkpTokenId}`);
|
|
@@ -601,26 +614,44 @@ class LitOps {
|
|
|
601
614
|
console.log(` Signer PKP: ${signerPkp.tokenId}`);
|
|
602
615
|
}
|
|
603
616
|
try {
|
|
604
|
-
|
|
605
|
-
|
|
617
|
+
const targetPkpTokenIdDecimal = ethers_1.ethers.BigNumber.from(targetPkpTokenId).toString();
|
|
618
|
+
console.log(` - targetPkpTokenId normalized (decimal): "${targetPkpTokenIdDecimal}"`);
|
|
619
|
+
// Get the PKP validator CID and PKP
|
|
620
|
+
const pkpValidatorConfig = (this.config.network === "datil"
|
|
606
621
|
? dh_lit_actions_1.DH_LIT_ACTIONS_DATIL
|
|
607
|
-
: dh_lit_actions_1.DH_LIT_ACTIONS_DATIL_TEST).pkpValidator
|
|
622
|
+
: dh_lit_actions_1.DH_LIT_ACTIONS_DATIL_TEST).pkpValidator;
|
|
623
|
+
const pkpValidatorCid = pkpValidatorConfig.cid;
|
|
624
|
+
if (!pkpValidatorConfig.pkp || !pkpValidatorConfig.pkp.publicKey) {
|
|
625
|
+
throw new Error(`PKP validator configuration missing PKP public key for network: ${this.config.network}`);
|
|
626
|
+
}
|
|
627
|
+
const pkpValidatorPublicKey = pkpValidatorConfig.pkp.publicKey;
|
|
608
628
|
if (this.config.debug) {
|
|
609
629
|
console.log(` PKP Validator CID: ${pkpValidatorCid}`);
|
|
630
|
+
console.log(` PKP Validator Public Key: ${pkpValidatorPublicKey}`);
|
|
610
631
|
}
|
|
611
632
|
// Execute PKP Validator LIT Action
|
|
612
|
-
//
|
|
613
|
-
//
|
|
614
|
-
//
|
|
615
|
-
//
|
|
616
|
-
|
|
617
|
-
|
|
633
|
+
// IMPORTANT: We must use the VALIDATOR PKP's public key to execute the validator action,
|
|
634
|
+
// not the target PKP's public key. The validator PKP is authorized for the validator CID
|
|
635
|
+
// and CAN sign because we pass its token ID to enable LitPKPResource signing scope.
|
|
636
|
+
// Even though the validator PKP is burned/immutable, it can sign when executed via
|
|
637
|
+
// its authorized action context with proper PKP signing scope.
|
|
638
|
+
console.log(`\nš LIT-OPS TRACE: About to call executeActionFromCID with jsParams:`);
|
|
639
|
+
console.log(` - targetPkpTokenId (decimal sent to action): "${targetPkpTokenIdDecimal}"`);
|
|
640
|
+
console.log(` - expectedCid: "${expectedCid}"`);
|
|
641
|
+
console.log(` - validatorPkpTokenId (decimal): "${pkpValidatorConfig.pkp.tokenId}"`);
|
|
642
|
+
// Convert validator PKP token ID to hex format for LitPKPResource
|
|
643
|
+
// LitPKPResource requires hex format with 0x prefix (max 66 chars including 0x)
|
|
644
|
+
const validatorPkpTokenIdHex = ethers_1.ethers.BigNumber.from(pkpValidatorConfig.pkp.tokenId).toHexString();
|
|
645
|
+
console.log(` - validatorPkpTokenId (hex): "${validatorPkpTokenIdHex}"`);
|
|
646
|
+
const litResult = await this.executeActionFromCID(pkpValidatorCid, pkpValidatorPublicKey, // Use validator PKP's public key, not target PKP's!
|
|
647
|
+
{
|
|
648
|
+
targetPkpTokenId: targetPkpTokenIdDecimal,
|
|
618
649
|
expectedCid, // Expected to be in hex format
|
|
619
650
|
message: `PKP validation: ${Date.now()}`,
|
|
620
651
|
// Ensure the LIT Action knows which network (datil vs datil-test)
|
|
621
652
|
network: this.config.network,
|
|
622
|
-
|
|
623
|
-
//
|
|
653
|
+
publicKey: pkpValidatorPublicKey, // Pass for signing context
|
|
654
|
+
}, signer, validatorPkpTokenIdHex // Pass validator PKP token ID in hex format for LitPKPResource
|
|
624
655
|
);
|
|
625
656
|
if (this.config.debug) {
|
|
626
657
|
console.log(` LIT Action Success: ${litResult.success}`);
|
|
@@ -636,45 +667,14 @@ class LitOps {
|
|
|
636
667
|
const responseData = typeof litResult.response === "string"
|
|
637
668
|
? JSON.parse(litResult.response)
|
|
638
669
|
: litResult.response;
|
|
639
|
-
//
|
|
640
|
-
// The LIT Action prints validation results to console before failing at signing
|
|
641
|
-
const isSigningError = responseData.error &&
|
|
642
|
-
(responseData.error.includes("Failed to sign ecdsa") ||
|
|
643
|
-
responseData.error.includes("NodeAuthSigScopeTooLimited"));
|
|
644
|
-
// If there's a signing error, treat it as expected for burned validator PKPs
|
|
645
|
-
// and mark as success (validation passed, signing is known limitation)
|
|
646
|
-
if (isSigningError) {
|
|
647
|
-
if (this.config.debug) {
|
|
648
|
-
console.log(" ā ļø Signing failed (expected for burned validator PKPs)");
|
|
649
|
-
console.log(" ā
Treating as validation success - burn timing preserved");
|
|
650
|
-
}
|
|
651
|
-
// Override success flag - validation actually succeeded
|
|
652
|
-
responseData.success = true;
|
|
653
|
-
responseData.error = undefined;
|
|
654
|
-
responseData.signatureNote =
|
|
655
|
-
"Signing skipped - burned PKP architectural limitation";
|
|
656
|
-
// Create synthetic validation result based on the fact that LIT Action ran
|
|
657
|
-
responseData.validated = {
|
|
658
|
-
exists: true, // PKP must exist for LIT Action to have run this far
|
|
659
|
-
immutable: true, // We verify burn in previous step
|
|
660
|
-
singleAction: true, // Assumed based on our authorization process
|
|
661
|
-
correctCid: true, // Assumed based on our authorization process
|
|
662
|
-
};
|
|
663
|
-
}
|
|
664
|
-
// Verify signature if present (optional for burned PKPs)
|
|
670
|
+
// Verify signature (now required with proper PKP signing scope)
|
|
665
671
|
let signatureValid = false;
|
|
666
672
|
let pkpAddress = "";
|
|
667
673
|
let recoveredAddress = "";
|
|
668
674
|
let signedMessage;
|
|
669
|
-
|
|
670
|
-
if (
|
|
671
|
-
|
|
672
|
-
if (this.config.debug) {
|
|
673
|
-
console.log(" ā¹ļø Signature verification skipped - burned PKP limitation");
|
|
674
|
-
}
|
|
675
|
-
}
|
|
676
|
-
else if (litResult.signatures &&
|
|
677
|
-
litResult.signatures.pkpValidation) {
|
|
675
|
+
let messageDigest;
|
|
676
|
+
if (litResult.signatures &&
|
|
677
|
+
litResult.signatures.pkpValidatorSignature) {
|
|
678
678
|
if (this.config.debug) {
|
|
679
679
|
console.log(" š Verifying signature authenticity...");
|
|
680
680
|
}
|
|
@@ -684,22 +684,30 @@ class LitOps {
|
|
|
684
684
|
? signerPkp.publicKey
|
|
685
685
|
: `0x${signerPkp.publicKey}`;
|
|
686
686
|
pkpAddress = ethers_1.ethers.utils.computeAddress(cleanPublicKey);
|
|
687
|
-
// Recover address from signature - LIT Action signs the
|
|
688
|
-
|
|
689
|
-
|
|
687
|
+
// Recover address from signature - LIT Action signs the Ethereum-prefixed hash
|
|
688
|
+
// The PKP Validator returns certificationMessage, not signedMessage
|
|
689
|
+
signedMessage = responseData.certificationMessage || responseData.signedMessage;
|
|
690
|
+
messageDigest =
|
|
691
|
+
responseData.messageHash ||
|
|
692
|
+
responseData.messageDigest ||
|
|
693
|
+
(signedMessage
|
|
694
|
+
? ethers_1.ethers.utils.hashMessage(signedMessage)
|
|
695
|
+
: undefined);
|
|
696
|
+
const signature = litResult.signatures.pkpValidatorSignature.signature;
|
|
690
697
|
if (this.config.debug) {
|
|
691
698
|
console.log(` š DEBUG - Full responseData:`, JSON.stringify(responseData, null, 2));
|
|
692
699
|
console.log(` š DEBUG - signedMessage from response:`, signedMessage);
|
|
693
700
|
console.log(` š DEBUG - signature:`, signature);
|
|
694
701
|
}
|
|
695
702
|
if (signedMessage && signature) {
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
703
|
+
if (!messageDigest) {
|
|
704
|
+
throw new Error("Missing message digest for signature verification");
|
|
705
|
+
}
|
|
706
|
+
recoveredAddress = ethers_1.ethers.utils.verifyMessage(signedMessage, signature);
|
|
699
707
|
signatureValid =
|
|
700
708
|
pkpAddress.toLowerCase() === recoveredAddress.toLowerCase();
|
|
701
709
|
if (this.config.debug) {
|
|
702
|
-
console.log(` š DEBUG -
|
|
710
|
+
console.log(` š DEBUG - messageDigest:`, messageDigest);
|
|
703
711
|
console.log(` PKP Address: ${pkpAddress}`);
|
|
704
712
|
console.log(` Recovered Address: ${recoveredAddress}`);
|
|
705
713
|
console.log(` Signature: ${signature}`);
|
|
@@ -722,11 +730,16 @@ class LitOps {
|
|
|
722
730
|
: verifyError}`);
|
|
723
731
|
}
|
|
724
732
|
}
|
|
733
|
+
else {
|
|
734
|
+
// No signature found - this should not happen with proper PKP signing scope
|
|
735
|
+
throw new Error("Validator PKP failed to generate signature. Ensure validator PKP token ID is passed for signing scope.");
|
|
736
|
+
}
|
|
725
737
|
// Return parsed result
|
|
726
738
|
return {
|
|
727
739
|
success: responseData.success || false,
|
|
728
|
-
signature: litResult.signatures?.
|
|
740
|
+
signature: litResult.signatures?.pkpValidatorSignature?.signature,
|
|
729
741
|
signedMessage, // Include the signedMessage for external verification
|
|
742
|
+
messageDigest,
|
|
730
743
|
error: responseData.error,
|
|
731
744
|
signatureValid,
|
|
732
745
|
pkpAddress,
|
|
@@ -739,7 +752,6 @@ class LitOps {
|
|
|
739
752
|
matchesExpectedCID: responseData.validated.correctCid || false,
|
|
740
753
|
allValid: responseData.validated.exists &&
|
|
741
754
|
responseData.validated.immutable &&
|
|
742
|
-
responseData.validated.singleAction &&
|
|
743
755
|
responseData.validated.correctCid,
|
|
744
756
|
}
|
|
745
757
|
: undefined,
|
|
@@ -791,13 +803,16 @@ class LitOps {
|
|
|
791
803
|
* @param signer - Optional signer (required for standalone mode, not used in service mode)
|
|
792
804
|
* @returns Complete PKP creation and validation result with audit trail
|
|
793
805
|
*/
|
|
794
|
-
async createAndValidatePkpToLitAction(
|
|
806
|
+
async createAndValidatePkpToLitAction(litActionCids, signer) {
|
|
795
807
|
const startTime = Date.now();
|
|
796
808
|
const auditSteps = [];
|
|
809
|
+
// Normalize to array for processing
|
|
810
|
+
const cids = Array.isArray(litActionCids) ? litActionCids : [litActionCids];
|
|
797
811
|
if (this.config.debug) {
|
|
798
812
|
console.log("\nšÆ LitOps.createAndValidatePkpToLitAction");
|
|
799
813
|
console.log(" ULTIMATE PKP SECURITY MACRO");
|
|
800
|
-
console.log(` Target LIT Action
|
|
814
|
+
console.log(` Target LIT Action CIDs (${cids.length}):`);
|
|
815
|
+
cids.forEach((cid, idx) => console.log(` ${idx + 1}. ${cid}`));
|
|
801
816
|
console.log(` Mode: ${this.config.mode}`);
|
|
802
817
|
}
|
|
803
818
|
// Service mode: Call the service endpoint directly
|
|
@@ -807,7 +822,7 @@ class LitOps {
|
|
|
807
822
|
}
|
|
808
823
|
const retries = this.config.pkpServiceRetryCount ?? 2;
|
|
809
824
|
const retryDelay = this.config.pkpServiceRetryDelayMs ?? 2000;
|
|
810
|
-
const timeoutMs = this.config.pkpServiceTimeoutMs ??
|
|
825
|
+
const timeoutMs = this.config.pkpServiceTimeoutMs ?? 480000; // 8 minutes to match server timeout
|
|
811
826
|
let attempt = 0;
|
|
812
827
|
let lastError = null;
|
|
813
828
|
while (attempt <= retries) {
|
|
@@ -821,7 +836,7 @@ class LitOps {
|
|
|
821
836
|
"Content-Type": "application/json",
|
|
822
837
|
},
|
|
823
838
|
body: JSON.stringify({
|
|
824
|
-
|
|
839
|
+
litActionCids: litActionCids,
|
|
825
840
|
}),
|
|
826
841
|
}, timeoutMs);
|
|
827
842
|
if (!response.ok) {
|
|
@@ -872,7 +887,9 @@ class LitOps {
|
|
|
872
887
|
error: message,
|
|
873
888
|
timestamp: startTime,
|
|
874
889
|
duration,
|
|
875
|
-
targetCid:
|
|
890
|
+
targetCid: Array.isArray(litActionCids)
|
|
891
|
+
? litActionCids[0]
|
|
892
|
+
: litActionCids,
|
|
876
893
|
pkpData: {},
|
|
877
894
|
validationResult: {},
|
|
878
895
|
auditTrail: {
|
|
@@ -907,7 +924,7 @@ class LitOps {
|
|
|
907
924
|
if (this.config.debug) {
|
|
908
925
|
console.log("\n Step 1: Creating production PKP...");
|
|
909
926
|
}
|
|
910
|
-
const pkpData = await this.createProductionPKP(
|
|
927
|
+
const pkpData = await this.createProductionPKP(cids, signer);
|
|
911
928
|
const step1Duration = Date.now() - step1Start;
|
|
912
929
|
auditSteps.push({
|
|
913
930
|
step: 1,
|
|
@@ -956,10 +973,14 @@ class LitOps {
|
|
|
956
973
|
}
|
|
957
974
|
}
|
|
958
975
|
// Additional delay after burn verification for network consensus
|
|
976
|
+
// YELLOWSTONE PROPAGATION: Chronicle Yellowstone requires longer propagation time
|
|
977
|
+
// than other networks. Empirical testing shows 30-45s is needed for reliable RPC visibility.
|
|
978
|
+
const yellowstonePropagationDelayMs = 45000; // 45 seconds for Yellowstone reliability
|
|
959
979
|
if (this.config.debug) {
|
|
960
|
-
console.log(
|
|
980
|
+
console.log(`\n ā³ Additional delay for Yellowstone RPC propagation (${yellowstonePropagationDelayMs}ms)...`);
|
|
981
|
+
console.log(` This ensures the PKP is visible to all RPC nodes before validation`);
|
|
961
982
|
}
|
|
962
|
-
await new Promise((resolve) => setTimeout(resolve,
|
|
983
|
+
await new Promise((resolve) => setTimeout(resolve, yellowstonePropagationDelayMs));
|
|
963
984
|
if (this.config.debug) {
|
|
964
985
|
console.log(` ā
Network propagation and consensus complete`);
|
|
965
986
|
}
|
|
@@ -993,20 +1014,30 @@ class LitOps {
|
|
|
993
1014
|
if (!validatorPkp) {
|
|
994
1015
|
throw new Error("PKP validator PKP not found in dh-lit-actions package");
|
|
995
1016
|
}
|
|
996
|
-
// Convert IPFS CID to hex format for validation
|
|
997
|
-
const
|
|
1017
|
+
// Convert IPFS CID to hex format for validation (using first CID)
|
|
1018
|
+
const firstCid = cids[0];
|
|
1019
|
+
console.log(`š LIT-OPS TRACE: firstCid (cids[0]) = "${firstCid}"`);
|
|
1020
|
+
console.log(`š LIT-OPS TRACE: All cids array:`, cids);
|
|
1021
|
+
const litActionCidHex = (0, dh_lit_actions_1.cidToHex)(firstCid);
|
|
1022
|
+
console.log(`š LIT-OPS TRACE: litActionCidHex after cidToHex() = "${litActionCidHex}"`);
|
|
998
1023
|
if (this.config.debug) {
|
|
999
|
-
console.log(` Converting CID: ${
|
|
1024
|
+
console.log(` Converting CID: ${firstCid} ā ${litActionCidHex}`);
|
|
1000
1025
|
}
|
|
1001
1026
|
// Attempt validation with retry logic for network propagation issues
|
|
1002
1027
|
let validationResult;
|
|
1003
|
-
const maxValidationRetries =
|
|
1028
|
+
const maxValidationRetries = 3;
|
|
1004
1029
|
let lastValidationError = null;
|
|
1005
1030
|
for (let attempt = 1; attempt <= maxValidationRetries; attempt++) {
|
|
1006
1031
|
try {
|
|
1007
1032
|
if (this.config.debug && attempt > 1) {
|
|
1008
1033
|
console.log(`\n š Validation retry attempt ${attempt}/${maxValidationRetries}`);
|
|
1009
1034
|
}
|
|
1035
|
+
console.log(`š LIT-OPS TRACE: validatePKPSecurity call parameters:`);
|
|
1036
|
+
console.log(` - pkpTokenId: "${pkpData.tokenId}"`);
|
|
1037
|
+
console.log(` - pkpTokenId type: ${typeof pkpData.tokenId}`);
|
|
1038
|
+
console.log(` - pkpTokenId startsWith '0x': ${pkpData.tokenId.startsWith("0x")}`);
|
|
1039
|
+
console.log(` - litActionCidHex (expectedCid): "${litActionCidHex}"`);
|
|
1040
|
+
console.log(` - validatorPkp: "${validatorPkp}"`);
|
|
1010
1041
|
validationResult = await this.validatePKPSecurity(pkpData.tokenId, litActionCidHex, // Pass hex format CID
|
|
1011
1042
|
validatorPkp, signer);
|
|
1012
1043
|
// If validation succeeds, break out of retry loop
|
|
@@ -1020,7 +1051,7 @@ class LitOps {
|
|
|
1020
1051
|
lastValidationError = new Error(`PKP validation failed: ${validationResult.error || "Unknown validation error"}`);
|
|
1021
1052
|
// If not the last attempt, wait before retrying
|
|
1022
1053
|
if (attempt < maxValidationRetries) {
|
|
1023
|
-
const retryDelay =
|
|
1054
|
+
const retryDelay = 15000; // 15 seconds between validation retries
|
|
1024
1055
|
if (this.config.debug) {
|
|
1025
1056
|
console.log(` ā³ Waiting ${retryDelay}ms before retry...`);
|
|
1026
1057
|
}
|
|
@@ -1087,7 +1118,9 @@ class LitOps {
|
|
|
1087
1118
|
success: true,
|
|
1088
1119
|
timestamp: startTime,
|
|
1089
1120
|
duration: totalDuration,
|
|
1090
|
-
targetCid:
|
|
1121
|
+
targetCid: Array.isArray(litActionCids)
|
|
1122
|
+
? litActionCids[0]
|
|
1123
|
+
: litActionCids,
|
|
1091
1124
|
pkpData,
|
|
1092
1125
|
validationResult,
|
|
1093
1126
|
auditTrail: {
|
|
@@ -1122,7 +1155,9 @@ class LitOps {
|
|
|
1122
1155
|
error: errorMessage,
|
|
1123
1156
|
timestamp: startTime,
|
|
1124
1157
|
duration: totalDuration,
|
|
1125
|
-
targetCid:
|
|
1158
|
+
targetCid: Array.isArray(litActionCids)
|
|
1159
|
+
? litActionCids[0]
|
|
1160
|
+
: litActionCids,
|
|
1126
1161
|
pkpData: {}, // Empty PKP data on failure
|
|
1127
1162
|
validationResult: {
|
|
1128
1163
|
success: false,
|
|
@@ -1172,9 +1207,21 @@ class LitOps {
|
|
|
1172
1207
|
if (this.config.mode === "standalone" && !effectiveSigner) {
|
|
1173
1208
|
throw new Error("Signer is required for standalone mode");
|
|
1174
1209
|
}
|
|
1175
|
-
|
|
1210
|
+
const selectedNetwork = networkOverride ?? this.config.network;
|
|
1211
|
+
const deployments = selectedNetwork === "datil"
|
|
1176
1212
|
? dh_lit_actions_1.DH_LIT_ACTIONS_DATIL
|
|
1177
|
-
: dh_lit_actions_1.DH_LIT_ACTIONS_DATIL_TEST
|
|
1213
|
+
: dh_lit_actions_1.DH_LIT_ACTIONS_DATIL_TEST;
|
|
1214
|
+
const authorizationCid = deployments.authorizationDummy.cid;
|
|
1215
|
+
const validatorCid = deployments.pkpValidator.cid;
|
|
1216
|
+
const ucdMintCid = deployments.ucdMintValidator.cid;
|
|
1217
|
+
console.log(`š LIT-OPS TRACE: getNewDiamondHandsLoanPkp - selectedNetwork = "${selectedNetwork}"`);
|
|
1218
|
+
console.log(`š LIT-OPS TRACE: getNewDiamondHandsLoanPkp - authorizationDummy.cid = "${authorizationCid}"`);
|
|
1219
|
+
console.log(`š LIT-OPS TRACE: getNewDiamondHandsLoanPkp - pkpValidator.cid = "${validatorCid}"`);
|
|
1220
|
+
console.log(`š LIT-OPS TRACE: getNewDiamondHandsLoanPkp - ucdMintValidator.cid = "${ucdMintCid}"`);
|
|
1221
|
+
// Pass validator CID first (for validation signature), then authorization CID (for authorization),
|
|
1222
|
+
// and ucdMintValidator CID (for UCD minting operations)
|
|
1223
|
+
// The validator will sign the FIRST CID (validator CID), which matches what the contract expects
|
|
1224
|
+
return this.createAndValidatePkpToLitAction([validatorCid, authorizationCid, ucdMintCid], effectiveSigner);
|
|
1178
1225
|
}
|
|
1179
1226
|
/**
|
|
1180
1227
|
* Request mint authorization from UCD Mint Validator LIT Action
|
|
@@ -1208,6 +1255,23 @@ class LitOps {
|
|
|
1208
1255
|
litNetwork: this.config.network,
|
|
1209
1256
|
debug: this.config.debug,
|
|
1210
1257
|
});
|
|
1258
|
+
// Determine chain from chainId in authMessage
|
|
1259
|
+
let chain;
|
|
1260
|
+
switch (request.authMessage.chainId) {
|
|
1261
|
+
case 1:
|
|
1262
|
+
chain = "ethereum";
|
|
1263
|
+
break;
|
|
1264
|
+
case 11155111:
|
|
1265
|
+
chain = "sepolia";
|
|
1266
|
+
break;
|
|
1267
|
+
case 31337: // Hardhat local testnet
|
|
1268
|
+
chain = "sepolia"; // Use sepolia config for local testing
|
|
1269
|
+
break;
|
|
1270
|
+
default:
|
|
1271
|
+
throw new Error(`Unsupported chainId: ${request.authMessage.chainId}`);
|
|
1272
|
+
}
|
|
1273
|
+
// Bitcoin provider URL (use env or default to mempool.space for now)
|
|
1274
|
+
const bitcoinProviderUrl = process.env.BITCOIN_PROVIDER_URL || "https://mempool.space/api";
|
|
1211
1275
|
// Execute LIT Action
|
|
1212
1276
|
// authMessage already contains quantumTimestamp calculated by SDK
|
|
1213
1277
|
// lit-ops just forwards - no business logic
|
|
@@ -1215,8 +1279,13 @@ class LitOps {
|
|
|
1215
1279
|
cid: litActionInfo.cid,
|
|
1216
1280
|
pkpPublicKey: litActionInfo.pkp.publicKey,
|
|
1217
1281
|
params: {
|
|
1218
|
-
|
|
1219
|
-
|
|
1282
|
+
chain,
|
|
1283
|
+
bitcoinProviderUrl,
|
|
1284
|
+
auth: {
|
|
1285
|
+
message: request.authMessage,
|
|
1286
|
+
signature: request.userSignature,
|
|
1287
|
+
},
|
|
1288
|
+
amount: request.authMessage.requestedAmount,
|
|
1220
1289
|
},
|
|
1221
1290
|
signer: this.config.signer,
|
|
1222
1291
|
}, litClient);
|
|
@@ -1229,18 +1298,134 @@ class LitOps {
|
|
|
1229
1298
|
}
|
|
1230
1299
|
// Return standardized response
|
|
1231
1300
|
return {
|
|
1232
|
-
|
|
1233
|
-
|
|
1301
|
+
approved: result.response?.approved ?? false,
|
|
1302
|
+
signature: result.signatures
|
|
1234
1303
|
? JSON.stringify(result.signatures)
|
|
1235
1304
|
: undefined,
|
|
1236
1305
|
mintAmount: result.response?.mintAmount,
|
|
1237
1306
|
mintFee: result.response?.mintFee,
|
|
1238
1307
|
newDebt: result.response?.newDebt,
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1308
|
+
timestamp: result.response?.timestamp,
|
|
1309
|
+
reason: result.response?.reason,
|
|
1310
|
+
failedStep: result.response?.failedStep,
|
|
1242
1311
|
};
|
|
1243
1312
|
}
|
|
1313
|
+
/**
|
|
1314
|
+
* Get trustless BTC price from Price Oracle LIT Action
|
|
1315
|
+
*
|
|
1316
|
+
* Fetches the current BTC price in USD using the decentralized price oracle.
|
|
1317
|
+
* Supports two modes:
|
|
1318
|
+
* - fast: Single source (faster, less secure)
|
|
1319
|
+
* - full: Consensus across multiple sources (slower, more secure)
|
|
1320
|
+
*
|
|
1321
|
+
* @param options - Price fetch options
|
|
1322
|
+
* @returns BTC price data with optional signature
|
|
1323
|
+
*/
|
|
1324
|
+
async getBTCPrice(options) {
|
|
1325
|
+
const { mode = "fast", sign = false, signer } = options;
|
|
1326
|
+
// Get LIT Action info from registry
|
|
1327
|
+
const litActions = (this.config.network === "datil"
|
|
1328
|
+
? dh_lit_actions_1.DH_LIT_ACTIONS_DATIL
|
|
1329
|
+
: dh_lit_actions_1.DH_LIT_ACTIONS_DATIL_TEST);
|
|
1330
|
+
console.log("litActions in getActions", litActions);
|
|
1331
|
+
const litActionInfo = litActions.priceOracle;
|
|
1332
|
+
if (!litActionInfo || !litActionInfo.cid) {
|
|
1333
|
+
return {
|
|
1334
|
+
success: false,
|
|
1335
|
+
error: "Price oracle LIT Action not found in registry",
|
|
1336
|
+
};
|
|
1337
|
+
}
|
|
1338
|
+
if (this.config.debug) {
|
|
1339
|
+
console.log("š° Calling Price Oracle LIT Action:");
|
|
1340
|
+
console.log(" Network:", this.config.network);
|
|
1341
|
+
console.log(" CID:", litActionInfo.cid);
|
|
1342
|
+
console.log(" Mode:", mode);
|
|
1343
|
+
console.log(" Sign:", sign);
|
|
1344
|
+
}
|
|
1345
|
+
try {
|
|
1346
|
+
// In service mode, do NOT attempt to create a Lit client; use HTTP service directly
|
|
1347
|
+
if (this.config.mode === "service") {
|
|
1348
|
+
const result = await this.actionExecutor.executeAction({
|
|
1349
|
+
cid: litActionInfo.cid,
|
|
1350
|
+
pkpPublicKey: litActionInfo.pkp?.publicKey || "",
|
|
1351
|
+
params: { mode, sign },
|
|
1352
|
+
signer: signer || this.config.signer,
|
|
1353
|
+
}, undefined);
|
|
1354
|
+
if (this.config.debug) {
|
|
1355
|
+
console.log("š„ Price Oracle response:", {
|
|
1356
|
+
success: result.success,
|
|
1357
|
+
response: result.response,
|
|
1358
|
+
error: result.error,
|
|
1359
|
+
});
|
|
1360
|
+
}
|
|
1361
|
+
if (result.success && result.response) {
|
|
1362
|
+
const responseData = typeof result.response === "string"
|
|
1363
|
+
? JSON.parse(result.response)
|
|
1364
|
+
: result.response;
|
|
1365
|
+
return {
|
|
1366
|
+
success: true,
|
|
1367
|
+
priceE8: responseData.priceE8,
|
|
1368
|
+
price: responseData.price,
|
|
1369
|
+
timestamp: responseData.timestamp,
|
|
1370
|
+
source: responseData.source,
|
|
1371
|
+
signature: responseData.signature,
|
|
1372
|
+
signer: responseData.signer,
|
|
1373
|
+
};
|
|
1374
|
+
}
|
|
1375
|
+
return {
|
|
1376
|
+
success: false,
|
|
1377
|
+
error: result.error || "Price oracle execution failed",
|
|
1378
|
+
};
|
|
1379
|
+
}
|
|
1380
|
+
// Standalone mode: require Lit client
|
|
1381
|
+
const litClient = await this.clientManager.getClient({
|
|
1382
|
+
litNetwork: this.config.network,
|
|
1383
|
+
debug: this.config.debug,
|
|
1384
|
+
});
|
|
1385
|
+
const result = await this.actionExecutor.executeAction({
|
|
1386
|
+
cid: litActionInfo.cid,
|
|
1387
|
+
pkpPublicKey: litActionInfo.pkp?.publicKey || "",
|
|
1388
|
+
params: { mode, sign },
|
|
1389
|
+
signer: signer || this.config.signer,
|
|
1390
|
+
}, litClient);
|
|
1391
|
+
if (this.config.debug) {
|
|
1392
|
+
console.log("š„ Price Oracle response:", {
|
|
1393
|
+
success: result.success,
|
|
1394
|
+
response: result.response,
|
|
1395
|
+
error: result.error,
|
|
1396
|
+
});
|
|
1397
|
+
}
|
|
1398
|
+
// Parse response
|
|
1399
|
+
if (result.success && result.response) {
|
|
1400
|
+
const responseData = typeof result.response === "string"
|
|
1401
|
+
? JSON.parse(result.response)
|
|
1402
|
+
: result.response;
|
|
1403
|
+
return {
|
|
1404
|
+
success: true,
|
|
1405
|
+
priceE8: responseData.priceE8,
|
|
1406
|
+
price: responseData.price,
|
|
1407
|
+
timestamp: responseData.timestamp,
|
|
1408
|
+
source: responseData.source,
|
|
1409
|
+
signature: responseData.signature,
|
|
1410
|
+
signer: responseData.signer,
|
|
1411
|
+
};
|
|
1412
|
+
}
|
|
1413
|
+
return {
|
|
1414
|
+
success: false,
|
|
1415
|
+
error: result.error || "Price oracle execution failed",
|
|
1416
|
+
};
|
|
1417
|
+
}
|
|
1418
|
+
catch (error) {
|
|
1419
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
1420
|
+
if (this.config.debug) {
|
|
1421
|
+
console.error("ā Price oracle failed:", error);
|
|
1422
|
+
}
|
|
1423
|
+
return {
|
|
1424
|
+
success: false,
|
|
1425
|
+
error: errorMessage,
|
|
1426
|
+
};
|
|
1427
|
+
}
|
|
1428
|
+
}
|
|
1244
1429
|
/**
|
|
1245
1430
|
* Cleanup - disconnect all clients
|
|
1246
1431
|
*/
|