Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Signing Route #70

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ import { mintClaimedKeyId } from "./routes/auth/claim";
import { registerPayerHandler } from "./routes/delegate/register";
import { addPayeeHandler } from "./routes/delegate/user";
import { sendTxnHandler } from "./routes/auth/sendTxn";
import { pkpSignHandler } from "./routes/auth/pkpSign

const app = express();

Expand Down Expand Up @@ -227,6 +228,9 @@ app.get("/auth/status/:requestId", getAuthStatusHandler);
app.post("/register-payer", registerPayerHandler);
app.post("/add-users", addPayeeHandler);

// --- PKP Signing
app.post("/pkp-sign", pkpSignHandler);

// --- Send TXN
app.post("/send-txn", sendTxnHandler);

Expand Down
205 changes: 113 additions & 92 deletions lit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,16 @@ import { Sequencer } from "./lib/sequencer";
import { parseEther } from "ethers/lib/utils";
import { CapacityToken } from "lit";
import { LIT_NETWORK_VALUES } from "@lit-protocol/constants";
import { LitNodeClientNodeJs } from "@lit-protocol/lit-node-client-nodejs";
import { PKPEthersWallet } from "@lit-protocol/pkp-ethers";
import { LitActionResource, LitPKPResource } from "@lit-protocol/auth-helpers";
import { LIT_ABILITY } from "@lit-protocol/constants";
import { LIT_NETWORKS_KEYS } from "@lit-protocol/types";

import {
datil,
datilDev,
datilTest,
habanero,
manzano,
datilTest
} from "@lit-protocol/contracts";

function getContractFromJsSdk(
Expand All @@ -29,18 +32,11 @@ function getContractFromJsSdk(

let contractsDataRes;
switch (network) {
case "manzano":
contractsDataRes = manzano;
break;
case "habanero":
contractsDataRes = habanero;
break;
case "datil-dev":
contractsDataRes = datilDev;
break;
case "datil-test":
contractsDataRes = datilTest;

break;
case "datil":
contractsDataRes = datil;
Expand Down Expand Up @@ -118,64 +114,25 @@ function getContract(abiPath: string, deployedContractAddress: string) {
return ethersContract;
}


// No datildev support
function getAccessControlConditionsContract() {
switch (config.network) {
case "serrano":
case "serrano" as LIT_NETWORK_VALUES:
return getContract(
"./contracts/serrano/AccessControlConditions.json",
config?.serranoContract
?.accessControlConditionsAddress as string,
config?.serranoContract?.accessControlConditionsAddress as string,
);
case "cayenne":
case "cayenne" as LIT_NETWORK_VALUES:
return getContract(
"./contracts/cayenne/AccessControlConditions.json",
config?.cayenneContracts
?.accessControlConditionsAddress as string,
config?.cayenneContracts?.accessControlConditionsAddress as string,
);
}
}

function getPkpHelperContractAbiPath() {
if (config.useSoloNet) {
return "./contracts/serrano/SoloNetPKPHelper.json";
}

switch (config.network) {
case "serrano":
return "./contracts/serrano/PKPHelper.json";
case "cayenne":
return "./contracts/cayenne/PKPHelper.json";
}
}

function getPkpNftContractAbiPath() {
if (config.useSoloNet) {
return "./contracts/serrano/SoloNetPKP.json";
}
switch (config.network) {
case "serrano":
return "./contracts/serrano/PKPNFT.json";
case "cayenne":
return "./contracts/cayenne/PKPNFT.json";
}
}

function getPkpHelperContract(network: string): ethers.Contract {
function getPkpHelperContract(network: LIT_NETWORK_VALUES): ethers.Contract {
switch (network) {
case "serrano":
return getContract(
getPkpHelperContractAbiPath()!,
config?.serranoContract?.pkpHelperAddress as string,
);
case "cayenne":
return getContract(
getPkpHelperContractAbiPath()!,
config?.cayenneContracts?.pkpHelperAddress as string,
);
case "manzano":
return getContractFromJsSdk("manzano", "PKPHelper");
case "habanero":
return getContractFromJsSdk("habanero", "PKPHelper");
case "datil-dev":
return getContractFromJsSdk("datil-dev", "PKPHelper");
case "datil-test":
Expand All @@ -189,20 +146,6 @@ function getPkpHelperContract(network: string): ethers.Contract {

function getPermissionsContract(): ethers.Contract {
switch (config.network) {
case "serrano":
return getContract(
"./contracts/serrano/PKPPermissions.json",
config?.serranoContract?.pkpPermissionsAddress as string,
);
case "cayenne":
return getContract(
"./contracts/cayenne/PKPPermissions.json",
config?.cayenneContracts?.pkpPermissionsAddress as string,
);
case "manzano":
return getContractFromJsSdk("manzano", "PKPPermissions");
case "habanero":
return getContractFromJsSdk("habanero", "PKPPermissions");
case "datil-dev":
return getContractFromJsSdk("datil-dev", "PKPPermissions");
case "datil-test":
Expand All @@ -216,33 +159,19 @@ function getPermissionsContract(): ethers.Contract {

async function getPaymentDelegationContract() {
switch (config.network) {
case "manzano":
return getContractFromJsSdk("manzano", "PaymentDelegation");
case "habanero":
return getContractFromJsSdk("habanero", "PaymentDelegation");
case "datil-test":
return getContractFromJsSdk("datil-test", "PaymentDelegation");
case "datil":
return getContractFromJsSdk("datil", "PaymentDelegation");
default:
throw new Error(
"PaymentDelegation contract not available for this network",
);
}
}

export function getPkpNftContract(network: string): ethers.Contract {
export function getPkpNftContract(network: LIT_NETWORK_VALUES): ethers.Contract {
switch (network) {
case "serrano":
return getContract(
getPkpNftContractAbiPath()!,
config?.serranoContract?.pkpNftAddress as string,
);
case "cayenne":
return getContract(
getPkpNftContractAbiPath()!,
config?.cayenneContracts?.pkpNftAddress as string,
);
case "manzano":
return getContractFromJsSdk("manzano", "PKPNFT");
case "habanero":
return getContractFromJsSdk("habanero", "PKPNFT");
case "datil-dev":
return getContractFromJsSdk("datil-dev", "PKPNFT");
case "datil-test":
Expand Down Expand Up @@ -626,7 +555,7 @@ export async function mintCapacityCredits({
}: {
signer: ethers.Wallet;
}) {
if (config.network === "serrano" || config.network === "cayenne") {
if (config.network === "datil-dev") {
throw new Error(
`Payment delegation is not available on ${config.network}`,
);
Expand Down Expand Up @@ -734,7 +663,7 @@ async function queryCapacityCredit(
}

export async function queryCapacityCredits(signer: ethers.Wallet) {
if (config.network === "serrano" || config.network === "cayenne") {
if (config.network === "datil-dev") {
throw new Error(
`Payment delegation is not available on ${config.network}`,
);
Expand All @@ -757,7 +686,7 @@ export async function addPaymentDelegationPayee({
wallet: ethers.Wallet;
payeeAddresses: string[];
}) {
if (config.network === "serrano" || config.network === "cayenne") {
if (config.network === "datil-dev") {
throw new Error(
`Payment delegation is not available on ${config.network}`,
);
Expand Down Expand Up @@ -828,3 +757,95 @@ export async function addPaymentDelegationPayee({
// console.log("packed", packed);
// return packed;
// }

export async function initializeLitClient() {
const litNodeClient = new LitNodeClientNodeJs({
litNetwork: process.env.NETWORK as LIT_NETWORKS_KEYS,
debug: false
});
await litNodeClient.connect();
return litNodeClient;
}

export async function getPkpSessionSigs(litNodeClient: any, pkpPublicKey: string, authMethod: any) {
let sessionSigsParams: any = {
pkpPublicKey: pkpPublicKey,
chain: "ethereum",
authMethods: [authMethod],
expiration: new Date(Date.now() + 1000 * 60 * 10).toISOString(), // 10 minutes
resourceAbilityRequests: [
{
resource: new LitActionResource("*"),
ability: LIT_ABILITY.LitActionExecution,
},
{
resource: new LitPKPResource("*"),
ability: LIT_ABILITY.PKPSigning,
},
],
};

// Get capacity delegation auth sig for datil networks before session sigs
if (config.network === "datil-test" || config.network === "datil") {
const signer = getSigner();

const capacityTokens = await queryCapacityCredits(signer);
const capacityToken = capacityTokens.find((token) => !token.isExpired);
let capacityTokenId;

if (!capacityToken) {
const mintResult = await mintCapacityCredits({ signer });
if (!mintResult || !mintResult.capacityTokenId) {
throw new Error("Failed to mint capacity credits");
}
capacityTokenId = mintResult.capacityTokenId;
} else {
capacityTokenId = capacityToken.tokenId;
}

const result = await litNodeClient.createCapacityDelegationAuthSig({
dAppOwnerWallet: signer,
capacityTokenId: capacityTokenId.toString(),
delegateeAddresses: [ethers.utils.computeAddress(pkpPublicKey)],
uses: "1",
});
sessionSigsParams.capabilityAuthSigs = [result.capacityDelegationAuthSig];
}

return await litNodeClient.getPkpSessionSigs(sessionSigsParams);
}

export async function signWithPkp(litNodeClient: any, pkpPublicKey: string, sessionSigs: any, toSign: Uint8Array) {
const signingResult = await litNodeClient.pkpSign({
pubKey: pkpPublicKey,
sessionSigs,
toSign,
});

if (!signingResult || !signingResult.signature) {
throw new Error("Failed to get signature from PKP");
}

return signingResult;
}

export async function initializePkpWallet({
sessionSigs,
pkpPublicKey,
litNodeClient,
provider,
}: {
sessionSigs: any;
pkpPublicKey: string;
litNodeClient: any;
provider: ethers.providers.Provider;
}) {
const pkpWallet = new PKPEthersWallet({
controllerSessionSigs: sessionSigs,
pkpPubKey: pkpPublicKey,
litNodeClient,
provider
});
await pkpWallet.init();
return pkpWallet;
}
8 changes: 5 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,19 @@
"start": "node dist/index.js",
"build": "tsc",
"postinstall": "cp patch/ethersCompat.d.ts node_modules/siwe/dist/ethersCompat.d.ts",
"test": "jest --detectOpenHandles",
"test": "jest --detectOpenHandles --forceExit",
"test:watch": "jest --watch",
"test:coverage": "jest --coverage"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"@lit-protocol/constants": "^6.2.4",
"@lit-protocol/constants": "^7.0.6",
"@lit-protocol/contracts": "^0.0.39",
"@lit-protocol/lit-node-client-nodejs": "^6.2.4",
"@lit-protocol/lit-auth-client": "^7.0.6",
"@lit-protocol/lit-node-client-nodejs": "^7.0.6",
"@lit-protocol/pkp-ethers": "^7.0.6",
"@simplewebauthn/server": "6.2.1",
"base64url": "^3.0.1",
"cbor": "^8.1.0",
Expand Down
Loading
Loading