import {
IframeStamper,
KeyFormat,
MessageType,
TransactionType,
} from "@turnkey/iframe-stamper";
import { useEffect, useState } from "react";
import axios from "axios";
const IFRAME_CONTAINER_ID = "turnkey-iframe-container";
const IFRAME_ELEMENT_ID = "turnkey-iframe";
interface Props {
organizationId: string;
walletAccountAddress: string;
}
export function ClientSideSigner({
organizationId,
walletAccountAddress,
}: Props) {
const [iframeStamper, setIframeStamper] = useState<IframeStamper | null>(
null
);
const [isKeyLoaded, setIsKeyLoaded] = useState(false);
const [message, setMessage] = useState("Hello, Turnkey!");
const [signature, setSignature] = useState("");
// Initialize iframe
useEffect(() => {
const stamper = new IframeStamper({
iframeUrl: process.env.NEXT_PUBLIC_EXPORT_SIGN_IFRAME_URL!,
iframeContainer: document.getElementById(IFRAME_CONTAINER_ID),
iframeElementId: IFRAME_ELEMENT_ID,
});
stamper
.init()
.then(() => setIframeStamper(stamper))
.catch(console.error);
return () => stamper.clear();
}, []);
// Export key to iframe
const exportKey = async () => {
if (!iframeStamper) return;
let embeddedKey = await iframeStamper.getEmbeddedPublicKey();
if (!embeddedKey) {
embeddedKey = await iframeStamper.initEmbeddedKey();
}
const response = await axios.post("/api/exportWalletAccount", {
walletAccountAddress,
targetPublicKey: embeddedKey,
});
await iframeStamper.injectKeyExportBundle(
response.data.exportBundle,
organizationId,
KeyFormat.Hexadecimal,
walletAccountAddress
);
setIsKeyLoaded(true);
};
// Sign message
const handleSignMessage = async () => {
if (!iframeStamper || !isKeyLoaded) return;
const sig = await iframeStamper.signMessage(
{ message, type: MessageType.Solana },
walletAccountAddress
);
setSignature(sig);
};
return (
<div>
<div id={IFRAME_CONTAINER_ID} />
{!isKeyLoaded ? (
<button
onClick={exportKey}
disabled={!iframeStamper}
>
Export Key
</button>
) : (
<div>
<textarea
value={message}
onChange={(e) => setMessage(e.target.value)}
/>
<button onClick={handleSignMessage}>Sign Message</button>
{signature && <pre>Signature: {signature}</pre>}
</div>
)}
</div>
);
}