Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions @/components/dashboard/DashboardLockerPortfolio.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { getCollectionFloor } from "@/lib/element";
import { getPortfolio } from "@/lib/moralis";
import { copyToClipboard, truncateAddress } from "@/lib/utils";
import TxTable from "app/TxTable";
import createOfframp from "app/actions/createOfframp";
import Image from "next/image";
import Link from "next/link";
import { useEffect, useState } from "react";
Expand Down Expand Up @@ -120,6 +121,10 @@ const DashboardLockerPortfolio = ({
setLockerInfo(newLockerInfo);
}, [transactions]);

const setupOfframp = async () => {
const data = await createOfframp();
};

return (
<div className="flex w-full flex-1 flex-col items-start justify-start p-4">
<div className="mb-12 flex flex-col">
Expand Down Expand Up @@ -168,6 +173,15 @@ const DashboardLockerPortfolio = ({
{lockerInfo && 100 - parseFloat(lockerInfo.savePercentage)}%
</span>
</div>

<div className="my-4">
<button
className="w-full rounded-md bg-cyan-600 p-3"
onClick={setupOfframp}
>
Add offramp
</button>
</div>
</div>

{txList && (
Expand Down
23 changes: 20 additions & 3 deletions @/pages/DashboardPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@ import DashboardLockerPortfolio from "@/components/dashboard/DashboardLockerPort
import DashboardLockerSetup from "@/components/dashboard/DashboardLockerSetup";
import DashboardNoLocker from "@/components/dashboard/DashboardNoLocker";
import { PATHS } from "@/lib/paths";
import { AarcProvider } from "@aarc-xyz/deposit-widget";
import "@rainbow-me/rainbowkit/styles.css";
import { getLocker } from "app/actions/getLocker";
import { useRouter } from "next/navigation";
import { useEffect, useRef, useState } from "react";

import { useAccount } from "wagmi";
// TODO: Since session keys are chain-specific, the DB needs account for this.
// Once DB is updated, need to update dashboard logic.

Expand All @@ -20,7 +21,8 @@ export default function DashboardPage() {
const [initialTxLength, setInitialTxLength] = useState<number>(0);
const [latestTxLength, setLatestTxLength] = useState<number>(0);
const router = useRouter();

const account = useAccount();
console.log("account", account);
const fetchLockerInfo = async () => {
const { locker, txs } = await getLocker();
setLockerInfo(locker);
Expand Down Expand Up @@ -69,10 +71,25 @@ export default function DashboardPage() {
<DashboardLockerPortfolio transactions={transactions} />
) : null;

const aarcConfig = {
aarcSDK: process.env.NEXT_PUBLIC_AARC_API_KEY!,
destination: {
walletAddress: lockerInfo?.lockerAddress,
},
appearance: {
logoUrl: "demo.aarc.xyz/AarcLogo.png",
themeColor: "#1677FF",
},
};

console.log("aarcConfig", aarcConfig);

return (
<div className="xs:grid xs:place-content-center size-full p-4">
<div className="flex flex-col justify-center">
<div className="flex flex-col space-y-12">{lockerState}</div>
<div className="flex flex-col space-y-12">
<AarcProvider config={aarcConfig}>{lockerState}</AarcProvider>
</div>
</div>
</div>
);
Expand Down
10 changes: 10 additions & 0 deletions __tests__/beam.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
test("decoding", async () => {
const msgEncoded = "dXNlcjpBQUE=";
const msgDecoded = Buffer.from(msgEncoded, "base64").toString("utf8");
expect(msgDecoded).toBe("user:AAA");
});

test("header decoding", () => {
const header = "Basic dXNlcjpBQUE=";
const [type, encoded] = header.split(" ");
});
38 changes: 38 additions & 0 deletions app/actions/createOfframp.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
"use server";

// https://docs.stripe.com/testing
export default async function createOfframp() {
console.log("Creating offramp...");
const emailAddress = "[email protected]";
try {
const url = "https://api.sandbox.ansiblelabs.xyz/accounts/individuals";
const apiKey = process.env.BEAM_API_KEY;
const response = await fetch(url, {
method: "POST",
headers: {
Authorization: `Bearer ${apiKey}`,
Accept: "application/json",
"Content-Type": "application/json",
},
body: JSON.stringify({
kyc: {
emailAddress,
},
walletAddress: "0xAF115955b028c145cE3A7367B25A274723C5104B",
walletAddressChain: "Ethereum",
}),
});

if (!response.ok) {
// If the API responded with an error status, handle it here
const errorData = await response.json();
throw new Error(errorData.message);
}

const data = await response.json();
console.log(JSON.stringify(data, null, 2));
return data;
} catch (error: any) {
throw new Error(error.message || "An unexpected error occurred");
}
}
26 changes: 26 additions & 0 deletions app/api/webhooks/beam/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
"use server";

import { headers } from "next/headers";

export async function POST(request: Request) {
console.log("beam-webhook");
const headersList = headers();
const authorization = headersList.get("authorization") || "";
console.log("authorization", authorization);
const [type, encoded] = authorization.split(" ");
const auth = Buffer.from(encoded, "base64").toString("utf8");
console.log("auth", auth);
const [username, password] = auth?.split(":");

if (password !== process.env.API_KEY) {
console.warn("Wrong api-key");
return new Response(`Wrong api-key`, {
status: 400,
});
}

const res = await request.json();
console.log(res);

return Response.json({ done: true });
}
1 change: 1 addition & 0 deletions middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export default authMiddleware({
"/",
"/api/webhooks/clerk-user-updated",
"/api/webhooks/moralis-tx-stream",
"/api/webhooks/beam",
],
});

Expand Down
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@
"stream:gen": "tsx scripts/gen-moralis-stream.ts"
},
"dependencies": {
"@aarc-xyz/deposit-widget": "^0.1.2",
"@aarc-xyz/deposit-widget-coinbase": "^0.0.1",
"@aarc-xyz/deposit-widget-transak": "^0.0.2",
"@clerk/nextjs": "^4.29.12",
"@hookform/resolvers": "^3.3.4",
"@metamask/sdk": "^0.18.4",
Expand Down
50 changes: 50 additions & 0 deletions scripts/get-beam-webhook.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import dotenv from "dotenv";
import path from "path";

// {
// "id": "f5d59089-5309-479b-abd7-b746bfa7eeed",
// "partnerId": "df803fcb-34f0-413d-99ef-dc777e88e6a4",
// "callbackUrl": "https://9358-2607-fb90-d51c-c8a1-d83d-9b1b-ca73-5552.ngrok-free.app/api/beam-webhook",
// "authUsername": "user",
// "status": "ACTIVE"
// }

dotenv.config({ path: path.resolve(__dirname, "../.env.development.local") });
async function getBeamWebhook() {
console.log("Getting webhook...");
try {
// curl --request POST \
// --url https://api.sandbox.ansiblelabs.xyz/webhooks \
// --header 'Authorization: Bearer {key}' \
// --header 'accept: application/json' \
// --header 'content-type: application/json'
const url = "https://api.sandbox.ansiblelabs.xyz/webhooks";
const apiKey = process.env.BEAM_API_KEY;
const response = await fetch(url, {
method: "GET",
headers: {
Authorization: `Bearer ${apiKey}`,
Accept: "application/json",
"Content-Type": "application/json",
},
});

if (!response.ok) {
// If the API responded with an error status, handle it here
const errorData = await response.json();
throw new Error(errorData.message);
}

const data = await response.json();
console.log(JSON.stringify(data, null, 2));
return data;
} catch (error: any) {
throw new Error(error.message || "An unexpected error occurred");
}
}

async function doIt() {
await getBeamWebhook();
}

doIt();
56 changes: 56 additions & 0 deletions scripts/new-beam-webhook.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import dotenv from "dotenv";
import path from "path";

// {
// "id": "f5d59089-5309-479b-abd7-b746bfa7eeed",
// "partnerId": "df803fcb-34f0-413d-99ef-dc777e88e6a4",
// "callbackUrl": "https://9358-2607-fb90-d51c-c8a1-d83d-9b1b-ca73-5552.ngrok-free.app/api/beam-webhook",
// "authUsername": "user",
// "status": "ACTIVE"
// }

dotenv.config({ path: path.resolve(__dirname, "../.env.development.local") });
async function createBeamWebhook() {
console.log("Creating webhook...");
try {
// curl --request POST \
// --url https://api.sandbox.ansiblelabs.xyz/webhooks \
// --header 'Authorization: Bearer {key}' \
// --header 'accept: application/json' \
// --header 'content-type: application/json'
const url = "https://api.sandbox.ansiblelabs.xyz/webhooks";
const apiKey = process.env.BEAM_API_KEY;
const response = await fetch(url, {
method: "PUT",
headers: {
Authorization: `Bearer ${apiKey}`,
Accept: "application/json",
"Content-Type": "application/json",
},
body: JSON.stringify({
authUsername: "user",
authPassword: "AAA",
callbackUrl:
"https://9358-2607-fb90-d51c-c8a1-d83d-9b1b-ca73-5552.ngrok-free.app/api/webhooks/beam",
}),
});

if (!response.ok) {
// If the API responded with an error status, handle it here
const errorData = await response.json();
throw new Error(errorData.message);
}

const data = await response.json();
console.log(JSON.stringify(data, null, 2));
return data;
} catch (error: any) {
throw new Error(error.message || "An unexpected error occurred");
}
}

async function doIt() {
await createBeamWebhook();
}

doIt();
Loading