Skip to content

Commit

Permalink
fix: added lit fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
Aman035 committed May 15, 2024
1 parent 1c6909b commit d975afe
Show file tree
Hide file tree
Showing 8 changed files with 162 additions and 39 deletions.
1 change: 1 addition & 0 deletions packages/restapi/src/lib/chat/helpers/signature.ts
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ export const verifyProfileSignature = async (
return true;
} else return false;
} catch (err) {
// todo smart contract wallet with EIP191 sig validation
return false;
}
}
Expand Down
16 changes: 11 additions & 5 deletions packages/restapi/src/lib/helpers/address.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import * as viem from 'viem';
import Constants, { ENV } from '../constants';
import { get } from '../user';
import { SignerType } from '../types';
import { Signer } from './signer';

export interface AddressValidatorsType {
[key: string]: ({ address }: { address: string }) => boolean;
Expand Down Expand Up @@ -102,8 +104,8 @@ export const isValidPushCAIP = (wallet: string): boolean => {
export const convertToValidDID = async (
wallet: string,
env: ENV = ENV.STAGING,
chainId?: number,
provider?: any
signer?: SignerType | null,
chainId?: number
) => {
/** @dev Why Not throw error? - Used by Group ChatID also */
if (!isValidPushCAIP(wallet)) return wallet;
Expand All @@ -121,10 +123,14 @@ export const convertToValidDID = async (
return `${wallet}:${epoch}`;
}

// TODO: Implement SCW DID CHECK
if (provider) {
if (signer) {
try {
const pushSigner = new Signer(signer);
const isSmartContract = await pushSigner.isSmartContract();
// check if onChain code exists
if (isSmartContract) {
return `scw:eip155:${await pushSigner.getChainId()}:${await pushSigner.getAddress()}`;
}
} catch (err) {
// Ignore if it fails
}
Expand Down Expand Up @@ -252,7 +258,7 @@ export const walletToPCAIP10 = (account: string): string => {
};

export const pCAIP10ToWallet = (wallet: string): string => {
if (isValidNFTCAIP(wallet)) return wallet;
if (isValidNFTCAIP(wallet) || isValidSCWCAIP(wallet)) return wallet;
wallet = wallet.replace('eip155:', '');
return wallet;
};
68 changes: 59 additions & 9 deletions packages/restapi/src/lib/helpers/crypto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import PROGRESSHOOK from '../progressHook';
import { Signer } from './signer';
import * as viem from 'viem';
import { mainnet } from 'viem/chains';
import { split } from 'shamir-secret-sharing';
import { combine, split } from 'shamir-secret-sharing';
import { Lit } from './lit';

const KDFSaltSize = 32; // bytes
Expand Down Expand Up @@ -81,7 +81,7 @@ export const encryptV1 = (
return encryptedSecret;
};

/** DEPRECATED */
/** @deprecated */
export const decryptWithWalletRPCMethod = async (
encryptedPGPPrivateKey: string,
account: string
Expand Down Expand Up @@ -237,7 +237,44 @@ export const decryptPGPKey = async (options: decryptPgpKeyProps) => {
break;
}
case Constants.ENC_TYPE_V5: {
// TODO
const { shardInfo } = JSON.parse(
encryptedPGPPrivateKey
) as encryptedPrivateKeyType;

if (!shardInfo) {
throw new Error('Invalid Shard Info');
}

const pushShard = shardInfo.shards[0].shard;
const litEncryptedShard = shardInfo.shards[1].shard;

const LitInstance = await Lit.createInstance(
wallet.signer as SignerType,
wallet.account as string,
'ethereum',
env
);

const pushSigner = new Signer(wallet.signer as SignerType);
const chainId = await pushSigner.getChainId();

const litShard = await LitInstance.decrypt(
litEncryptedShard.ciphertext,
litEncryptedShard.dataToEncryptHash,
chainId
);

const secret = await combine([
hexToBytes(pushShard),
hexToBytes(litShard),
]);

const encodedPrivateKey = await decryptV2(
JSON.parse(encryptedPGPPrivateKey),
secret
);
const dec = new TextDecoder();
privateKey = dec.decode(encodedPrivateKey);
break;
}
default:
Expand Down Expand Up @@ -266,13 +303,17 @@ export const decryptPGPKey = async (options: decryptPgpKeyProps) => {
progressHook?.(PROGRESSHOOK['PUSH-DECRYPT-02'] as ProgressHookType);
return privateKey;
} catch (err) {
// TODO: Remove Later
console.log(err);
// Report Progress
const errorProgressHook = PROGRESSHOOK[
'PUSH-ERROR-00'
] as ProgressHookTypeFunction;
progressHook?.(errorProgressHook(decryptPGPKey.name, err));
throw Error(
`[Push SDK] - API - Error - API ${decryptPGPKey.name} -: ${err}`
`[Push SDK] - API - Error - API ${decryptPGPKey.name} -: ${JSON.stringify(
err
)}`
);
}
};
Expand Down Expand Up @@ -468,6 +509,9 @@ export const encryptPGPKey = async (
break;
}
case Constants.ENC_TYPE_V5: {
if (!additionalMeta?.SCWPGP_V1?.password) {
throw new Error('Password is required!');
}
// 1. Generate secret to encrypt private key
const encryptionSecret = await getRandomValues(new Uint8Array(32));
// 2. Split secret into 3 shards ( Combining any 2 shards can decrypt the secret )
Expand Down Expand Up @@ -499,7 +543,13 @@ export const encryptPGPKey = async (
env
);

const litEncryptedShard = await LitInstance.encrypt(bytesToHex(shard2));
const pushSigner = new Signer(wallet.signer as SignerType);
const chainId = await pushSigner.getChainId();

const litEncryptedShard = await LitInstance.encrypt(
bytesToHex(shard2),
chainId
);

// 6. Encrypt and store shard3 on push nodes
const encodedShard3 = enc.encode(bytesToHex(shard3));
Expand All @@ -508,19 +558,19 @@ export const encryptPGPKey = async (
hexToBytes(stringToHex(additionalMeta?.SCWPGP_V1?.password as string))
);

encryptedPrivateKey.pushShard = {
encryptedPrivateKey.shardInfo = {
shards: [
{
shard: pushShard,
type: 'PUSH_SHARD',
encryptionType: 'NONE',
},
{
shard: litEncryptedShard,
type: 'LIT_SHARD_ENC_V1',
encryptionType: 'LIT_SHARD_ENC_V1',
},
{
shard: pushEncryptedShard,
type: 'PUSH_SHARD_ENC_V1',
encryptionType: 'PUSH_SHARD_ENC_V1',
},
],
pattern: `${QUORUM}-${PARTS}`,
Expand Down
60 changes: 43 additions & 17 deletions packages/restapi/src/lib/helpers/lit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import * as LitJsSdk from '@lit-protocol/lit-node-client';
import * as siwe from 'siwe';
import { SignerType } from '../types';
import { ENV } from '../constants';
import { pCAIP10ToWallet } from './address';
import { isValidSCWCAIP, pCAIP10ToWallet } from './address';
import * as viem from 'viem';

export class Lit {
public static LitInstance: Lit;
Expand All @@ -19,7 +20,9 @@ export class Lit {
litNodeClient: LitJsSdk.LitNodeClient
) {
this.signer = signer;
this.address = address;
this.address = isValidSCWCAIP(address)
? address.split(':')[3]
: pCAIP10ToWallet(address);
this.chain = chain;
this.litNodeClient = litNodeClient;
// Access control conditions for encryption and decryption
Expand All @@ -33,22 +36,28 @@ export class Lit {
parameters: [':userAddress'],
returnValueTest: {
comparator: '=',
value: address,
value: this.address,
},
},
];
}

private async prepareSCWAuthSig(signer: SignerType, address: string) {
private async prepareSCWAuthSig(
signer: SignerType,
address: string,
chainId: number
) {
const domain = 'push.org';
const origin = 'https://app.push.org';
const statement = 'Create Push Profile';
const statement = 'Enable Push Profile';
const siweMessage = new siwe.SiweMessage({
domain,
address,
statement,
uri: origin,
version: '1',
chainId,
expirationTime: new Date(Date.now() + 1000 * 60 * 60 * 24).toISOString(),
});
const messageToSign = siweMessage.prepareMessage();

Expand All @@ -58,18 +67,29 @@ export class Lit {
const authSig = {
sig: signature,
derivedVia: 'EIP1271',
signedMessage: messageToSign,
signedMessage: viem.hashMessage(messageToSign),
address,
};
return authSig;
}

public async encrypt(dataToEncrypt: string) {
const authSig = await this.prepareSCWAuthSig(this.signer, this.address);
public async encrypt(dataToEncrypt: string, chainId: number) {
const authSig = await this.prepareSCWAuthSig(
this.signer,
this.address,
chainId
);

console.log(authSig);
console.log(this.accessControlConditions);
console.log(this.chain);
console.log(dataToEncrypt);

const { ciphertext, dataToEncryptHash } = await LitJsSdk.encryptString(
{
accessControlConditions: this.accessControlConditions,
authSig,
// `ethereum` chain is valid for all EVM chains
chain: this.chain,
dataToEncrypt,
},
Expand All @@ -84,11 +104,22 @@ export class Lit {

public async decrypt(
ciphertext: string,
dataToEncryptHash: string
dataToEncryptHash: string,
chainId: number
): Promise<string> {
const authSig = await this.prepareSCWAuthSig(this.signer, this.address);
const authSig = await this.prepareSCWAuthSig(
this.signer,
this.address,
chainId
);

console.log(authSig);
console.log(this.accessControlConditions);
console.log(this.chain);
console.log(dataToEncryptHash);
console.log(ciphertext);

return LitJsSdk.decryptToString(
return await LitJsSdk.decryptToString(
{
accessControlConditions: this.accessControlConditions,
ciphertext,
Expand All @@ -112,12 +143,7 @@ export class Lit {
litNetwork: env === ENV.PROD ? 'habanero' : 'manzano',
});
await litNodeClient.connect();
this.LitInstance = new Lit(
signer,
pCAIP10ToWallet(address),
chain,
LitNodeClient
);
this.LitInstance = new Lit(signer, address, chain, litNodeClient);
}
return this.LitInstance;
}
Expand Down
17 changes: 17 additions & 0 deletions packages/restapi/src/lib/helpers/signer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,4 +86,21 @@ export class Signer {
return 1; // Return default chainId
}
}

async isSmartContract(): Promise<boolean> {
let code: string;
const address = await this.getAddress();
if (this.isViemSigner(this.signer)) {
// Viem signer has a direct method for getCode
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
code = await this.signer.getBytecode({ address });
} else if ('provider' in this.signer && this.signer.provider) {
// EthersV5 and EthersV6
code = await this.signer.provider.getCode(address);
} else {
code = '0x'; // Return default
}
return code !== '0x';
}
}
Loading

0 comments on commit d975afe

Please sign in to comment.