Skip to content

Commit

Permalink
feat(aleph): Service setup started
Browse files Browse the repository at this point in the history
  • Loading branch information
RezaRahemtola committed Oct 25, 2024
1 parent 33ef083 commit 621da82
Show file tree
Hide file tree
Showing 5 changed files with 728 additions and 16 deletions.
4 changes: 4 additions & 0 deletions front/.env.example
Original file line number Diff line number Diff line change
@@ -1,2 +1,6 @@
# Service used for auth (with wallets and social providers)
NEXT_PUBLIC_PRIVY_APP_ID=

# --- Aleph settings ---
# Use the testnet in development
# NEXT_PUBLIC_ALEPH_API_URL=https://api.twentysix.testnet.network
7 changes: 7 additions & 0 deletions front/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@
"storybook:build": "storybook build"
},
"dependencies": {
"@aleph-sdk/account": "^1.2.0",
"@aleph-sdk/client": "1.0.6",
"@aleph-sdk/core": "^1.2.0",
"@aleph-sdk/ethereum": "1.0.3",
"@aleph-sdk/evm": "^1.2.0",
"@aleph-sdk/message": "1.0.7",
"@privy-io/react-auth": "^1.92.0",
"@privy-io/wagmi": "^0.2.12",
"@radix-ui/react-avatar": "^1.1.1",
Expand All @@ -37,6 +43,7 @@
"tailwindcss-animate": "^1.0.7",
"viem": "2.21.19",
"wagmi": "^2.12.17",
"web3": "^4.14.0",
"zod": "^3.23.8"
},
"devDependencies": {
Expand Down
6 changes: 5 additions & 1 deletion front/src/config/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@ import { z } from "zod";

const envSchema = z.object({
PRIVY_APP_ID: z.string(),
ALEPH_API_URL: z.string().optional(),
});

const env = envSchema.parse({ PRIVY_APP_ID: process.env.NEXT_PUBLIC_PRIVY_APP_ID });
const env = envSchema.parse({
PRIVY_APP_ID: process.env.NEXT_PUBLIC_PRIVY_APP_ID,
ALEPH_API_URL: process.env.NEXT_PUBLIC_ALEPH_API_URL,
});

export default env;
104 changes: 104 additions & 0 deletions front/src/services/aleph.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import { AuthenticatedAlephHttpClient } from "@aleph-sdk/client";
import { ETHAccount, getAccountFromProvider, importAccountFromPrivateKey } from "@aleph-sdk/ethereum";
import { PrivateKey } from "eciesjs";
import { SignMessageReturnType } from "viem";
import web3 from "web3";

import env from "@/config/env";

// Aleph keys and channels settings
const SECURITY_AGGREGATE_KEY = "security";
const BEDROCK_GENERAL_CHANNEL = "bedrock";

export class AlephService {
constructor(
/* eslint-disable-next-line no-unused-vars */
private account: ETHAccount,
/* eslint-disable-next-line no-unused-vars */
private subAccountClient: AuthenticatedAlephHttpClient,
// eslint-disable-next-line no-unused-vars
private encryptionPrivateKey: PrivateKey,
) {}

static async initialize(hash: SignMessageReturnType) {
const privateKey = web3.utils.sha3(hash);

if (privateKey === undefined) {
console.error("Private key generation failed");
return undefined;
}
const encryptionPrivateKey = PrivateKey.fromHex(privateKey);

const subAccount = importAccountFromPrivateKey(privateKey);
const account = await getAccountFromProvider(window.ethereum);
const accountClient = new AuthenticatedAlephHttpClient(account, env.ALEPH_API_URL);
const subAccountClient = new AuthenticatedAlephHttpClient(subAccount, env.ALEPH_API_URL);

await AlephService.getSecurityPermission(account, subAccount, accountClient);

return new AlephService(account, subAccountClient, encryptionPrivateKey);
}

static async getSecurityPermission(
account: ETHAccount,
subAccount: ETHAccount,
accountClient: AuthenticatedAlephHttpClient,
) {
try {
// TODO: Add zod parsing
const securitySettings = (await accountClient.fetchAggregate(
account.address,
SECURITY_AGGREGATE_KEY,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
)) as unknown as any;

type SecurityAuthorization = {
address: string;
chain?: string;
channels?: string;
types?: string;
post_types?: string;
aggregate_keys?: string;
};

if (
!securitySettings.authorizations.find(
(authorization: SecurityAuthorization) =>
authorization.address === subAccount.address &&
authorization.types === undefined &&
authorization.channels?.includes(BEDROCK_GENERAL_CHANNEL),
)
) {
const oldAuthorizations = securitySettings.authorizations.filter(
(a: SecurityAuthorization) => a.address !== subAccount.address,
);

await accountClient.createAggregate({
key: SECURITY_AGGREGATE_KEY,
content: {
authorizations: [
...oldAuthorizations,
{
address: subAccount.address,
channels: [BEDROCK_GENERAL_CHANNEL],
},
],
},
});
}
} catch (error) {
// Security aggregate does not exist or with invalid content, creating a new one
await accountClient.createAggregate({
key: SECURITY_AGGREGATE_KEY,
content: {
authorizations: [
{
address: subAccount.address,
channels: [BEDROCK_GENERAL_CHANNEL],
},
],
},
});
}
}
}
Loading

0 comments on commit 621da82

Please sign in to comment.