From c7d57d3c139321a61b5d1efa3a44d7a84a0d9ac0 Mon Sep 17 00:00:00 2001 From: anson Date: Fri, 24 Oct 2025 02:39:27 +0100 Subject: [PATCH 1/5] feat(lit-client,contracts): add `getDerivedKeyId` utils --- packages/contracts/dist/dev/develop.cjs | 5 ---- packages/contracts/dist/dev/develop.js | 5 ---- packages/contracts/dist/dev/develop.json | 5 ---- packages/contracts/dist/dev/develop.ts | 5 ---- .../contracts/dist/signatures/datil-dev.cjs | 24 +++++++++++++++ .../contracts/dist/signatures/datil-dev.d.ts | 24 +++++++++++++++ .../contracts/dist/signatures/datil-dev.js | 24 +++++++++++++++ .../contracts/dist/signatures/datil-test.cjs | 24 +++++++++++++++ .../contracts/dist/signatures/datil-test.d.ts | 24 +++++++++++++++ .../contracts/dist/signatures/datil-test.js | 24 +++++++++++++++ packages/contracts/dist/signatures/datil.cjs | 24 +++++++++++++++ packages/contracts/dist/signatures/datil.d.ts | 24 +++++++++++++++ packages/contracts/dist/signatures/datil.js | 24 +++++++++++++++ .../contracts/dist/signatures/develop.cjs | 29 +++++++++++++++++++ .../contracts/dist/signatures/develop.d.ts | 29 +++++++++++++++++++ packages/contracts/dist/signatures/develop.js | 29 +++++++++++++++++++ .../contracts/dist/signatures/naga-dev.cjs | 29 +++++++++++++++++++ .../contracts/dist/signatures/naga-dev.d.ts | 29 +++++++++++++++++++ .../contracts/dist/signatures/naga-dev.js | 29 +++++++++++++++++++ .../dist/signatures/naga-staging.cjs | 29 +++++++++++++++++++ .../dist/signatures/naga-staging.d.ts | 29 +++++++++++++++++++ .../contracts/dist/signatures/naga-staging.js | 29 +++++++++++++++++++ .../contracts/dist/signatures/naga-test.cjs | 29 +++++++++++++++++++ .../contracts/dist/signatures/naga-test.d.ts | 29 +++++++++++++++++++ .../contracts/dist/signatures/naga-test.js | 29 +++++++++++++++++++ packages/contracts/src/config/methods.ts | 1 + .../e2e/src/tickets/derived-pubkey.spec.ts | 18 ++++++++++++ .../src/lib/LitClient/createLitClient.ts | 27 +++++++++++++++++ .../createContractsManager.ts | 1 + .../state-manager/createStateManager.ts | 3 ++ 30 files changed, 614 insertions(+), 20 deletions(-) create mode 100644 packages/e2e/src/tickets/derived-pubkey.spec.ts diff --git a/packages/contracts/dist/dev/develop.cjs b/packages/contracts/dist/dev/develop.cjs index 68c964778..a94c15d8b 100644 --- a/packages/contracts/dist/dev/develop.cjs +++ b/packages/contracts/dist/dev/develop.cjs @@ -15431,11 +15431,6 @@ module.exports = { "name": "CallerNotOwner", "type": "error" }, - { - "inputs": [], - "name": "MustBeLessThan100", - "type": "error" - }, { "inputs": [], "name": "MustBeNonzero", diff --git a/packages/contracts/dist/dev/develop.js b/packages/contracts/dist/dev/develop.js index e4ee8767a..8f5c6d742 100644 --- a/packages/contracts/dist/dev/develop.js +++ b/packages/contracts/dist/dev/develop.js @@ -15429,11 +15429,6 @@ export const develop = { "name": "CallerNotOwner", "type": "error" }, - { - "inputs": [], - "name": "MustBeLessThan100", - "type": "error" - }, { "inputs": [], "name": "MustBeNonzero", diff --git a/packages/contracts/dist/dev/develop.json b/packages/contracts/dist/dev/develop.json index 3f0ead8e1..edb5c53df 100644 --- a/packages/contracts/dist/dev/develop.json +++ b/packages/contracts/dist/dev/develop.json @@ -15429,11 +15429,6 @@ "name": "CallerNotOwner", "type": "error" }, - { - "inputs": [], - "name": "MustBeLessThan100", - "type": "error" - }, { "inputs": [], "name": "MustBeNonzero", diff --git a/packages/contracts/dist/dev/develop.ts b/packages/contracts/dist/dev/develop.ts index 23cfb5053..a7c4b1936 100644 --- a/packages/contracts/dist/dev/develop.ts +++ b/packages/contracts/dist/dev/develop.ts @@ -15429,11 +15429,6 @@ export const develop = { "name": "CallerNotOwner", "type": "error" }, - { - "inputs": [], - "name": "MustBeLessThan100", - "type": "error" - }, { "inputs": [], "name": "MustBeNonzero", diff --git a/packages/contracts/dist/signatures/datil-dev.cjs b/packages/contracts/dist/signatures/datil-dev.cjs index ab91df099..e76149ec6 100644 --- a/packages/contracts/dist/signatures/datil-dev.cjs +++ b/packages/contracts/dist/signatures/datil-dev.cjs @@ -673,6 +673,30 @@ const signatures = { "stateMutability": "view", "type": "function" }, + "getDerivedPubkey": { + "inputs": [ + { + "internalType": "address", + "name": "stakingContract", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "derivedKeyId", + "type": "bytes32" + } + ], + "name": "getDerivedPubkey", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, "getEthAddress": { "inputs": [ { diff --git a/packages/contracts/dist/signatures/datil-dev.d.ts b/packages/contracts/dist/signatures/datil-dev.d.ts index 987c785ad..7869843d0 100644 --- a/packages/contracts/dist/signatures/datil-dev.d.ts +++ b/packages/contracts/dist/signatures/datil-dev.d.ts @@ -673,6 +673,30 @@ export const signatures = { "stateMutability": "view", "type": "function" }, + "getDerivedPubkey": { + "inputs": [ + { + "internalType": "address", + "name": "stakingContract", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "derivedKeyId", + "type": "bytes32" + } + ], + "name": "getDerivedPubkey", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, "getEthAddress": { "inputs": [ { diff --git a/packages/contracts/dist/signatures/datil-dev.js b/packages/contracts/dist/signatures/datil-dev.js index 56ce87ed8..26a4baacd 100644 --- a/packages/contracts/dist/signatures/datil-dev.js +++ b/packages/contracts/dist/signatures/datil-dev.js @@ -673,6 +673,30 @@ export const signatures = { "stateMutability": "view", "type": "function" }, + "getDerivedPubkey": { + "inputs": [ + { + "internalType": "address", + "name": "stakingContract", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "derivedKeyId", + "type": "bytes32" + } + ], + "name": "getDerivedPubkey", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, "getEthAddress": { "inputs": [ { diff --git a/packages/contracts/dist/signatures/datil-test.cjs b/packages/contracts/dist/signatures/datil-test.cjs index 25d299bbd..44e21a9ef 100644 --- a/packages/contracts/dist/signatures/datil-test.cjs +++ b/packages/contracts/dist/signatures/datil-test.cjs @@ -673,6 +673,30 @@ const signatures = { "stateMutability": "view", "type": "function" }, + "getDerivedPubkey": { + "inputs": [ + { + "internalType": "address", + "name": "stakingContract", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "derivedKeyId", + "type": "bytes32" + } + ], + "name": "getDerivedPubkey", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, "getEthAddress": { "inputs": [ { diff --git a/packages/contracts/dist/signatures/datil-test.d.ts b/packages/contracts/dist/signatures/datil-test.d.ts index 1b427544a..13ae18825 100644 --- a/packages/contracts/dist/signatures/datil-test.d.ts +++ b/packages/contracts/dist/signatures/datil-test.d.ts @@ -673,6 +673,30 @@ export const signatures = { "stateMutability": "view", "type": "function" }, + "getDerivedPubkey": { + "inputs": [ + { + "internalType": "address", + "name": "stakingContract", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "derivedKeyId", + "type": "bytes32" + } + ], + "name": "getDerivedPubkey", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, "getEthAddress": { "inputs": [ { diff --git a/packages/contracts/dist/signatures/datil-test.js b/packages/contracts/dist/signatures/datil-test.js index 850a4ff32..6a878e482 100644 --- a/packages/contracts/dist/signatures/datil-test.js +++ b/packages/contracts/dist/signatures/datil-test.js @@ -673,6 +673,30 @@ export const signatures = { "stateMutability": "view", "type": "function" }, + "getDerivedPubkey": { + "inputs": [ + { + "internalType": "address", + "name": "stakingContract", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "derivedKeyId", + "type": "bytes32" + } + ], + "name": "getDerivedPubkey", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, "getEthAddress": { "inputs": [ { diff --git a/packages/contracts/dist/signatures/datil.cjs b/packages/contracts/dist/signatures/datil.cjs index 4699b01b5..0176461b8 100644 --- a/packages/contracts/dist/signatures/datil.cjs +++ b/packages/contracts/dist/signatures/datil.cjs @@ -673,6 +673,30 @@ const signatures = { "stateMutability": "view", "type": "function" }, + "getDerivedPubkey": { + "inputs": [ + { + "internalType": "address", + "name": "stakingContract", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "derivedKeyId", + "type": "bytes32" + } + ], + "name": "getDerivedPubkey", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, "getEthAddress": { "inputs": [ { diff --git a/packages/contracts/dist/signatures/datil.d.ts b/packages/contracts/dist/signatures/datil.d.ts index 53b19b0eb..8bfe3ba1d 100644 --- a/packages/contracts/dist/signatures/datil.d.ts +++ b/packages/contracts/dist/signatures/datil.d.ts @@ -673,6 +673,30 @@ export const signatures = { "stateMutability": "view", "type": "function" }, + "getDerivedPubkey": { + "inputs": [ + { + "internalType": "address", + "name": "stakingContract", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "derivedKeyId", + "type": "bytes32" + } + ], + "name": "getDerivedPubkey", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, "getEthAddress": { "inputs": [ { diff --git a/packages/contracts/dist/signatures/datil.js b/packages/contracts/dist/signatures/datil.js index e6e8b27e0..8636f7f00 100644 --- a/packages/contracts/dist/signatures/datil.js +++ b/packages/contracts/dist/signatures/datil.js @@ -673,6 +673,30 @@ export const signatures = { "stateMutability": "view", "type": "function" }, + "getDerivedPubkey": { + "inputs": [ + { + "internalType": "address", + "name": "stakingContract", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "derivedKeyId", + "type": "bytes32" + } + ], + "name": "getDerivedPubkey", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, "getEthAddress": { "inputs": [ { diff --git a/packages/contracts/dist/signatures/develop.cjs b/packages/contracts/dist/signatures/develop.cjs index 1fa8fd6d7..c0ae731dd 100644 --- a/packages/contracts/dist/signatures/develop.cjs +++ b/packages/contracts/dist/signatures/develop.cjs @@ -1072,6 +1072,35 @@ const signatures = { "stateMutability": "view", "type": "function" }, + "getDerivedPubkey": { + "inputs": [ + { + "internalType": "address", + "name": "stakingContract", + "type": "address" + }, + { + "internalType": "string", + "name": "keySetId", + "type": "string" + }, + { + "internalType": "bytes32", + "name": "derivedKeyId", + "type": "bytes32" + } + ], + "name": "getDerivedPubkey", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, "getEthAddress": { "inputs": [ { diff --git a/packages/contracts/dist/signatures/develop.d.ts b/packages/contracts/dist/signatures/develop.d.ts index 98d219194..d1a353046 100644 --- a/packages/contracts/dist/signatures/develop.d.ts +++ b/packages/contracts/dist/signatures/develop.d.ts @@ -1072,6 +1072,35 @@ export const signatures = { "stateMutability": "view", "type": "function" }, + "getDerivedPubkey": { + "inputs": [ + { + "internalType": "address", + "name": "stakingContract", + "type": "address" + }, + { + "internalType": "string", + "name": "keySetId", + "type": "string" + }, + { + "internalType": "bytes32", + "name": "derivedKeyId", + "type": "bytes32" + } + ], + "name": "getDerivedPubkey", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, "getEthAddress": { "inputs": [ { diff --git a/packages/contracts/dist/signatures/develop.js b/packages/contracts/dist/signatures/develop.js index 981584fdf..5cbc839ee 100644 --- a/packages/contracts/dist/signatures/develop.js +++ b/packages/contracts/dist/signatures/develop.js @@ -1072,6 +1072,35 @@ export const signatures = { "stateMutability": "view", "type": "function" }, + "getDerivedPubkey": { + "inputs": [ + { + "internalType": "address", + "name": "stakingContract", + "type": "address" + }, + { + "internalType": "string", + "name": "keySetId", + "type": "string" + }, + { + "internalType": "bytes32", + "name": "derivedKeyId", + "type": "bytes32" + } + ], + "name": "getDerivedPubkey", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, "getEthAddress": { "inputs": [ { diff --git a/packages/contracts/dist/signatures/naga-dev.cjs b/packages/contracts/dist/signatures/naga-dev.cjs index bdd8aa3bc..7a686724e 100644 --- a/packages/contracts/dist/signatures/naga-dev.cjs +++ b/packages/contracts/dist/signatures/naga-dev.cjs @@ -1072,6 +1072,35 @@ const signatures = { "stateMutability": "view", "type": "function" }, + "getDerivedPubkey": { + "inputs": [ + { + "internalType": "address", + "name": "stakingContract", + "type": "address" + }, + { + "internalType": "string", + "name": "keySetId", + "type": "string" + }, + { + "internalType": "bytes32", + "name": "derivedKeyId", + "type": "bytes32" + } + ], + "name": "getDerivedPubkey", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, "getEthAddress": { "inputs": [ { diff --git a/packages/contracts/dist/signatures/naga-dev.d.ts b/packages/contracts/dist/signatures/naga-dev.d.ts index aebf82da5..d3fc0190f 100644 --- a/packages/contracts/dist/signatures/naga-dev.d.ts +++ b/packages/contracts/dist/signatures/naga-dev.d.ts @@ -1072,6 +1072,35 @@ export const signatures = { "stateMutability": "view", "type": "function" }, + "getDerivedPubkey": { + "inputs": [ + { + "internalType": "address", + "name": "stakingContract", + "type": "address" + }, + { + "internalType": "string", + "name": "keySetId", + "type": "string" + }, + { + "internalType": "bytes32", + "name": "derivedKeyId", + "type": "bytes32" + } + ], + "name": "getDerivedPubkey", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, "getEthAddress": { "inputs": [ { diff --git a/packages/contracts/dist/signatures/naga-dev.js b/packages/contracts/dist/signatures/naga-dev.js index 3a0e4bc82..ce8337944 100644 --- a/packages/contracts/dist/signatures/naga-dev.js +++ b/packages/contracts/dist/signatures/naga-dev.js @@ -1072,6 +1072,35 @@ export const signatures = { "stateMutability": "view", "type": "function" }, + "getDerivedPubkey": { + "inputs": [ + { + "internalType": "address", + "name": "stakingContract", + "type": "address" + }, + { + "internalType": "string", + "name": "keySetId", + "type": "string" + }, + { + "internalType": "bytes32", + "name": "derivedKeyId", + "type": "bytes32" + } + ], + "name": "getDerivedPubkey", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, "getEthAddress": { "inputs": [ { diff --git a/packages/contracts/dist/signatures/naga-staging.cjs b/packages/contracts/dist/signatures/naga-staging.cjs index 2cb8426aa..2aa12ebd5 100644 --- a/packages/contracts/dist/signatures/naga-staging.cjs +++ b/packages/contracts/dist/signatures/naga-staging.cjs @@ -1072,6 +1072,35 @@ const signatures = { "stateMutability": "view", "type": "function" }, + "getDerivedPubkey": { + "inputs": [ + { + "internalType": "address", + "name": "stakingContract", + "type": "address" + }, + { + "internalType": "string", + "name": "keySetId", + "type": "string" + }, + { + "internalType": "bytes32", + "name": "derivedKeyId", + "type": "bytes32" + } + ], + "name": "getDerivedPubkey", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, "getEthAddress": { "inputs": [ { diff --git a/packages/contracts/dist/signatures/naga-staging.d.ts b/packages/contracts/dist/signatures/naga-staging.d.ts index 727b54b01..139c06c6c 100644 --- a/packages/contracts/dist/signatures/naga-staging.d.ts +++ b/packages/contracts/dist/signatures/naga-staging.d.ts @@ -1072,6 +1072,35 @@ export const signatures = { "stateMutability": "view", "type": "function" }, + "getDerivedPubkey": { + "inputs": [ + { + "internalType": "address", + "name": "stakingContract", + "type": "address" + }, + { + "internalType": "string", + "name": "keySetId", + "type": "string" + }, + { + "internalType": "bytes32", + "name": "derivedKeyId", + "type": "bytes32" + } + ], + "name": "getDerivedPubkey", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, "getEthAddress": { "inputs": [ { diff --git a/packages/contracts/dist/signatures/naga-staging.js b/packages/contracts/dist/signatures/naga-staging.js index ad718fabf..ea43e368f 100644 --- a/packages/contracts/dist/signatures/naga-staging.js +++ b/packages/contracts/dist/signatures/naga-staging.js @@ -1072,6 +1072,35 @@ export const signatures = { "stateMutability": "view", "type": "function" }, + "getDerivedPubkey": { + "inputs": [ + { + "internalType": "address", + "name": "stakingContract", + "type": "address" + }, + { + "internalType": "string", + "name": "keySetId", + "type": "string" + }, + { + "internalType": "bytes32", + "name": "derivedKeyId", + "type": "bytes32" + } + ], + "name": "getDerivedPubkey", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, "getEthAddress": { "inputs": [ { diff --git a/packages/contracts/dist/signatures/naga-test.cjs b/packages/contracts/dist/signatures/naga-test.cjs index ab0c59b32..0af31a7c0 100644 --- a/packages/contracts/dist/signatures/naga-test.cjs +++ b/packages/contracts/dist/signatures/naga-test.cjs @@ -1072,6 +1072,35 @@ const signatures = { "stateMutability": "view", "type": "function" }, + "getDerivedPubkey": { + "inputs": [ + { + "internalType": "address", + "name": "stakingContract", + "type": "address" + }, + { + "internalType": "string", + "name": "keySetId", + "type": "string" + }, + { + "internalType": "bytes32", + "name": "derivedKeyId", + "type": "bytes32" + } + ], + "name": "getDerivedPubkey", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, "getEthAddress": { "inputs": [ { diff --git a/packages/contracts/dist/signatures/naga-test.d.ts b/packages/contracts/dist/signatures/naga-test.d.ts index 1f8c34253..be18c1a33 100644 --- a/packages/contracts/dist/signatures/naga-test.d.ts +++ b/packages/contracts/dist/signatures/naga-test.d.ts @@ -1072,6 +1072,35 @@ export const signatures = { "stateMutability": "view", "type": "function" }, + "getDerivedPubkey": { + "inputs": [ + { + "internalType": "address", + "name": "stakingContract", + "type": "address" + }, + { + "internalType": "string", + "name": "keySetId", + "type": "string" + }, + { + "internalType": "bytes32", + "name": "derivedKeyId", + "type": "bytes32" + } + ], + "name": "getDerivedPubkey", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, "getEthAddress": { "inputs": [ { diff --git a/packages/contracts/dist/signatures/naga-test.js b/packages/contracts/dist/signatures/naga-test.js index 83f86b272..302113c9f 100644 --- a/packages/contracts/dist/signatures/naga-test.js +++ b/packages/contracts/dist/signatures/naga-test.js @@ -1072,6 +1072,35 @@ export const signatures = { "stateMutability": "view", "type": "function" }, + "getDerivedPubkey": { + "inputs": [ + { + "internalType": "address", + "name": "stakingContract", + "type": "address" + }, + { + "internalType": "string", + "name": "keySetId", + "type": "string" + }, + { + "internalType": "bytes32", + "name": "derivedKeyId", + "type": "bytes32" + } + ], + "name": "getDerivedPubkey", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, "getEthAddress": { "inputs": [ { diff --git a/packages/contracts/src/config/methods.ts b/packages/contracts/src/config/methods.ts index bf676ba7a..1e2d7f53e 100644 --- a/packages/contracts/src/config/methods.ts +++ b/packages/contracts/src/config/methods.ts @@ -40,6 +40,7 @@ export const METHODS_TO_EXTRACT = [ 'PubkeyRouter.ethAddressToPkpId', 'PubkeyRouter.getPubkey', 'PubkeyRouter.getEthAddress', + 'PubkeyRouter.getDerivedPubkey', // Ledger: 'Ledger.deposit', diff --git a/packages/e2e/src/tickets/derived-pubkey.spec.ts b/packages/e2e/src/tickets/derived-pubkey.spec.ts new file mode 100644 index 000000000..ab6a7e241 --- /dev/null +++ b/packages/e2e/src/tickets/derived-pubkey.spec.ts @@ -0,0 +1,18 @@ +import { createLitClient } from '@lit-protocol/lit-client'; +import { nagaTest } from '@lit-protocol/networks'; +import { keccak256, stringToBytes } from 'viem'; + +const IPFS_CID = 'QmcA9npUnrzsmvx9sfmZDnEnPAEbMA5kp4tnkueYqiJKZv'; +const EXPECTED_DERIVED_PUBKEY = + '0x044e8f8e87e6192869a369b774fd9feba4607df95057eb58981626bd108f77d50674e587cc48c8a0a8c69ad650825ee1adf5f31acb4075e9327e625cd880a1dfdb'; + +describe('Derived Pubkey Ticket', () => { + test('should derive pubkey', async () => { + const derivedKeyId = keccak256(stringToBytes(`lit_action_${IPFS_CID}`)); + const litClient = await createLitClient({ + network: nagaTest, + }); + const ctx = await litClient.utils.getDerivedKeyId(derivedKeyId); + expect(ctx).toBe(EXPECTED_DERIVED_PUBKEY); + }); +}); diff --git a/packages/lit-client/src/lib/LitClient/createLitClient.ts b/packages/lit-client/src/lib/LitClient/createLitClient.ts index 089553ade..e0ea39c57 100644 --- a/packages/lit-client/src/lib/LitClient/createLitClient.ts +++ b/packages/lit-client/src/lib/LitClient/createLitClient.ts @@ -732,6 +732,33 @@ export const _createNagaLitClient = async ( executeJs: _executeJs, }; }, + utils: { + getDerivedKeyId: async (derivedKeyId: string) => { + const contractManager = _stateManager.contractManager; + + if (!contractManager) { + throw new Error('Contract manager is not available from state manager'); + } + + const pubkeyRouterContract = contractManager.pubkeyRouterContract; + + if ( + !pubkeyRouterContract?.read?.getDerivedPubkey || + !contractManager.stakingContract + ) { + throw new Error('Required contracts are not available on the contract manager'); + } + + // TODO: support configurable key set ids per network when required + const DEFAULT_KEY_SET_ID = 'naga-keyset1'; + + return pubkeyRouterContract.read.getDerivedPubkey([ + contractManager.stakingContract.address, + DEFAULT_KEY_SET_ID, + derivedKeyId, + ]); + }, + }, getChainConfig: () => { const viemConfig = networkModule.getChainConfig(); const rpcUrl = networkModule.getRpcUrl(); diff --git a/packages/networks/src/networks/vNaga/shared/managers/contract-manager/createContractsManager.ts b/packages/networks/src/networks/vNaga/shared/managers/contract-manager/createContractsManager.ts index c8b7593cd..41c20bd19 100644 --- a/packages/networks/src/networks/vNaga/shared/managers/contract-manager/createContractsManager.ts +++ b/packages/networks/src/networks/vNaga/shared/managers/contract-manager/createContractsManager.ts @@ -157,6 +157,7 @@ export const createContractsManager = ( contractData.PubkeyRouter.methods.deriveEthAddressFromPubkey, contractData.PubkeyRouter.methods.ethAddressToPkpId, contractData.PubkeyRouter.methods.getEthAddress, + contractData.PubkeyRouter.methods.getDerivedPubkey, contractData.PubkeyRouter.methods.getPubkey, ...contractData.PubkeyRouter.events, ], diff --git a/packages/networks/src/networks/vNaga/shared/managers/state-manager/createStateManager.ts b/packages/networks/src/networks/vNaga/shared/managers/state-manager/createStateManager.ts index aeb4fb038..3b871bb68 100644 --- a/packages/networks/src/networks/vNaga/shared/managers/state-manager/createStateManager.ts +++ b/packages/networks/src/networks/vNaga/shared/managers/state-manager/createStateManager.ts @@ -235,5 +235,8 @@ export const createStateManager = async (params: { eventStateManager.stop(); // clearInterval(timer); }, + + contractManager, + stakingContract }; }; From 720ca41d5433d8027fe1b25bd2045e91084aa715 Mon Sep 17 00:00:00 2001 From: anson Date: Fri, 24 Oct 2025 02:48:29 +0100 Subject: [PATCH 2/5] feat(docs): add `getDerivedKeyId` utility and usage examples for deriving Lit Action public keys --- docs/guides/lit-action-sign-as-action.mdx | 18 ++++++++++++ .../lit-client/functions/createLitClient.mdx | 29 ++++++++++++++++++- 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/docs/guides/lit-action-sign-as-action.mdx b/docs/guides/lit-action-sign-as-action.mdx index ba6bb2ce2..2c7ea4682 100644 --- a/docs/guides/lit-action-sign-as-action.mdx +++ b/docs/guides/lit-action-sign-as-action.mdx @@ -69,3 +69,21 @@ const { keccak256, arrayify } = ethers.utils; ``` This approach keeps the derivation entirely within the Lit Action context. Because the public key depends only on the Action CID and signing scheme, you can rely on `Lit.Actions.getActionPublicKey` for a deterministic identity without needing to execute the Action externally first. + +## Derive the Same Public Key from Client Code + +If you prefer to resolve the Lit Action public key outside of the Action runtime—e.g., inside tests or other tooling—the SDK now exposes a helper that calls the on-chain PubkeyRouter contract. + +```ts +import { createLitClient } from "@lit-protocol/lit-client"; +import { nagaDev } from "@lit-protocol/networks"; +import { keccak256, stringToBytes } from "viem"; + +const litClient = await createLitClient({ network: nagaDev }); +const derivedKeyId = keccak256(stringToBytes(`lit_action_${actionIpfsCid}`)); +const actionPublicKey = await litClient.utils.getDerivedKeyId(derivedKeyId); + +console.log("Derived Lit Action pubkey:", actionPublicKey); +``` + +Under the hood, `getDerivedKeyId` routes through `PubkeyRouter.getDerivedPubkey`, passing the staking contract address and the default Naga key set (`naga-keyset1`) (will be dynamic in the future). This mirrors the same key derivation the nodes perform, letting you confirm identities or signatures without re-running the Lit Action. diff --git a/docs/sdk/sdk-reference/lit-client/functions/createLitClient.mdx b/docs/sdk/sdk-reference/lit-client/functions/createLitClient.mdx index f62160754..35a3bf5fa 100644 --- a/docs/sdk/sdk-reference/lit-client/functions/createLitClient.mdx +++ b/docs/sdk/sdk-reference/lit-client/functions/createLitClient.mdx @@ -1046,6 +1046,33 @@ Create a Viem-compatible account backed by a PKP. +### utils.getDerivedKeyId + +Resolve the uncompressed PKP public key for a given derived key identifier. + +#### Parameters + + + 0x-prefixed bytes32 identifier (for example, keccak256(stringToBytes(`lit_action_${ipfsCid}`))). + + +#### Returns + + + 0x-prefixed uncompressed public key as returned by the PubkeyRouter contract. + + +#### Example + +```ts +import { keccak256, stringToBytes } from "viem"; + +const derivedKeyId = keccak256(stringToBytes(`lit_action_${ipfsCid}`)); +const derivedPubkey = await litClient.utils.getDerivedKeyId(derivedKeyId); +``` + +> Note: this helper currently calls `PubkeyRouter.getDerivedPubkey` with the default Naga key set (`naga-keyset1`). See the [Derive Lit Action Public Keys guide](../../../../guides/lit-action-sign-as-action) for an end-to-end workflow. + ### getChainConfig Returns the chain configuration for the current network. @@ -1074,4 +1101,4 @@ Stop background state updates and release resources. none #### Returns -void \ No newline at end of file +void From 84c1b12c3503c592f7c92e81ff455c43d74d5bc9 Mon Sep 17 00:00:00 2001 From: anson Date: Fri, 24 Oct 2025 02:56:37 +0100 Subject: [PATCH 3/5] fmt --- packages/lit-client/src/lib/LitClient/createLitClient.ts | 8 ++++++-- .../shared/managers/state-manager/createStateManager.ts | 4 +--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/packages/lit-client/src/lib/LitClient/createLitClient.ts b/packages/lit-client/src/lib/LitClient/createLitClient.ts index e0ea39c57..79bb3c17e 100644 --- a/packages/lit-client/src/lib/LitClient/createLitClient.ts +++ b/packages/lit-client/src/lib/LitClient/createLitClient.ts @@ -737,7 +737,9 @@ export const _createNagaLitClient = async ( const contractManager = _stateManager.contractManager; if (!contractManager) { - throw new Error('Contract manager is not available from state manager'); + throw new Error( + 'Contract manager is not available from state manager' + ); } const pubkeyRouterContract = contractManager.pubkeyRouterContract; @@ -746,7 +748,9 @@ export const _createNagaLitClient = async ( !pubkeyRouterContract?.read?.getDerivedPubkey || !contractManager.stakingContract ) { - throw new Error('Required contracts are not available on the contract manager'); + throw new Error( + 'Required contracts are not available on the contract manager' + ); } // TODO: support configurable key set ids per network when required diff --git a/packages/networks/src/networks/vNaga/shared/managers/state-manager/createStateManager.ts b/packages/networks/src/networks/vNaga/shared/managers/state-manager/createStateManager.ts index 3b871bb68..b1453e46b 100644 --- a/packages/networks/src/networks/vNaga/shared/managers/state-manager/createStateManager.ts +++ b/packages/networks/src/networks/vNaga/shared/managers/state-manager/createStateManager.ts @@ -235,8 +235,6 @@ export const createStateManager = async (params: { eventStateManager.stop(); // clearInterval(timer); }, - - contractManager, - stakingContract + stakingContract, }; }; From 4d339d1b075e2730713eaecda2a12f9e344dedea Mon Sep 17 00:00:00 2001 From: anson Date: Fri, 24 Oct 2025 02:58:26 +0100 Subject: [PATCH 4/5] chore: add changeset --- .changeset/two-mangos-lead.md | 8 ++++++++ docs/guides/lit-action-sign-as-action.mdx | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 .changeset/two-mangos-lead.md diff --git a/.changeset/two-mangos-lead.md b/.changeset/two-mangos-lead.md new file mode 100644 index 000000000..5956fb2db --- /dev/null +++ b/.changeset/two-mangos-lead.md @@ -0,0 +1,8 @@ +--- +'@lit-protocol/lit-client': minor +'@lit-protocol/contracts': minor +'@lit-protocol/networks': minor +'@lit-protocol/e2e': minor +--- + +introduce `litClient.utils.getDerivedKeyId` - a little helper to resolve the Lit Action public key outside of the Action runtime diff --git a/docs/guides/lit-action-sign-as-action.mdx b/docs/guides/lit-action-sign-as-action.mdx index 2c7ea4682..6a919ba6f 100644 --- a/docs/guides/lit-action-sign-as-action.mdx +++ b/docs/guides/lit-action-sign-as-action.mdx @@ -72,7 +72,7 @@ This approach keeps the derivation entirely within the Lit Action context. Becau ## Derive the Same Public Key from Client Code -If you prefer to resolve the Lit Action public key outside of the Action runtime—e.g., inside tests or other tooling—the SDK now exposes a helper that calls the on-chain PubkeyRouter contract. +If you prefer to resolve the Lit Action public key outside of the Action runtime - e.g., inside tests or other tooling—the SDK now exposes a helper that calls the on-chain PubkeyRouter contract. ```ts import { createLitClient } from "@lit-protocol/lit-client"; From 38a8e84d44443616dbfc51ce7051e5df0acd73c2 Mon Sep 17 00:00:00 2001 From: anson Date: Fri, 24 Oct 2025 03:01:36 +0100 Subject: [PATCH 5/5] fix(networks): re-export the correct instance --- .../vNaga/shared/managers/state-manager/createStateManager.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/networks/src/networks/vNaga/shared/managers/state-manager/createStateManager.ts b/packages/networks/src/networks/vNaga/shared/managers/state-manager/createStateManager.ts index b1453e46b..9ab10a449 100644 --- a/packages/networks/src/networks/vNaga/shared/managers/state-manager/createStateManager.ts +++ b/packages/networks/src/networks/vNaga/shared/managers/state-manager/createStateManager.ts @@ -235,6 +235,6 @@ export const createStateManager = async (params: { eventStateManager.stop(); // clearInterval(timer); }, - stakingContract, + contractManager, }; };