Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 278381b

Browse files
authored
Merge pull request #487 from LIT-Protocol/feature/lit-3125-sdk-for-wrapping-up-walletx-2
Feature/lit 3125 sdk for wrapping up walletx 2
2 parents c5206a6 + 7af4f67 commit 278381b

File tree

104 files changed

+4687
-879
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

104 files changed

+4687
-879
lines changed

.prettierignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,5 @@
1111
/tmp
1212
/packages/*/dist
1313
.nx
14-
tools
14+
tools
15+
**/*/dist

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ If you're a tech-savvy user and wish to utilize only specific submodules that ou
8080
| [@lit-protocol/sev-snp-utils-sdk](https://github.com/LIT-Protocol/js-sdk/tree/master/packages/sev-snp-utils-sdk) | ![sev-snp-utils-sdk](https://img.shields.io/badge/-universal-8A6496 'sev-snp-utils-sdk') | <a target="_blank" href="https://www.npmjs.com/package/@lit-protocol/sev-snp-utils-sdk"><img src="https://img.shields.io/npm/v/@lit-protocol/sev-snp-utils-sdk"/></a> |
8181
| [@lit-protocol/types](https://github.com/LIT-Protocol/js-sdk/tree/master/packages/types) | ![types](https://img.shields.io/badge/-universal-8A6496 'types') | <a target="_blank" href="https://www.npmjs.com/package/@lit-protocol/types"><img src="https://img.shields.io/npm/v/@lit-protocol/types"/></a> |
8282
| [@lit-protocol/uint8arrays](https://github.com/LIT-Protocol/js-sdk/tree/master/packages/uint8arrays) | ![uint8arrays](https://img.shields.io/badge/-universal-8A6496 'uint8arrays') | <a target="_blank" href="https://www.npmjs.com/package/@lit-protocol/uint8arrays"><img src="https://img.shields.io/npm/v/@lit-protocol/uint8arrays"/></a> |
83+
| [@lit-protocol/wrapped-keys](https://github.com/LIT-Protocol/js-sdk/tree/master/packages/wrapped-keys) | ![wrapped-keys](https://img.shields.io/badge/-universal-8A6496 'wrapped-keys') | <a target="_blank" href="https://www.npmjs.com/package/@lit-protocol/wrapped-keys"><img src="https://img.shields.io/npm/v/@lit-protocol/wrapped-keys"/></a> |
8384
| [@lit-protocol/auth-browser](https://github.com/LIT-Protocol/js-sdk/tree/master/packages/auth-browser) | ![auth-browser](https://img.shields.io/badge/-browser-E98869 'auth-browser') | <a target="_blank" href="https://www.npmjs.com/package/@lit-protocol/auth-browser"><img src="https://img.shields.io/npm/v/@lit-protocol/auth-browser"/></a> |
8485
| [@lit-protocol/misc-browser](https://github.com/LIT-Protocol/js-sdk/tree/master/packages/misc-browser) | ![misc-browser](https://img.shields.io/badge/-browser-E98869 'misc-browser') | <a target="_blank" href="https://www.npmjs.com/package/@lit-protocol/misc-browser"><img src="https://img.shields.io/npm/v/@lit-protocol/misc-browser"/></a> |
8586

lerna.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22
"$schema": "node_modules/lerna/schemas/lerna-schema.json",
33
"useNx": true,
44
"useWorkspaces": true,
5-
"version": "6.0.3"
5+
"version": "6.0.3-wrapped-keys.beta.5"
66
}

local-tests/setup/session-sigs/get-pkp-session-sigs.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ import { TinnyPerson } from '../tinny-person';
88
export const getPkpSessionSigs = async (
99
devEnv: TinnyEnvironment,
1010
alice: TinnyPerson,
11-
resourceAbilityRequests?: LitResourceAbilityRequest[]
11+
resourceAbilityRequests?: LitResourceAbilityRequest[],
12+
expiration?: string
1213
) => {
1314
if (devEnv.litNodeClient.config.litNetwork === LitNetwork.Manzano) {
1415
console.warn(
@@ -31,6 +32,7 @@ export const getPkpSessionSigs = async (
3132
const pkpSessionSigs = await devEnv.litNodeClient.getPkpSessionSigs({
3233
pkpPublicKey: alice.authMethodOwnedPkp.publicKey,
3334
authMethods: [alice.authMethod],
35+
expiration,
3436
resourceAbilityRequests: _resourceAbilityRequests,
3537

3638
// -- only add this for manzano network

local-tests/setup/tinny-environment.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,29 @@ export class TinnyEnvironment {
391391
}
392392
//============= END SHIVA ENDPOINTS =============
393393

394+
/**
395+
* Sends funds from the current wallet to the specified wallet address.
396+
* @param walletAddress - The address of the recipient wallet.
397+
* @param amount - The amount of funds to send (default: '0.001').
398+
* @throws If there is an error sending the funds.
399+
*/
400+
getFunds = async (walletAddress: string, amount = '0.001') => {
401+
try {
402+
const privateKey = await this.getAvailablePrivateKey();
403+
const provider = new ethers.providers.JsonRpcBatchProvider(this.rpc);
404+
const wallet = new ethers.Wallet(privateKey.privateKey, provider);
405+
406+
const tx = await wallet.sendTransaction({
407+
to: walletAddress,
408+
value: ethers.utils.parseEther(amount),
409+
});
410+
411+
await tx.wait();
412+
} catch (e) {
413+
throw new Error(`Failed to send funds to ${walletAddress}: ${e}`);
414+
}
415+
};
416+
394417
/**
395418
* Context: the reason this is created instead of individually is because we can't allocate capacity beyond the global
396419
* max capacity.

local-tests/setup/tinny-utils.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,17 @@ export async function stringToIpfsHash(input: string): Promise<string> {
3131

3232
return ipfsHash;
3333
}
34+
35+
export function randomSolanaPrivateKey() {
36+
const BASE58_ALPHABET =
37+
'123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';
38+
const SOLANA_PRIVATE_KEY_LENGTH = 88;
39+
40+
let result = '';
41+
const charactersLength = BASE58_ALPHABET.length;
42+
for (let i = 0; i < SOLANA_PRIVATE_KEY_LENGTH; i++) {
43+
const randomIndex = Math.floor(Math.random() * charactersLength);
44+
result += BASE58_ALPHABET.charAt(randomIndex);
45+
}
46+
return result;
47+
}

local-tests/test.ts

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,12 +83,73 @@ import { testExecuteJsSignAndCombineEcdsa } from './tests/testExecuteJsSignAndCo
8383
import { testExecutJsDecryptAndCombine } from './tests/testExecuteJsDecryptAndCombine';
8484
import { testExecuteJsBroadcastAndCollect } from './tests/testExecuteJsBroadcastAndCollect';
8585

86+
import { testEthereumSignMessageGeneratedKey } from './tests/testEthereumSignMessageGeneratedKey';
87+
import { testEthereumBroadcastTransactionGeneratedKey } from './tests/testEthereumBroadcastTransactionGeneratedKey';
88+
import { testEthereumSignMessageWrappedKey } from './tests/testEthereumSignMessageWrappedKey';
89+
import { testFailEthereumSignTransactionWrappedKeyInvalidDecryption } from './tests/testFailEthereumSignTransactionWrappedKeyInvalidDecryption';
90+
import { testEthereumSignTransactionWrappedKey } from './tests/testEthereumSignTransactionWrappedKey';
91+
import { testFailEthereumSignTransactionWrappedKeyWithInvalidParam } from './tests/testFailEthereumSignTransactionWrappedKeyWithInvalidParam';
92+
import { testFailEthereumSignTransactionWrappedKeyWithMissingParam } from './tests/testFailEthereumSignTransactionWrappedKeyWithMissingParam';
93+
import { testEthereumBroadcastTransactionWrappedKey } from './tests/testEthereumBroadcastTransactionWrappedKey';
94+
import { testEthereumBroadcastWrappedKeyWithFetchGasParams } from './tests/testEthereumBroadcastWrappedKeyWithFetchGasParams';
95+
import { testFailEthereumBroadcastTransactionWrappedKeysInsufficientFunds } from './tests/testFailEthereumBroadcastTransactionWrappedKeysInsufficientFunds';
96+
import { testImportWrappedKey } from './tests/testImportWrappedKey';
97+
import { testGenerateEthereumWrappedKey } from './tests/testGenerateEthereumWrappedKey';
98+
import { testGenerateSolanaWrappedKey } from './tests/testGenerateSolanaWrappedKey';
99+
import { testFailImportWrappedKeysWithSamePkp } from './tests/testFailImportWrappedKeysWithSamePkp';
100+
import { testFailImportWrappedKeysWithSamePrivateKey } from './tests/testFailImportWrappedKeysWithSamePrivateKey';
101+
import { testFailImportWrappedKeysWithEoaSessionSig } from './tests/testFailImportWrappedKeysWithEoaSessionSig';
102+
import { testFailImportWrappedKeysWithMaxExpirySessionSig } from './tests/testFailImportWrappedKeysWithMaxExpirySessionSig';
103+
import { testFailImportWrappedKeysWithInvalidSessionSig } from './tests/testFailImportWrappedKeysWithInvalidSessionSig';
104+
import { testFailImportWrappedKeysWithExpiredSessionSig } from './tests/testFailImportWrappedKeysWithExpiredSessionSig';
105+
import { testExportWrappedKey } from './tests/testExportWrappedKey';
106+
import { testSignMessageWithSolanaEncryptedKey } from './tests/testSignMessageWithSolanaEncryptedKey';
107+
import { testSignTransactionWithSolanaEncryptedKey } from './tests/testSignTransactionWithSolanaEncryptedKey';
108+
86109
(async () => {
87110
console.log('[𐬺🧪 Tinny𐬺] Running tests...');
88111
const devEnv = new TinnyEnvironment();
89112

90113
await devEnv.init();
91114

115+
const wrappedKeysTests = {
116+
// -- valid cases
117+
testEthereumSignMessageGeneratedKey,
118+
testEthereumBroadcastTransactionGeneratedKey,
119+
testEthereumSignMessageWrappedKey,
120+
testEthereumSignTransactionWrappedKey,
121+
testEthereumBroadcastTransactionWrappedKey,
122+
testEthereumBroadcastWrappedKeyWithFetchGasParams,
123+
124+
// -- generate wrapped keys
125+
testGenerateEthereumWrappedKey,
126+
testGenerateSolanaWrappedKey,
127+
128+
// -- import wrapped keys
129+
testImportWrappedKey,
130+
131+
// -- export wrapped keys
132+
testExportWrappedKey,
133+
134+
// -- solana wrapped keys
135+
testSignMessageWithSolanaEncryptedKey,
136+
testSignTransactionWithSolanaEncryptedKey,
137+
138+
// -- invalid cases
139+
testFailEthereumSignTransactionWrappedKeyWithMissingParam,
140+
testFailEthereumSignTransactionWrappedKeyWithInvalidParam,
141+
testFailEthereumSignTransactionWrappedKeyInvalidDecryption,
142+
testFailEthereumBroadcastTransactionWrappedKeysInsufficientFunds,
143+
144+
// -- import wrapped keys
145+
testFailImportWrappedKeysWithSamePkp,
146+
testFailImportWrappedKeysWithSamePrivateKey,
147+
testFailImportWrappedKeysWithEoaSessionSig,
148+
testFailImportWrappedKeysWithMaxExpirySessionSig,
149+
testFailImportWrappedKeysWithInvalidSessionSig,
150+
testFailImportWrappedKeysWithExpiredSessionSig,
151+
};
152+
92153
const eoaSessionSigsTests = {
93154
testUseEoaSessionSigsToExecuteJsSigning,
94155
testUseEoaSessionSigsToPkpSign,
@@ -233,6 +294,8 @@ import { testExecuteJsBroadcastAndCollect } from './tests/testExecuteJsBroadcast
233294
...litActionCombiningTests.broadcastAndCombine,
234295
...litActionCombiningTests.decryptAndCombine,
235296
...litActionCombiningTests.ecdsaSignAndCombine,
297+
298+
...wrappedKeysTests,
236299
},
237300
devEnv,
238301
};
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import { log } from '@lit-protocol/misc';
2+
import { ethers } from 'ethers';
3+
import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
4+
import { api, EthereumLitTransaction } from '@lit-protocol/wrapped-keys';
5+
import { getPkpSessionSigs } from 'local-tests/setup/session-sigs/get-pkp-session-sigs';
6+
7+
const { signTransactionWithEncryptedKey, generatePrivateKey } = api;
8+
9+
/**
10+
* Test Commands:
11+
* ✅ NETWORK=cayenne yarn test:local --filter=testEthereumBroadcastTransactionGeneratedKey
12+
* ✅ NETWORK=manzano yarn test:local --filter=testEthereumBroadcastTransactionGeneratedKey
13+
* ✅ NETWORK=localchain yarn test:local --filter=testEthereumBroadcastTransactionGeneratedKey
14+
*/
15+
export const testEthereumBroadcastTransactionGeneratedKey = async (
16+
devEnv: TinnyEnvironment
17+
) => {
18+
const alice = await devEnv.createRandomPerson();
19+
20+
const pkpSessionSigs = await getPkpSessionSigs(
21+
devEnv,
22+
alice,
23+
null,
24+
new Date(Date.now() + 1000 * 60 * 10).toISOString()
25+
); // 10 mins expiry
26+
27+
console.log(pkpSessionSigs);
28+
29+
const { pkpAddress, generatedPublicKey } = await generatePrivateKey({
30+
pkpSessionSigs,
31+
network: 'evm',
32+
litNodeClient: devEnv.litNodeClient,
33+
});
34+
35+
const generatedKeysWalletAddress =
36+
ethers.utils.computeAddress(generatedPublicKey);
37+
console.log(`Sending funds to ${generatedKeysWalletAddress}`);
38+
await devEnv.getFunds(generatedKeysWalletAddress, '0.005');
39+
40+
const alicePkpAddress = alice.authMethodOwnedPkp.ethAddress;
41+
if (pkpAddress !== alicePkpAddress) {
42+
throw new Error(
43+
`Received address: ${pkpAddress} doesn't match Alice's PKP address: ${alicePkpAddress}`
44+
);
45+
}
46+
47+
const pkpSessionSigsSigning = await getPkpSessionSigs(
48+
devEnv,
49+
alice,
50+
null,
51+
new Date(Date.now() + 1000 * 60 * 10).toISOString()
52+
); // 10 mins expiry
53+
54+
console.log(pkpSessionSigsSigning);
55+
56+
const unsignedTransaction: EthereumLitTransaction = {
57+
toAddress: alice.wallet.address,
58+
value: '0.0001', // in ethers (Lit tokens)
59+
chainId: 175177, // Chronicle
60+
gasPrice: '0.001',
61+
gasLimit: 30000,
62+
dataHex: ethers.utils.hexlify(
63+
ethers.utils.toUtf8Bytes('Test transaction from Alice to bob')
64+
),
65+
chain: 'chronicleTestnet',
66+
};
67+
68+
const signedTx = await signTransactionWithEncryptedKey({
69+
pkpSessionSigs: pkpSessionSigsSigning,
70+
network: 'evm',
71+
unsignedTransaction,
72+
broadcast: true,
73+
litNodeClient: devEnv.litNodeClient,
74+
});
75+
76+
console.log('signedTx');
77+
console.log(signedTx);
78+
79+
if (!ethers.utils.isHexString(signedTx)) {
80+
throw new Error(`signedTx isn't hex: ${signedTx}`);
81+
}
82+
83+
log('✅ testEthereumBroadcastTransactionGeneratedKey');
84+
};
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
import { log } from '@lit-protocol/misc';
2+
import { ethers } from 'ethers';
3+
import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
4+
import { api, EthereumLitTransaction } from '@lit-protocol/wrapped-keys';
5+
import { getPkpSessionSigs } from 'local-tests/setup/session-sigs/get-pkp-session-sigs';
6+
7+
const { importPrivateKey, signTransactionWithEncryptedKey } = api;
8+
9+
/**
10+
* Test Commands:
11+
* ✅ NETWORK=cayenne yarn test:local --filter=testEthereumBroadcastTransactionWrappedKey
12+
* ✅ NETWORK=manzano yarn test:local --filter=testEthereumBroadcastTransactionWrappedKey
13+
* ✅ NETWORK=localchain yarn test:local --filter=testEthereumBroadcastTransactionWrappedKey
14+
*/
15+
export const testEthereumBroadcastTransactionWrappedKey = async (
16+
devEnv: TinnyEnvironment
17+
) => {
18+
const alice = await devEnv.createRandomPerson();
19+
20+
const pkpSessionSigs = await getPkpSessionSigs(
21+
devEnv,
22+
alice,
23+
null,
24+
new Date(Date.now() + 1000 * 60 * 10).toISOString()
25+
); // 10 mins expiry
26+
27+
console.log(pkpSessionSigs);
28+
29+
const wrappedKeysWallet = ethers.Wallet.createRandom();
30+
const wrappedKeysWalletPrivateKey = wrappedKeysWallet.privateKey;
31+
32+
const wrappedKeysWalletAddress = wrappedKeysWallet.address;
33+
console.log(`Sending funds to ${wrappedKeysWalletAddress}`);
34+
await devEnv.getFunds(wrappedKeysWallet.address, '0.005');
35+
36+
const pkpAddress = await importPrivateKey({
37+
pkpSessionSigs,
38+
privateKey: wrappedKeysWalletPrivateKey,
39+
litNodeClient: devEnv.litNodeClient,
40+
publicKey: '0xdeadbeef',
41+
keyType: 'K256',
42+
});
43+
44+
const alicePkpAddress = alice.authMethodOwnedPkp.ethAddress;
45+
if (pkpAddress !== alicePkpAddress) {
46+
throw new Error(
47+
`Received address: ${pkpAddress} doesn't match Alice's PKP address: ${alicePkpAddress}`
48+
);
49+
}
50+
51+
const pkpSessionSigsSigning = await getPkpSessionSigs(
52+
devEnv,
53+
alice,
54+
null,
55+
new Date(Date.now() + 1000 * 60 * 10).toISOString()
56+
); // 10 mins expiry
57+
58+
console.log(pkpSessionSigsSigning);
59+
60+
const unsignedTransaction: EthereumLitTransaction = {
61+
toAddress: alice.wallet.address,
62+
value: '0.0001', // in ethers (Lit tokens)
63+
chainId: 175177, // Chronicle
64+
gasPrice: '0.001',
65+
gasLimit: 30000,
66+
dataHex: ethers.utils.hexlify(
67+
ethers.utils.toUtf8Bytes('Test transaction from Alice to bob')
68+
),
69+
chain: 'chronicleTestnet',
70+
};
71+
72+
const signedTx = await signTransactionWithEncryptedKey({
73+
pkpSessionSigs: pkpSessionSigsSigning,
74+
network: 'evm',
75+
unsignedTransaction,
76+
broadcast: true,
77+
litNodeClient: devEnv.litNodeClient,
78+
});
79+
80+
console.log('signedTx');
81+
console.log(signedTx);
82+
83+
// TODO: Get the raw input from the tx hash, convert it to UTF-8 and assert that it contains "Test transaction from Alice to bob"
84+
if (!ethers.utils.isHexString(signedTx)) {
85+
throw new Error(`signedTx isn't hex: ${signedTx}`);
86+
}
87+
88+
log('✅ testEthereumBroadcastTransactionWrappedKey');
89+
};

0 commit comments

Comments
 (0)