Skip to content

Commit

Permalink
save untested payme paymaster
Browse files Browse the repository at this point in the history
  • Loading branch information
ngundotra committed Nov 4, 2024
1 parent 4d03b21 commit de9648e
Show file tree
Hide file tree
Showing 8 changed files with 263 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ async function handleGet(req: Request): Promise<ActionGetResponse> {
parameters: [
{
type: "url",
// type: "blink",
name: "blink",
label: "Blink",
required: true,
Expand Down Expand Up @@ -144,13 +145,14 @@ async function handlePost(req: Request): Promise<ActionPostResponse> {
},
}).getInstructions()[0],
),
toWeb3JsInstruction(
memoryClose(umi, {
memory: publicKey(memory),
memoryId: 0,
memoryBump,
}).getInstructions()[0],
),
// Close instruction when I want the Sol back haha
// toWeb3JsInstruction(
// memoryClose(umi, {
// memory: publicKey(memory),
// memoryId: 0,
// memoryBump,
// }).getInstructions()[0],
// ),
];

txMessage.instructions = [
Expand Down
101 changes: 101 additions & 0 deletions examples/next-js/src/app/api/actions/pay-me/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import {
ActionGetResponse,
ActionPostRequest,
ActionPostResponse,
createActionHeaders,
createPostResponse,
} from "@solana/actions";
import { createActionRoutes } from "../../utils/action-handler";
import { PayMeQuerySchema } from "./schema";
import { createQueryParser } from "../../utils/validation";
import { VersionedTransaction } from "@solana/web3.js";
import { fetchBlink } from "../../utils/fetch";
import {
getConnection,
hydrateTransactionMessage,
} from "../../utils/connection";
import { createTransferInstruction } from "@solana/spl-token";

async function handleGet(req: Request): Promise<ActionGetResponse> {
const requestUrl = new URL(req.url);
const baseHref = new URL("/api/actions/memo", requestUrl.origin).toString();

return {
type: "action",
title: "Actions Example - Pay Me",
icon: new URL("/solana_devs.jpg", requestUrl.origin).toString(),
description: "Append a payment instruction to a recipient",
label: "Write",
links: {
actions: [
{
label: "Pay Me",
href: `${baseHref}?mint={mint}&recipient={recipient}&amountUsd={amountUsd}&blink={blink}`,
parameters: [
{
type: "text",
name: "mint",
label: "Mint",
required: false,
},
{
type: "text",
name: "recipient",
label: "Recipient",
required: true,
},
{
type: "number",
name: "amountUsd",
label: "Amount USD",
required: true,
},
],
},
],
},
};
}

const parseQueryParams = createQueryParser(PayMeQuerySchema);

async function handlePost(req: Request): Promise<ActionPostResponse> {
const requestUrl = new URL(req.url);
const { blink, amountUsd, mint, payer, recipient } =
parseQueryParams(requestUrl);

const body: ActionPostRequest = await req.json();

// get a quote for the amount in USD
const jupPrice: { data: { [key: string]: { price: number } } } = await (
await fetch(`https://api.jup.ag/price/v2?ids=${mint.toBase58()}`)
).json();

const amountInMint = Math.ceil(
jupPrice.data[mint.toBase58()].price * amountUsd,
);

const txResponseBody = await fetchBlink(blink, body.account);
const connection = getConnection();
const tx = VersionedTransaction.deserialize(
Buffer.from(txResponseBody.transaction, "base64"),
);
const txMessage = await hydrateTransactionMessage(tx, connection);

const finalTx = new VersionedTransaction(txMessage.compileToV0Message());

return createPostResponse({
fields: {
transaction: finalTx,
message: `Payed ${amountUsd} in ${mint.toBase58()} to ${recipient.toBase58()}"`,
},
});
}

export const { GET, POST, OPTIONS } = createActionRoutes(
{
GET: handleGet,
POST: handlePost,
},
createActionHeaders(),
);
18 changes: 18 additions & 0 deletions examples/next-js/src/app/api/actions/pay-me/schema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { z } from "zod";
import {
publicKeySchema,
numberFromStringSchema,
} from "../../utils/validation";

export const PayMeQuerySchema = z.object({
blink: z.string(),
amountUsd: numberFromStringSchema(),
mint: publicKeySchema.default(
// USDC
"EPjFWdd5AufqSSqeM2gEi2U9jFw27yN25g8yLWkxfV8rauYU",
),
payer: publicKeySchema,
recipient: publicKeySchema,
});

export type PayMeQuery = z.infer<typeof PayMeQuerySchema>;
22 changes: 22 additions & 0 deletions examples/next-js/src/app/api/actions/paymaster/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,28 @@ const parseQueryParams = createQueryParser(GenericTransactionExtensionSchema);
// http%3A%2F%2Flocalhost%3A3000%2Fapi%2Factions%2Ftransfer-sol%3Famount%3D0.01%26to%3D67ZiM1TRqPFR5s2Jz1z4d6noHHBRRzt1Te6xbWmPgYF7
// localhost:3000/api/actions/transfer-sol?amount=0.01&to=67ZiM1TRqPFR5s2Jz1z4d6noHHBRRzt1Te6xbWmPgYF7

// blink
// wrap lighthouse
// i as user want to wrap myself in a blink
// wrap paymaster

// send USDC to ilan.sol
// [getOrCreateAta, transfer]

// lighthouse 2 ixs
// [pre, [...ix], postAssert]

// user ? how do intelligent config my txs
// human readable description & parameters

// Distribution
// Consumers | Developers
// Developers - we now "vibrant" API ecosystem
// anyone can write 3p API
// "AI Agents are Wallets"
// wallets agnostic of stack - go, ios / objective C, bahjj
// Consumers -

async function handlePost(req: Request): Promise<ActionPostResponse> {
console.log("Request", req);
const requestUrl = new URL(req.url);
Expand Down
55 changes: 50 additions & 5 deletions examples/next-js/src/app/api/actions/transfer-sol/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,21 @@ import {
PublicKey,
SystemProgram,
Transaction,
TransactionInstruction,
VersionedTransaction,
} from "@solana/web3.js";
import { createQueryParser } from "../../utils/validation";
import { createQueryParser, InsertionType } from "../../utils/validation";
import { TransferSolQuerySchema } from "./schema";
import { createActionRoutes } from "../../utils/action-handler";
import { getConnection } from "../../utils/connection";
import {
createActionRoutes,
insertInstructionsInBlink,
} from "../../utils/action-handler";
import {
getConnection,
hydrateTransactionMessage,
} from "../../utils/connection";
import { Url } from "next/dist/shared/lib/router/router";
import { fetchBlink } from "../../utils/fetch";

// create the standard headers for this route (including CORS)
const headers = createActionHeaders();
Expand All @@ -42,7 +52,7 @@ async function handleGet(req: Request): Promise<ActionGetResponse> {
actions: [
{
label: "Send SOL",
href: `${baseHref}&amount={amount}&to={to}`,
href: `${baseHref}&amount={amount}&to={to}&blink={blink}&insertion={insertion}`,
parameters: [
{
name: "amount",
Expand All @@ -54,6 +64,22 @@ async function handleGet(req: Request): Promise<ActionGetResponse> {
label: "Enter the address to send SOL",
required: true,
},
{
type: "url",
name: "blink",
label: "",
required: false,
},
{
type: "radio",
name: "insertion",
label: "",
required: false,
options: [
{ label: "Prepend", value: "prepend" },
{ label: "Append", value: "append" },
],
},
],
},
],
Expand All @@ -63,7 +89,12 @@ async function handleGet(req: Request): Promise<ActionGetResponse> {

async function handlePost(req: Request): Promise<ActionPostResponse> {
const requestUrl = new URL(req.url);
const { to: toPubkey, amount } = parseQueryParams(requestUrl);
const {
to: toPubkey,
amount,
blink,
insertion,
} = parseQueryParams(requestUrl);

const body: ActionPostRequest = await req.json();
const account = new PublicKey(body.account);
Expand All @@ -82,6 +113,20 @@ async function handlePost(req: Request): Promise<ActionPostResponse> {
lamports: amount * LAMPORTS_PER_SOL,
});

if (blink) {
return createPostResponse({
fields: {
transaction: await insertInstructionsInBlink(
blink,
insertion,
body.account,
[transferSolInstruction],
),
message: `Send ${amount} SOL to ${toPubkey.toBase58()}`,
},
});
}

const { blockhash, lastValidBlockHeight } =
await connection.getLatestBlockhash();

Expand Down
14 changes: 10 additions & 4 deletions examples/next-js/src/app/api/actions/transfer-sol/schema.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
import { z } from "zod";
import { PublicKey } from "@solana/web3.js";
import { DEFAULT_SOL_AMOUNT } from "./const";
import { numberFromStringSchema, publicKeySchema } from "../../utils/validation";
import {
blinkSchema,
insertionTypeSchema,
numberFromStringSchema,
publicKeySchema,
} from "../../utils/validation";

// Define the input type (what comes from URL params)
export const TransferSolQuerySchema = z.object({
to: publicKeySchema,
amount: numberFromStringSchema({ min: 0 }),
blink: blinkSchema,
// insertion one of "prepend", "append"
insertion: insertionTypeSchema,
});

// Type representing the parsed and transformed data
export type TransferSolQuery = z.infer<typeof TransferSolQuerySchema>;
export type TransferSolQuery = z.infer<typeof TransferSolQuerySchema>;
Loading

0 comments on commit de9648e

Please sign in to comment.