Skip to content

Commit

Permalink
Merge pull request #54 from DeezStealth/boris
Browse files Browse the repository at this point in the history
fixed and refactored upRegistry, contracts in README, LSP24 verification
  • Loading branch information
bshevchenko authored Nov 30, 2023
2 parents 28a9ae6 + e478571 commit 69f0030
Show file tree
Hide file tree
Showing 9 changed files with 289 additions and 147 deletions.
16 changes: 14 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,13 @@ It leverages [Lukso Network](https://lukso.network/), [Univeral Profiles browser

✅ Chainlink Functions are currently not supported on Lukso networks, so users can connect with both their Polygon Mumbai wallet and their Universal Profile browser extension to deploy their Universal Profile onto Polygon Mumbai where Chainlink Functions are supported.

✅ LSP24 (experimental) verification of user's Universal Profiles.

✅ Profile page where users can connect their web2/web3 accounts and see all information associated with them, as well as users original Lukso Mainnet Universal Profiles metadata.

✅ Discover Profiles page that lists a directory of all upDev developers.

[TODO] deploy UP on Polygon Mumbai AT THE SAME ADDRESS using LSP23<br />
[TODO] implement LSP24 to link UPs on different chains
[TODO] deploy UP on Polygon Mumbai AT THE SAME ADDRESS using LSP23

## Integrations

Expand Down Expand Up @@ -63,6 +64,17 @@ run the app

`yarn start`

## Verified Smart Contracts

upDevAccountOwnership (LSP8 – NFT 2.0 Soulbound Collection)
https://mumbai.polygonscan.com/address/0x9fc4937f337A7f20F290a4f532b7b2A8CB5BeDBf

upDevFunctionsConsumer (Chainlink Functions Consumer & Minter)
https://mumbai.polygonscan.com/address/0xaBc51E822d1F590615145B02B8a67Cca56CD612D

upRegistry (upDev Profiles Registry)
https://mumbai.polygonscan.com/address/0xB665840C5929d140494708A619dA834d944d8CBC

### Technologies Used

- [scaffold-eth-2](https://scaffoldeth.io/)
Expand Down
58 changes: 29 additions & 29 deletions packages/hardhat/contracts/upRegistry.sol
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

interface ILSP6KeyManager {
/**
* @dev Get The address of the contract linked to this Key Manager.
* @return The address of the linked contract
*/
function target() external view returns (address);
}
import { ERC725Y } from "@erc725/smart-contracts/contracts/ERC725Y.sol";
import { LSP6Utils } from "@lukso/lsp-smart-contracts/contracts/LSP6KeyManager/LSP6Utils.sol";
import { _PERMISSION_SIGN } from "@lukso/lsp-smart-contracts/contracts/LSP6KeyManager/LSP6Constants.sol";

interface ERC725Y {
function getPermissionsFor(address) external view returns (bytes32);
interface ILSP6KeyManager {
/**
* @dev Get The address of the contract linked to this Key Manager.
* @return The address of the linked contract
*/
function target() external view returns (address);
}

contract upRegistry {
using LSP6Utils for *;

struct Profile {
address up;
Expand All @@ -22,42 +23,41 @@ contract upRegistry {
address eoa;
}

mapping (address => Profile) public upByEOA; // TODO no duplicate
mapping (address => Profile) public up;
Profile[] public _ups;
mapping(address => Profile) public up;
mapping(address => address) public _upByEOA;
address[] public _ups;

error InvalidKeyManager();
error NoPermissionsSet();

function target(address km) public view returns (address) {
return ILSP6KeyManager(km).target();
}
error NoPermissions();

function permissions(address _up) public view returns (bytes32) {
return ERC725Y(_up).getPermissionsFor(msg.sender);
function upByEOA(address eoa) external returns (Profile memory) {
return up[_upByEOA[eoa]];
}

function setUp(address _up, address _km, address _upLukso) public {

if (ILSP6KeyManager(_km).target() != _up) {
revert InvalidKeyManager();
}
if (!ERC725Y(_up).getPermissionsFor(msg.sender).hasPermission(_PERMISSION_SIGN)) {
revert NoPermissions();
}

// bytes32 permissions = ERC725Y(_up).getPermissionsFor(msg.sender); TODO reverts, prob wrong version
// if (permissions == bytes32(0)) revert NoPermissionsSet();

Profile memory p = Profile({
up[_up] = Profile({
up: _up,
keyManager: _km,
upLukso: _upLukso,
eoa: msg.sender
});
upByEOA[msg.sender] = p;
up[_up] = p;
_ups.push(p);
_upByEOA[msg.sender] = _up;
_ups.push(_up);
}

function ups() public view returns (Profile[] memory) {
return _ups;
function ups() external view returns (Profile[] memory) {
uint256 upsCount = _ups.length;
Profile[] memory profiles = new Profile[](upsCount);
for (uint256 i = 0; i < upsCount; i++) {
profiles[i] = up[_ups[i]];
}
return profiles;
}
}
72 changes: 72 additions & 0 deletions packages/nextjs/LSP3ProfileMetadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
[
{
"name": "SupportedStandards:LSP3Profile",
"key": "0xeafec4d89fa9619884b600005ef83ad9559033e6e941db7d7c495acdce616347",
"keyType": "Mapping",
"valueType": "bytes4",
"valueContent": "0x5ef83ad9"
},
{
"name": "LSP3Profile",
"key": "0x5ef83ad9559033e6e941db7d7c495acdce616347d28e90c7ce47cbfcfcad3bc5",
"keyType": "Singleton",
"valueType": "bytes",
"valueContent": "JSONURL"
},
{
"name": "LSP12IssuedAssets[]",
"key": "0x7c8c3416d6cda87cd42c71ea1843df28ac4850354f988d55ee2eaa47b6dc05cd",
"keyType": "Array",
"valueType": "address",
"valueContent": "Address"
},
{
"name": "LSP12IssuedAssetsMap:<address>",
"key": "0x74ac2555c10b9349e78f0000<address>",
"keyType": "Mapping",
"valueType": "(bytes4,uint128)",
"valueContent": "(Bytes4,Number)"
},
{
"name": "LSP5ReceivedAssets[]",
"key": "0x6460ee3c0aac563ccbf76d6e1d07bada78e3a9514e6382b736ed3f478ab7b90b",
"keyType": "Array",
"valueType": "address",
"valueContent": "Address"
},
{
"name": "LSP5ReceivedAssetsMap:<address>",
"key": "0x812c4334633eb816c80d0000<address>",
"keyType": "Mapping",
"valueType": "(bytes4,uint128)",
"valueContent": "(Bytes4,Number)"
},
{
"name": "LSP1UniversalReceiverDelegate",
"key": "0x0cfc51aec37c55a4d0b1a65c6255c4bf2fbdf6277f3cc0730c45b828b6db8b47",
"keyType": "Singleton",
"valueType": "address",
"valueContent": "Address"
},
{
"name": "LSP1UniversalReceiverDelegate:<bytes32>",
"key": "0x0cfc51aec37c55a4d0b10000<bytes32>",
"keyType": "Mapping",
"valueType": "address",
"valueContent": "Address"
},
{
"name": "LSP17Extension:<bytes4>",
"key": "0xcee78b4094da860110960000<bytes4>",
"keyType": "Mapping",
"valueType": "address",
"valueContent": "Address"
},
{
"name": "LSP24MultichainAddressResolutionPolygon",
"key": "0xc5e773c54da703f2723fb8f3553ae61f92dffc427a27a6f89484d24befd75efe",
"keyType": "Singleton",
"valueType": "address",
"valueContent": "Address"
}
]
18 changes: 10 additions & 8 deletions packages/nextjs/components/updev/ConnectSocialAccounts.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { CopyToClipboard } from "react-copy-to-clipboard";
import { useAccount, useWalletClient } from "wagmi";
import { ArrowTopRightOnSquareIcon, CheckCircleIcon, DocumentDuplicateIcon } from "@heroicons/react/24/outline";
import { useScaffoldContract, useScaffoldContractRead, useScaffoldEventSubscriber } from "~~/hooks/scaffold-eth";
import Profile from "~~/types/Profile";

const socialAccounts = [
{
Expand Down Expand Up @@ -84,11 +85,12 @@ export const ConnectSocialAccounts = () => {
const [copied, setCopied] = useState(false);
const [id, setId] = useState("");

const { data: profile } = useScaffoldContractRead({
contractName: "upRegistry",
const { data: _profile } = useScaffoldContractRead({
contractName: "upRegistry", // @ts-ignore
functionName: "upByEOA",
args: [account.address],
});
}); // @ts-ignore
const profile: Profile | undefined = _profile;

const { data: walletClient } = useWalletClient();
const { data: consumer } = useScaffoldContract({
Expand All @@ -99,7 +101,7 @@ export const ConnectSocialAccounts = () => {
const { data: requests } = useScaffoldContractRead({
contractName: "upDevFunctionsConsumer",
functionName: "getUPRequests",
args: [profile && profile[0]],
args: [profile && profile.up],
});

useScaffoldEventSubscriber({
Expand All @@ -111,7 +113,7 @@ export const ConnectSocialAccounts = () => {
if (!profile) {
return;
}
if (up != profile[0]) {
if (up != profile.up) {
return; // TODO how to subscribe only to up's events?
}
if (isOwned) {
Expand Down Expand Up @@ -151,9 +153,9 @@ export const ConnectSocialAccounts = () => {
if (!consumer || !profile) {
return;
}
console.log("handleVerify", sourceName, id, profile[0]);
console.log("handleVerify", sourceName, id, profile.up);
try {
await consumer.write.sendRequest([877n, "0x", 0, 0n, sourceName, profile[0], id]);
await consumer.write.sendRequest([877n, "0x", 0, 0n, sourceName, profile.up, id]);
setActiveModal(null);
alert("Your account will appear on your page once it is verified.");
} catch (e) {
Expand All @@ -164,7 +166,7 @@ export const ConnectSocialAccounts = () => {
const renderModalContent = (title: string) => {
const account = socialAccounts.find(account => account.title === title);

const link = `https://updev-v1.vercel.app/profile/${profile && profile[0]}`;
const link = `https://updev-v1.vercel.app/profile/${profile && profile.up}`;
return (
<div className="flex gap-5 items-center">
<div className="rounded-lg overflow-hidden">
Expand Down
Loading

0 comments on commit 69f0030

Please sign in to comment.