Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/staging/3.2.0' into staging/3.2.0
Browse files Browse the repository at this point in the history
  • Loading branch information
Ansonhkg committed Feb 21, 2024
2 parents 4067d93 + cc980c2 commit 04657c1
Show file tree
Hide file tree
Showing 3 changed files with 206 additions and 177 deletions.
184 changes: 184 additions & 0 deletions e2e-nodejs/group-rli/test-rli-from-lit-node-client-no-delegatee.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
// Usage:
// DEBUG=true NETWORK=manzano MINT_NEW=true yarn test:e2e:nodejs --filter=test-rli-from-lit-node-client-no-delegatee.mjs
import path from 'path';
import { success, fail, testThis } from '../../tools/scripts/utils.mjs';
import LITCONFIG from '../../lit.config.json' assert { type: 'json' };
import { LitNodeClient } from '@lit-protocol/lit-node-client';
import { LitAbility, LitActionResource } from '@lit-protocol/auth-helpers';

import { LitContracts } from '@lit-protocol/contracts-sdk';
import { ethers } from 'ethers';
import * as siwe from 'siwe';

export async function main() {
if (process.env.LOAD_ENV === 'false') {
console.log('❗️ This test cannot be run with LOAD_ENV=false');
process.exit();
}

// NOTE: In this example, there will be no delegatees in the array
// ==================== Setup ====================

// ====================================================
// = dApp Owner's Perspetive =
// ====================================================
const provider = new ethers.providers.JsonRpcProvider(
LITCONFIG.CHRONICLE_RPC
);
globalThis.LitCI.wallet = new ethers.Wallet(
LITCONFIG.CONTROLLER_PRIVATE_KEY,
provider
);
const dAppOwnerWallet = globalThis.LitCI.wallet;

// As a dApp owner, I want to mint a Rate Limit Increase NFT so he who owns or delegated to
// would be able to perform 14400 requests per day
let contractClient = new LitContracts({
signer: dAppOwnerWallet,
debug: process.env.DEBUG === 'true' ?? LITCONFIG.TEST_ENV.debug,
network: process.env.NETWORK ?? LITCONFIG.TEST_ENV.litNetwork,
});

await contractClient.connect();

// -- mint new Capacity Credits NFT
const { capacityTokenIdStr } = await contractClient.mintCapacityCreditsNFT({
requestsPerDay: 14400, // 10 request per minute
daysUntilUTCMidnightExpiration: 2,
});

const litNodeClient = new LitNodeClient({
litNetwork: process.env.NETWORK ?? LITCONFIG.TEST_ENV.litNetwork,
debug: process.env.DEBUG === 'true' ?? LITCONFIG.TEST_ENV.debug,
minNodeCount: undefined,
checkNodeAttestation: process.env.CHECK_SEV ?? false,
});

await litNodeClient.connect();

// we will create an delegation auth sig, which internally we will create
// a recap object, add the resource "lit-ratelimitincrease://{tokenId}" to it, and add it to the siwe
// message. We will then sign the siwe message with the dApp owner's wallet.
const { capacityDelegationAuthSig } =
await litNodeClient.createCapacityDelegationAuthSig({
uses: '1',
dAppOwnerWallet: dAppOwnerWallet,
capacityTokenId: capacityTokenIdStr,
});

// ====================================================
// = As an end user =
// ====================================================
const endUserContractClient = new LitContracts({
signer: dAppOwnerWallet,
debug: process.env.DEBUG === 'true' ?? LITCONFIG.TEST_ENV.debug,
network: process.env.NETWORK ?? LITCONFIG.TEST_ENV.litNetwork,
});

await endUserContractClient.connect();

let endUserPkpMintRes =
await endUserContractClient.pkpNftContractUtils.write.mint();

const endUserPkpInfo = endUserPkpMintRes.pkp;

// We need to setup a generic siwe auth callback that will be called by the lit-node-client
const endUserControllerAuthNeededCallback = async ({
resources,
expiration,
uri,
}) => {
const litResource = new LitActionResource('*');

const recapObject =
await litNodeClient.generateSessionCapabilityObjectWithWildcards([
litResource,
]);

recapObject.addCapabilityForResource(
litResource,
LitAbility.LitActionExecution
);

const verified = recapObject.verifyCapabilitiesForResource(
litResource,
LitAbility.LitActionExecution
);

if (!verified) {
throw new Error('Failed to verify capabilities for resource');
}

console.log('authCallback verified:', verified);

let siweMessage = new siwe.SiweMessage({
domain: 'localhost:3000',
address: dAppOwnerWallet.address,
statement: 'Some custom statement.',
uri,
version: '1',
chainId: '1',
expirationTime: expiration,
resources,
});

siweMessage = recapObject.addToSiweMessage(siweMessage);

const messageToSign = siweMessage.prepareMessage();
const signature = await dAppOwnerWallet.signMessage(messageToSign);

const authSig = {
sig: signature.replace('0x', ''),
derivedVia: 'web3.eth.personal.sign',
signedMessage: messageToSign,
address: dAppOwnerWallet.address,
};

return authSig;
};

// - When generating a session sigs, we need to specify the resourceAbilityRequests, which
// is a list of resources and abilities that we want to be able to perform.
// "lit-ratelimitincrease://{tokenId}" that the dApp owner has delegated to us.
// - We also included the capacityDelegationAuthSig that we created earlier, which would be
// added to the capabilities array in the signing template.
let sessionSigs = await litNodeClient.getSessionSigs({
expiration: new Date(Date.now() + 1000 * 60 * 60 * 24).toISOString(), // 24 hours
chain: 'ethereum',
resourceAbilityRequests: [
{
resource: new LitActionResource('*'),
ability: LitAbility.LitActionExecution,
},
],
authNeededCallback: endUserControllerAuthNeededCallback,
capacityDelegationAuthSig,
});

// /web/execute
const res = await litNodeClient.executeJs({
sessionSigs,
code: `(async () => {
const sigShare = await LitActions.signEcdsa({
toSign: dataToSign,
publicKey,
sigName: "sig",
});
})();`,
authMethods: [],
jsParams: {
dataToSign: ethers.utils.arrayify(
ethers.utils.keccak256([1, 2, 3, 4, 5])
),
publicKey: endUserPkpInfo.publicKey,
},
});

if (res) {
return success('delegatee able to sign');
}

return fail(`Failed to get proof from Recap Session Capability`);
}

await testThis({ name: path.basename(import.meta.url), fn: main });
31 changes: 15 additions & 16 deletions packages/lit-node-client-nodejs/src/lib/lit-node-client-nodejs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ import * as siwe from 'siwe';
interface CapacityCreditsReq {
dAppOwnerWallet: ethers.Wallet;
capacityTokenId: string;
delegateeAddresses: string[];
delegateeAddresses?: string[];
uses?: string;
domain?: string;
expiration?: string;
Expand All @@ -135,8 +135,7 @@ interface CapacityCreditsRes {

export class LitNodeClientNodeJs
extends LitCore
implements LitClientSessionManager
{
implements LitClientSessionManager {
defaultAuthCallback?: (authSigParams: AuthCallbackParams) => Promise<AuthSig>;

// ========== Constructor ==========
Expand Down Expand Up @@ -195,6 +194,11 @@ export class LitNodeClientNodeJs
statement,
} = params;

// -- if delegateeAddresses is not provided, set it to an empty array
if (!delegateeAddresses) {
delegateeAddresses = [];
}

// -- This is the owner address who holds the Capacity Credits NFT token and wants to delegate its
// usage to a list of delegatee addresses
const dAppOwnerWalletAddress = ethers.utils.getAddress(
Expand All @@ -221,19 +225,19 @@ export class LitNodeClientNodeJs
}

// -- validate
if (!dAppOwnerWallet || !delegateeAddresses) {
throw new Error('Both parameters must exist');
if (!dAppOwnerWallet) {
throw new Error('dAppOwnerWallet must exist');
}

// -- validate dAppOwnerWallet is an ethers wallet
// if (!(dAppOwnerWallet instanceof ethers.Wallet || ethers.Signer)) {
// throw new Error('dAppOwnerWallet must be an ethers wallet');
// }

// -- validate delegateeAddresses has to be an array and has to have at least one address
if (!Array.isArray(delegateeAddresses) || delegateeAddresses.length === 0) {
throw new Error(
'delegateeAddresses must be an array and has to have at least one'
// -- Strip the 0x prefix from each element in the addresses array if it exists
if (delegateeAddresses && delegateeAddresses.length > 0) {
delegateeAddresses = delegateeAddresses.map((address) =>
address.startsWith('0x') ? address.slice(2) : address
);
}

Expand All @@ -242,11 +246,6 @@ export class LitNodeClientNodeJs
// lit-ratelimitincrease://{tokenId}
const litResource = new LitRLIResource(capacityTokenId);

// Strip the 0x prefix from each element in the addresses array
delegateeAddresses = delegateeAddresses.map((address) =>
address.startsWith('0x') ? address.slice(2) : address
);

const recapObject = await this.generateSessionCapabilityObjectWithWildcards(
[litResource]
);
Expand Down Expand Up @@ -2768,8 +2767,8 @@ export class LitNodeClientNodeJs
const sessionCapabilityObject = params.sessionCapabilityObject
? params.sessionCapabilityObject
: await this.generateSessionCapabilityObjectWithWildcards(
params.resourceAbilityRequests.map((r) => r.resource)
);
params.resourceAbilityRequests.map((r) => r.resource)
);
const expiration = params.expiration || LitNodeClientNodeJs.getExpiration();

if (!this.latestBlockhash) {
Expand Down
Loading

0 comments on commit 04657c1

Please sign in to comment.