From e053d29574dbc9da7816579b305abe37e82fdfcb Mon Sep 17 00:00:00 2001 From: Felix Hildebrandt Date: Fri, 12 Apr 2024 18:45:17 +0200 Subject: [PATCH 1/5] update erc725.js --- bun.lockb | Bin 279109 -> 279109 bytes package.json | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/bun.lockb b/bun.lockb index 518c5575ef695944ccecb7941f4407d74ea7ee5d..16826dde17e1ab0d8ab2955a7bdf4f04657fb434 100755 GIT binary patch delta 163 zcmV;U09^mYgb~Gr5s)q*mnJ+;^{41CAyqS}qe!vy2ey-5ByE%3e&>z1I!LH|u}+rR z0T`3vMk|95+P4te0reX|d4beWqWR^2gu<<+6~vCHjGQwvP(FmZAHp>bxQtH3Sj4N% zxj9X7N~bcUE7%UN=iV7kPd_4A!>{;`k$F?$w?*~=dF=x`Op*Wq delta 163 zcmV;U09^mYgb~Gr5s)q*Hy4{`Md`<`b%S(}?faV1F;EzZZGMW$xvH|8vHM0mu}+rR z0T+`YH!Fh>+P4te0reX|7?X0~t?sqlo$=(7hhB56e`Ibd`eDZ*ic1L*9x^ed8+F6j`q}3QNsETty8Pm_yfa;iw?*~=dF=x;E-;6|;{vzA;{#h<0W+6D Ro&zD5;JyP5w@W|-`T^Y6PWS)- diff --git a/package.json b/package.json index b9ae6c7..a7808a9 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,7 @@ "lint:fix": "eslint . --fix" }, "devDependencies": { - "@erc725/erc725.js": "^0.23.0", + "@erc725/erc725.js": "^0.24.2", "@lukso/lsp-smart-contracts": "^0.14.0", "@typescript-eslint/eslint-plugin": "^6.20.0", "@typescript-eslint/parser": "^6.20.0", From f1ae0ed1fa8bb16d02ca2b4e2c50c09b777e44a1 Mon Sep 17 00:00:00 2001 From: Felix Hildebrandt Date: Fri, 12 Apr 2024 18:46:49 +0200 Subject: [PATCH 2/5] add .env for private keys --- .gitignore | 3 ++- key-manager/.env.example | 2 ++ key-manager/execute-relay-call.ts | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) create mode 100644 key-manager/.env.example diff --git a/.gitignore b/.gitignore index 28f1ba7..9bdf355 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ node_modules -.DS_Store \ No newline at end of file +.DS_Store +.env \ No newline at end of file diff --git a/key-manager/.env.example b/key-manager/.env.example new file mode 100644 index 0000000..fb80cc2 --- /dev/null +++ b/key-manager/.env.example @@ -0,0 +1,2 @@ +PRIVATE_KEY=0x... +UP_ADDR=0x... \ No newline at end of file diff --git a/key-manager/execute-relay-call.ts b/key-manager/execute-relay-call.ts index 180d460..b5fc8e3 100644 --- a/key-manager/execute-relay-call.ts +++ b/key-manager/execute-relay-call.ts @@ -14,7 +14,7 @@ const universalProfileAddress = '0x...'; const recipientAddress = '0x...'; // Setup the Universal Profile controller account -const controllerPrivateKey = '0x...'; +const controllerPrivateKey = process.env.PRIVATE_KEY || ''; const controllerAccount = new ethers.Wallet(controllerPrivateKey).connect( provider, ); From bb4e48c146f87629b8f289af9b91a12bdfb5d008 Mon Sep 17 00:00:00 2001 From: Felix Hildebrandt Date: Fri, 12 Apr 2024 18:47:15 +0200 Subject: [PATCH 3/5] remove outdated permission guide --- key-manager/set-permissions.ts | 64 ---------------------------------- 1 file changed, 64 deletions(-) delete mode 100644 key-manager/set-permissions.ts diff --git a/key-manager/set-permissions.ts b/key-manager/set-permissions.ts deleted file mode 100644 index f055e8b..0000000 --- a/key-manager/set-permissions.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { ethers } from 'ethers'; -import { - PERMISSIONS, - ERC725YDataKeys, -} from '@lukso/lsp-smart-contracts/constants'; -import UniversalProfile from '@lukso/lsp-smart-contracts/artifacts/UniversalProfile.json'; - -// Connect to the LUKSO Testnet -const RPC_ENDPOINT = 'https://rpc.testnet.lukso.network'; -const provider = new ethers.JsonRpcProvider(RPC_ENDPOINT); - -const myUniversalProfileAddress = '0x9fc7e5095A054dfA3c6b237E0e5d686638394248'; -const myKeyManagerAddress = '0x87fa9105cA247897Acb4F12Ddf6EC3CEF23F6059'; - -const walletPrivateKey = - '0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80'; // Replace with your wallet's private key -const wallet = new ethers.Wallet(walletPrivateKey, provider); - -const universalProfile = new ethers.Contract( - myUniversalProfileAddress, - UniversalProfile.abi, - wallet, -); - -// EOA address of an exemplary person -const bobAddress = '0xcafecafecafecafecafecafecafecafecafecafe'; -const bobPermissions = PERMISSIONS.SETDATA; - -// give the permission SETDATA to Bob -async function setPermission() { - try { - const permissionData = [ - ERC725YDataKeys.LSP6['AddressPermissions:Permissions'] + - bobAddress.substring(2), // allow Bob to setData on your UP - ERC725YDataKeys.LSP6['AddressPermissions[]'].length, // length of AddressPermissions[] - ERC725YDataKeys.LSP6['AddressPermissions[]'].index + - '00000000000000000000000000000001', // add Bob's address into the list of permissions - ]; - - const permissionParams = [ - bobPermissions, - 3, // 3 because UP owner + Universal Receiver Delegate permission have already been set on profile creation - bobAddress, - ]; - - const tx = await universalProfile.setDataBatch.populateTransaction( - permissionData, - permissionParams, - ); - - const txResponse = await wallet.sendTransaction({ - to: myKeyManagerAddress, - data: tx.data, - gasLimit: 300000, - }); - - await txResponse.wait(); - console.log('Permission set successfully.'); - } catch (error) { - console.error('Error:', error); - } -} - -setPermission(); From 3081241ad7843ad02fba29c92502b60805572aa0 Mon Sep 17 00:00:00 2001 From: Felix Hildebrandt Date: Fri, 12 Apr 2024 18:47:23 +0200 Subject: [PATCH 4/5] add new permission guide --- key-manager/grant-permissions.ts | 86 ++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 key-manager/grant-permissions.ts diff --git a/key-manager/grant-permissions.ts b/key-manager/grant-permissions.ts new file mode 100644 index 0000000..04ac1cd --- /dev/null +++ b/key-manager/grant-permissions.ts @@ -0,0 +1,86 @@ +import { ethers } from 'ethers'; +import { ERC725 } from '@erc725/erc725.js'; +import LSP6Schema from '@erc725/erc725.js/schemas/LSP6KeyManager.json'; +import UniversalProfileArtefact from '@lukso/lsp-smart-contracts/artifacts/UniversalProfile.json'; + +const myUniversalProfileAddress = process.env.UP_ADDR || ''; + +const RPC_ENDPOINT = 'https://4201.rpc.thirdweb.com'; +const provider = new ethers.JsonRpcProvider(RPC_ENDPOINT); + +// Initialize erc725.js with the permission data keys from LSP6 Key Manager +const erc725 = new ERC725( + LSP6Schema, + myUniversalProfileAddress, + RPC_ENDPOINT, + {}, +); + +// Create the permissions for the beneficiary address +const beneficiaryPermissions = erc725.encodePermissions({ + SETDATA: true, +}); + +// EOA address of the new controller +const myBeneficiaryAddress = '0xcafecafecafecafecafecafecafecafecafecafe'; + +// Retrieve the current controllers of the Universal Profile +const addressPermissionsArray = await erc725.getData('AddressPermissions[]'); +let currentControllerAddresses = null; +let currentControllerLength: number = 0; + +if (Array.isArray(addressPermissionsArray.value)) { + currentControllerAddresses = addressPermissionsArray.value; + currentControllerLength = currentControllerAddresses.length; +} + +// Encode the key-value pairs of the controller permission +const permissionData = erc725.encodeData([ + // the permission of the beneficiary address + { + keyName: 'AddressPermissions:Permissions:
', + dynamicKeyParts: myBeneficiaryAddress, + value: beneficiaryPermissions, + }, + // The new incremented list of permissioned controllers addresses + { + keyName: 'AddressPermissions[]', + value: [myBeneficiaryAddress], + startingIndex: currentControllerLength, + totalArrayLength: currentControllerLength + 1, + }, +]); + +// Private key to sign the transaction +const PRIVATE_KEY = process.env.PRIVATE_KEY || ''; + +// Existing UP controller +const controller = new ethers.Wallet(PRIVATE_KEY).connect(provider); + +// instantiate the Universal Profile +const myUniversalProfile = new ethers.Contract( + myUniversalProfileAddress, + UniversalProfileArtefact.abi, +); + +// Execute the transaction +await myUniversalProfile + .connect(controller) + // @ts-expect-error Ethers BaseContract does not pick dynamic types from ABIs + .setData(permissionData.keys, permissionData.values); + +const updatedPermissions = await erc725.getData({ + keyName: 'AddressPermissions:Permissions:
', + dynamicKeyParts: myBeneficiaryAddress, +}); + +if (updatedPermissions && typeof updatedPermissions.value === 'string') { + console.log( + `The beneficiary address ${myBeneficiaryAddress} has the following permissions:`, + erc725.decodePermissions(updatedPermissions.value), + ); +} else { + console.error( + `No permissions for beneficiary address ${myBeneficiaryAddress} found`, + ); +} From 41fcf3d8493061c147d83ba259e4d079e8f24143 Mon Sep 17 00:00:00 2001 From: Felix Hildebrandt Date: Tue, 16 Apr 2024 11:51:09 +0200 Subject: [PATCH 5/5] apply suggestion + add try-catch --- key-manager/grant-permissions.ts | 46 +++++++++++++++++--------------- 1 file changed, 25 insertions(+), 21 deletions(-) diff --git a/key-manager/grant-permissions.ts b/key-manager/grant-permissions.ts index 04ac1cd..7e2f6fb 100644 --- a/key-manager/grant-permissions.ts +++ b/key-manager/grant-permissions.ts @@ -1,7 +1,7 @@ import { ethers } from 'ethers'; import { ERC725 } from '@erc725/erc725.js'; import LSP6Schema from '@erc725/erc725.js/schemas/LSP6KeyManager.json'; -import UniversalProfileArtefact from '@lukso/lsp-smart-contracts/artifacts/UniversalProfile.json'; +import UniversalProfileArtifact from '@lukso/lsp-smart-contracts/artifacts/UniversalProfile.json'; const myUniversalProfileAddress = process.env.UP_ADDR || ''; @@ -27,7 +27,7 @@ const myBeneficiaryAddress = '0xcafecafecafecafecafecafecafecafecafecafe'; // Retrieve the current controllers of the Universal Profile const addressPermissionsArray = await erc725.getData('AddressPermissions[]'); let currentControllerAddresses = null; -let currentControllerLength: number = 0; +let currentControllerLength = 0; if (Array.isArray(addressPermissionsArray.value)) { currentControllerAddresses = addressPermissionsArray.value; @@ -60,27 +60,31 @@ const controller = new ethers.Wallet(PRIVATE_KEY).connect(provider); // instantiate the Universal Profile const myUniversalProfile = new ethers.Contract( myUniversalProfileAddress, - UniversalProfileArtefact.abi, + UniversalProfileArtifact.abi, ); -// Execute the transaction -await myUniversalProfile - .connect(controller) - // @ts-expect-error Ethers BaseContract does not pick dynamic types from ABIs - .setData(permissionData.keys, permissionData.values); +try { + // Execute the transaction + await myUniversalProfile + .connect(controller) + // @ts-expect-error Ethers BaseContract does not pick dynamic types from ABIs + .setData(permissionData.keys, permissionData.values); -const updatedPermissions = await erc725.getData({ - keyName: 'AddressPermissions:Permissions:
', - dynamicKeyParts: myBeneficiaryAddress, -}); + const updatedPermissions = await erc725.getData({ + keyName: 'AddressPermissions:Permissions:
', + dynamicKeyParts: myBeneficiaryAddress, + }); -if (updatedPermissions && typeof updatedPermissions.value === 'string') { - console.log( - `The beneficiary address ${myBeneficiaryAddress} has the following permissions:`, - erc725.decodePermissions(updatedPermissions.value), - ); -} else { - console.error( - `No permissions for beneficiary address ${myBeneficiaryAddress} found`, - ); + if (updatedPermissions && typeof updatedPermissions.value === 'string') { + console.log( + `The beneficiary address ${myBeneficiaryAddress} has the following permissions:`, + erc725.decodePermissions(updatedPermissions.value), + ); + } else { + console.error( + `No permissions for beneficiary address ${myBeneficiaryAddress} found`, + ); + } +} catch (error) { + console.error('Could not execute the controller update:', error); }