Skip to content

Commit

Permalink
chore: create ui page for activate card and wipe card
Browse files Browse the repository at this point in the history
  • Loading branch information
Nicolas Burtey committed Sep 23, 2023
1 parent 85897b0 commit ca9554e
Show file tree
Hide file tree
Showing 9 changed files with 91 additions and 30 deletions.
9 changes: 5 additions & 4 deletions apps/boltcard/app/api/activate/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { aesDecryptKey, serverUrl } from "@/services/config"
import { fetchByOneTimeCode } from "@/services/db/card-init"

interface ActivateCardResponse {
warning: boolean
protocol_name: string
protocol_version: number
card_name: string
Expand Down Expand Up @@ -36,11 +37,10 @@ export async function GET(req: NextRequest) {
)
}

let warningReusedCode = false

if (cardKeysSetup.status !== "init") {
return NextResponse.json(
{ status: "ERROR", reason: "code has already been used" },
{ status: 400 },
)
warningReusedCode = true
}

const lnurlwBase = `${serverUrl}/api/ln`
Expand All @@ -50,6 +50,7 @@ export async function GET(req: NextRequest) {
const k1DecryptKey = aesDecryptKey.toString("hex")

const response: ActivateCardResponse = {
warning: warningReusedCode,
protocol_name: "create_bolt_card_response",
protocol_version: 2,
card_name: "",
Expand Down
2 changes: 1 addition & 1 deletion apps/boltcard/app/api/create/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export async function GET(req: NextRequest) {
}

const apiActivationUrl = `${serverUrl}/api/activate?a=${oneTimeCode}`
const uiActivationUrl = `${serverUrl}/card/activate?a=${oneTimeCode}`
const uiActivationUrl = `${serverUrl}/card/activate/${oneTimeCode}`
return NextResponse.json({
status: "OK",
apiActivationUrl,
Expand Down
40 changes: 35 additions & 5 deletions apps/boltcard/app/card/[id]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,30 @@
import { serverApi } from "@/services/config"
import QRCode from "qrcode"
import Image from "next/image"

import { isAdmin, serverUrl } from "@/services/config"

export default async function Card({ params }: { params: { id: string } }) {
const { id } = params

const cardApi = `${serverApi}/card/id/${id}`
const cardApi = `${serverUrl}/api/card/id/${id}`
const cardResult = await fetch(cardApi, { cache: "no-store" })
const cardInfo = await cardResult.json()

const transactionsApi = `${serverApi}/card/id/${id}/transactions`
const transactionsResult = await fetch(transactionsApi)
const transactionsApi = `${serverUrl}/api/card/id/${id}/transactions`
const transactionsResult = await fetch(transactionsApi, { cache: "no-store" })
const transactionInfo = await transactionsResult.json()

let qrCode = ""

if (isAdmin) {
const wipeApi = `${serverUrl}/api/wipe?cardId=${id}`
const wipeResult = await fetch(wipeApi, { cache: "no-store" })
const wipeInfo = await wipeResult.json()

// generate QR code
qrCode = await QRCode.toDataURL(JSON.stringify(wipeInfo), { width: 400 })
}

return (
<main className="flex flex-col min-h-screen items-center justify-center">
<h1>boltcard</h1>
Expand Down Expand Up @@ -63,12 +77,28 @@ export default async function Card({ params }: { params: { id: string } }) {
<strong>Fee:</strong> {tx.settlementDisplayFee}{" "}
{tx.settlementDisplayCurrency}
</li>
{/* Add more fields as required */}
</ul>
</li>
))}
</ul>
</section>

<section className="my-4">
<h2>Wipe Card:</h2>
<p>
<strong>Warning:</strong> This will wipe the card and remove all funds. This
action cannot be undone.
</p>
<p>
<Image
src={qrCode}
alt={"qr code to activate"}
width={400}
height={400}
unoptimized
/>
</p>
</section>
</main>
)
}
33 changes: 33 additions & 0 deletions apps/boltcard/app/card/activate/[a]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import QRCode from "qrcode"
import Image from "next/image"

import { serverUrl } from "@/services/config"

export default async function ActivateCard({ params }: { params: { a: string } }) {
const { a } = params

const url = `${serverUrl}/api/activate/?a=${a}`
const res = await fetch(url, { cache: "no-store" })
const activationParams = await res.json()
const warning = activationParams.warning

const qrCode = await QRCode.toDataURL(url, { width: 400 })

return (
<>
<div>
<h1>Activate Card</h1>
{warning && (
<p>{"card should not be programmed twice with the same sets of keys"}</p>
)}
<Image
src={qrCode}
alt={"qr code to activate"}
width={400}
height={400}
unoptimized
/>
</div>
</>
)
}
13 changes: 0 additions & 13 deletions apps/boltcard/app/card/activate/page.tsx

This file was deleted.

14 changes: 10 additions & 4 deletions apps/boltcard/bats/e2e-test.bats
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@ random_phone() {
export TOKEN_ALICE=$(read_value "alice")

RESPONSE=$(curl -s "http://localhost:3000/api/create?token=${TOKEN_ALICE}")
CALLBACK_URL=$(echo $RESPONSE | jq -r '.apiActivationUrl')
CALLBACK_API_URL=$(echo $RESPONSE | jq -r '.apiActivationUrl')
CALLBACK_UI_URL=$(echo $RESPONSE | jq -r '.uiActivationUrl')

# echo "CALLBACK_URL: $CALLBACK_URL"
# exit 1
# TODO: test CALLBACK_UI_URL

# Making the follow-up curl request
RESPONSE=$(curl -s "${CALLBACK_URL}")
RESPONSE=$(curl -s "${CALLBACK_API_URL}")
echo "$RESPONSE"
[[ $(echo $RESPONSE | jq -r '.protocol_name') == "create_bolt_card_response" ]] || exit 1

Expand Down Expand Up @@ -86,6 +86,12 @@ random_phone() {
[[ $(echo $result | jq -r '.status') == "OK" ]] || exit 1
}

@test "card ui" {
cardId=$(read_value "cardId")
http_status=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:3000/card/${cardId})
[[ "$http_status" -eq 200 ]] || exit 1
}

@test "wipecard" {
cardId=$(read_value "cardId")
result=$(curl -s http://localhost:3000/api/wipe?cardId=${cardId})
Expand Down
Binary file modified apps/boltcard/bun.lockb
Binary file not shown.
8 changes: 5 additions & 3 deletions apps/boltcard/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,21 @@
"node-aes-cmac": "^0.1.1",
"pg": "^8.11.3",
"postcss": "8.4.29",
"qrcode": "^1.5.3",
"react": "18.2.0",
"react-dom": "18.2.0",
"tailwindcss": "3.3.3",
"typescript": "5.2.2"
},
"devDependencies": {
"@types/pg": "^8.10.2",
"encoding": "^0.1.13",
"@graphql-codegen/add": "^5.0.0",
"@graphql-codegen/cli": "^5.0.0",
"@graphql-codegen/client-preset": "^4.1.0",
"@graphql-codegen/typescript": "^4.0.1",
"@graphql-codegen/typescript-operations": "^4.0.1",
"@graphql-codegen/typescript-react-apollo": "^3.3.7"
"@graphql-codegen/typescript-react-apollo": "^3.3.7",
"@types/pg": "^8.10.2",
"@types/qrcode": "^1.5.2",
"encoding": "^0.1.13"
}
}
2 changes: 2 additions & 0 deletions apps/boltcard/services/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,5 @@ export const AES_DECRYPT_KEY =
export const aesDecryptKey = Buffer.from(AES_DECRYPT_KEY, "hex")

export const lightningDomain = process.env.LIGHTNING_DOMAIN ?? "localhost"

export const isAdmin = true

0 comments on commit ca9554e

Please sign in to comment.