From b1f11c57ec488cbb921ebe29e60396bf76b4861b Mon Sep 17 00:00:00 2001 From: Yolfi Date: Mon, 20 Jul 2026 22:09:12 +0700 Subject: [PATCH 1/4] Add Yolfi payments plugin Signed-off-by: Yolfi --- .cursor-plugin/marketplace.json | 5 +++ yolfi/.cursor-plugin/plugin.json | 34 +++++++++++++++++++ yolfi/LICENSE | 21 ++++++++++++ yolfi/README.md | 15 ++++++++ yolfi/assets/favicon.ico | Bin 0 -> 15406 bytes yolfi/skills/yolfi-payments/SKILL.md | 49 +++++++++++++++++++++++++++ 6 files changed, 124 insertions(+) create mode 100644 yolfi/.cursor-plugin/plugin.json create mode 100644 yolfi/LICENSE create mode 100644 yolfi/README.md create mode 100644 yolfi/assets/favicon.ico create mode 100644 yolfi/skills/yolfi-payments/SKILL.md diff --git a/.cursor-plugin/marketplace.json b/.cursor-plugin/marketplace.json index 49f6d8ec..48730643 100644 --- a/.cursor-plugin/marketplace.json +++ b/.cursor-plugin/marketplace.json @@ -72,6 +72,11 @@ "name": "pstack", "source": "pstack", "description": "if you want to go fast, go deep first. pstack helps you write less, but higher quality code. rigorous agent workflows you can parallelize with confidence." + }, + { + "name": "yolfi", + "source": "yolfi", + "description": "Add crypto checkout, payment links, signed webhooks, and payment verification with Yolfi." } ] } diff --git a/yolfi/.cursor-plugin/plugin.json b/yolfi/.cursor-plugin/plugin.json new file mode 100644 index 00000000..afb4ffa0 --- /dev/null +++ b/yolfi/.cursor-plugin/plugin.json @@ -0,0 +1,34 @@ +{ + "name": "yolfi", + "displayName": "Yolfi Payments", + "version": "0.2.0", + "description": "Add crypto checkout, payment links, signed webhooks, and payment verification with Yolfi.", + "author": { + "name": "Yolfi" + }, + "homepage": "https://yolfi.com/ai-agent-kit", + "repository": "https://github.com/yolfinance/yolfi-agent", + "license": "MIT", + "logo": "./assets/favicon.ico", + "keywords": [ + "payments", + "crypto", + "stablecoins", + "checkout", + "webhooks", + "mcp" + ], + "category": "payments", + "tags": [ + "payments", + "crypto", + "checkout", + "mcp" + ], + "skills": "./skills/", + "mcpServers": { + "yolfi": { + "url": "https://app.yolfi.com/mcp" + } + } +} diff --git a/yolfi/LICENSE b/yolfi/LICENSE new file mode 100644 index 00000000..4466f570 --- /dev/null +++ b/yolfi/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 Yolfi + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/yolfi/README.md b/yolfi/README.md new file mode 100644 index 00000000..41fa0732 --- /dev/null +++ b/yolfi/README.md @@ -0,0 +1,15 @@ +# Yolfi Payments + +Add non-custodial crypto checkout flows to applications from Cursor. The plugin combines Yolfi's hosted OAuth MCP server with an integration skill for creating payment links and checkout sessions, configuring signed webhooks, and verifying payment status. + +## Connect + +Install the plugin from Cursor's marketplace and invoke a Yolfi tool. Cursor opens the Yolfi authorization flow in your browser; no API key needs to be pasted into the MCP configuration. + +The server is also available locally with: + +```bash +npx -y @yolfi/agent mcp +``` + +Documentation: https://yolfi.com/ai-agent-kit diff --git a/yolfi/assets/favicon.ico b/yolfi/assets/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..2f5a8c81f73e0524e30f5e65ebbbd63b916df348 GIT binary patch literal 15406 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 TZtmZI4KDxI@ox|O91r|IVYi(S literal 0 HcmV?d00001 diff --git a/yolfi/skills/yolfi-payments/SKILL.md b/yolfi/skills/yolfi-payments/SKILL.md new file mode 100644 index 00000000..d1593fb0 --- /dev/null +++ b/yolfi/skills/yolfi-payments/SKILL.md @@ -0,0 +1,49 @@ +--- +name: yolfi-payments +description: Add Yolfi crypto checkout, payment links, and webhook handling to an app through @yolfi/agent or the Yolfi MCP server. +--- + +# Yolfi Payments Skill + +Use this when the user asks to add crypto payments, payment links, checkout, subscriptions, donations, or webhook-based entitlements with Yolfi. + +## Workflow + +1. Inspect the target app first. +2. Identify the framework, env system, server routes, existing checkout code, existing webhook handlers, and entitlement logic. +3. Check auth with `yolfi auth:status` or `yolfi_auth_status`; an explicit `YOLFI_API_KEY` takes precedence over the protected local credential. +4. If auth is missing and the user already has a Yolfi account, use `yolfi setup --agent ` followed by browser authorization and `yolfi checkin --agent `. The bundled plugin and local MCP server expose `yolfi_agent_setup_start` and `yolfi_agent_checkin`; manually configured remote MCP uses OAuth managed by the host instead. For a new user on the bundled/local transport, first ask them to confirm their email and project name, then call `yolfi_agent_register`. Ask them to open the emailed confirmation link, then call the same tool again with the same arguments. Existing emails must not be re-registered. The tool stores the credential locally, redacts it from model output, and reuses its pending idempotency key across confirmation check-ins. +5. Ask the user for settlement wallet addresses. Never invent them. +6. Ask the user for product name, price, currency, payment type, and recurring interval. +7. Configure settlement settings through `PUT /api/private/organization/current`, then create each webhook through `POST /api/private/organization/webhook-endpoints`. The CLI/local MCP stores the one-time signing secret in the protected local Yolfi config and redacts it from output. +8. List existing paylinks before creating a new one. +9. Create or reuse a paylink. +10. Store paylink ids in env/config, not hard-coded source when avoidable. +11. Add checkout UI or a server route that calls `POST /api/public/payments`. Pass a stable merchant-side customer/user id as `clientReferenceId` whenever webhook-driven attribution or subscription lifecycle updates must resolve that customer. +12. Add webhook signature verification for `X-Yolfi-Signature`. In native (`NONE`) payloads read `data.customer.clientReferenceId`; Stripe-compatible Checkout Session uses `data.object.client_reference_id`, while Stripe-compatible Invoice and Subscription objects use `data.object.metadata.client_reference_id`; Lemon Squeezy-compatible payloads use `meta.custom_data.client_reference_id`. +13. Connect webhook events to the app's existing entitlement/business logic when possible. +14. Verify payment status with `GET /api/public/payments/:id`. +15. Report changed files and exact verification commands. + +## Webhook Contract + +- Publicly supported endpoint adapters are `NONE`, `STRIPE`, and `LEMON_SQUEEZY`. Treat `NONE` as native Yolfi payload format, not as the absence of a provider. +- Create independent endpoints through `POST /api/private/organization/webhook-endpoints`; the removed organization-level `webhookUrl` and `webhookAdapter` fields are not supported. +- Each endpoint has its own signing secret. CLI/MCP create and rotate store it in the protected local config; use the endpoint id for local verification or provision `YOLFI_WEBHOOK_SECRET` through the target deployment's secret manager. +- `YOLFI_API_KEY` authorizes Yolfi API calls and must never be used to verify webhook signatures. Verify `X-Yolfi-Signature` with that endpoint's signing secret only. +- Endpoint create/update accepts optional flat `metadataFilters` string maps (at most 10 entries; keys at most 100 characters; values at most 255 characters); a delivery must match every configured key/value. +- Browser setup and agent-first signup each issue a scoped `yolfi_agent_*` credential. Neither credential is a webhook signing secret. +- Analytics routing uses `website_id`. Provision an adapter `NONE` endpoint with `metadataFilters: { "website_id": "" }`. + +## Do Not + +- Do not invent wallet addresses. +- Do not invent prices, plans, currencies, or recurring intervals. +- Do not commit API keys or webhook secrets. +- Do not print or echo the `yolfi_agent_*` credential returned during check-in. +- Do not pass webhook signing secrets as MCP arguments or CLI flags. +- Do not replace existing billing logic unnecessarily. +- Do not use frontend redirect as proof of payment. +- Do not disable paylinks without explicit user approval. +- Do not duplicate webhook business handlers when an existing handler can be reused. +- Do not use email as the primary subscription identity when `clientReferenceId` can be supplied. From a96fd751423c1fd2a9829107d8ec66deea2e980f Mon Sep 17 00:00:00 2001 From: Yolfi Date: Tue, 21 Jul 2026 13:57:54 +0700 Subject: [PATCH 2/4] Fix hosted MCP workflow guidance Signed-off-by: Yolfi --- yolfi/skills/yolfi-payments/SKILL.md | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/yolfi/skills/yolfi-payments/SKILL.md b/yolfi/skills/yolfi-payments/SKILL.md index d1593fb0..b1495785 100644 --- a/yolfi/skills/yolfi-payments/SKILL.md +++ b/yolfi/skills/yolfi-payments/SKILL.md @@ -1,6 +1,6 @@ --- name: yolfi-payments -description: Add Yolfi crypto checkout, payment links, and webhook handling to an app through @yolfi/agent or the Yolfi MCP server. +description: Add Yolfi crypto checkout, payment links, and webhook handling to an app through the hosted Yolfi MCP server. --- # Yolfi Payments Skill @@ -11,37 +11,39 @@ Use this when the user asks to add crypto payments, payment links, checkout, sub 1. Inspect the target app first. 2. Identify the framework, env system, server routes, existing checkout code, existing webhook handlers, and entitlement logic. -3. Check auth with `yolfi auth:status` or `yolfi_auth_status`; an explicit `YOLFI_API_KEY` takes precedence over the protected local credential. -4. If auth is missing and the user already has a Yolfi account, use `yolfi setup --agent ` followed by browser authorization and `yolfi checkin --agent `. The bundled plugin and local MCP server expose `yolfi_agent_setup_start` and `yolfi_agent_checkin`; manually configured remote MCP uses OAuth managed by the host instead. For a new user on the bundled/local transport, first ask them to confirm their email and project name, then call `yolfi_agent_register`. Ask them to open the emailed confirmation link, then call the same tool again with the same arguments. Existing emails must not be re-registered. The tool stores the credential locally, redacts it from model output, and reuses its pending idempotency key across confirmation check-ins. -5. Ask the user for settlement wallet addresses. Never invent them. +3. This marketplace plugin uses the hosted MCP transport. Complete Cursor's host-managed OAuth flow, then call `yolfi_auth_status`. Do not run local CLI setup, check-in, or signup commands; they are not part of this plugin transport. +4. Call `yolfi_organization_get`, `yolfi_webhooks_list`, and `yolfi_paylinks_list` before proposing mutations. +5. Ask the user for the exact settlement account ids, wallet addresses, and enabled token ids. Never invent them. Configure only approved values with `yolfi_settlement_configure`. 6. Ask the user for product name, price, currency, payment type, and recurring interval. -7. Configure settlement settings through `PUT /api/private/organization/current`, then create each webhook through `POST /api/private/organization/webhook-endpoints`. The CLI/local MCP stores the one-time signing secret in the protected local Yolfi config and redacts it from output. -8. List existing paylinks before creating a new one. -9. Create or reuse a paylink. +7. Before creating a webhook, ask for its publicly reachable HTTPS callback URL and choose the adapter that matches the app's existing handler: `NONE`, `STRIPE`, or `LEMON_SQUEEZY`. Never guess the URL or adapter. Create it with `yolfi_webhooks_configure`; use `yolfi_webhooks_update` for an existing endpoint. +8. Treat a signing secret returned by webhook creation or rotation as one-time secret material. Never repeat it in chat, commit it, or put it in ordinary source/config. Store it only through a user-approved deployment secret mechanism; if none is available, stop and ask the user to store it. +9. Reuse a matching result from `yolfi_paylinks_list`; otherwise create an approved paylink with `yolfi_paylinks_create`. 10. Store paylink ids in env/config, not hard-coded source when avoidable. 11. Add checkout UI or a server route that calls `POST /api/public/payments`. Pass a stable merchant-side customer/user id as `clientReferenceId` whenever webhook-driven attribution or subscription lifecycle updates must resolve that customer. 12. Add webhook signature verification for `X-Yolfi-Signature`. In native (`NONE`) payloads read `data.customer.clientReferenceId`; Stripe-compatible Checkout Session uses `data.object.client_reference_id`, while Stripe-compatible Invoice and Subscription objects use `data.object.metadata.client_reference_id`; Lemon Squeezy-compatible payloads use `meta.custom_data.client_reference_id`. 13. Connect webhook events to the app's existing entitlement/business logic when possible. -14. Verify payment status with `GET /api/public/payments/:id`. +14. Verify payment status with `yolfi_payments_status`; a frontend redirect is not proof of payment. 15. Report changed files and exact verification commands. ## Webhook Contract - Publicly supported endpoint adapters are `NONE`, `STRIPE`, and `LEMON_SQUEEZY`. Treat `NONE` as native Yolfi payload format, not as the absence of a provider. -- Create independent endpoints through `POST /api/private/organization/webhook-endpoints`; the removed organization-level `webhookUrl` and `webhookAdapter` fields are not supported. -- Each endpoint has its own signing secret. CLI/MCP create and rotate store it in the protected local config; use the endpoint id for local verification or provision `YOLFI_WEBHOOK_SECRET` through the target deployment's secret manager. +- Create and manage independent endpoints with `yolfi_webhooks_configure`, `yolfi_webhooks_update`, `yolfi_webhooks_rotate_secret`, and `yolfi_webhooks_delete`; the removed organization-level `webhookUrl` and `webhookAdapter` fields are not supported. +- Each endpoint has its own signing secret. The hosted MCP returns it once on create or rotation, so provision it through the target deployment's secret manager immediately and never expose it in normal output. - `YOLFI_API_KEY` authorizes Yolfi API calls and must never be used to verify webhook signatures. Verify `X-Yolfi-Signature` with that endpoint's signing secret only. - Endpoint create/update accepts optional flat `metadataFilters` string maps (at most 10 entries; keys at most 100 characters; values at most 255 characters); a delivery must match every configured key/value. -- Browser setup and agent-first signup each issue a scoped `yolfi_agent_*` credential. Neither credential is a webhook signing secret. +- Cursor owns OAuth for this hosted MCP connection. Local `yolfi_agent_*` setup, check-in, and signup flows are not exposed by this plugin transport. - Analytics routing uses `website_id`. Provision an adapter `NONE` endpoint with `metadataFilters: { "website_id": "" }`. ## Do Not - Do not invent wallet addresses. +- Do not invent webhook callback URLs or adapters. - Do not invent prices, plans, currencies, or recurring intervals. - Do not commit API keys or webhook secrets. -- Do not print or echo the `yolfi_agent_*` credential returned during check-in. -- Do not pass webhook signing secrets as MCP arguments or CLI flags. +- Do not call local setup, check-in, or signup tools from this hosted plugin. +- Do not pass webhook signing secrets as MCP arguments or ordinary CLI flags. +- Do not bypass available MCP tools with private REST endpoints. - Do not replace existing billing logic unnecessarily. - Do not use frontend redirect as proof of payment. - Do not disable paylinks without explicit user approval. From 7de41e80962248ee862e06344c1644d7e8c27fc9 Mon Sep 17 00:00:00 2001 From: Yolfi Date: Tue, 21 Jul 2026 14:06:21 +0700 Subject: [PATCH 3/4] Prevent duplicate webhook setup Signed-off-by: Yolfi --- yolfi/skills/yolfi-payments/SKILL.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yolfi/skills/yolfi-payments/SKILL.md b/yolfi/skills/yolfi-payments/SKILL.md index b1495785..3dc34277 100644 --- a/yolfi/skills/yolfi-payments/SKILL.md +++ b/yolfi/skills/yolfi-payments/SKILL.md @@ -15,7 +15,7 @@ Use this when the user asks to add crypto payments, payment links, checkout, sub 4. Call `yolfi_organization_get`, `yolfi_webhooks_list`, and `yolfi_paylinks_list` before proposing mutations. 5. Ask the user for the exact settlement account ids, wallet addresses, and enabled token ids. Never invent them. Configure only approved values with `yolfi_settlement_configure`. 6. Ask the user for product name, price, currency, payment type, and recurring interval. -7. Before creating a webhook, ask for its publicly reachable HTTPS callback URL and choose the adapter that matches the app's existing handler: `NONE`, `STRIPE`, or `LEMON_SQUEEZY`. Never guess the URL or adapter. Create it with `yolfi_webhooks_configure`; use `yolfi_webhooks_update` for an existing endpoint. +7. Before creating a webhook, ask for its publicly reachable HTTPS callback URL and choose the adapter that matches the app's existing handler: `NONE`, `STRIPE`, or `LEMON_SQUEEZY`. Never guess the URL or adapter. Match both against the `yolfi_webhooks_list` result: reuse or update a matching endpoint with `yolfi_webhooks_update`, and call `yolfi_webhooks_configure` only when no matching endpoint exists. 8. Treat a signing secret returned by webhook creation or rotation as one-time secret material. Never repeat it in chat, commit it, or put it in ordinary source/config. Store it only through a user-approved deployment secret mechanism; if none is available, stop and ask the user to store it. 9. Reuse a matching result from `yolfi_paylinks_list`; otherwise create an approved paylink with `yolfi_paylinks_create`. 10. Store paylink ids in env/config, not hard-coded source when avoidable. From d78f2412a7566c369a1fb4dcd2feca576d146d10 Mon Sep 17 00:00:00 2001 From: Yolfi Date: Tue, 21 Jul 2026 14:12:47 +0700 Subject: [PATCH 4/4] Match webhook routing filters Signed-off-by: Yolfi --- yolfi/skills/yolfi-payments/SKILL.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yolfi/skills/yolfi-payments/SKILL.md b/yolfi/skills/yolfi-payments/SKILL.md index 3dc34277..9b4b9cde 100644 --- a/yolfi/skills/yolfi-payments/SKILL.md +++ b/yolfi/skills/yolfi-payments/SKILL.md @@ -15,7 +15,7 @@ Use this when the user asks to add crypto payments, payment links, checkout, sub 4. Call `yolfi_organization_get`, `yolfi_webhooks_list`, and `yolfi_paylinks_list` before proposing mutations. 5. Ask the user for the exact settlement account ids, wallet addresses, and enabled token ids. Never invent them. Configure only approved values with `yolfi_settlement_configure`. 6. Ask the user for product name, price, currency, payment type, and recurring interval. -7. Before creating a webhook, ask for its publicly reachable HTTPS callback URL and choose the adapter that matches the app's existing handler: `NONE`, `STRIPE`, or `LEMON_SQUEEZY`. Never guess the URL or adapter. Match both against the `yolfi_webhooks_list` result: reuse or update a matching endpoint with `yolfi_webhooks_update`, and call `yolfi_webhooks_configure` only when no matching endpoint exists. +7. Before creating a webhook, ask for its publicly reachable HTTPS callback URL, the adapter that matches the app's existing handler (`NONE`, `STRIPE`, or `LEMON_SQUEEZY`), and any `metadataFilters` needed for routing. Never guess these values. Compare the URL, adapter, and complete filter map with `yolfi_webhooks_list`: reuse an exact match; update a specifically user-approved endpoint with `yolfi_webhooks_update`; otherwise create a distinct endpoint with `yolfi_webhooks_configure`. 8. Treat a signing secret returned by webhook creation or rotation as one-time secret material. Never repeat it in chat, commit it, or put it in ordinary source/config. Store it only through a user-approved deployment secret mechanism; if none is available, stop and ask the user to store it. 9. Reuse a matching result from `yolfi_paylinks_list`; otherwise create an approved paylink with `yolfi_paylinks_create`. 10. Store paylink ids in env/config, not hard-coded source when avoidable.