Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

hotfix: Single entry per stream rather than global #122

Merged
merged 1 commit into from Sep 6, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
37 changes: 27 additions & 10 deletions components/atoms/VerifyNode.js
Expand Up @@ -19,7 +19,11 @@ const getWeb3SignatureFaucetContents = (hoprAddress, ethAddress) => ({
ethAddress,
});

const getWeb3SignatureVerifyContents = (hoprAddress, hoprSignature, ethAddress) => ({
const getWeb3SignatureVerifyContents = (
hoprAddress,
hoprSignature,
ethAddress
) => ({
hoprAddress,
hoprSignature,
ethAddress,
Expand Down Expand Up @@ -160,7 +164,11 @@ export const VerifyNode = ({ idx, copyCodeToClipboard }) => {
};

const signSignature = async (hoprAddress, hoprSignature, ethAddress) => {
const message = getWeb3SignatureVerifyContents(hoprAddress, hoprSignature, ethAddress);
const message = getWeb3SignatureVerifyContents(
hoprAddress,
hoprSignature,
ethAddress
);
const signature = await library
.getSigner()
._signTypedData(
Expand Down Expand Up @@ -338,16 +346,15 @@ export const VerifyNode = ({ idx, copyCodeToClipboard }) => {
Now, copy your Ethereum address (the one you want your NFT rewards to
go to and you can use for signing, usually your MetaMask one) and go
to the admin interface of your HOPR node. Using the command “sign”,
sign your copied address and paste the result here. e.g. “sign
{' '}{account}”
sign your copied address and paste the result here. e.g. “sign{" "}
{account}”
</small>
<br />
<br />
<small>
Copy and paste the contents of the sign function in the following text
field and click on “Verify node for rewards”. If valid, your node
will then be shown as verified in our network with your Ethereum
address.
field and click on “Verify node for rewards”. If valid, your node will
then be shown as verified in our network with your Ethereum address.
</small>
<div display="block" style={{ marginTop: "5px" }}>
<textarea
Expand All @@ -361,14 +368,24 @@ export const VerifyNode = ({ idx, copyCodeToClipboard }) => {
<button
disabled={!signatureValue || isLoading}
onClick={async () => {
let message;
setLoading(true);
const message = await signSignature(inputValue, signatureValue, account);
setLoading(false);
try {
message = await signSignature(
inputValue,
signatureValue,
account
);
setLoading(false);
} catch (e) {
message = "Server error, please try again later.";
setLoading(false);
}
alert(message);
}}
style={{ backgroundColor: "rgba(248, 114, 54, 0.5)" }}
>
{ isLoading ? 'Adding your node' : 'Verify node for rewards' }
{isLoading ? "Adding your node" : "Verify node for rewards"}
</button>
</div>
</div>
Expand Down
2 changes: 1 addition & 1 deletion constants/ceramic.js
Expand Up @@ -4,4 +4,4 @@ export const CERAMIC_IDX_ALIASES = {
alias1: "basicProfile",
};
export const CERAMIC_IDX_HOPR_NAMESPACE = 'hopr-wildhorn'
export const CERAMIC_TILE_ID = 'kjzl6cwe1jw1468n6gtygg5kdg0j69treni29fruvwxvatff9ebb4p4q995fv4i'
export const OLD_CERAMIC_TILE_ID = 'kjzl6cwe1jw1468n6gtygg5kdg0j69treni29fruvwxvatff9ebb4p4q995fv4i'
20 changes: 15 additions & 5 deletions pages/api/sign/get/[address].js
Expand Up @@ -5,7 +5,7 @@ import CeramicClient from "@ceramicnetwork/http-client";
import { TileDocument } from "@ceramicnetwork/stream-tile";
import {
CERAMIC_API_URL,
CERAMIC_TILE_ID,
OLD_CERAMIC_TILE_ID
} from "../../../../constants/ceramic";

import { utils } from "ethers";
Expand All @@ -16,19 +16,29 @@ const secretKey = Uint8Array.from(
const provider = new Ed25519Provider(secretKey);
const did = new DID({ provider, resolver: KeyResolver.getResolver() });
const client = new CeramicClient(CERAMIC_API_URL);
const tileId = CERAMIC_TILE_ID;

const filterPerAddress = (records, address) => Object.keys(records.content).filter(hoprNode => records.content[hoprNode] == address);

export default async (req, res) => {
const { address } = req.query;
await did.authenticate();
client.setDID(did);

const records = await TileDocument.load(client, tileId);
const addressRecords = Object.keys(records.content).filter(hoprNode => records.content[hoprNode] == address);
const oldRecords = await TileDocument.load(client, OLD_CERAMIC_TILE_ID);
const records = await TileDocument.create(
client,
null,
{ deterministic: true, family: "hopr-wildhorn", tags: [address] },
{ anchor: false, publish: false }
);

const addressRecords = filterPerAddress(records, address);
const oldAddressRecords = filterPerAddress(oldRecords, address);

return res.status(200).json({
status: "ok",
tileId,
tileId: records.id.toString(),
records: addressRecords,
oldRecords: oldAddressRecords
});
};
24 changes: 10 additions & 14 deletions pages/api/sign/get/all.js
Expand Up @@ -5,7 +5,7 @@ import CeramicClient from "@ceramicnetwork/http-client";
import { TileDocument } from "@ceramicnetwork/stream-tile";
import {
CERAMIC_API_URL,
CERAMIC_TILE_ID,
OLD_CERAMIC_TILE_ID,
} from "../../../../constants/ceramic";

import { utils } from "ethers";
Expand All @@ -16,28 +16,24 @@ const secretKey = Uint8Array.from(
const provider = new Ed25519Provider(secretKey);
const did = new DID({ provider, resolver: KeyResolver.getResolver() });
const client = new CeramicClient(CERAMIC_API_URL);
const tileId = CERAMIC_TILE_ID;

export default async (req, res) => {
const { flattened } = req.query;
await did.authenticate();
client.setDID(did);

const records = await TileDocument.load(client, tileId);

if (flattened) {
const ethAddress = Object.values(records.content);
const correspondingHoprNode = Object.keys(records.content);
return res.status(200).json({
status: "ok",
ethAddress,
correspondingHoprNode
})
}
const oldRecords = await TileDocument.load(client, OLD_CERAMIC_TILE_ID) || {};
const records = await TileDocument.create(
client,
null,
{ deterministic: true, family: "hopr-wildhorn", tags: ["hopr-dashboard"] },
{ anchor: false, publish: false }
);

return res.status(200).json({
status: "ok",
tileId,
tileId: records.id.toString(),
records: records.content,
oldRecords: oldRecords.content
});
};
23 changes: 18 additions & 5 deletions pages/api/sign/verify/[address].js
Expand Up @@ -9,11 +9,10 @@ import {
} from "../../../../constants/hopr";
import {
CERAMIC_API_URL,
CERAMIC_TILE_ID,
} from "../../../../constants/ceramic";

import { verifySignatureFromPeerId } from "@hoprnet/hopr-utils";
import { utils} from "ethers";
import { utils } from "ethers";

// NB: HOPR Node sign messages using the prefix to avoid having
// the nodes sign any generic data which could be used maliciously
Expand All @@ -28,7 +27,6 @@ const secretKey = Uint8Array.from(
const provider = new Ed25519Provider(secretKey);
const did = new DID({ provider, resolver: KeyResolver.getResolver() });
const client = new CeramicClient(CERAMIC_API_URL);
const tileId = CERAMIC_TILE_ID;

export default async (req, res) => {
const { address } = req.query;
Expand All @@ -54,16 +52,31 @@ export default async (req, res) => {
);

if (isAddressOwnerOfNode) {

await did.authenticate();
client.setDID(did);

const docs = await TileDocument.load(client, tileId);
const docs = await TileDocument.create(client, null, {
deterministic: true,
tags: [ethAddress],
family: "hopr-wildhorn",
});

const mutatedDoc = Object.assign({}, docs.content, {
[hoprAddress]: ethAddress,
});
await docs.update(mutatedDoc);

const dashboard = await TileDocument.create(client, null, {
deterministic: true,
tags: ["hopr-dashboard"],
family: "hopr-wildhorn",
});

const mutatedDashboard = Object.assign({}, dashboard.content, {
[docs.id.toString()]: ethAddress,
});
await dashboard.update(mutatedDashboard);

return res.status(200).json({
status: "ok",
tile: docs.id.toString(),
Expand Down
6 changes: 3 additions & 3 deletions pages/nfts.js
Expand Up @@ -80,12 +80,12 @@ const dataTable = [
];

export default function HoprAllocation() {
const { account, library } = useEthers();
const { account } = useEthers();
const [records, setRecords] = useState([]);
useEffect(() => {
const loadRecords = async () => {
const response = await (await fetch(`/api/sign/get/${account}`)).json();
setRecords(response.records);
const { records, oldRecords } = await (await fetch(`/api/sign/get/${account}`)).json();
setRecords(oldRecords.concat(records));
};
account && loadRecords();
}, [account]);
Expand Down