Skip to content

Commit

Permalink
Merge branch 'master' into feat/hide-session-sigs
Browse files Browse the repository at this point in the history
  • Loading branch information
Ansonhkg authored Dec 16, 2024
2 parents a4ee232 + 806264a commit e0e0c00
Show file tree
Hide file tree
Showing 37 changed files with 789 additions and 650 deletions.
17 changes: 12 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,20 +42,27 @@ jobs:
integration-tests:
runs-on: ubuntu-latest
timeout-minutes: 30
env:
DATIL_COMMIT_HASH: ae3c20e07eb933b61073689b95f56867c03de252
steps:
- name: Checkout repo
uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Checkout Lit Actions
- name: Find latest datil commit hash for last successful "rust/lit-node-build-commit-hash" workflow in the Lit Assets repo
uses: LIT-Protocol/last-successful-build-action@372ea3325a894558ee74d970217ca421ea562fba
id: last-successful-build
with:
token: "${{ secrets.GH_PAT_FOR_SHIVA }}"
branch: "datil"
workflow: "rust/lit-node-build-commit-hash"
repo: LIT-Protocol/lit-assets
# this outputs to dollarSign{{ steps.last-successful-build.outputs.lastSuccessfulBuildSha }}
- name: Checkout Lit Assets
uses: actions/checkout@v4
id: checkout
with:
fetch-depth: 0
repository: LIT-Protocol/lit-assets
ref: ${{env.DATIL_COMMIT_HASH}}
ref: ${{ steps.last-successful-build.outputs.lastSuccessfulBuildSha }}
token: ${{secrets.GH_PAT_FOR_SHIVA}}
path: ${{ github.workspace }}/lit-assets/
submodules: false
Expand All @@ -75,7 +82,7 @@ jobs:
run: docker pull ghcr.io/lit-protocol/shiva:latest
- name: Run Shiva Container
id: shiva-runner
run: docker run -d -m 32g -p 8000:8000 -p 8545:8545 -p 7470:7470 -p 7471:7471 -p 7472:7472 -p 7473:7473 -p 7474:7474 -p 7475:7475 -v ${{github.workspace}}/lit-assets:/data -e GH_PAT=${{secrets.GH_PAT_FOR_SHIVA}} -e HASH=$DATIL_COMMIT_HASH -e IPFS_API_KEY=${{secrets.IPFS_API_KEY}} --name shiva ghcr.io/lit-protocol/shiva:latest
run: docker run -d -m 32g -p 8000:8000 -p 8545:8545 -p 7470:7470 -p 7471:7471 -p 7472:7472 -p 7473:7473 -p 7474:7474 -p 7475:7475 -v ${{github.workspace}}/lit-assets:/data -e GH_PAT=${{secrets.GH_PAT_FOR_SHIVA}} -e HASH=${{ steps.last-successful-build.outputs.lastSuccessfulBuildSha }} -e IPFS_API_KEY=${{secrets.IPFS_API_KEY}} --name shiva ghcr.io/lit-protocol/shiva:latest
- name: Set up Node.js
uses: actions/setup-node@v3
with:
Expand Down
2 changes: 1 addition & 1 deletion lerna.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@
"$schema": "node_modules/lerna/schemas/lerna-schema.json",
"useNx": true,
"useWorkspaces": true,
"version": "7.0.0"
"version": "7.0.2"
}
8 changes: 8 additions & 0 deletions local-tests/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ import { testUseInvalidLitActionIpfsCodeToGenerateSessionSigs } from './tests/te
import { testSolAuthSigToEncryptDecryptString } from './tests/testSolAuthSigToEncryptDecryptString';
import { testEthAuthSigToEncryptDecryptString } from './tests/testEthAuthSigToEncryptDecryptString';
import { testCosmosAuthSigToEncryptDecryptString } from './tests/testCosmosAuthSigToEncryptDecryptString';
import { testKeccakEip1271AuthSigToEncryptDecryptString } from './tests/testKeccakEip1271AuthSigToEncryptDecryptString';
import { testShaEip1271AuthSigToEncryptDecryptString } from './tests/testShaEip1271AuthSigToEncryptDecryptString';
import { testPkpEthersWithEoaSessionSigsToSignMessage } from './tests/testPkpEthersWithEoaSessionSigsToSignMessage';
import { testPkpEthersWithEoaSessionSigsToSignWithAuthContext } from './tests/testPkpEthersWithEoaSessionSigsToSignWithAuthContext';
import { testPkpEthersWithEoaSessionSigsToEthSign } from './tests/testPkpEthersWithEoaSessionSigsToEthSign';
Expand Down Expand Up @@ -232,6 +234,11 @@ setLitActionsCodeToLocal();
testCosmosAuthSigToEncryptDecryptString,
};

const eip1271AuthSigTests = {
testKeccakEip1271AuthSigToEncryptDecryptString,
testShaEip1271AuthSigToEncryptDecryptString,
};

const pkpEthersTest = {
eoaSessionSigs: {
testPkpEthersWithEoaSessionSigsToSignWithAuthContext,
Expand Down Expand Up @@ -294,6 +301,7 @@ setLitActionsCodeToLocal();
...litActionIpfsIdSessionSigsTests,
...capacityDelegationTests,
...bareAuthSigTests,
...eip1271AuthSigTests,

...pkpEthersTest.eoaSessionSigs,
...pkpEthersTest.pkpSessionSigs,
Expand Down
174 changes: 174 additions & 0 deletions local-tests/tests/testKeccakEip1271AuthSigToEncryptDecryptString.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
import { AuthSig, BaseSiweMessage, ILitNodeClient } from '@lit-protocol/types';
import { AccessControlConditions } from 'local-tests/setup/accs/accs';
import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
import { log } from '@lit-protocol/misc';
import { encryptString, decryptToString } from '@lit-protocol/encryption';
import { CENTRALISATION_BY_NETWORK } from '@lit-protocol/constants';
import { createSiweMessage } from '@lit-protocol/auth-helpers';
import { hashMessage } from 'ethers/lib/utils';
import { ethers } from 'ethers';
import { createHash } from 'crypto';

/**
* Test Commands:
* ✅ NETWORK=datil-dev yarn test:local --filter=testKeccakEip1271AuthSigToEncryptDecryptString
* ✅ NETWORK=datil-test yarn test:local --filter=testKeccakEip1271AuthSigToEncryptDecryptString
* ✅ NETWORK=custom yarn test:local --filter=testKeccakEip1271AuthSigToEncryptDecryptString
*/
export const testKeccakEip1271AuthSigToEncryptDecryptString = async (
devEnv: TinnyEnvironment
) => {
const dataToEncrypt = 'Decrypted from EIP1271 AuthSig';
const contractAddress = '0x88105De2349f59767278Fd15c0858f806c08d615';
const deployerAddress = '0x0b1C5E9E82393AD5d1d1e9a498BF7bAAC13b31Ee'; // No purpose other than to be a random address
const abi = [
'function setTempOwner(address _tempOwner) external',
'function getTempOwner() external view returns (address)',
'function isValidSignature(bytes32 _hash, bytes calldata _signature) external view returns (bytes4)',
];

const alice = await devEnv.createRandomPerson();
if (CENTRALISATION_BY_NETWORK[devEnv.network] === 'decentralised') {
// The capacity credits NFT owner automatically uses the capacity credits
// to pay for the encryption
await alice.mintCapacityCreditsNFT();
}

let accs = AccessControlConditions.getEmvBasicAccessControlConditions({
userAddress: contractAddress,
});
accs[0].chain = 'yellowstone'; // Contract deployed on Yellowstone

const encryptRes = await encryptString(
{
accessControlConditions: accs,
dataToEncrypt,
},
devEnv.litNodeClient as unknown as ILitNodeClient
);

// log('encryptRes:', encryptRes);

if (!encryptRes.ciphertext) {
throw new Error(`Expected "ciphertext" in encryptRes`);
}

if (!encryptRes.dataToEncryptHash) {
throw new Error(`Expected "dataToEncryptHash" to in encryptRes`);
}

// Craft the SiweMessage to be hashed & signed
const siweMessage = await createSiweMessage<BaseSiweMessage>({
nonce: await devEnv.litNodeClient.getLatestBlockhash(),
walletAddress: alice.wallet.address,
});

const siweSignature = await alice.wallet.signMessage(siweMessage);
log('siweSignature: ', siweSignature);

// Internally generate from wallet.signMessage
const hash = hashMessage(siweMessage);
const hashUint8Array = ethers.utils.arrayify(hash);
log('hash:', hash);
log('hashUint8Array: ', hashUint8Array); // Match it against the hash done on the nodes before calling verifySignature()

const eip1271AuthSig: AuthSig = {
address: contractAddress,
sig: siweSignature,
derivedVia: 'EIP1271',
signedMessage: siweMessage,
};

// log(eip1271AuthSig);

// Test from the contract
const contract = new ethers.Contract(contractAddress, abi, alice.wallet);
const setDeployerAsTempOwnerTx = await contract.setTempOwner(deployerAddress);
await setDeployerAsTempOwnerTx.wait();

log(
'0. isValidSignature should FAIL since Alice (AuthSig.sig) is not the tempOwner yet'
);
try {
const isValid = await contract.isValidSignature(hash, siweSignature);
if (isValid === '0x1626ba7e') {
throw new Error(
`Expected isValidSignature to be 0xffffffff but got ${isValid}`
);
}
} catch (error) {
log('Error calling isValidSignature:', error);
throw error;
}

try {
const _decryptRes = await decryptToString(
{
accessControlConditions: accs,
ciphertext: encryptRes.ciphertext,
dataToEncryptHash: encryptRes.dataToEncryptHash,
authSig: eip1271AuthSig,
chain: 'yellowstone', // Deployed chain
},
devEnv.litNodeClient as unknown as ILitNodeClient
);
} catch (error) {
if (
!error.message.includes('NodeContractAuthsigUnauthorized') ||
!error.message.includes('Access control failed for Smart contract') ||
!error.message.includes(
'validation error: Authsig failed for contract 0x88105De2349f59767278Fd15c0858f806c08d615. Return value was ffffffff.'
)
) {
throw new Error(
`Expected error message to contain specific EIP1271 validation failure, but got: ${error}`
);
}
}

// Should PASS now
log('1. Setting temp owner...');
const setTempOwnerTx = await contract.setTempOwner(alice.wallet.address);
await setTempOwnerTx.wait();
log('Set tempOwner transaction hash: ', setTempOwnerTx.hash);

const tempOwner = await contract.getTempOwner();
if (tempOwner.toLowerCase() !== alice.wallet.address.toLowerCase()) {
throw new Error(
`Expected temp owner to be ${alice.wallet.address} but got ${tempOwner}`
);
}

log('2. Checking isValidSignature...');
try {
const isValid = await contract.isValidSignature(hash, siweSignature);
if (isValid !== '0x1626ba7e') {
throw new Error(
`Expected isValidSignature to be 0x1626ba7e but got ${isValid}`
);
}
} catch (error) {
log('Error calling isValidSignature:', error);
throw error;
}

// -- Decrypt the encrypted string
const decryptRes = await decryptToString(
{
accessControlConditions: accs,
ciphertext: encryptRes.ciphertext,
dataToEncryptHash: encryptRes.dataToEncryptHash,
authSig: eip1271AuthSig,
chain: 'yellowstone', // Deployed chain
},
devEnv.litNodeClient as unknown as ILitNodeClient
);

if (decryptRes !== dataToEncrypt) {
throw new Error(
`Expected decryptRes to be ${dataToEncrypt} but got ${decryptRes}`
);
}

log('✅ decryptRes:', decryptRes);
};
Loading

0 comments on commit e0e0c00

Please sign in to comment.