{"id":21870047,"url":"https://github.com/SolDapper/solana-action-express","last_synced_at":"2025-07-21T04:31:27.834Z","repository":{"id":245943920,"uuid":"819000788","full_name":"SolDapper/solana-action-express","owner":"SolDapper","description":"Solana Actions Server for Blinks","archived":false,"fork":false,"pushed_at":"2025-02-06T22:40:52.000Z","size":623,"stargazers_count":8,"open_issues_count":0,"forks_count":6,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-07-04T11:48:31.006Z","etag":null,"topics":["actions","api","blinks","express","node","server","solana"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/SolDapper.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-06-23T13:46:58.000Z","updated_at":"2025-02-06T22:40:54.000Z","dependencies_parsed_at":"2024-06-24T23:57:21.844Z","dependency_job_id":"cfe591dc-10d6-47aa-a81b-65f522794d7b","html_url":"https://github.com/SolDapper/solana-action-express","commit_stats":null,"previous_names":["mcdegens-dao/solana-action-express","soldapper/solana-action-express"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/SolDapper/solana-action-express","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SolDapper%2Fsolana-action-express","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SolDapper%2Fsolana-action-express/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SolDapper%2Fsolana-action-express/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SolDapper%2Fsolana-action-express/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/SolDapper","download_url":"https://codeload.github.com/SolDapper/solana-action-express/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SolDapper%2Fsolana-action-express/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266240773,"owners_count":23898062,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["actions","api","blinks","express","node","server","solana"],"created_at":"2024-11-28T06:10:00.878Z","updated_at":"2025-07-21T04:31:27.825Z","avatar_url":"https://github.com/SolDapper.png","language":"JavaScript","readme":"# solana-action-express\nsolana actions server powered by node \u0026 express js\n\nprovides modular action endpoints for solana blinks\n\nsupport: contact [@SolDapper](https://x.com/SolDapper)\n\n# auto install and start\ninstalls and starts the server\n\n*this command creates the your-projects/solana-action-express working directory\n```javascript\ngit clone https://github.com/SolDapper/solana-action-express.git \u0026\u0026 cd solana-action-express \u0026\u0026 npm install \u0026\u0026 npm run actions\n```\n\n# normal start\n```javascript\nnpm run actions\n```\n\n# creating new actions\n1. create your new action file\n```javascript\ntouch src/actions/my_new_action.js\n```\n2. include the new file in actions.js\n```javascript\n// *********************************************************************************\n// include actions\nimport { my_new_action } from './actions/my_new_action.js';\napp.use(\"/\", my_new_action);\nimport { donation_sol } from './actions/donation_sol.js';\napp.use(\"/\", donation_sol);\nimport { donation_usdc } from './actions/donation_usdc.js';\napp.use(\"/\", donation_usdc);\n// include actions\n// *********************************************************************************\n```\n3. build your new action module\n\n *src/actions/my_new_action.js*\n```javascript\n'use strict';\n// *********************************************************************************\n// sol donation action\nimport {rpc,host} from '../config.js';\nimport Express from 'express';\nconst my_new_action = Express.Router();\nmy_new_action.get('/my-new-action-config',(req,res)=\u003e{\n    const obj = {}\n    obj.icon = \"\";\n    obj.title = \"\";\n    obj.description = \"\";\n    obj.label = \"donate\";\n    obj.links = {\n    \"actions\": [\n        {\n          \"label\": \"Send\",\n          \"href\": host+\"/my-new-action-build?amount={amount}\",\n          \"parameters\": [\n            {\n              \"name\": \"amount\", // input field name\n              \"label\": \"SOL Amount\", // text input placeholder\n              \"required\": true\n            }\n          ]\n        }\n      ]\n    }\n    res.json(obj);\n});\n// *********************************************************************************\n\n// *********************************************************************************\n// sol donation tx\nmy_new_action.route('/my-new-action-build').post(async function(req,res){\n  \n  let error = false;\n  let message = false;\n\n  // validate inputs\n  if(typeof req.body.account==\"undefined\"){\n    error = true;\n    message = \"user wallet missing\";\n  }\n  else if(typeof req.query.amount==\"undefined\" || req.query.amount==\"\u003camount\u003e\" || isNaN(req.query.amount)){\n    error = true;\n    message = \"no amount defined\";\n  }\n\n  if(error === true){\n    res.status(400).json({\"message\":message});\n  }\n  else{\n\n    try{\n\n      // create instructions\n      const lamports = req.query.amount * 1000000000;\n      const from = new PublicKey(req.body.account);\n      const to = new PublicKey(\"GUFxwDrsLzSQ27xxTVe4y9BARZ6cENWmjzwe8XPy7AKu\");\n      const donateIx = SystemProgram.transfer({fromPubkey:from, lamports:lamports, toPubkey:to});\n      \n      // build transaction\n      const _tx_ = {};\n      _tx_.rpc = rpc;                     // string : required\n      _tx_.account = req.body.account;    // string : required\n      _tx_.instructions = [ donateIx ];   // array  : required\n      _tx_.signers = false;               // array  : default false\n      _tx_.serialize = true;              // bool   : default false\n      _tx_.encode = true;                 // bool   : default false\n      _tx_.table = false;                 // array  : default false\n      _tx_.tolerance = 1.2;               // int    : default 1.1    \n      _tx_.compute = false;               // bool   : default true\n      _tx_.fees = false;                  // bool   : default true : helius rpc required when true\n      _tx_.priority = req.query.priority; // string : VeryHigh,High,Medium,Low,Min : default Medium\n      const tx = await mcswap.tx(_tx_);  // package the tx\n      tx.message = \"You sent \"+req.query.amount+\" SOL!\";\n      res.json(tx); // output\n\n    } catch (err) {\n      console.error(err);\n      res.status(500).json({ message: err.message });\n    }\n\n  }\n\n});\nexport {my_new_action};\n// *********************************************************************************\n```\n\n# cloud deployment\nby default your \"host\" is localhost. when deploying your server live you must update the host setting in src/config.js to your live domain.\n```javascript\nvar host = \"https://your-domain-name.com\";\n```\n[heroku](https://www.heroku.com) hosting conviennently allows you to auto deploy or manually deploy from your github repo with one click.\n\ncreate a config var in your apps hosting settings with the name \"RPC\" and the value being your protected rpc endpoint url. your solana-action-express server will then use it automatically.\n\n# rendering on x\nAlthough you can test locally on Dial.to and other tools, it's important to note that in order for a blink to render on x.com you must have:\n1. your actions deployed live on a fully qualified domain name.\n2. blinks must be enabled in your wallet settings.\n3. the page you're sharing must have twitter-card metatags.\n\nwe use the following metatags\n```javascript\n  \u003ctitle\u003eTitle\u003c/title\u003e\n  \u003cmeta name=\"description\" content=\"\" /\u003e\n  \u003cmeta name=\"twitter:card\" content=\"summary_large_image\" /\u003e\n  \u003cmeta name=\"twitter:site\" content=\"@xHandle\" /\u003e\n  \u003cmeta name=\"twitter:creator\" content=\"@xHandle\" /\u003e\n  \u003cmeta name=\"twitter:title\" content=\"\" /\u003e\n  \u003cmeta name=\"twitter:description\" content=\"\" /\u003e\n  \u003cmeta name=\"twitter:image\" content=\"\" /\u003e\n  \u003cmeta property=\"og:title\" content=\"\" /\u003e\n  \u003cmeta property=\"og:image\" content=\"\" /\u003e\n  \u003cmeta property=\"og:url\" content=\"\" /\u003e\n  \u003cmeta property=\"og:description\" content=\"\" /\u003e\n  \u003clink rel=\"apple-touch-icon\" href=\"\" type=\"image/png\"\u003e\n  \u003clink rel=\"icon\" href=\"\" type=\"image/png\"\u003e\n```\nyou can test that your page is twitter-card enabled using this tool:\n\nhttps://www.bannerbear.com/tools/twitter-card-preview-tool/\n\n# actions registration\nIt is currently necessary to register the domain of your actions server or else your blinks will not render on x.\n\nDialect Action Registration: https://dial.to/register\n\n# x users\nusers on x need to have a supporting wallet or the dialect extension to see the blinks. otherwise the post will default to the normal twitter-card.\n\n**supporting wallets/extensions**\n\nphantom wallet (enable in settings under \"experimental features\") [web store](https://chromewebstore.google.com/detail/phantom/bfnaelmomeimhlpmgjnjophhpkkoljpa)\n\nsolflare wallet [web store](https://chromewebstore.google.com/detail/solflare-wallet/bhhhlbepdkbapadjdnnojkbgioiodbic)\n\nbackpack wallet [web store](https://chromewebstore.google.com/detail/backpack/aflkmfhebedbjioipglgcbcmnbpgliof)\n\ndialect blinks [web store](https://chromewebstore.google.com/detail/dialect-blinks/mhklkgpihchphohoiopkidjnbhdoilof) \n\n# non-node web apps\nif the twitter-card metatags for your blink are located on a non-node website, blog, one the many oss ecom platforms, anything running on apache, you can use this php file in place of your actions.json to allow public access from blink clients without opening up cross domain requests to other files on your system. you will also need to add a RewriteRule in your your .htaccess file to route all requests for actions.json to the actions.php file.\n\n**actions.php**\n```javascript\n\u003c?php header(\"Access-Control-Allow-Origin:*\");header('Access-Control-Max-Age:86400');header('Content-Type:application/json');\nheader(\"Access-Control-Allow-Methods:GET\");if(isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS'])){header(\"Access-Control-Allow-Headers:{$_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']}\");}\n$response=new stdClass;\n$rules=array();\n// ***************************************************************\n$rule = new stdClass;\n$rule-\u003epathPattern = \"/donate-sol\";\n$rule-\u003eapiPath = \"https://www.solana-action-express.com/donate-sol-config\";\n$rules[] = $rule;\n$rule = new stdClass;\n$rule-\u003epathPattern = \"/donate-usdc\";\n$rule-\u003eapiPath = \"https://www.solana-action-express.com/donate-usdc-config\";\n$rules[] = $rule;\n$rule = new stdClass;\n$rule-\u003epathPattern = \"/mcsend\";\n$rule-\u003eapiPath = \"https://www.solana-action-express.com/mcsend\";\n$rules[] = $rule;\n// ***************************************************************\n$response-\u003erules=$rules;\necho json_encode($response);\nexit();\n```\n**.htaccess**\n```javascript\nRewriteRule ^actions.json$ actions.php [L]\n```\n\n# official solana actions docs\n\nhttps://solana.com/docs/advanced/actions\n\nhttps://github.com/solana-developers/solana-actions\n","funding_links":[],"categories":["Developer Tools"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FSolDapper%2Fsolana-action-express","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FSolDapper%2Fsolana-action-express","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FSolDapper%2Fsolana-action-express/lists"}