Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
4 changes: 2 additions & 2 deletions advanced/dapps/pos-dapp/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@
"lint": "eslint"
},
"dependencies": {
"@reown/appkit": "1.8.2",
"@reown/appkit": "1.8.12",
"next": "15.5.2",
"react": "19.1.0",
"react-dom": "19.1.0",
"react-hot-toast": "^2.6.0",
"@walletconnect/pos-client": "0.0.0-canary.1"
"@walletconnect/pos-client": "0.0.0-canary.4"
},
"devDependencies": {
"@eslint/eslintrc": "^3",
Expand Down
115 changes: 98 additions & 17 deletions advanced/dapps/pos-dapp/src/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,9 @@ export default function Home() {
const [merchantAddress, setMerchantAddress] = useState("");
const [isSetupComplete, setIsSetupComplete] = useState(false);
const [tempMerchantAddress, setTempMerchantAddress] = useState("");
const [isManualControl, setIsManualControl] = useState(false);
const [isWalletConnected, setIsWalletConnected] = useState(false);
const [hasRequestsSent, setHasRequestsSent] = useState(false);

useEffect(() => {
// Check for saved merchant address in localStorage
Expand All @@ -91,6 +94,12 @@ export default function Home() {
setIsSetupComplete(true);
}

// Check for saved manual mode state
const savedManualMode = localStorage.getItem("isManualMode");
Copy link

Copilot AI Oct 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inconsistent localStorage key: saving as 'isManualControl' (line 466) but reading as 'isManualMode'. This will prevent the manual mode preference from persisting correctly across page reloads.

Suggested change
const savedManualMode = localStorage.getItem("isManualMode");
const savedManualMode = localStorage.getItem("isManualControl");

Copilot uses AI. Check for mistakes.
if (savedManualMode !== null) {
setIsManualControl(savedManualMode === "true");
}

if (appkit) return;

setPaymentState("connecting");
Expand Down Expand Up @@ -134,9 +143,9 @@ export default function Home() {
const setupEventListeners = () => {
if (!posClient) return;

posClient.on("connected", (connected) => {
connected = true;
console.log("connected", connected);
posClient.on("connected", ({ session }) => {
console.log("connected", session);
setIsWalletConnected(true);
toast.success("Customer wallet connected", {
icon: "🔗",
duration: 3000,
Expand All @@ -146,6 +155,7 @@ export default function Home() {

posClient.on("disconnected", (disconnected) => {
console.log("disconnected", disconnected);
setIsWalletConnected(false);
toast.error("Customer wallet disconnected", {
icon: "🔌",
duration: 3000,
Expand Down Expand Up @@ -195,11 +205,11 @@ export default function Home() {
setPaymentState("payment_failed");
});

posClient.on("payment_broadcasted", (paymentBroadcasted) => {
console.log("paymentBroadcasted", paymentBroadcasted);
posClient.on("payment_broadcasted", ({ result }) => {
console.log("paymentBroadcasted", result);
setTransactionHashes((prev) => {
const newTransaction: TransactionHash = {
hash: paymentBroadcasted,
hash: result,
status: "pending",
};
const newHashes = [...prev, newTransaction];
Expand All @@ -224,14 +234,13 @@ export default function Home() {
setPaymentState("payment_requesting");
});

posClient.on("payment_successful", (paymentSuccessful) => {
console.log("paymentSuccessful", paymentSuccessful);
const { transaction } = paymentSuccessful;
posClient.on("payment_successful", ({ result }) => {
console.log("paymentSuccessful", result);

// Update transaction status to successful
setTransactionHashes((prev) =>
prev.map((tx) =>
tx.hash === transaction
tx.hash === result
? { ...tx, status: "success" as TransactionStatus }
: tx
)
Expand Down Expand Up @@ -351,7 +360,10 @@ export default function Home() {
);

try {
await posClient.createPaymentIntent({ paymentIntents });
await posClient.createPaymentIntent({
paymentIntents,
manualControl: isManualControl,
});
toast.success(
`Payment request created for ${paymentItems.length} item${
paymentItems.length > 1 ? "s" : ""
Expand Down Expand Up @@ -401,6 +413,8 @@ export default function Home() {
const resetTransaction = () => {
setPaymentState("idle");
setTransactionHashes([]);
setIsWalletConnected(false);
setHasRequestsSent(false);
// Reset all payment item statuses to idle
setPaymentItems((prev) =>
prev.map((item) => ({ ...item, status: "idle" as PaymentItemStatus }))
Expand All @@ -410,6 +424,8 @@ export default function Home() {
const restart = (reinit = true) => {
setPaymentState("idle");
setTransactionHashes([]);
setIsWalletConnected(false);
setHasRequestsSent(false);
// Reset all payment item statuses to idle
setPaymentItems((prev) =>
prev.map((item) => ({ ...item, status: "idle" as PaymentItemStatus }))
Expand Down Expand Up @@ -444,6 +460,33 @@ export default function Home() {
setIsSetupComplete(false);
};

const handleManualModeToggle = () => {
const newValue = !isManualControl;
setIsManualControl(newValue);
localStorage.setItem("isManualControl", String(newValue));
Copy link

Copilot AI Oct 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function should clear the hasRequestsSent state when toggling manual mode. If a user switches from manual to automatic mode after sending requests, the state should reset to allow proper functionality if they switch back.

Suggested change
localStorage.setItem("isManualControl", String(newValue));
localStorage.setItem("isManualControl", String(newValue));
setHasRequestsSent(false);

Copilot uses AI. Check for mistakes.
};

const handleSendRequestsToWallet = async () => {
if (!posClient) {
toast.error("POS client not available");
return;
}

setHasRequestsSent(true);

try {
await posClient.sendPaymentsToWallet();
toast.success("Payment requests sent to wallet", {
icon: "📤",
duration: 3000,
});
} catch (error) {
console.error("Failed to send payment requests:", error);
toast.error("Failed to send payment requests");
setHasRequestsSent(false);
}
};

const getStatusMessage = () => {
switch (paymentState) {
case "connecting":
Expand Down Expand Up @@ -549,12 +592,37 @@ export default function Home() {

{/* Merchant Address Display */}
<div className="p-4 bg-blue-50 dark:bg-blue-900 border-b border-gray-200 dark:border-gray-700">
<p className="text-xs text-blue-700 dark:text-blue-300 mb-1">
Merchant Address:
</p>
<p className="text-xs font-mono text-blue-800 dark:text-blue-200 break-all">
{merchantAddress}
</p>
<div className="flex items-start justify-between gap-4">
<div className="flex-1 min-w-0">
<p className="text-xs text-blue-700 dark:text-blue-300 mb-1">
Merchant Address:
</p>
<p className="text-xs font-mono text-blue-800 dark:text-blue-200 break-all">
{merchantAddress}
</p>
</div>
<div className="flex flex-col items-center gap-1">
<label className="text-xs text-blue-700 dark:text-blue-300 font-medium">
Manual Control
</label>
<button
onClick={handleManualModeToggle}
className={`relative inline-flex h-6 w-11 items-center rounded-full transition-colors focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 ${
isManualControl
? "bg-blue-600"
: "bg-gray-300 dark:bg-gray-600"
}`}
role="switch"
aria-checked={isManualControl}
>
<span
className={`inline-block h-4 w-4 transform rounded-full bg-white transition-transform ${
isManualControl ? "translate-x-6" : "translate-x-1"
}`}
/>
</button>
</div>
</div>
</div>

{/* Status Display */}
Expand Down Expand Up @@ -801,6 +869,19 @@ export default function Home() {
</button>
) : (
<div className="flex flex-col items-center justify-center py-4 space-y-4">
{isManualControl && isWalletConnected && (
<button
onClick={handleSendRequestsToWallet}
disabled={hasRequestsSent}
Copy link

Copilot AI Oct 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The button lacks an aria-label or accessible text when disabled. Consider adding aria-label=\"Send payment requests to wallet\" to improve screen reader support.

Suggested change
disabled={hasRequestsSent}
disabled={hasRequestsSent}
aria-label="Send payment requests to wallet"

Copilot uses AI. Check for mistakes.
className={`w-full font-bold py-4 px-6 rounded-lg transition-all shadow-lg text-lg ${
hasRequestsSent
? "bg-gray-400 cursor-not-allowed"
: "bg-gradient-to-r from-blue-500 to-blue-600 hover:from-blue-600 hover:to-blue-700 transform hover:scale-105"
} text-white`}
>
📤 Send Payments to Wallet
</button>
)}
<Spinner />
<button
onClick={() => {
Expand Down
Loading
Loading