Skip to content
Open
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
19 changes: 19 additions & 0 deletions docs/experiments/whatsapp-share.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Experiment: WhatsApp Share Button for Claim Links

This document outlines an experimental feature added to the Bridgelet UI: allowing the sender to directly share the generated claim link via WhatsApp.

## Overview
In many African and Latin American markets, WhatsApp is the dominant communication channel—far outpacing email or standard SMS. While the current Bridgelet UI defaults to sending claim links via email, providing a frictionless way to share the link via WhatsApp significantly reduces the friction of cross-border or local physical disbursements.

## Implementation Details
1. **Send Success State:** Upon successful generation of a payment intent, the UI transitions to the success screen (`ConfirmStep` component).
2. **Dynamic Deep Linking:** A new "Share via WhatsApp" button is displayed. This button utilizes the `wa.me` deep link scheme.
3. **Encoding:** The generated claim URL is securely embedded into the `text` query parameter: `https://wa.me/?text=Here%20is%20your%20payment%20link:%20[CLAIM_URL]`.

## Behavior
- **On Desktop:** Clicking the button will open a new tab prompting the user to either open the WhatsApp Desktop application or use WhatsApp Web.
- **On Mobile:** Clicking the button will immediately launch the native WhatsApp application on the device, prompting the user to select a contact to send the pre-filled message to.

## Future Considerations
- Allow the sender to optionally input the recipient's phone number before sharing, changing the deep link to `https://wa.me/[PHONE_NUMBER]/?text=...` to skip the contact selection step.
- Implement similar share buttons for Telegram or native Web Share API (`navigator.share`) for broader social sharing capabilities.
21 changes: 21 additions & 0 deletions frontend/components/send-form/steps/confirm-step.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,16 @@ export function ConfirmStep({ state, onBack }: ConfirmStepProps) {
const [submitting, setSubmitting] = useState(false);
const [submitted, setSubmitted] = useState(false);
const [error, setError] = useState<string | null>(null);
const [claimUrl, setClaimUrl] = useState<string | null>(null);

async function handleConfirm() {
setSubmitting(true);
setError(null);
try {
// Placeholder: wire up to POST /api/accounts + POST /send in a real impl.
await new Promise((res) => setTimeout(res, 800));
// Set a mock claim URL for the experiment since the backend isn't wired
setClaimUrl('https://bridgelet.example.com/claim/mock-token-123');
setSubmitted(true);
} catch (err) {
setError(err instanceof Error ? err.message : 'Something went wrong.');
Expand All @@ -39,6 +42,24 @@ export function ConfirmStep({ state, onBack }: ConfirmStepProps) {
A claim link has been sent to <strong>{state.recipientEmail}</strong>. They have 24
hours to claim their funds.
</p>

{claimUrl && (
<div className="mt-4 border-t border-green-200 pt-4">
<a
href={`https://wa.me/?text=${encodeURIComponent(
`Here is your payment link: ${claimUrl}`
)}`}
target="_blank"
rel="noopener noreferrer"
className="inline-flex items-center rounded-lg bg-[#25D366] px-4 py-2 text-sm font-medium text-white transition hover:bg-[#128C7E]"
>
<svg className="mr-2 h-4 w-4" fill="currentColor" viewBox="0 0 24 24">
<path d="M17.472 14.382c-.297-.149-1.758-.867-2.03-.967-.273-.099-.471-.148-.67.15-.197.297-.767.966-.94 1.164-.173.199-.347.223-.644.075-.297-.15-1.255-.463-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.298-.347.446-.52.149-.174.198-.298.298-.497.099-.198.05-.371-.025-.52-.075-.149-.669-1.612-.916-2.207-.242-.579-.487-.5-.669-.51a12.8 12.8 0 0 0-.57-.01c-.198 0-.52.074-.792.372-.272.297-1.04 1.016-1.04 2.479 0 1.462 1.065 2.875 1.213 3.074.149.198 2.096 3.2 5.077 4.487.709.306 1.262.489 1.694.625.712.227 1.36.195 1.871.118.571-.085 1.758-.719 2.006-1.413.248-.694.248-1.289.173-1.413-.074-.124-.272-.198-.57-.347m-5.421 7.403h-.004a9.87 9.87 0 0 1-5.031-1.378l-.361-.214-3.741.982.998-3.648-.235-.374a9.86 9.86 0 0 1-1.51-5.26c.001-5.45 4.436-9.884 9.888-9.884 2.64 0 5.122 1.03 6.988 2.898a9.825 9.825 0 0 1 2.893 6.994c-.003 5.45-4.437 9.884-9.885 9.884m8.413-18.297A11.815 11.815 0 0 0 12.05 0C5.495 0 .16 5.335.157 11.892c0 2.096.547 4.142 1.588 5.945L.057 24l6.305-1.654a11.882 11.882 0 0 0 5.683 1.448h.005c6.554 0 11.89-5.335 11.893-11.893a11.821 11.821 0 0 0-3.48-8.413Z" />
</svg>
Share via WhatsApp
</a>
</div>
)}
</div>
);
}
Expand Down
7 changes: 6 additions & 1 deletion frontend/lib/bridgelet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,11 +74,16 @@ export interface ApiError {
statusCode: number;
}

export {
import {
BridgeletClient,
type BridgeletClientOptions,
} from '@/lib/create-bridgelet-client';

export {
BridgeletClient,
type BridgeletClientOptions,
};

let _defaultClient: BridgeletClient | null = null;

function defaultClient(): BridgeletClient {
Expand Down
6 changes: 3 additions & 3 deletions frontend/lib/wallet → frontend/lib/wallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,12 @@ export async function connectFreighter(): Promise<ConnectedWallet> {
// Request access — this opens the Freighter popup
await freighter.requestAccess();

const { publicKey } = await freighter.getPublicKey();
if (!publicKey) {
const { address } = await freighter.getAddress();
if (!address) {
throw new Error("Freighter did not return a public key. Did you approve the request?");
}

return { publicKey, type: "freighter" };
return { publicKey: address, type: "freighter" };
}

// LOBSTR is mobile-only, so on desktop we deeplink and poll for a result
Expand Down
1 change: 1 addition & 0 deletions frontend/mocks/browser.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { setupWorker } from 'msw/browser';
import { accountHandlers } from './handlers/accounts';
import { claimsHandlers } from './handlers/claims';
import { horizonHandlers } from './handlers/horizon';

/**
* MSW service worker for browser environments.
Expand Down
2 changes: 1 addition & 1 deletion frontend/next-env.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/// <reference types="next" />
/// <reference types="next/image-types/global" />
import "./.next/dev/types/routes.d.ts";
import "./.next/types/routes.d.ts";

// NOTE: This file should not be edited
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
Loading
Loading