Email TipLinks Guide
The following snippets are from reference code for a live example you can try yourself.
Send Escrow Example
Escrows allow you to create TipLinks without knowing the private key. This works great for multisig situations and also adds a layer of security and recoverability.
Escrows currently only support SOL and SPL tokens like USDC (not NFTs). Support for other assets is in development.
Backend
Please run the following code on your backend to not expose your API key, and send the results to your frontend if needed.
import { createReceiverTipLink } from "@tiplink/api";
// Create Receiver TipLink which associates a keypair with an email address
// We only get the public key back, the private key is sent to the email recipient
const receiverTipLink = await createReceiverTipLink(
process.env.MAILER_API_KEY as string,
toEmail,
);
Frontend or Backend
import { sendAndConfirmTransaction } from "@solana/web3.js";
import { EscrowTipLink } from "@tiplink/api";
// Create Escrow
const escrowTipLink = await EscrowTipLink.create({
connection,
amount: amountSol * LAMPORTS_PER_SOL, // Convert to lamports
toEmail,
depositor: depositor.publicKey,
receiverTipLink,
});
// Deposit funds
const tx = await escrowTipLink.depositTx(connection);
await sendAndConfirmTransaction(connection, tx, [depositor]);
Backend
Please run the following code on your backend to not expose your API key.
import { mailEscrow } from "@tiplink/api";
// Mail it to the email associated with the Receiver TipLink
await mailEscrow({
apiKey: process.env.MAILER_API_KEY as string,
toEmail,
pda,
receiverTipLink,
toName,
replyEmail,
replyName,
});
Claimback Escrow Example
Escrow TipLinks can be claimed back by the same public key
that deposited them. The pda
is required to construct the transaction.
Frontend or Backend
import { getEscrowReceiverTipLink } from "@tiplink/api";
// Get Receiver TipLink associated with the escrow
// We only get the public key back
const receiverTipLink = await getEscrowReceiverTipLink(connection, pda);
Backend
Please run the following code on your backend to not expose your API key, and send the results to your frontend if needed.
import { getReceiverEmail } from "@tiplink/api";
// Get email address associated with the Receiver TipLink
const receiverEmail = await getReceiverEmail(
process.env.MAILER_API_KEY as string,
receiverTipLink,
);
Frontend or Backend
import { sendAndConfirmTransaction } from "@solana/web3.js";
import { EscrowTipLink } from "@tiplink/api";
// Reconstruct EscrowTipLink object
const escrowTipLink = await EscrowTipLink.get({
connection,
pda,
receiverEmail,
});
// Withdraw funds back to depositor
const tx = await escrowTipLink.withdrawTx(
connection,
depositor, // authority
depositor // destination
);
await sendAndConfirmTransaction(connection, tx, [depositor]);
Non-Escrow Example
Optionally, you can email regular TipLinks.
Claimbacks are not natively supported and only possible if the TipLink URL is saved somewhere. Anyone can withdraw with the URL, so store it securely if using this method.
Frontend or Backend
// Create regular TipLink and add funds
// ...
Backend
import { mail } from "@tiplink/api";
// Mail it to whoever
await mail(
process.env.MAILER_API_KEY as string,
tipLink,
toEmail,
toName,
replyEmail,
replyName,
);