@moonpay/cli 0.9.3 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunk-QKMQZGJZ.js +33 -0
- package/dist/{chunk-2KI3H3A7.js → chunk-RWULBSKJ.js} +1 -1
- package/dist/index.js +6 -6
- package/dist/{mcp-YZE6ZZRA.js → mcp-ESIBPHE2.js} +1 -1
- package/dist/{store-TCMIGPOP.js → store-GLKXZHAJ.js} +1 -1
- package/package.json +1 -1
- package/skills/moonpay-commerce/SKILL.md +100 -0
- package/dist/chunk-HH5BMFIU.js +0 -30
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
process.noDeprecation = true; import { createRequire as __createRequire } from "module"; const require = __createRequire(import.meta.url);
|
|
2
|
-
import{existsSync as qe,readFileSync as Qe,writeFileSync as Ze,renameSync as et}from"fs";import{join as W}from"path";import{homedir as tt}from"os";import{randomBytes as rt}from"crypto";import{z as c}from"zod";import{randomBytes as P,scryptSync as L,createCipheriv as oe,createDecipheriv as ie}from"crypto";import{z as a}from"zod";var B=2**18,D=8,U=1,j=32,$=512*1024*1024,m=a.object({encryption:a.object({cipher:a.literal("aes-256-gcm"),kdf:a.literal("scrypt"),kdfparams:a.object({n:a.number(),r:a.number(),p:a.number()}),salt:a.string(),iv:a.string(),tag:a.string()}),data:a.string()});function v(e,t){let r=P(32),n=L(t,r,j,{N:B,r:D,p:U,maxmem:$}),o=P(12),s=oe("aes-256-gcm",n,o),f=Buffer.concat([s.update(e,"utf8"),s.final()]);return{encryption:{cipher:"aes-256-gcm",kdf:"scrypt",kdfparams:{n:B,r:D,p:U},salt:r.toString("base64"),iv:o.toString("base64"),tag:s.getAuthTag().toString("base64")},data:f.toString("base64")}}function E(e,t){let{salt:r,iv:n,tag:o,kdfparams:s}=e.encryption,f=L(t,Buffer.from(r,"base64"),j,{N:s.n,r:s.r,p:s.p,maxmem:$}),p=ie("aes-256-gcm",f,Buffer.from(n,"base64"),{authTagLength:16});return p.setAuthTag(Buffer.from(o,"base64")),Buffer.concat([p.update(Buffer.from(e.data,"base64")),p.final()]).toString("utf8")}var ut=c.enum(["solana","ethereum","base","arbitrum","polygon","optimism","bnb","avalanche","bitcoin","tron"]),se=c.enum(["solana","ethereum","bitcoin","tron"]),Y={solana:"solana",ethereum:"ethereum",base:"ethereum",arbitrum:"ethereum",polygon:"ethereum",optimism:"ethereum",bnb:"ethereum",avalanche:"ethereum",bitcoin:"bitcoin",tron:"tron"},H=c.object({solana:c.string().optional(),ethereum:c.string().optional(),bitcoin:c.string().optional(),tron:c.string().optional()}),ce=["base","arbitrum","polygon","optimism","bnb","avalanche"];function dt(e){let t={};if(e.solana&&(t.solana=e.solana),e.ethereum){t.ethereum=e.ethereum;for(let r of ce)t[r]=e.ethereum}return e.bitcoin&&(t.bitcoin=e.bitcoin),e.tron&&(t.tron=e.tron),t}var ae=c.object({name:c.string(),type:c.literal("hd"),mnemonic:c.string(),addresses:H,createdAt:c.string()}),fe=c.object({name:c.string(),type:c.literal("imported"),chain:se,privateKey:c.string(),addresses:H,createdAt:c.string()}),J=c.discriminatedUnion("type",[ae,fe]),mt=c.object({name:c.string(),type:c.enum(["hd","imported"]),addresses:c.record(c.string(),c.string()),createdAt:c.string()});import{execFileSync as k,execSync as we}from"child_process";import{randomBytes as Ke}from"crypto";import{existsSync as ke,readFileSync as _e,writeFileSync as Ae}from"fs";import{homedir as Te,platform as G}from"os";import{join as Oe}from"path";import*as i from"fs";import*as V from"os";import*as C from"path";import{readFileSync as pe}from"fs";import{join as le}from"path";import{homedir as ue}from"os";var de="0.
|
|
2
|
+
import{existsSync as qe,readFileSync as Qe,writeFileSync as Ze,renameSync as et}from"fs";import{join as W}from"path";import{homedir as tt}from"os";import{randomBytes as rt}from"crypto";import{z as c}from"zod";import{randomBytes as P,scryptSync as L,createCipheriv as oe,createDecipheriv as ie}from"crypto";import{z as a}from"zod";var B=2**18,D=8,U=1,j=32,$=512*1024*1024,m=a.object({encryption:a.object({cipher:a.literal("aes-256-gcm"),kdf:a.literal("scrypt"),kdfparams:a.object({n:a.number(),r:a.number(),p:a.number()}),salt:a.string(),iv:a.string(),tag:a.string()}),data:a.string()});function v(e,t){let r=P(32),n=L(t,r,j,{N:B,r:D,p:U,maxmem:$}),o=P(12),s=oe("aes-256-gcm",n,o),f=Buffer.concat([s.update(e,"utf8"),s.final()]);return{encryption:{cipher:"aes-256-gcm",kdf:"scrypt",kdfparams:{n:B,r:D,p:U},salt:r.toString("base64"),iv:o.toString("base64"),tag:s.getAuthTag().toString("base64")},data:f.toString("base64")}}function E(e,t){let{salt:r,iv:n,tag:o,kdfparams:s}=e.encryption,f=L(t,Buffer.from(r,"base64"),j,{N:s.n,r:s.r,p:s.p,maxmem:$}),p=ie("aes-256-gcm",f,Buffer.from(n,"base64"),{authTagLength:16});return p.setAuthTag(Buffer.from(o,"base64")),Buffer.concat([p.update(Buffer.from(e.data,"base64")),p.final()]).toString("utf8")}var ut=c.enum(["solana","ethereum","base","arbitrum","polygon","optimism","bnb","avalanche","bitcoin","tron"]),se=c.enum(["solana","ethereum","bitcoin","tron"]),Y={solana:"solana",ethereum:"ethereum",base:"ethereum",arbitrum:"ethereum",polygon:"ethereum",optimism:"ethereum",bnb:"ethereum",avalanche:"ethereum",bitcoin:"bitcoin",tron:"tron"},H=c.object({solana:c.string().optional(),ethereum:c.string().optional(),bitcoin:c.string().optional(),tron:c.string().optional()}),ce=["base","arbitrum","polygon","optimism","bnb","avalanche"];function dt(e){let t={};if(e.solana&&(t.solana=e.solana),e.ethereum){t.ethereum=e.ethereum;for(let r of ce)t[r]=e.ethereum}return e.bitcoin&&(t.bitcoin=e.bitcoin),e.tron&&(t.tron=e.tron),t}var ae=c.object({name:c.string(),type:c.literal("hd"),mnemonic:c.string(),addresses:H,createdAt:c.string()}),fe=c.object({name:c.string(),type:c.literal("imported"),chain:se,privateKey:c.string(),addresses:H,createdAt:c.string()}),J=c.discriminatedUnion("type",[ae,fe]),mt=c.object({name:c.string(),type:c.enum(["hd","imported"]),addresses:c.record(c.string(),c.string()),createdAt:c.string()});import{execFileSync as k,execSync as we}from"child_process";import{randomBytes as Ke}from"crypto";import{existsSync as ke,readFileSync as _e,writeFileSync as Ae}from"fs";import{homedir as Te,platform as G}from"os";import{join as Oe}from"path";import*as i from"fs";import*as V from"os";import*as C from"path";import{readFileSync as pe}from"fs";import{join as le}from"path";import{homedir as ue}from"os";var de="0.11.0",me="X-CLI-Version",ye="X-Agent-Id",y;function he(){if(y!==void 0)return y;try{y=JSON.parse(pe(le(ue(),".config","moonpay","consent.json"),"utf-8")).agentId??null}catch{y=null}return y??null}function M(){let e={"Content-Type":"application/json",[me]:de},t=he();return t&&(e[ye]=t),e}var g=C.join(V.homedir(),".config","moonpay"),N=C.join(g,"config.json"),S=C.join(g,"credentials.json"),h=C.join(g,".credentials.lock"),I={baseUrl:"https://agents.moonpay.com"};function l(){i.existsSync(g)||i.mkdirSync(g,{recursive:!0,mode:448})}function z(e,t,r){let n=e+`.tmp.${process.pid}`;i.writeFileSync(n,t,{encoding:"utf-8",mode:r}),i.renameSync(n,e)}var ge=3e4;function Se(){l();try{let e=i.openSync(h,i.constants.O_CREAT|i.constants.O_EXCL|i.constants.O_WRONLY,384);i.writeSync(e,JSON.stringify({pid:process.pid,ts:Date.now()})),i.closeSync(e)}catch(e){if(e.code!=="EEXIST")throw e;try{let t=JSON.parse(i.readFileSync(h,"utf-8"));if(Date.now()-t.ts<ge)return null}catch{}try{i.unlinkSync(h)}catch{}try{let t=i.openSync(h,i.constants.O_CREAT|i.constants.O_EXCL|i.constants.O_WRONLY,384);i.writeSync(t,JSON.stringify({pid:process.pid,ts:Date.now()})),i.closeSync(t)}catch{return null}}return()=>{try{i.unlinkSync(h)}catch{}}}function X(){if(!i.existsSync(N))return null;try{let e=JSON.parse(i.readFileSync(N,"utf-8"));return e.baseUrl?e:null}catch{return null}}function Et(){let e=X();return e||(Ce(I),I)}function w(){if(!i.existsSync(S))return null;let e=x();if(!e)return null;try{let t=JSON.parse(i.readFileSync(S,"utf-8")),r=m.parse(t),n=E(r,e),o=JSON.parse(n);return!o.accessToken||!o.baseUrl?null:o}catch{return null}}function xe(e){let t=K(),r=v(JSON.stringify(e),t);l(),z(S,JSON.stringify(r,null,2),384)}function Ce(e){l(),z(N,JSON.stringify(e,null,2),384)}function wt(){i.existsSync(S)&&i.unlinkSync(S)}function Kt(){let e=X(),t=w();return e?.baseUrl??t?.baseUrl??I.baseUrl}async function be(e,t,r){let n=await fetch(`${e}/api/tools/${encodeURIComponent(t)}`,{method:"POST",signal:AbortSignal.timeout(15e3),headers:M(),body:JSON.stringify(r)}),o=await n.json();if(!n.ok){let s=o;throw new Error(s?.error??`${t} failed (${n.status})`)}return o}async function ve(e){if(!e.refreshToken)throw new Error("No refresh token available");let t=Se();if(!t){await new Promise(n=>setTimeout(n,2e3));let r=w();if(r&&r.expiresAt>Date.now())return r;throw new Error("Token refresh failed (concurrent refresh in progress)")}try{let r=w();if(r&&r.expiresAt>Date.now()+6e4)return r;let n=await be(e.baseUrl,"refresh",{refreshToken:e.refreshToken}),o={accessToken:n.accessToken,refreshToken:n.refreshToken,expiresAt:n.expiresAt*1e3,baseUrl:e.baseUrl};return xe(o),o}finally{t()}}var Ee=300*1e3;async function kt(){let e=w();if(!e)return null;if(Date.now()>=e.expiresAt-Ee){if(e.refreshToken)try{return(await ve(e)).accessToken}catch{return null}return null}return e.accessToken}var u="moonpay-cli",b="encryption-key",_=Oe(Te(),".config","moonpay",".encryption-key");function Ne(e){try{k("security",["delete-generic-password","-s",u,"-a",b],{stdio:"ignore"})}catch{}k("security",["add-generic-password","-s",u,"-a",b,"-w",e],{stdio:"ignore"})}function Ie(){try{return k("security",["find-generic-password","-s",u,"-a",b,"-w"],{encoding:"utf-8",stdio:["ignore","pipe","ignore"]}).trim()}catch{return null}}function Fe(e){we(`printf '%s' | secret-tool store --label="${u}" service "${u}" account "${b}"`,{input:e,stdio:["pipe","ignore","ignore"]})}function Re(){try{return k("secret-tool",["lookup","service",u,"account",b],{encoding:"utf-8",stdio:["ignore","pipe","ignore"]}).trim()}catch{return null}}function We(e){l(),Ae(_,e,{encoding:"utf-8",mode:384})}function Pe(){try{return ke(_)&&_e(_,"utf-8").trim()||null}catch{return null}}function Be(e){try{let t=G();return t==="darwin"?(Ne(e),!0):t==="linux"?(Fe(e),!0):!1}catch{return!1}}function De(){let e=G();return e==="darwin"?Ie():e==="linux"?Re():null}function x(){let e=process.env.MOONPAY_ENCRYPTION_KEY;return e||(De()??Pe())}function K(){let e=x();if(e)return e;let t=Ke(32).toString("hex");return Be(t)||(We(t),process.stderr.write("Note: Keychain unavailable. Encryption key stored in "+_+`
|
|
3
3
|
`)),t}import{createHash as q}from"crypto";import{HDKey as F}from"@scure/bip32";import{mnemonicToSeedSync as A}from"@scure/bip39";import{keccak_256 as Q}from"@noble/hashes/sha3";import{derivePath as Ue}from"ed25519-hd-key";import*as Z from"bitcoinjs-lib";import Le from"ecpair";import*as T from"tiny-secp256k1";import{Keypair as je}from"@solana/web3.js";import $e from"bs58";var Ye=Le(T);function O(e,t=0){switch(e){case"solana":return`m/44'/501'/${t}'/0'`;case"ethereum":return`m/44'/60'/${t}'/0/0`;case"bitcoin":return`m/84'/0'/${t}'/0/0`;case"tron":return`m/44'/195'/${t}'/0/0`}}function d(e,t,r=0){switch(t){case"solana":return He(e,r);case"ethereum":return Je(e,r);case"bitcoin":return ze(e,r);case"tron":return Xe(e,r)}}function Yt(e,t=0){return{solana:d(e,"solana",t).address,ethereum:d(e,"ethereum",t).address,bitcoin:d(e,"bitcoin",t).address,tron:d(e,"tron",t).address}}function He(e,t){let r=A(e),n=O("solana",t),{key:o}=Ue(n,Buffer.from(r).toString("hex")),s=je.fromSeed(Uint8Array.from(o));return{privateKey:s.secretKey,address:s.publicKey.toBase58()}}function Je(e,t){let r=A(e),n=F.fromMasterSeed(r),o=O("ethereum",t),s=n.derive(o);if(!s.privateKey)throw new Error("Failed to derive EVM private key");let f=Me(s.publicKey);return{privateKey:s.privateKey,address:f}}function Me(e){let t=T.pointCompress(e,!1),n=ee(t.slice(1)).slice(-20),o="0x"+Buffer.from(n).toString("hex");return Ve(o)}function ee(e){return Q(e)}function Ve(e){let t=e.toLowerCase().replace("0x",""),r=Buffer.from(Q(Buffer.from(t,"utf8"))).toString("hex"),n="0x";for(let o=0;o<t.length;o++)n+=parseInt(r[o],16)>=8?t[o].toUpperCase():t[o];return n}function ze(e,t){let r=A(e),n=F.fromMasterSeed(r),o=O("bitcoin",t),s=n.derive(o);if(!s.privateKey)throw new Error("Failed to derive Bitcoin private key");let f=Ye.fromPrivateKey(Buffer.from(s.privateKey)),{address:p}=Z.payments.p2wpkh({pubkey:Buffer.from(f.publicKey)});if(!p)throw new Error("Failed to derive Bitcoin address");return{privateKey:s.privateKey,address:p}}function Xe(e,t){let r=A(e),n=F.fromMasterSeed(r),o=O("tron",t),s=n.derive(o);if(!s.privateKey)throw new Error("Failed to derive Tron private key");let f=Ge(s.publicKey);return{privateKey:s.privateKey,address:f}}function Ge(e){let t=T.pointCompress(e,!1),n=ee(t.slice(1)).slice(-20),o=Buffer.concat([Buffer.from([65]),Buffer.from(n)]),s=q("sha256").update(o).digest(),f=q("sha256").update(s).digest(),p=Buffer.concat([o,f.slice(0,4)]);return $e.encode(p)}import nt from"bs58";var te=W(tt(),".config","moonpay"),R=W(te,"wallets.json");function re(){if(!qe(R))return[];let e=x();if(!e)throw new Error("Encryption key not found. Set MOONPAY_ENCRYPTION_KEY or ensure OS keychain is accessible.");let t=JSON.parse(Qe(R,"utf-8")),r=m.parse(t),n=E(r,e);return(JSON.parse(n).wallets??[]).map(s=>J.parse(s))}function ot(e){let t=K(),r=JSON.stringify({wallets:e}),n=v(r,t);l();let o=W(te,`.wallets.${rt(4).toString("hex")}.tmp`);Ze(o,JSON.stringify(n,null,2),{mode:384}),et(o,R)}function ne(e){let t=re();e(t),ot(t)}function it(e){let t=re();for(let r of t){if(r.name===e)return r;for(let n of Object.values(r.addresses))if(n===e)return r}return null}function tr(e){let t=it(e);if(!t)throw new Error(`Wallet "${e}" not found`);return t}function rr(e){ne(t=>{if(t.some(r=>r.name===e.name))throw new Error(`Wallet "${e.name}" already exists`);t.push(e)})}function nr(e){ne(t=>{let r=t.findIndex(n=>n.name===e);if(r===-1)throw new Error(`Wallet "${e}" not found`);t.splice(r,1)})}function or(e,t){let r=Y[t];if(e.type==="imported"){if(e.chain!==r)throw new Error(`Wallet "${e.name}" was imported for ${e.chain}, cannot sign for ${t}.`);return{privateKey:st(e.privateKey,r),address:e.addresses[r]}}let n=d(e.mnemonic,r);return{privateKey:n.privateKey,address:n.address}}function st(e,t){if(t==="solana")return nt.decode(e);let r=e.startsWith("0x")?e.slice(2):e;return Uint8Array.from(Buffer.from(r,"hex"))}export{de as a,M as b,l as c,Et as d,w as e,xe as f,wt as g,Kt as h,be as i,ve as j,kt as k,Yt as l,ut as m,Y as n,H as o,dt as p,mt as q,re as r,ot as s,ne as t,it as u,tr as v,rr as w,nr as x,or as y};
|
package/dist/index.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
process.noDeprecation = true; import { createRequire as __createRequire } from "module"; const require = __createRequire(import.meta.url);
|
|
3
|
-
import{a as R,b as S,c as T,d as j,e as k}from"./chunk-
|
|
4
|
-
`):e.map(r=>{if(typeof r!="object"||r===null)return`${n}- ${
|
|
3
|
+
import{a as R,b as S,c as T,d as j,e as k}from"./chunk-QKMQZGJZ.js";import{a as C,h as A,n as v,u as J}from"./chunk-RWULBSKJ.js";import{Command as ne}from"commander";var Y=!process.env.NO_COLOR&&process.stdout.isTTY===!0;function $(e){return t=>Y?`${e}${t}\x1B[0m`:t}var p={bold:$("\x1B[1m"),dim:$("\x1B[2m"),green:$("\x1B[32m"),yellow:$("\x1B[33m"),cyan:$("\x1B[36m"),red:$("\x1B[31m")};function O(e){if(e==null)return!0;let t=typeof e;return t==="string"||t==="number"||t==="boolean"}function _(e){return e==null?"-":String(e)}function N(e,t=0){let n=" ".repeat(t);return O(e)?`${n}${_(e)}`:Array.isArray(e)?e.length===0?`${n}${p.dim("(empty)")}`:e.every(O)?e.map(r=>`${n}- ${_(r)}`).join(`
|
|
4
|
+
`):e.map(r=>{if(typeof r!="object"||r===null)return`${n}- ${_(r)}`;let o=Object.entries(r),a=[],[c,f]=o[0];O(f)?a.push(`${n}- ${p.bold(c)}: ${_(f)}`):(a.push(`${n}- ${p.bold(c)}:`),a.push(N(f,t+2)));for(let[m,y]of o.slice(1))O(y)?a.push(`${n} ${p.bold(m)}: ${_(y)}`):(a.push(`${n} ${p.bold(m)}:`),a.push(N(y,t+2)));return a.join(`
|
|
5
5
|
`)}).join(`
|
|
6
6
|
|
|
7
|
-
`):typeof e=="object"&&e!==null?Object.entries(e).map(([o,a])=>
|
|
8
|
-
${
|
|
9
|
-
`):""}function H(e){if(typeof e!="object"||e===null)return e;let t=e;return"data"in t?t.data:"items"in t&&Array.isArray(t.items)&&Object.keys(t).filter(r=>r!=="items").length===0?t.items:e}function F(e,t){return t==="json"?JSON.stringify(e,null,2):
|
|
7
|
+
`):typeof e=="object"&&e!==null?Object.entries(e).map(([o,a])=>O(a)?`${n}${p.bold(o)}: ${_(a)}`:`${n}${p.bold(o)}:
|
|
8
|
+
${N(a,t+1)}`).join(`
|
|
9
|
+
`):""}function H(e){if(typeof e!="object"||e===null)return e;let t=e;return"data"in t?t.data:"items"in t&&Array.isArray(t.items)&&Object.keys(t).filter(r=>r!=="items").length===0?t.items:e}function F(e,t){return t==="json"?JSON.stringify(e,null,2):N(H(e))}import{readFileSync as z,writeFileSync as W,mkdirSync as B}from"fs";import{join as E}from"path";import{homedir as G}from"os";var x=E(G(),".config","moonpay"),I=E(x,"update-check.json"),V=1440*60*1e3,Q=3e3;function X(){try{let e=z(I,"utf-8");return JSON.parse(e)}catch{return null}}function ee(e){try{B(x,{recursive:!0}),W(I,JSON.stringify(e))}catch{}}function K(e,t){let n=e.split(".").map(Number),r=t.split(".").map(Number);for(let o=0;o<3;o++){if((n[o]??0)>(r[o]??0))return!0;if((n[o]??0)<(r[o]??0))return!1}return!1}function P(e,t){return["",p.yellow(`Update available: ${e} \u2192 ${t}`),p.dim("Run `npm i -g @moonpay/cli` to update."),""].join(`
|
|
10
10
|
`)}function L(e){let t=null,n=X();if(n&&Date.now()-n.checkedAt<V)return K(n.latest,e)&&(t=P(e,n.latest)),()=>t;let r=new AbortController,o=setTimeout(()=>r.abort(),Q);return fetch("https://registry.npmjs.org/@moonpay%2fcli/latest",{signal:r.signal}).then(a=>a.json()).then(a=>{let c=a.version;c&&(ee({latest:c,checkedAt:Date.now()}),K(c,e)&&(t=P(e,c)))}).catch(()=>{}).finally(()=>clearTimeout(o)),()=>t}var te=L(C),h=new ne;h.name("moonpay").description(`MoonPay CLI \u2014 the crypto onramp for AI agents
|
|
11
11
|
|
|
12
12
|
Your agents need money. MoonPay gives them wallets, funds, and tools
|
|
@@ -14,5 +14,5 @@ ${_(a,t+1)}`).join(`
|
|
|
14
14
|
|
|
15
15
|
Run \`mp skill install\` to install AI skills for Claude Code.
|
|
16
16
|
|
|
17
|
-
`+T).version(C).option("--json","Output as JSON instead of YAML");function re(){return h.opts().json?"json":"yaml"}function D(e){console.log(F(e,re()))}function U(){let e=te();e&&process.stderr.write(e)}h.command("mcp").description("Start MCP server over stdio (for Claude Desktop, Claude Code, etc.)").action(async()=>{let{startMcpServer:e}=await import("./mcp-
|
|
17
|
+
`+T).version(C).option("--json","Output as JSON instead of YAML");function re(){return h.opts().json?"json":"yaml"}function D(e){console.log(F(e,re()))}function U(){let e=te();e&&process.stderr.write(e)}h.command("mcp").description("Start MCP server over stdio (for Claude Desktop, Claude Code, etc.)").action(async()=>{let{startMcpServer:e}=await import("./mcp-ESIBPHE2.js");await e()});function M(e,t){let n=e;for(let r of t){let o=n.commands.find(a=>a.name()===r);o||(o=n.command(r)),n=o}return n}function Z(e,t=""){let n=[];for(let[r,o]of Object.entries(e)){let a=t?`${t}-${r}`:r,c=o;for(;c._def.typeName==="ZodEffects";)c=c._def.schema;let f=c;f._def.typeName==="ZodNullable"&&(f=f._def.innerType),f._def.typeName==="ZodObject"&&f.shape?n.push(...Z(f.shape,a)):n.push({flatKey:a,field:o,path:a.split("-")})}return n}function oe(e,t){let n={};for(let{flatKey:r,path:o}of t){let a=r.replace(/-([a-z])/g,(f,m)=>m.toUpperCase()),c=a in e?e[a]:e[r];if(o.length===1)n[o[0]]=c;else{let f=n;for(let m=0;m<o.length-1;m++)(!f[o[m]]||typeof f[o[m]]!="object")&&(f[o[m]]={}),f=f[o[m]];f[o[o.length-1]]=c}}return n}function se(e,t){for(let n of t){let r=n.schema.name.split("_"),o=r.pop(),c=M(e,r).command(o).description(n.schema.description),f=n.schema.input.shape??{},m=Z(f),y=[],b=[],w=[];for(let{flatKey:u,field:i}of m){let s=i.description??u,l=i;for(;l._def.typeName==="ZodEffects";)l=l._def.schema;let g=l._def.typeName,d=l;d._def.typeName==="ZodNullable"&&(d=d._def.innerType),d._def.typeName==="ZodNumber"&&b.push(u),d._def.typeName==="ZodRecord"&&w.push(u),g==="ZodBoolean"?c.option(`--${u}`,s,!1):g==="ZodNullable"?(c.option(`--${u} <${u}>`,s),y.push(u)):c.requiredOption(`--${u} <${u}>`,s)}c.action(async u=>{n.schema.name.startsWith("consent_")||await j.handler({});for(let s of y){let l=s.replace(/-([a-z])/g,(g,d)=>d.toUpperCase());u[l]===void 0&&(u[l]=null)}for(let s of b){let l=s.replace(/-([a-z])/g,(g,d)=>d.toUpperCase());u[l]!=null&&typeof u[l]=="string"&&(u[l]=Number(u[l]))}for(let s of w){let l=s.replace(/-([a-z])/g,(g,d)=>d.toUpperCase());if(typeof u[l]=="string")try{u[l]=JSON.parse(u[l])}catch{console.error(`Invalid JSON for --${s}`),process.exit(1)}}let i=oe(u,m);try{let s=await n.handler(i);D(s)}catch(s){console.error(s.message),process.exit(1)}})}}function ie(e){if(e.$ref&&e.definitions){let t=e.$ref.replace("#/definitions/","");return e.definitions[t]}return e}function ae(e){return Array.isArray(e.type)?e.type.includes("null"):e.anyOf?e.anyOf.some(t=>t.type==="null"):!1}function ce(e){return Array.isArray(e.type)?e.type.includes("object"):e.anyOf?e.anyOf.some(t=>t.type==="object"):e.type==="object"}function le(e){return Array.isArray(e.type)?e.type.some(t=>t==="number"||t==="integer"):e.anyOf?e.anyOf.some(t=>t.type==="number"||t.type==="integer"):e.type==="number"||e.type==="integer"}function fe(e){let t=e.wallet,n=e.chain;if(typeof t!="string"||typeof n!="string")return;let r=J(t);if(!r)return;let o=v[n];if(!o)return;let a=r.addresses[o];a&&(e.wallet=a)}var q=new Set(["swaps_transaction_build","token_transfer","transaction_register","virtual-account_offramp_initiate","prediction-market_position_buy","prediction-market_position_sell","commerce_cart_update","commerce_checkout_start","commerce_checkout_pay"]);function ue(e,t){for(let n of t){if(q.has(n.name))continue;let r=n.name.split("_"),o=r.pop(),a=M(e,r);if(a.commands.find(i=>i.name()===o))continue;let c=a.command(o).description(n.description),f=ie(n.inputSchema),m=f.properties??{},y=new Set(f.required??[]),b=[],w=[],u=[];for(let[i,s]of Object.entries(m)){let l=s.description??i,g=ae(s),d=ce(s);le(s)&&w.push(i),d?(u.push(i),y.has(i)&&!g?c.requiredOption(`--${i} <json>`,`${l} (as JSON)`):(c.option(`--${i} <json>`,`${l} (as JSON)`),b.push(i))):g||!y.has(i)?(c.option(`--${i} <${i}>`,l),b.push(i)):c.requiredOption(`--${i} <${i}>`,l)}c.action(async i=>{await j.handler({});for(let s of b)i[s]===void 0&&(i[s]=null);for(let s of w)i[s]!=null&&typeof i[s]=="string"&&(i[s]=Number(i[s]));for(let s of u)if(typeof i[s]=="string")try{i[s]=JSON.parse(i[s])}catch{console.error(`Invalid JSON for --${s}`),process.exit(1)}try{fe(i);let s=A(),l=await R(s,n.name,i);D(l),U()}catch(s){console.error(s.message),process.exit(1)}})}}se(h,k);ue(h,S);h.command("tools").description("List available tools").action(()=>{let e=[...k.map(n=>({name:n.schema.name,description:n.schema.description})),...S.filter(n=>!k.some(r=>r.schema.name===n.name)&&!q.has(n.name)).map(n=>({name:n.name,description:n.description}))].sort((n,r)=>n.name.localeCompare(r.name)),t=[];for(let n of e){let r=n.name.replace(/_/g," ");t.push(` ${p.green(r.padEnd(28))} ${p.dim(n.description)}`)}t.push(""),t.push(p.dim(`${e.length} tools`)),console.log(t.join(`
|
|
18
18
|
`)),U()});h.parse();
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
process.noDeprecation = true; import { createRequire as __createRequire } from "module"; const require = __createRequire(import.meta.url);
|
|
2
|
-
import{a as d,b as y,e as l}from"./chunk-
|
|
2
|
+
import{a as d,b as y,e as l}from"./chunk-QKMQZGJZ.js";import{a as u,h as f}from"./chunk-RWULBSKJ.js";import{Server as x}from"@modelcontextprotocol/sdk/server/index.js";import{StdioServerTransport as N}from"@modelcontextprotocol/sdk/server/stdio.js";import{CallToolRequestSchema as T,ListToolsRequestSchema as v}from"@modelcontextprotocol/sdk/types.js";import{zodToJsonSchema as q}from"zod-to-json-schema";var h=new Map(l.map(s=>[s.schema.name,s]));function A(s){let n=s.inputSchema;if(n.$ref&&n.definitions){let c=n.$ref.replace("#/definitions/","");return n.definitions[c]??n}return n}async function J(){let s=new x({name:"moonpay",version:u},{capabilities:{tools:{listChanged:!0}}}),n=l.map(e=>({name:e.schema.name,description:e.schema.description,inputSchema:q(e.schema.input)})),c=new Map;for(let e of y){if(h.has(e.name))continue;let t=A(e);c.set(e.name,t.properties??{}),n.push({name:e.name,description:e.description,inputSchema:{type:"object",properties:t.properties??{},...t.required?{required:t.required}:{},...t.additionalProperties!==void 0?{additionalProperties:t.additionalProperties}:{}}})}let g=new Map(n.map(e=>[e.name,e]));s.setRequestHandler(v,async()=>({tools:n.map(e=>({name:e.name,description:e.description,inputSchema:e.inputSchema}))})),s.setRequestHandler(T,async e=>{let{name:t,arguments:o={}}=e.params;if(!g.has(t))return{content:[{type:"text",text:`Unknown tool: ${t}`}],isError:!0};try{let i=h.get(t);if(i){let p=i.schema.input.shape??{};for(let[m,a]of Object.entries(p))o[m]===void 0&&a._def.typeName==="ZodNullable"&&(o[m]=null);let r=await i.handler(o);return{content:[{type:"text",text:JSON.stringify(r,null,2)}]}}let b=c.get(t)??{};for(let[p,r]of Object.entries(b))o[p]===void 0&&(Array.isArray(r.type)?r.type.includes("null"):r.anyOf?.some(R=>R.type==="null"))&&(o[p]=null),(r.type==="number"||r.type==="integer"||Array.isArray(r.type)&&r.type.some(a=>a==="number"||a==="integer")||r.anyOf?.some(a=>a.type==="number"||a.type==="integer"))&&typeof o[p]=="string"&&(o[p]=Number(o[p]));let w=f(),O=await d(w,t,o);return{content:[{type:"text",text:JSON.stringify(O,null,2)}]}}catch(i){return{content:[{type:"text",text:i instanceof Error?i.message:String(i)}],isError:!0}}});let S=new N;await s.connect(S)}export{J as startMcpServer};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
process.noDeprecation = true; import { createRequire as __createRequire } from "module"; const require = __createRequire(import.meta.url);
|
|
2
|
-
import{r as a,s as b,t as c,u as d,v as e,w as f,x as g,y as h}from"./chunk-
|
|
2
|
+
import{r as a,s as b,t as c,u as d,v as e,w as f,x as g,y as h}from"./chunk-RWULBSKJ.js";export{f as addWallet,d as findWallet,e as findWalletOrThrow,a as loadWallets,c as mutateWallets,g as removeWallet,h as resolveSigningKey,b as saveWallets};
|
package/package.json
CHANGED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: moonpay-commerce
|
|
3
|
+
description: Browse Shopify stores, search products, manage a cart, and checkout with crypto via Solana Pay. No login required.
|
|
4
|
+
tags: [commerce, shopping]
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Shop with crypto
|
|
8
|
+
|
|
9
|
+
## Goal
|
|
10
|
+
|
|
11
|
+
Browse Solana Pay-enabled Shopify stores, add items to a cart, and pay with crypto. The entire flow runs from the CLI — no browser needed.
|
|
12
|
+
|
|
13
|
+
## Commands
|
|
14
|
+
|
|
15
|
+
### List stores
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
mp commerce store list
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### Search products
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
mp commerce product search --store <store> --query <search-term>
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### Get product details
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
mp commerce product retrieve --store <store> --productId <product-id>
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Add item to cart
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
mp commerce cart add \
|
|
37
|
+
--store <store> \
|
|
38
|
+
--variantId <variant-id> \
|
|
39
|
+
--quantity <number> \
|
|
40
|
+
--cartId <cart-id> # omit to create a new cart
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### View cart
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
mp commerce cart retrieve --store <store> --cartId <cart-id>
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Remove item from cart
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
mp commerce cart remove --store <store> --cartId <cart-id> --lineId <line-id>
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### Checkout and pay
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
mp commerce checkout \
|
|
59
|
+
--wallet <wallet-name> \
|
|
60
|
+
--store <store> \
|
|
61
|
+
--cartId <cart-id> \
|
|
62
|
+
--chain solana \
|
|
63
|
+
--email <buyer-email> \
|
|
64
|
+
--firstName <first> \
|
|
65
|
+
--lastName <last> \
|
|
66
|
+
--address <street-address> \
|
|
67
|
+
--city <city> \
|
|
68
|
+
--postalCode <zip> \
|
|
69
|
+
--country <country-name>
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Example flow
|
|
73
|
+
|
|
74
|
+
1. Browse stores: `mp commerce store list`
|
|
75
|
+
2. Search: `mp commerce product search --store ryder.id --query "ryder"`
|
|
76
|
+
3. Add to cart: `mp commerce cart add --store ryder.id --variantId "gid://shopify/ProductVariant/51751218774319" --quantity 1`
|
|
77
|
+
4. Check cart: `mp commerce cart retrieve --store ryder.id --cartId <id-from-step-3>`
|
|
78
|
+
5. Checkout: `mp commerce checkout --wallet main --store ryder.id --cartId <id> --chain solana --email buyer@example.com --firstName John --lastName Doe --address "123 Main St" --city Amsterdam --postalCode 1011 --country Netherlands`
|
|
79
|
+
|
|
80
|
+
## How it works
|
|
81
|
+
|
|
82
|
+
1. Stores expose a Shopify MCP endpoint for browsing and cart management
|
|
83
|
+
2. `cart add` creates or updates a cart (no auth needed, cart ID is the handle)
|
|
84
|
+
3. `checkout` calls the API to start a Helio payment, signs the transaction locally, and submits
|
|
85
|
+
4. Helio pays gas — the buyer only pays the item price in USDC
|
|
86
|
+
5. Returns a transaction signature and order confirmation URL
|
|
87
|
+
|
|
88
|
+
## Tips
|
|
89
|
+
|
|
90
|
+
- Run `cart add` multiple times to add different items — pass the `--cartId` from the first call
|
|
91
|
+
- Use `product search` to find variant IDs — each variant has a Shopify GID
|
|
92
|
+
- The `--country` flag takes full country names (e.g. "United States", "Netherlands")
|
|
93
|
+
- Checkout takes 30-90 seconds — the API automates the Shopify checkout flow
|
|
94
|
+
- Currently supports Solana chain only for payment
|
|
95
|
+
|
|
96
|
+
## Related skills
|
|
97
|
+
|
|
98
|
+
- **moonpay-auth** — Set up a local wallet for signing
|
|
99
|
+
- **moonpay-check-wallet** — Check USDC balance before checkout
|
|
100
|
+
- **moonpay-swap-tokens** — Swap tokens to get USDC for payment
|