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

feat: refactor lit protocol provider #1512

Merged
merged 31 commits into from
Dec 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
650095e
feat: integrate Lit Protocol with enhanced testing and configuration …
rodrigopavezi Dec 5, 2024
153667e
fix: readme
rodrigopavezi Dec 5, 2024
0a4a75d
Update .circleci/config.yml
rodrigopavezi Dec 5, 2024
a64801f
fix: build
rodrigopavezi Dec 5, 2024
7eb71e1
fix: build giving more memory
rodrigopavezi Dec 5, 2024
1b3f85e
fix: memory issu
rodrigopavezi Dec 5, 2024
11a4e86
fix: out of memory issue
rodrigopavezi Dec 6, 2024
0229d47
chore: upgrade lit protocol sdk version
rodrigopavezi Dec 6, 2024
b953258
fix: package lint
rodrigopavezi Dec 6, 2024
c48b7f6
fix: as per review
rodrigopavezi Dec 6, 2024
14a6aed
Update packages/lit-protocol-cipher/README.md
rodrigopavezi Dec 6, 2024
e1d6c49
fix: revert memory change
rodrigopavezi Dec 9, 2024
42c83d5
Update packages/lit-protocol-cipher/src/lit-protocol-cipher-provider.ts
rodrigopavezi Dec 9, 2024
50aca1a
Update README.md
rodrigopavezi Dec 9, 2024
e64f15b
fix: rename LitProtocolCipherProvider
rodrigopavezi Dec 9, 2024
c73fb44
fix: update lit integration test
rodrigopavezi Dec 9, 2024
c216c24
fix: duplicate files
rodrigopavezi Dec 10, 2024
0a481cc
Merge branch 'master' into refactor/lit-protocol-provider
rodrigopavezi Dec 10, 2024
e48d2ee
fix: tests
rodrigopavezi Dec 10, 2024
af6c986
Merge branch 'refactor/lit-protocol-provider' of https://github.com/R…
rodrigopavezi Dec 10, 2024
8ba492f
Merge branch 'master' into refactor/lit-protocol-provider
rodrigopavezi Dec 10, 2024
605154e
refactor: add lit-protocol-cipher tsconfig and rename provider class
rodrigopavezi Dec 11, 2024
7fb3bae
refactor: enhance encryption parameter validation and condition creation
rodrigopavezi Dec 13, 2024
586467d
Merge branch 'master' into refactor/lit-protocol-provider
rodrigopavezi Dec 13, 2024
5b89fac
chore: update @lit-protocol packages to version 7.0.2
rodrigopavezi Dec 13, 2024
c19db75
fix: add crypto module for Node.js compatibility in jest config
rodrigopavezi Dec 13, 2024
f7c4825
chore: reorder test script execution in integration-test package.json
rodrigopavezi Dec 13, 2024
c3c771a
Update packages/integration-test/test/lit-protocol.test.ts
rodrigopavezi Dec 13, 2024
4975d24
fix: format
rodrigopavezi Dec 13, 2024
4100d89
fix: test timeouts
rodrigopavezi Dec 13, 2024
a847618
fix: per review
rodrigopavezi Dec 13, 2024
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
8 changes: 5 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,14 @@
"publish-manual-prerelease": "lerna publish prerelease --conventional-commits --conventional-prerelease --exact --no-git-tag-version --no-push --preid next --no-verify-access --dist-tag next",
"publish-prerelease": "FORCE_PUBLISH=$(lerna changed --json | jq '. | map(.name) | join (\",\")' -r) && echo $FORCE_PUBLISH && lerna publish --conventional-commits --conventional-prerelease --exact --no-git-tag-version --no-push --preid next --no-verify-access --dist-tag next --yes --force-publish=${FORCE_PUBLISH}",
"deploy:contracts": "yarn workspace @requestnetwork/smart-contracts deploy",
"start:request-node": "yarn workspace @requestnetwork/request-node start",
"start:request-node": "LIT_PROTOCOL_NETWORK=datil-dev yarn workspace @requestnetwork/request-node start",
"test": "lerna run test",
"format": "prettier . -w",
"format:check": "prettier . -c",
"link:all": "for d in packages/*; do cd $d; yarn link; cd -; done",
"unlink:all": "for d in packages/*; do cd $d; yarn unlink; cd -; done"
"link:all-npm": "for d in packages/*; do cd $d; npm link; cd -; done",
"unlink:all-npm": "for d in packages/*; do cd $d; npm unlink; cd -; done",
"link:all-yarn": "for d in packages/*; do cd $d; yarn link; cd -; done",
"unlink:all-yarn": "for d in packages/*; do cd $d; yarn unlink; cd -; done"
},
"devDependencies": {
"@typescript-eslint/eslint-plugin": "4.18.0",
Expand Down
1 change: 1 addition & 0 deletions packages/ethereum-storage/test/ipfs-manager.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import IpfsManager from '../src/ipfs-manager';
import { setupServer } from 'msw/node';
import { HttpResponse, delay, http } from 'msw';

jest.setTimeout(30000);
const testErrorHandling: StorageTypes.IIpfsErrorHandlingConfiguration = {
delayBetweenRetries: 0,
maxRetries: 0,
Expand Down
5 changes: 5 additions & 0 deletions packages/integration-test/jest.config.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
// The error ReferenceError: crypto is not defined occurs because the Node.js environment needs the crypto module to be explicitly available.
// For Node.js versions before 19, you need to add the crypto global explicitly.
const { webcrypto } = require('crypto');
global.crypto = webcrypto;

const jestCommonConfig = require('../../jest.config');

/** @type {import('jest').Config} */
Expand Down
6 changes: 4 additions & 2 deletions packages/integration-test/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,19 @@
"build": "tsc -b tsconfig.build.json",
"clean": "rm -rf dist tsconfig.tsbuildinfo tsconfig.build.tsbuildinfo",
"lint": "eslint \"test/**/*.ts\"",
"test": "run-s test:node test:layers",
"test": "run-s test:lit test:node test:layers",
"test:scheduled": "run-s test:erc20 test:any test:erc777 test:eth test:btc ",
"test:layers": "jest test/layers.test.ts --forceExit",
"test:node": "jest test/node-client.test.ts --forceExit",
"test:any": "jest test/scheduled/any*.test.ts --forceExit",
"test:eth": "jest test/scheduled/eth*.test.ts --forceExit",
"test:erc20": "jest test/scheduled/erc20*.test.ts --forceExit",
"test:erc777": "jest test/scheduled/erc777*.test.ts --forceExit",
"test:btc": "jest test/scheduled/btc.test.ts --forceExit"
"test:btc": "jest test/scheduled/btc.test.ts --forceExit",
"test:lit": "jest test/lit-protocol.test.ts --forceExit"
},
"devDependencies": {
"@lit-protocol/lit-node-client": "7.0.2",
"@requestnetwork/advanced-logic": "0.47.0",
"@requestnetwork/currency": "0.21.0",
"@requestnetwork/data-access": "0.38.0",
Expand Down
220 changes: 220 additions & 0 deletions packages/integration-test/test/lit-protocol.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
import { EthereumPrivateKeySignatureProvider } from '@requestnetwork/epk-signature';
import { LitProtocolCipherProvider } from '@requestnetwork/lit-protocol-cipher';
import { RequestNetwork, Types, Utils } from '@requestnetwork/request-client.js';
import { ethers } from 'ethers';
import { LitNodeClient } from '@lit-protocol/lit-node-client';

jest.setTimeout(30000);
const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));

async function waitForConfirmation(request: any, maxAttempts = 10, delayMs = 1000): Promise<void> {
let attempts = 0;
while (attempts < maxAttempts) {
try {
const data = await request.getData();
if (data.state === Types.RequestLogic.STATE.CREATED) {
console.log(`Request confirmed with state: ${data.state}`);
return;
}
console.log(
`Attempt ${attempts + 1}: Request not confirmed yet. Current state: ${data.state}`,
);
} catch (error) {
console.log(`Attempt ${attempts + 1} failed:`, error);
}
await sleep(delayMs);
attempts++;
}
throw new Error(`Request not confirmed after ${maxAttempts} attempts`);
}

describe('Lit Protocol Integration Tests', () => {
let requestNetwork: RequestNetwork;
let litProvider: LitProtocolCipherProvider;
let epkSignatureProvider: EthereumPrivateKeySignatureProvider;
let userWallet: ethers.Wallet;
let litClient: LitNodeClient;

const nodeConnectionConfig = {
baseURL: 'http://localhost:3000',
headers: {
'Content-Type': 'application/json',
},
};

beforeAll(async () => {
// Create wallet
userWallet = new ethers.Wallet(
'0x7b595b2bb732edddc4d4fe758ae528c7a748c40f0f6220f4494e214f15c5bfeb',
);

// Initialize signature provider
epkSignatureProvider = new EthereumPrivateKeySignatureProvider({
method: Types.Signature.METHOD.ECDSA,
privateKey: userWallet.privateKey,
});

// Initialize Lit Protocol client
litClient = new LitNodeClient({
litNetwork: 'datil-dev',
alertWhenUnauthorized: false,
debug: false,
});

// Initialize Lit Protocol provider
litProvider = new LitProtocolCipherProvider(litClient, nodeConnectionConfig);
await litProvider.initializeClient();
await litProvider.enableDecryption(true);
await litProvider.getSessionSignatures(userWallet, userWallet.address);

// Initialize Request Network client
requestNetwork = new RequestNetwork({
nodeConnectionConfig,
signatureProvider: epkSignatureProvider,
cipherProvider: litProvider,
});
}, 30000);

afterAll(async () => {
try {
// Get all pending promises
const promises = [];
if (litProvider) {
promises.push(litProvider.disconnectClient());
promises.push(litProvider.disconnectWallet());
}
if (litClient) {
promises.push(litClient.disconnect());
}

// Wait for all cleanup operations to complete
await Promise.all(promises);
} catch (error) {
console.error('Cleanup error:', error);
}
});

it('should encrypt and decrypt data directly', async () => {
const testData = 'test encryption';
const encryptionParams = [
{
key: userWallet.address,
method: Types.Encryption.METHOD.KMS,
},
];

const encrypted = await litProvider.encrypt(testData, { encryptionParams });
expect(encrypted).toBeDefined();
expect(encrypted?.ciphertext).toBeDefined();
expect(encrypted?.dataToEncryptHash).toBeDefined();

const decrypted = await litProvider.decrypt(encrypted!, { encryptionParams });
expect(decrypted).toBe(testData);
});

it('should create and encrypt a request', async () => {
const requestParams = {
requestInfo: {
currency: {
type: Types.RequestLogic.CURRENCY.ETH,
value: '0x0000000000000000000000000000000000000000',
network: 'sepolia',
},
expectedAmount: ethers.utils.parseEther('0.1').toString(),
payee: {
type: Types.Identity.TYPE.ETHEREUM_ADDRESS,
value: userWallet.address,
},
payer: {
type: Types.Identity.TYPE.ETHEREUM_ADDRESS,
value: '0xb07D2398d2004378cad234DA0EF14f1c94A530e4',
},
timestamp: Utils.getCurrentTimestampInSecond(),
},
paymentNetwork: {
id: Types.Extension.PAYMENT_NETWORK_ID.ETH_FEE_PROXY_CONTRACT,
parameters: {
paymentNetworkName: 'sepolia',
paymentAddress: userWallet.address,
feeAddress: '0x0000000000000000000000000000000000000000',
feeAmount: '0',
tokenAddress: '0x0000000000000000000000000000000000000000',
},
},
contentData: {
meta: {
format: 'rnf_invoice',
version: '0.0.3',
},
creationDate: new Date().toISOString(),
invoiceNumber: 'INV-2023-001',
invoiceItems: [
{
name: 'Test Service',
quantity: 1,
unitPrice: ethers.utils.parseEther('0.1').toString(),
discount: '0',
tax: {
type: 'percentage',
amount: '0',
},
currency: 'ETH',
},
],
},
signer: {
type: Types.Identity.TYPE.ETHEREUM_ADDRESS,
value: userWallet.address,
},
};

const encryptionParams = [
{
key: userWallet.address,
method: Types.Encryption.METHOD.KMS,
},
];

const encryptedRequest = await requestNetwork._createEncryptedRequest(
requestParams as Types.ICreateRequestParameters,
encryptionParams,
);

await waitForConfirmation(encryptedRequest, 15, 2000);

const requestData = await encryptedRequest.getData();
expect(requestData).toBeDefined();
expect([Types.RequestLogic.STATE.CREATED]).toContain(requestData.state);
});

it('should handle encryption errors gracefully', async () => {
const invalidEncryptionParams = [
{
key: '',
method: Types.Encryption.METHOD.KMS,
},
];

await expect(
litProvider.encrypt('test data', { encryptionParams: invalidEncryptionParams }),
).rejects.toThrow(/invalid.*key/i);
});

it('should handle decryption errors gracefully', async () => {
const invalidEncryptedData = {
ciphertext: 'invalid-ciphertext',
dataToEncryptHash: 'invalid-hash',
};

await expect(
litProvider.decrypt(invalidEncryptedData, {
encryptionParams: [
{
key: userWallet.address,
method: Types.Encryption.METHOD.KMS,
},
],
}),
).rejects.toThrow();
});
});
1 change: 1 addition & 0 deletions packages/integration-test/tsconfig.build.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
{ "path": "../ethereum-storage/tsconfig.build.json" },
{ "path": "../epk-decryption/tsconfig.build.json" },
{ "path": "../epk-signature/tsconfig.build.json" },
{ "path": "../lit-protocol-cipher/tsconfig.build.json" },
{ "path": "../multi-format/tsconfig.build.json" },
{ "path": "../payment-processor/tsconfig.build.json" },
{ "path": "../request-logic/tsconfig.build.json" },
Expand Down
33 changes: 22 additions & 11 deletions packages/lit-protocol-cipher/README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# @requestnetwork/lit-protocol-cipher

Lit Protocol Provider.
Lit Protocol Provider for Request Network.

`@requestnetwork/lit-protocol-cipher` is a typescript library part of the [Request Network protocol](https://github.com/RequestNetwork/requestNetwork).
`@requestnetwork/lit-protocol-cipher` is a typescript library part of the [Request Network protocol](https://github.com/RequestNetwork/requestNetwork) that provides encryption and decryption capabilities using the Lit Protocol.

## Installation

Expand All @@ -12,22 +12,33 @@ npm install @requestnetwork/lit-protocol-cipher

## Usage

The `LitProvider` class provides encryption and decryption capabilities using the Lit Protocol. Here's how to implement and use it:
The `LitProtocolCipherProvider` class provides encryption and decryption capabilities using the Lit Protocol. Here's how to implement and use it:

```typescript
import { ethers } from 'ethers';
import LitProvider from './LitProvider';
import { LitProtocolCipherProvider } from '@requestnetwork/lit-protocol-cipher';
import { LIT_NETWORKS } from '@lit-protocol/types';
import { LitNodeClient } from '@lit-protocol/lit-node-client';

// Initialize the provider
const litProvider = new LitProvider(
'ethereum', // chain
LIT_NETWORKS.MAINNET, // network
const litProvider = new LitProtocolCipherProvider(
new LitNodeClient({
litNetwork: LIT_NETWORKS.datil,
}),
{
nodeUrl: 'https://your-request-network-node.com',
baseURL: 'https://gnosis.gateway.request.network',
headers: {
'Content-Type': 'application/json',
},
}, // nodeConnectionConfig
);

// Initialize the client
await litProvider.initializeClient();

// Enable decryption
await litProvider.enableDecryption(true);

// Example usage with wallet connection
async function example() {
try {
Expand Down Expand Up @@ -70,11 +81,11 @@ async function example() {
const parsedData = JSON.parse(decryptedData);
console.log('Decrypted data:', parsedData);
}

// Disconnect wallet when done
await litProvider.disconnectWallet();
} catch (error) {
console.error('Error:', error);
} finally {
// Disconnect wallet when done
await litProvider.disconnectWallet();
}
}

Expand Down
12 changes: 6 additions & 6 deletions packages/lit-protocol-cipher/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,13 @@
"test:watch": "yarn test --watch"
},
"dependencies": {
"@lit-protocol/auth-helpers": "7.0.0",
"@lit-protocol/constants": "7.0.0",
"@lit-protocol/auth-helpers": "7.0.2",
"@lit-protocol/constants": "7.0.2",
"@lit-protocol/contracts": "0.0.74",
"@lit-protocol/encryption": "7.0.0",
"@lit-protocol/lit-node-client": "7.0.0",
"@lit-protocol/lit-node-client-nodejs": "7.0.0",
"@lit-protocol/types": "7.0.0",
"@lit-protocol/encryption": "7.0.2",
"@lit-protocol/lit-node-client": "7.0.2",
"@lit-protocol/lit-node-client-nodejs": "7.0.2",
"@lit-protocol/types": "7.0.2",
"@requestnetwork/request-client.js": "0.52.0",
"@requestnetwork/types": "0.47.0",
"@walletconnect/modal": "2.7.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/lit-protocol-cipher/src/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export { default as LitProtocolProvider } from './lit-protocol-cipher-provider';
export { default as LitProtocolCipherProvider } from './lit-protocol-cipher-provider';
Loading