@moonpay/cli 1.43.0 → 1.44.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-Y4OG6H5I.js → chunk-7VEPX3MI.js} +3 -3
- package/dist/{chunk-ACVWTCVT.js → chunk-HKDLPDJU.js} +1 -1
- package/dist/{chunk-LSW2X7PQ.js → chunk-IBLWQCA2.js} +1 -1
- package/dist/{chunk-O3GX6BAR.js → chunk-V4NDQ53W.js} +2 -2
- package/dist/{client-RPDEID5C.js → client-S2OYW27G.js} +1 -1
- package/dist/index.js +2 -2
- package/dist/{ledger-RZLTSHHM.js → ledger-MQBFDQFZ.js} +2 -2
- package/dist/{mcp-IFJKTYLK.js → mcp-Q4CQRNQ2.js} +1 -1
- package/dist/{store-ZN2XIIR5.js → store-FO6TZ6MZ.js} +1 -1
- package/package.json +1 -1
- package/skills/moonpay-buy-the-dip/SKILL.md +160 -0
- package/skills/moonpay-take-profit-ladder/SKILL.md +154 -0
- package/skills/moonpay-trading-automation/SKILL.md +22 -7
- package/skills/moonpay-trailing-stop/SKILL.md +153 -0
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
process.noDeprecation = true; import { createRequire as __createRequire } from "module"; const require = __createRequire(import.meta.url);
|
|
2
|
-
import{b as m,d as b}from"./chunk-LMDE72OE.js";var G={};b(G,{decrypt:()=>k,encrypt:()=>T,encryptedFileSchema:()=>O});import{randomBytes as A,scryptSync as v,createCipheriv as X,createDecipheriv as $}from"crypto";import{z as i}from"zod";function T(n,t){let r=A(32),o=v(t,r,D,{N:R,r:L,p:F,maxmem:K}),s=A(12),c=X("aes-256-gcm",o,s),_=Buffer.concat([c.update(n,"utf8"),c.final()]);return{encryption:{cipher:"aes-256-gcm",kdf:"scrypt",kdfparams:{n:R,r:L,p:F},salt:r.toString("base64"),iv:s.toString("base64"),tag:c.getAuthTag().toString("base64")},data:_.toString("base64")}}function k(n,t){let{salt:r,iv:o,tag:s,kdfparams:c}=n.encryption,_=v(t,Buffer.from(r,"base64"),D,{N:c.n,r:c.r,p:c.p,maxmem:K}),x=$("aes-256-gcm",_,Buffer.from(o,"base64"),{authTagLength:16});return x.setAuthTag(Buffer.from(s,"base64")),Buffer.concat([x.update(Buffer.from(n.data,"base64")),x.final()]).toString("utf8")}var R,L,F,D,K,O,P=m(()=>{"use strict";R=2**18,L=8,F=1,D=32,K=512*1024*1024,O=i.object({encryption:i.object({cipher:i.literal("aes-256-gcm"),kdf:i.literal("scrypt"),kdfparams:i.object({n:i.number(),r:i.number(),p:i.number()}),salt:i.string(),iv:i.string(),tag:i.string()}),data:i.string()})});import{readFileSync as W}from"fs";import{join as z}from"path";import{homedir as q}from"os";function en(){if(f!==void 0)return f;try{f=JSON.parse(W(z(q(),".config","moonpay","consent.json"),"utf-8")).agentId??null}catch{f=null}return f??null}function rn(){return process.env.OPENCLAW_SHELL?"openclaw":process.env.CLAUDECODE?"claude-code":process.env.CODEX_CI?"codex":process.env.GEMINI_CLI?"gemini-cli":"human"}function U(){let n={"Content-Type":"application/json",[Z]:Q,[tn]:rn()},t=en();return t&&(n[nn]=t),n}var Q,Z,nn,f,tn,j=m(()=>{"use strict";Q="1.
|
|
2
|
+
import{b as m,d as b}from"./chunk-LMDE72OE.js";var G={};b(G,{decrypt:()=>k,encrypt:()=>T,encryptedFileSchema:()=>O});import{randomBytes as A,scryptSync as v,createCipheriv as X,createDecipheriv as $}from"crypto";import{z as i}from"zod";function T(n,t){let r=A(32),o=v(t,r,D,{N:R,r:L,p:F,maxmem:K}),s=A(12),c=X("aes-256-gcm",o,s),_=Buffer.concat([c.update(n,"utf8"),c.final()]);return{encryption:{cipher:"aes-256-gcm",kdf:"scrypt",kdfparams:{n:R,r:L,p:F},salt:r.toString("base64"),iv:s.toString("base64"),tag:c.getAuthTag().toString("base64")},data:_.toString("base64")}}function k(n,t){let{salt:r,iv:o,tag:s,kdfparams:c}=n.encryption,_=v(t,Buffer.from(r,"base64"),D,{N:c.n,r:c.r,p:c.p,maxmem:K}),x=$("aes-256-gcm",_,Buffer.from(o,"base64"),{authTagLength:16});return x.setAuthTag(Buffer.from(s,"base64")),Buffer.concat([x.update(Buffer.from(n.data,"base64")),x.final()]).toString("utf8")}var R,L,F,D,K,O,P=m(()=>{"use strict";R=2**18,L=8,F=1,D=32,K=512*1024*1024,O=i.object({encryption:i.object({cipher:i.literal("aes-256-gcm"),kdf:i.literal("scrypt"),kdfparams:i.object({n:i.number(),r:i.number(),p:i.number()}),salt:i.string(),iv:i.string(),tag:i.string()}),data:i.string()})});import{readFileSync as W}from"fs";import{join as z}from"path";import{homedir as q}from"os";function en(){if(f!==void 0)return f;try{f=JSON.parse(W(z(q(),".config","moonpay","consent.json"),"utf-8")).agentId??null}catch{f=null}return f??null}function rn(){return process.env.OPENCLAW_SHELL?"openclaw":process.env.CLAUDECODE?"claude-code":process.env.CODEX_CI?"codex":process.env.GEMINI_CLI?"gemini-cli":"human"}function U(){let n={"Content-Type":"application/json",[Z]:Q,[tn]:rn()},t=en();return t&&(n[nn]=t),n}var Q,Z,nn,f,tn,j=m(()=>{"use strict";Q="1.44.0",Z="X-CLI-Version",nn="X-Agent-Id";tn="X-Agent"});import*as e from"fs";import*as Y from"os";import*as g from"path";function d(){e.existsSync(l)||e.mkdirSync(l,{recursive:!0,mode:448})}function H(n,t,r){let o=n+`.tmp.${process.pid}`;e.writeFileSync(o,t,{encoding:"utf-8",mode:r}),e.renameSync(o,n)}function sn(){d();try{let n=e.openSync(u,e.constants.O_CREAT|e.constants.O_EXCL|e.constants.O_WRONLY,384);e.writeSync(n,JSON.stringify({pid:process.pid,ts:Date.now()})),e.closeSync(n)}catch(n){if(n.code!=="EEXIST")throw n;try{let t=JSON.parse(e.readFileSync(u,"utf-8"));if(Date.now()-t.ts<on)return null}catch{}try{e.unlinkSync(u)}catch{}try{let t=e.openSync(u,e.constants.O_CREAT|e.constants.O_EXCL|e.constants.O_WRONLY,384);e.writeSync(t,JSON.stringify({pid:process.pid,ts:Date.now()})),e.closeSync(t)}catch{return null}}return()=>{try{e.unlinkSync(u)}catch{}}}function B(){if(!e.existsSync(w))return null;try{let n=JSON.parse(e.readFileSync(w,"utf-8"));return n.baseUrl?n:null}catch{return null}}function Pn(){let n=B();return n||(an(N),N)}function S(){if(!e.existsSync(p))return null;let n=h();if(!n)return null;try{let t=JSON.parse(e.readFileSync(p,"utf-8")),r=O.parse(t),o=k(r,n),s=JSON.parse(o);return!s.accessToken||!s.baseUrl?null:s}catch{return null}}function cn(n){let t=I(),r=T(JSON.stringify(n),t);d(),H(p,JSON.stringify(r,null,2),384)}function an(n){d(),H(w,JSON.stringify(n,null,2),384)}function Un(){e.existsSync(p)&&e.unlinkSync(p)}function jn(){let n=B(),t=S();return n?.baseUrl??t?.baseUrl??N.baseUrl}async function fn(n,t,r){let o=await fetch(`${n}/api/tools/${encodeURIComponent(t)}`,{method:"POST",signal:AbortSignal.timeout(15e3),headers:U(),body:JSON.stringify(r)}),s=await o.json();if(!o.ok){let c=s;throw new Error(c?.error??`${t} failed (${o.status})`)}return s}async function un(n){if(!n.refreshToken)throw new Error("No refresh token available");let t=sn();if(!t){await new Promise(o=>setTimeout(o,2e3));let r=S();if(r&&r.expiresAt>Date.now())return r;throw new Error("Token refresh failed (concurrent refresh in progress)")}try{let r=S();if(r&&r.expiresAt>Date.now()+6e4)return r;let o=await fn(n.baseUrl,"refresh",{refreshToken:n.refreshToken}),s={accessToken:o.accessToken,refreshToken:o.refreshToken,expiresAt:o.expiresAt*1e3,baseUrl:n.baseUrl};return cn(s),s}finally{t()}}async function Jn(){let n=S();if(!n)return null;if(Date.now()>=n.expiresAt-ln){if(n.refreshToken)try{return(await un(n)).accessToken}catch{return null}return null}return n.accessToken}var l,w,p,u,N,on,ln,V=m(()=>{"use strict";P();J();j();l=g.join(Y.homedir(),".config","moonpay"),w=g.join(l,"config.json"),p=g.join(l,"credentials.json"),u=g.join(l,".credentials.lock"),N={baseUrl:"https://agents.moonpay.com"};on=3e4;ln=300*1e3});var Nn={};b(Nn,{ensureEncryptionKey:()=>I,getEncryptionKey:()=>h});import{execFileSync as C,execSync as pn}from"child_process";import{randomBytes as gn}from"crypto";import{existsSync as dn,readFileSync as yn,writeFileSync as mn}from"fs";import{homedir as Sn,platform as M}from"os";import{join as hn}from"path";function Cn(n){try{C("security",["delete-generic-password","-s",a,"-a",y],{stdio:"ignore"})}catch{}C("security",["add-generic-password","-s",a,"-a",y,"-w",n],{stdio:"ignore"})}function En(){try{return C("security",["find-generic-password","-s",a,"-a",y,"-w"],{encoding:"utf-8",stdio:["ignore","pipe","ignore"]}).trim()}catch{return null}}function _n(n){pn(`printf '%s' | secret-tool store --label="${a}" service "${a}" account "${y}"`,{input:n,stdio:["pipe","ignore","ignore"]})}function xn(){try{return C("secret-tool",["lookup","service",a,"account",y],{encoding:"utf-8",stdio:["ignore","pipe","ignore"]}).trim()}catch{return null}}function On(n){d(),mn(E,n,{encoding:"utf-8",mode:384})}function Tn(){try{return dn(E)&&yn(E,"utf-8").trim()||null}catch{return null}}function kn(n){try{let t=M();return t==="darwin"?(Cn(n),!0):t==="linux"?(_n(n),!0):!1}catch{return!1}}function wn(){let n=M();return n==="darwin"?En():n==="linux"?xn():null}function h(){let n=process.env.MOONPAY_ENCRYPTION_KEY;return n||(wn()??Tn())}function I(){let n=h();if(n)return n;let t=gn(32).toString("hex");return kn(t)||(On(t),process.stderr.write("Note: Keychain unavailable. Encryption key stored in "+E+`
|
|
3
3
|
`)),t}var a,y,E,J=m(()=>{"use strict";V();a="moonpay-cli",y="encryption-key",E=hn(Sn(),".config","moonpay",".encryption-key")});export{G as a,P as b,Nn as c,J as d,Q as e,U as f,j as g,d as h,Pn as i,S as j,cn as k,Un as l,jn as m,un as n,Jn as o,V as p};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
process.noDeprecation = true; import { createRequire as __createRequire } from "module"; const require = __createRequire(import.meta.url);
|
|
2
|
-
import{f as vt,g as yt,j as Pt,m as Ct,n as kt,o as It,p as At}from"./chunk-ACVWTCVT.js";var n=class extends Error{constructor(r,i,u){super(r);this.status=i;this.toolName=u;this.name="MoonPayError"}},c=class extends n{constructor(t="Authentication required"){super(t,401),this.name="AuthError"}},o=class extends n{constructor(t="Rate limit exceeded"){super(t,429),this.name="RateLimitError"}},l=class extends n{constructor(t,r){super(t,400,r),this.name="ValidationError"}},s=class extends n{constructor(t){super(`Tool not found: ${t}`,404,t),this.name="ToolNotFoundError"}},p=class extends n{constructor(t,r){super(`Tool "${t}" has been renamed to "${r}"`,410,t),this.name="ToolRenamedError",this.newName=r}};var Mt="https://agents.moonpay.com",Rt=36e4,h=class{constructor(t={}){this.baseUrl=(t.baseUrl??Mt).replace(/\/$/,""),this.auth=t.auth??{type:"none"},this.timeout=t.timeout??Rt,this.headers=t.headers??{}}async _call(t,r){let i=`${this.baseUrl}/api/tools/${encodeURIComponent(t)}`,u=await this.buildHeaders(),a=await fetch(i,{method:"POST",headers:u,body:JSON.stringify(r),signal:AbortSignal.timeout(this.timeout)});if(a.status===401&&this.auth.type==="bearer"&&this.auth.refreshToken)try{let gt=await this.auth.refreshToken();u.Authorization=`Bearer ${gt}`,a=await fetch(i,{method:"POST",headers:u,body:JSON.stringify(r),signal:AbortSignal.timeout(this.timeout)})}catch{throw new c("Token refresh failed")}return this.handleResponse(a,t)}async buildHeaders(){let t={"Content-Type":"application/json",...this.headers};if(this.auth.type==="bearer"){let r=await this.auth.getToken();r&&(t.Authorization=`Bearer ${r}`)}return t}async handleResponse(t,r){if(t.ok)return t.json();let i;try{i=await t.json()}catch{i={error:t.statusText}}let u=i?.error??i?.message,a=typeof u=="string"?u:u?JSON.stringify(u):`Request failed with status ${t.status}`;switch(t.status){case 400:throw new l(a,r);case 401:throw new c(a);case 404:throw new s(r);case 410:throw new p(r,i?.newName??"unknown");case 429:throw new o(a);default:throw new n(a,t.status,r)}}};var _=class{constructor(t){this.client=t}build(t){return this.client._call("card_delegation_approve_transaction_build",t)}},O=class{constructor(t){this.client=t}get transaction(){return new _(this.client)}},v=class{constructor(t){this.client=t}build(t){return this.client._call("card_delegation_revoke_transaction_build",t)}},P=class{constructor(t){this.client=t}get transaction(){return new v(this.client)}},C=class{constructor(t){this.client=t}retrieve(t){return this.client._call("card_delegation_token_retrieve",t)}},k=class{constructor(t){this.client=t}get approve(){return new O(this.client)}get revoke(){return new P(this.client)}get token(){return new C(this.client)}},I=class{constructor(t){this.client=t}check(t){return this.client._call("card_onboarding_check",t)}finish(t){return this.client._call("card_onboarding_finish",t)}start(t){return this.client._call("card_onboarding_start",t)}},g=class{constructor(t){this.client=t}list(t){return this.client._call("card_transaction_list",t)}},y=class{constructor(t){this.client=t}retrieve(t){return this.client._call("card_user_retrieve",t)}},A=class{constructor(t){this.client=t}check(t){return this.client._call("card_wallet_check",t)}link(t){return this.client._call("card_wallet_link",t)}list(t){return this.client._call("card_wallet_list",t)}unlink(t){return this.client._call("card_wallet_unlink",t)}},M=class{constructor(t){this.client=t}get delegation(){return new k(this.client)}get onboarding(){return new I(this.client)}get transaction(){return new g(this.client)}get user(){return new y(this.client)}get wallet(){return new A(this.client)}create(t){return this.client._call("card_create",t)}freeze(t){return this.client._call("card_freeze",t)}retrieve(t){return this.client._call("card_retrieve",t)}reveal(t){return this.client._call("card_reveal",t)}unfreeze(t){return this.client._call("card_unfreeze",t)}},R=class{constructor(t){this.client=t}list(t){return this.client._call("chain_list",t)}retrieve(t){return this.client._call("chain_retrieve",t)}},f=class{constructor(t){this.client=t}create(t){return this.client._call("cli_activation_create",t)}update(t){return this.client._call("cli_activation_update",t)}},w=class{constructor(t){this.client=t}get activation(){return new f(this.client)}},T=class{constructor(t){this.client=t}add(t){return this.client._call("commerce_cart_add",t)}remove(t){return this.client._call("commerce_cart_remove",t)}retrieve(t){return this.client._call("commerce_cart_retrieve",t)}update(t){return this.client._call("commerce_cart_update",t)}},L=class{constructor(t){this.client=t}pay(t){return this.client._call("commerce_checkout_pay",t)}start(t){return this.client._call("commerce_checkout_start",t)}},V=class{constructor(t){this.client=t}retrieve(t){return this.client._call("commerce_product_retrieve",t)}search(t){return this.client._call("commerce_product_search",t)}},x=class{constructor(t){this.client=t}list(t){return this.client._call("commerce_store_list",t)}retrieve(t){return this.client._call("commerce_store_retrieve",t)}},b=class{constructor(t){this.client=t}get cart(){return new T(this.client)}get checkout(){return new L(this.client)}get product(){return new V(this.client)}get store(){return new x(this.client)}search(t){return this.client._call("commerce_search",t)}},S=class{constructor(t){this.client=t}list(t){return this.client._call("deposit_transaction_list",t)}},B=class{constructor(t){this.client=t}get transaction(){return new S(this.client)}create(t){return this.client._call("deposit_create",t)}retrieve(t){return this.client._call("deposit_retrieve",t)}},U=class{constructor(t){this.client=t}create(t){return this.client._call("feedback_create",t)}},W=class{constructor(t){this.client=t}buy(t){return this.client._call("gateway_buy",t)}search(t){return this.client._call("gateway_search",t)}},D=class{constructor(t){this.client=t}list(t){return this.client._call("prediction-market_activity_list",t)}},E=class{constructor(t){this.client=t}retrieve(t){return this.client._call("prediction-market_market_event_retrieve",t)}},F=class{constructor(t){this.client=t}list(t){return this.client._call("prediction-market_market_price_history_list",t)}},z=class{constructor(t){this.client=t}get history(){return new F(this.client)}retrieve(t){return this.client._call("prediction-market_market_price_retrieve",t)}},H=class{constructor(t){this.client=t}list(t){return this.client._call("prediction-market_market_tag_list",t)}},$=class{constructor(t){this.client=t}list(t){return this.client._call("prediction-market_market_trending_list",t)}},G=class{constructor(t){this.client=t}get event(){return new E(this.client)}get price(){return new z(this.client)}get tag(){return new H(this.client)}get trending(){return new $(this.client)}search(t){return this.client._call("prediction-market_market_search",t)}},K=class{constructor(t){this.client=t}retrieve(t){return this.client._call("prediction-market_pnl_retrieve",t)}},j=class{constructor(t){this.client=t}buy(t){return this.client._call("prediction-market_position_buy",t)}list(t){return this.client._call("prediction-market_position_list",t)}redeem(t){return this.client._call("prediction-market_position_redeem",t)}sell(t){return this.client._call("prediction-market_position_sell",t)}},J=class{constructor(t){this.client=t}list(t){return this.client._call("prediction-market_trade_list",t)}},q=class{constructor(t){this.client=t}create(t){return this.client._call("prediction-market_user_create",t)}},Q=class{constructor(t){this.client=t}get activity(){return new D(this.client)}get market(){return new G(this.client)}get pnl(){return new K(this.client)}get position(){return new j(this.client)}get trade(){return new J(this.client)}get user(){return new q(this.client)}},X=class{constructor(t){this.client=t}build(t){return this.client._call("swaps_transaction_build",t)}},Y=class{constructor(t){this.client=t}get transaction(){return new X(this.client)}},Z=class{constructor(t){this.client=t}list(t){return this.client._call("token_balance_list",t)}},N=class{constructor(t){this.client=t}list(t){return this.client._call("token_holder_list",t)}},tt=class{constructor(t){this.client=t}list(t){return this.client._call("token_ohlcv_list",t)}},et=class{constructor(t){this.client=t}list(t){return this.client._call("token_trending_list",t)}},rt=class{constructor(t){this.client=t}get balance(){return new Z(this.client)}get holder(){return new N(this.client)}get ohlcv(){return new tt(this.client)}get trending(){return new et(this.client)}check(t){return this.client._call("token_check",t)}retrieve(t){return this.client._call("token_retrieve",t)}search(t){return this.client._call("token_search",t)}},nt=class{constructor(t){this.client=t}list(t){return this.client._call("transaction_list",t)}prepare(t){return this.client._call("transaction_prepare",t)}register(t){return this.client._call("transaction_register",t)}retrieve(t){return this.client._call("transaction_retrieve",t)}send(t){return this.client._call("transaction_send",t)}},it=class{constructor(t){this.client=t}retrieve(t){return this.client._call("user_retrieve",t)}},ut=class{constructor(t){this.client=t}accept(t){return this.client._call("virtual-account_agreement_accept",t)}list(t){return this.client._call("virtual-account_agreement_list",t)}},at=class{constructor(t){this.client=t}delete(t){return this.client._call("virtual-account_bank-account_delete",t)}list(t){return this.client._call("virtual-account_bank-account_list",t)}register(t){return this.client._call("virtual-account_bank-account_register",t)}retrieve(t){return this.client._call("virtual-account_bank-account_retrieve",t)}},ct=class{constructor(t){this.client=t}continue(t){return this.client._call("virtual-account_kyc_continue",t)}restart(t){return this.client._call("virtual-account_kyc_restart",t)}},ot=class{constructor(t){this.client=t}cancel(t){return this.client._call("virtual-account_offramp_cancel",t)}create(t){return this.client._call("virtual-account_offramp_create",t)}initiate(t){return this.client._call("virtual-account_offramp_initiate",t)}list(t){return this.client._call("virtual-account_offramp_list",t)}retrieve(t){return this.client._call("virtual-account_offramp_retrieve",t)}update(t){return this.client._call("virtual-account_offramp_update",t)}},lt=class{constructor(t){this.client=t}create(t){return this.client._call("virtual-account_onramp_payment_create",t)}retrieve(t){return this.client._call("virtual-account_onramp_payment_retrieve",t)}},st=class{constructor(t){this.client=t}get payment(){return new lt(this.client)}cancel(t){return this.client._call("virtual-account_onramp_cancel",t)}create(t){return this.client._call("virtual-account_onramp_create",t)}list(t){return this.client._call("virtual-account_onramp_list",t)}retrieve(t){return this.client._call("virtual-account_onramp_retrieve",t)}update(t){return this.client._call("virtual-account_onramp_update",t)}},pt=class{constructor(t){this.client=t}list(t){return this.client._call("virtual-account_transaction_list",t)}},mt=class{constructor(t){this.client=t}list(t){return this.client._call("virtual-account_wallet_list",t)}register(t){return this.client._call("virtual-account_wallet_register",t)}},ht=class{constructor(t){this.client=t}get agreement(){return new ut(this.client)}get bankAccount(){return new at(this.client)}get kyc(){return new ct(this.client)}get offramp(){return new ot(this.client)}get onramp(){return new st(this.client)}get transaction(){return new pt(this.client)}get wallet(){return new mt(this.client)}create(t){return this.client._call("virtual-account_create",t)}retrieve(t){return this.client._call("virtual-account_retrieve",t)}},dt=class{constructor(t){this.client=t}list(t){return this.client._call("wallet_activity_list",t)}},_t=class{constructor(t){this.client=t}retrieve(t){return this.client._call("wallet_pnl_retrieve",t)}},Ot=class{constructor(t){this.client=t}get activity(){return new dt(this.client)}get pnl(){return new _t(this.client)}discover(t){return this.client._call("wallet_discover",t)}},m=class extends h{constructor(t={}){super(t)}get card(){return new M(this)}get chain(){return new R(this)}get cli(){return new w(this)}get commerce(){return new b(this)}get deposit(){return new B(this)}get feedback(){return new U(this)}get gateway(){return new W(this)}get predictionMarket(){return new Q(this)}get swaps(){return new Y(this)}get token(){return new rt(this)}get transaction(){return new nt(this)}get user(){return new it(this)}get virtualAccount(){return new ht(this)}get wallet(){return new Ot(this)}buy(t){return this._call("buy",t)}login(t){return this._call("login",t)}refresh(t){return this._call("refresh",t)}verify(t){return this._call("verify",t)}};At();yt();var d=null;function ft(){return d||(d=new m({baseUrl:Ct(),auth:{type:"bearer",getToken:It,refreshToken:async()=>{let e=Pt();if(!e?.refreshToken)throw new Error("No refresh token available");return(await kt(e)).accessToken}},headers:vt()})),d}var Ft=new Proxy({},{get(e,t){return Reflect.get(ft(),t)}});function zt(){d=null}export{m as a,Ft as b,zt as c};
|
|
2
|
+
import{f as vt,g as yt,j as Pt,m as Ct,n as kt,o as It,p as At}from"./chunk-HKDLPDJU.js";var n=class extends Error{constructor(r,i,u){super(r);this.status=i;this.toolName=u;this.name="MoonPayError"}},c=class extends n{constructor(t="Authentication required"){super(t,401),this.name="AuthError"}},o=class extends n{constructor(t="Rate limit exceeded"){super(t,429),this.name="RateLimitError"}},l=class extends n{constructor(t,r){super(t,400,r),this.name="ValidationError"}},s=class extends n{constructor(t){super(`Tool not found: ${t}`,404,t),this.name="ToolNotFoundError"}},p=class extends n{constructor(t,r){super(`Tool "${t}" has been renamed to "${r}"`,410,t),this.name="ToolRenamedError",this.newName=r}};var Mt="https://agents.moonpay.com",Rt=36e4,h=class{constructor(t={}){this.baseUrl=(t.baseUrl??Mt).replace(/\/$/,""),this.auth=t.auth??{type:"none"},this.timeout=t.timeout??Rt,this.headers=t.headers??{}}async _call(t,r){let i=`${this.baseUrl}/api/tools/${encodeURIComponent(t)}`,u=await this.buildHeaders(),a=await fetch(i,{method:"POST",headers:u,body:JSON.stringify(r),signal:AbortSignal.timeout(this.timeout)});if(a.status===401&&this.auth.type==="bearer"&&this.auth.refreshToken)try{let gt=await this.auth.refreshToken();u.Authorization=`Bearer ${gt}`,a=await fetch(i,{method:"POST",headers:u,body:JSON.stringify(r),signal:AbortSignal.timeout(this.timeout)})}catch{throw new c("Token refresh failed")}return this.handleResponse(a,t)}async buildHeaders(){let t={"Content-Type":"application/json",...this.headers};if(this.auth.type==="bearer"){let r=await this.auth.getToken();r&&(t.Authorization=`Bearer ${r}`)}return t}async handleResponse(t,r){if(t.ok)return t.json();let i;try{i=await t.json()}catch{i={error:t.statusText}}let u=i?.error??i?.message,a=typeof u=="string"?u:u?JSON.stringify(u):`Request failed with status ${t.status}`;switch(t.status){case 400:throw new l(a,r);case 401:throw new c(a);case 404:throw new s(r);case 410:throw new p(r,i?.newName??"unknown");case 429:throw new o(a);default:throw new n(a,t.status,r)}}};var _=class{constructor(t){this.client=t}build(t){return this.client._call("card_delegation_approve_transaction_build",t)}},O=class{constructor(t){this.client=t}get transaction(){return new _(this.client)}},v=class{constructor(t){this.client=t}build(t){return this.client._call("card_delegation_revoke_transaction_build",t)}},P=class{constructor(t){this.client=t}get transaction(){return new v(this.client)}},C=class{constructor(t){this.client=t}retrieve(t){return this.client._call("card_delegation_token_retrieve",t)}},k=class{constructor(t){this.client=t}get approve(){return new O(this.client)}get revoke(){return new P(this.client)}get token(){return new C(this.client)}},I=class{constructor(t){this.client=t}check(t){return this.client._call("card_onboarding_check",t)}finish(t){return this.client._call("card_onboarding_finish",t)}start(t){return this.client._call("card_onboarding_start",t)}},g=class{constructor(t){this.client=t}list(t){return this.client._call("card_transaction_list",t)}},y=class{constructor(t){this.client=t}retrieve(t){return this.client._call("card_user_retrieve",t)}},A=class{constructor(t){this.client=t}check(t){return this.client._call("card_wallet_check",t)}link(t){return this.client._call("card_wallet_link",t)}list(t){return this.client._call("card_wallet_list",t)}unlink(t){return this.client._call("card_wallet_unlink",t)}},M=class{constructor(t){this.client=t}get delegation(){return new k(this.client)}get onboarding(){return new I(this.client)}get transaction(){return new g(this.client)}get user(){return new y(this.client)}get wallet(){return new A(this.client)}create(t){return this.client._call("card_create",t)}freeze(t){return this.client._call("card_freeze",t)}retrieve(t){return this.client._call("card_retrieve",t)}reveal(t){return this.client._call("card_reveal",t)}unfreeze(t){return this.client._call("card_unfreeze",t)}},R=class{constructor(t){this.client=t}list(t){return this.client._call("chain_list",t)}retrieve(t){return this.client._call("chain_retrieve",t)}},f=class{constructor(t){this.client=t}create(t){return this.client._call("cli_activation_create",t)}update(t){return this.client._call("cli_activation_update",t)}},w=class{constructor(t){this.client=t}get activation(){return new f(this.client)}},T=class{constructor(t){this.client=t}add(t){return this.client._call("commerce_cart_add",t)}remove(t){return this.client._call("commerce_cart_remove",t)}retrieve(t){return this.client._call("commerce_cart_retrieve",t)}update(t){return this.client._call("commerce_cart_update",t)}},L=class{constructor(t){this.client=t}pay(t){return this.client._call("commerce_checkout_pay",t)}start(t){return this.client._call("commerce_checkout_start",t)}},V=class{constructor(t){this.client=t}retrieve(t){return this.client._call("commerce_product_retrieve",t)}search(t){return this.client._call("commerce_product_search",t)}},x=class{constructor(t){this.client=t}list(t){return this.client._call("commerce_store_list",t)}retrieve(t){return this.client._call("commerce_store_retrieve",t)}},b=class{constructor(t){this.client=t}get cart(){return new T(this.client)}get checkout(){return new L(this.client)}get product(){return new V(this.client)}get store(){return new x(this.client)}search(t){return this.client._call("commerce_search",t)}},S=class{constructor(t){this.client=t}list(t){return this.client._call("deposit_transaction_list",t)}},B=class{constructor(t){this.client=t}get transaction(){return new S(this.client)}create(t){return this.client._call("deposit_create",t)}retrieve(t){return this.client._call("deposit_retrieve",t)}},U=class{constructor(t){this.client=t}create(t){return this.client._call("feedback_create",t)}},W=class{constructor(t){this.client=t}buy(t){return this.client._call("gateway_buy",t)}search(t){return this.client._call("gateway_search",t)}},D=class{constructor(t){this.client=t}list(t){return this.client._call("prediction-market_activity_list",t)}},E=class{constructor(t){this.client=t}retrieve(t){return this.client._call("prediction-market_market_event_retrieve",t)}},F=class{constructor(t){this.client=t}list(t){return this.client._call("prediction-market_market_price_history_list",t)}},z=class{constructor(t){this.client=t}get history(){return new F(this.client)}retrieve(t){return this.client._call("prediction-market_market_price_retrieve",t)}},H=class{constructor(t){this.client=t}list(t){return this.client._call("prediction-market_market_tag_list",t)}},$=class{constructor(t){this.client=t}list(t){return this.client._call("prediction-market_market_trending_list",t)}},G=class{constructor(t){this.client=t}get event(){return new E(this.client)}get price(){return new z(this.client)}get tag(){return new H(this.client)}get trending(){return new $(this.client)}search(t){return this.client._call("prediction-market_market_search",t)}},K=class{constructor(t){this.client=t}retrieve(t){return this.client._call("prediction-market_pnl_retrieve",t)}},j=class{constructor(t){this.client=t}buy(t){return this.client._call("prediction-market_position_buy",t)}list(t){return this.client._call("prediction-market_position_list",t)}redeem(t){return this.client._call("prediction-market_position_redeem",t)}sell(t){return this.client._call("prediction-market_position_sell",t)}},J=class{constructor(t){this.client=t}list(t){return this.client._call("prediction-market_trade_list",t)}},q=class{constructor(t){this.client=t}create(t){return this.client._call("prediction-market_user_create",t)}},Q=class{constructor(t){this.client=t}get activity(){return new D(this.client)}get market(){return new G(this.client)}get pnl(){return new K(this.client)}get position(){return new j(this.client)}get trade(){return new J(this.client)}get user(){return new q(this.client)}},X=class{constructor(t){this.client=t}build(t){return this.client._call("swaps_transaction_build",t)}},Y=class{constructor(t){this.client=t}get transaction(){return new X(this.client)}},Z=class{constructor(t){this.client=t}list(t){return this.client._call("token_balance_list",t)}},N=class{constructor(t){this.client=t}list(t){return this.client._call("token_holder_list",t)}},tt=class{constructor(t){this.client=t}list(t){return this.client._call("token_ohlcv_list",t)}},et=class{constructor(t){this.client=t}list(t){return this.client._call("token_trending_list",t)}},rt=class{constructor(t){this.client=t}get balance(){return new Z(this.client)}get holder(){return new N(this.client)}get ohlcv(){return new tt(this.client)}get trending(){return new et(this.client)}check(t){return this.client._call("token_check",t)}retrieve(t){return this.client._call("token_retrieve",t)}search(t){return this.client._call("token_search",t)}},nt=class{constructor(t){this.client=t}list(t){return this.client._call("transaction_list",t)}prepare(t){return this.client._call("transaction_prepare",t)}register(t){return this.client._call("transaction_register",t)}retrieve(t){return this.client._call("transaction_retrieve",t)}send(t){return this.client._call("transaction_send",t)}},it=class{constructor(t){this.client=t}retrieve(t){return this.client._call("user_retrieve",t)}},ut=class{constructor(t){this.client=t}accept(t){return this.client._call("virtual-account_agreement_accept",t)}list(t){return this.client._call("virtual-account_agreement_list",t)}},at=class{constructor(t){this.client=t}delete(t){return this.client._call("virtual-account_bank-account_delete",t)}list(t){return this.client._call("virtual-account_bank-account_list",t)}register(t){return this.client._call("virtual-account_bank-account_register",t)}retrieve(t){return this.client._call("virtual-account_bank-account_retrieve",t)}},ct=class{constructor(t){this.client=t}continue(t){return this.client._call("virtual-account_kyc_continue",t)}restart(t){return this.client._call("virtual-account_kyc_restart",t)}},ot=class{constructor(t){this.client=t}cancel(t){return this.client._call("virtual-account_offramp_cancel",t)}create(t){return this.client._call("virtual-account_offramp_create",t)}initiate(t){return this.client._call("virtual-account_offramp_initiate",t)}list(t){return this.client._call("virtual-account_offramp_list",t)}retrieve(t){return this.client._call("virtual-account_offramp_retrieve",t)}update(t){return this.client._call("virtual-account_offramp_update",t)}},lt=class{constructor(t){this.client=t}create(t){return this.client._call("virtual-account_onramp_payment_create",t)}retrieve(t){return this.client._call("virtual-account_onramp_payment_retrieve",t)}},st=class{constructor(t){this.client=t}get payment(){return new lt(this.client)}cancel(t){return this.client._call("virtual-account_onramp_cancel",t)}create(t){return this.client._call("virtual-account_onramp_create",t)}list(t){return this.client._call("virtual-account_onramp_list",t)}retrieve(t){return this.client._call("virtual-account_onramp_retrieve",t)}update(t){return this.client._call("virtual-account_onramp_update",t)}},pt=class{constructor(t){this.client=t}list(t){return this.client._call("virtual-account_transaction_list",t)}},mt=class{constructor(t){this.client=t}list(t){return this.client._call("virtual-account_wallet_list",t)}register(t){return this.client._call("virtual-account_wallet_register",t)}},ht=class{constructor(t){this.client=t}get agreement(){return new ut(this.client)}get bankAccount(){return new at(this.client)}get kyc(){return new ct(this.client)}get offramp(){return new ot(this.client)}get onramp(){return new st(this.client)}get transaction(){return new pt(this.client)}get wallet(){return new mt(this.client)}create(t){return this.client._call("virtual-account_create",t)}retrieve(t){return this.client._call("virtual-account_retrieve",t)}},dt=class{constructor(t){this.client=t}list(t){return this.client._call("wallet_activity_list",t)}},_t=class{constructor(t){this.client=t}retrieve(t){return this.client._call("wallet_pnl_retrieve",t)}},Ot=class{constructor(t){this.client=t}get activity(){return new dt(this.client)}get pnl(){return new _t(this.client)}discover(t){return this.client._call("wallet_discover",t)}},m=class extends h{constructor(t={}){super(t)}get card(){return new M(this)}get chain(){return new R(this)}get cli(){return new w(this)}get commerce(){return new b(this)}get deposit(){return new B(this)}get feedback(){return new U(this)}get gateway(){return new W(this)}get predictionMarket(){return new Q(this)}get swaps(){return new Y(this)}get token(){return new rt(this)}get transaction(){return new nt(this)}get user(){return new it(this)}get virtualAccount(){return new ht(this)}get wallet(){return new Ot(this)}buy(t){return this._call("buy",t)}login(t){return this._call("login",t)}refresh(t){return this._call("refresh",t)}verify(t){return this._call("verify",t)}};At();yt();var d=null;function ft(){return d||(d=new m({baseUrl:Ct(),auth:{type:"bearer",getToken:It,refreshToken:async()=>{let e=Pt();if(!e?.refreshToken)throw new Error("No refresh token available");return(await kt(e)).accessToken}},headers:vt()})),d}var Ft=new Proxy({},{get(e,t){return Reflect.get(ft(),t)}});function zt(){d=null}export{m as a,Ft as b,zt as c};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
process.noDeprecation = true; import { createRequire as __createRequire } from "module"; const require = __createRequire(import.meta.url);
|
|
2
|
-
import{a as V,b as T,c as G,d as L,h as D,p as Z}from"./chunk-
|
|
2
|
+
import{a as V,b as T,c as G,d as L,h as D,p as Z}from"./chunk-HKDLPDJU.js";import{a as q,f as I}from"./chunk-LMDE72OE.js";import{existsSync as H,readFileSync as N,writeFileSync as he,renameSync as J}from"fs";import{join as S}from"path";import{homedir as ge}from"os";import{randomBytes as we}from"crypto";import*as i from"@open-wallet-standard/core";import Y from"bs58";T();import{z as s}from"zod";var M={"eip155:1":"ethereum","solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp":"solana","bip122:000000000019d6689c085ae165831e93":"bitcoin","tron:mainnet":"tron","ton:mainnet":"ton","fil:mainnet":"filecoin"},E=s.object({solana:s.string().optional(),ethereum:s.string().optional(),bitcoin:s.string().optional(),tron:s.string().optional(),ton:s.string().optional(),filecoin:s.string().optional()}),Q=["base","arbitrum","polygon","optimism","bnb","bnb-testnet","avalanche","tempo","tempo-moderato","ethereum-sepolia","base-sepolia","arbitrum-sepolia","polygon-amoy"];function Ie(e){let t={};if(e.solana&&(t.solana=e.solana,t["solana-devnet"]=e.solana),e.ethereum){t.ethereum=e.ethereum;for(let r of Q)t[r]=e.ethereum}return e.bitcoin&&(t.bitcoin=e.bitcoin),e.tron&&(t.tron=e.tron),e.ton&&(t.ton=e.ton),e.filecoin&&(t.filecoin=e.filecoin),t}var X=s.object({name:s.string(),type:s.literal("hd"),mnemonic:s.string().optional(),addresses:E,createdAt:s.string()}),ee=s.object({name:s.string(),type:s.literal("imported"),chain:s.string().optional(),privateKey:s.string().optional(),addresses:E,createdAt:s.string()}),R=s.enum(["ledger"]),$=s.object({name:s.string(),type:s.literal("hardware"),device:R,addresses:E,createdAt:s.string()}),Te=s.discriminatedUnion("type",[X,ee,$]),De=s.object({name:s.string(),type:s.enum(["hd","imported","hardware"]),device:R.optional(),addresses:s.record(s.string(),s.string()),createdAt:s.string()});import{createHash as U}from"crypto";import{HDKey as x}from"@scure/bip32";import{mnemonicToSeedSync as y}from"@scure/bip39";import{keccak_256 as F}from"@noble/hashes/sha3";import{derivePath as _}from"ed25519-hd-key";import*as j from"bitcoinjs-lib";import te from"ecpair";import*as K from"@bitcoinerlab/secp256k1";import{Keypair as re}from"@solana/web3.js";import ne from"bs58";import{WalletContractV5R1 as oe}from"@ton/ton";import{keyPairFromSeed as ie}from"@ton/crypto";import*as O from"@open-wallet-standard/core";var se=te(K);function z(e,t,r=0){switch(t){case"solana":return ae(e,r);case"ethereum":return le(e,r);case"bitcoin":return fe(e,r);case"tron":return pe(e,r);case"ton":return me(e,r);case"filecoin":return ye(e,r);default:throw new Error(`Unsupported key family for derivation: ${t}`)}}function ae(e,t){let r=y(e),n=`m/44'/501'/${t}'/0'`,{key:o}=_(n,Buffer.from(r).toString("hex")),a=re.fromSeed(Uint8Array.from(o));return{privateKey:a.secretKey,address:a.publicKey.toBase58()}}function le(e,t){let r=y(e),n=x.fromMasterSeed(r),o=`m/44'/60'/${t}'/0/0`,a=n.derive(o);if(!a.privateKey)throw new Error("Failed to derive EVM private key");let l=ce(a.publicKey);return{privateKey:a.privateKey,address:l}}function ce(e){let t=K.pointCompress(e,!1),n=F(t.slice(1)).slice(-20),o="0x"+Buffer.from(n).toString("hex");return de(o)}function de(e){let t=e.toLowerCase().replace("0x",""),r=Buffer.from(F(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 fe(e,t){let r=y(e),n=x.fromMasterSeed(r),o=`m/84'/0'/${t}'/0/0`,a=n.derive(o);if(!a.privateKey)throw new Error("Failed to derive Bitcoin private key");let l=se.fromPrivateKey(Buffer.from(a.privateKey)),{address:f}=j.payments.p2wpkh({pubkey:Buffer.from(l.publicKey)});if(!f)throw new Error("Failed to derive Bitcoin address");return{privateKey:a.privateKey,address:f}}function pe(e,t){let r=y(e),n=x.fromMasterSeed(r),o=`m/44'/195'/${t}'/0/0`,a=n.derive(o);if(!a.privateKey)throw new Error("Failed to derive Tron private key");let l=ue(a.publicKey);return{privateKey:a.privateKey,address:l}}function ue(e){let t=K.pointCompress(e,!1),n=F(t.slice(1)).slice(-20),o=Buffer.concat([Buffer.from([65]),Buffer.from(n)]),a=U("sha256").update(o).digest(),l=U("sha256").update(a).digest(),f=Buffer.concat([o,l.slice(0,4)]);return ne.encode(f)}function me(e,t){let r=y(e),n=`m/44'/607'/${t}'/0'`,{key:o}=_(n,Buffer.from(r).toString("hex")),a=ie(Buffer.from(o)),l=oe.create({publicKey:Buffer.from(a.publicKey)});return{privateKey:a.secretKey,address:l.address.toString({bounceable:!1})}}function ye(e,t){let r=y(e),n=x.fromMasterSeed(r),o=`m/44'/461'/${t}'/0/0`,a=n.derive(o);if(!a.privateKey)throw new Error("Failed to derive Filecoin private key");let l=O.deriveAddress(e,"filecoin",t);return{privateKey:a.privateKey,address:l}}Z();var b=S(ge(),".config","moonpay"),B=S(b,"hardware-wallets.json");function c(){return b}function ve(e){let t={};for(let r of e){let n=M[r.chainId];n&&(t[n]=r.address)}return t}function h(e){let t=ve(e.accounts);if(!t.filecoin)try{let r=i.exportWallet(e.id,null,c());r&&!r.startsWith("{")&&(t.filecoin=i.deriveAddress(r,"filecoin"))}catch{}return{name:e.name,type:"hd",addresses:t,createdAt:e.createdAt}}function m(){if(!H(B))return[];try{return(JSON.parse(N(B,"utf-8")).wallets??[]).map(t=>$.parse(t))}catch{return[]}}function We(e,t){D();let r=S(b,`.tmp.${we(4).toString("hex")}`);he(r,JSON.stringify(t,null,2),{mode:384}),J(r,e)}function g(e){We(B,{wallets:e})}var w=S(b,"wallets.json");function P(){if(H(w)){process.stderr.write(`Migrating legacy wallets...
|
|
3
3
|
`);let{migrated:e,skipped:t}=xe();process.stderr.write(`Migrated ${e} wallet(s), skipped ${t}.
|
|
4
|
-
`)}}function xe(){if(!H(w))throw new Error("No legacy wallets.json found \u2014 nothing to migrate.");let{getEncryptionKey:e}=(L(),I(G)),{decrypt:t,encryptedFileSchema:r}=(T(),I(V)),n=e();if(!n)throw new Error("Encryption key not found. Set MOONPAY_ENCRYPTION_KEY or ensure OS keychain is accessible.");let o=JSON.parse(N(w,"utf-8")),a=r.parse(o),l=t(a,n),f=JSON.parse(l).wallets??[],p=c(),W=m(),C=0,k=0;for(let d of f){try{i.getWallet(d.name,p),k++;continue}catch{}if(W.some(u=>u.name===d.name)){k++;continue}if(d.type==="hardware")W.push({name:d.name,type:"hardware",device:d.device,addresses:d.addresses,createdAt:d.createdAt});else if(d.type==="hd"&&d.mnemonic)i.importWalletMnemonic(d.name,d.mnemonic,null,null,p);else if(d.type==="imported"&&d.privateKey){let u=d.privateKey;if(!/^[0-9a-fA-F]+$/.test(u)){let A=Y.decode(u);u=Buffer.from(A.length===64?A.slice(0,32):A).toString("hex")}i.importWalletPrivateKey(d.name,u,null,p,null,u,u)}C++}return W.length>0&&g(W),J(w,w+".migrated"),{migrated:C,skipped:k}}function Ke(e){P(),v(e);let t=i.createWallet(e,null,24,c());return h(t)}function Se(e,t){v(e);let r=i.importWalletMnemonic(e,t,null,null,c());return h(r)}function be(e,t){return v(e),h(i.importWalletPrivateKey(e,t,null,c()))}function ke(){P();let e=[];try{e=i.listWallets(c())}catch{}return[...e.map(r=>h(r)),...m()]}function Ae(e){P();let t=c();try{let r=i.getWallet(e,t);return h(r)}catch{}try{for(let r of i.listWallets(t))for(let n of r.accounts)if(n.address===e)return h(r)}catch{}for(let r of m()){if(r.name===e)return r;for(let n of Object.values(r.addresses))if(n===e)return r}return null}function nt(e){let t=Ae(e);if(!t)throw new Error(`Wallet "${e}" not found`);return t}function Ee(e){try{i.deleteWallet(e,c());return}catch{}let t=m(),r=t.findIndex(n=>n.name===e);if(r===-1)throw new Error(`Wallet "${e}" not found`);t.splice(r,1),g(t)}function ot(e,t){if(e===t)return;v(t);try{i.getWallet(e,c()),i.renameWallet(e,t,c());return}catch(o){if(o instanceof Error&&!o.message.includes("not found"))throw o}let r=m(),n=r.find(o=>o.name===e);if(!n)throw new Error(`Wallet "${e}" not found`);n.name=t,g(r)}function it(e){return i.exportWallet(e,null,c())}function $e(e){v(e.name);let t=m();t.push(e),g(t)}function st(e,t){let r=m(),n=r.find(o=>o.name===e);if(!n)throw new Error(`Hardware wallet "${e}" not found`);n.addresses=t,g(r)}function at(e,t,r){return i.signTransaction(e,t,r,null,null,c())}function lt(e,t,r,n){return i.signMessage(e,t,r,null,n??null,null,c())}function ct(e,t,r){return i.signTypedData(e,t,r,null,null,c())}async function dt(e,t){if(e.type==="hardware")throw new Error(`Wallet "${e.name}" is a hardware wallet. Signing must happen on the device.`);let{moonpay:r}=await import("./client-
|
|
4
|
+
`)}}function xe(){if(!H(w))throw new Error("No legacy wallets.json found \u2014 nothing to migrate.");let{getEncryptionKey:e}=(L(),I(G)),{decrypt:t,encryptedFileSchema:r}=(T(),I(V)),n=e();if(!n)throw new Error("Encryption key not found. Set MOONPAY_ENCRYPTION_KEY or ensure OS keychain is accessible.");let o=JSON.parse(N(w,"utf-8")),a=r.parse(o),l=t(a,n),f=JSON.parse(l).wallets??[],p=c(),W=m(),C=0,k=0;for(let d of f){try{i.getWallet(d.name,p),k++;continue}catch{}if(W.some(u=>u.name===d.name)){k++;continue}if(d.type==="hardware")W.push({name:d.name,type:"hardware",device:d.device,addresses:d.addresses,createdAt:d.createdAt});else if(d.type==="hd"&&d.mnemonic)i.importWalletMnemonic(d.name,d.mnemonic,null,null,p);else if(d.type==="imported"&&d.privateKey){let u=d.privateKey;if(!/^[0-9a-fA-F]+$/.test(u)){let A=Y.decode(u);u=Buffer.from(A.length===64?A.slice(0,32):A).toString("hex")}i.importWalletPrivateKey(d.name,u,null,p,null,u,u)}C++}return W.length>0&&g(W),J(w,w+".migrated"),{migrated:C,skipped:k}}function Ke(e){P(),v(e);let t=i.createWallet(e,null,24,c());return h(t)}function Se(e,t){v(e);let r=i.importWalletMnemonic(e,t,null,null,c());return h(r)}function be(e,t){return v(e),h(i.importWalletPrivateKey(e,t,null,c()))}function ke(){P();let e=[];try{e=i.listWallets(c())}catch{}return[...e.map(r=>h(r)),...m()]}function Ae(e){P();let t=c();try{let r=i.getWallet(e,t);return h(r)}catch{}try{for(let r of i.listWallets(t))for(let n of r.accounts)if(n.address===e)return h(r)}catch{}for(let r of m()){if(r.name===e)return r;for(let n of Object.values(r.addresses))if(n===e)return r}return null}function nt(e){let t=Ae(e);if(!t)throw new Error(`Wallet "${e}" not found`);return t}function Ee(e){try{i.deleteWallet(e,c());return}catch{}let t=m(),r=t.findIndex(n=>n.name===e);if(r===-1)throw new Error(`Wallet "${e}" not found`);t.splice(r,1),g(t)}function ot(e,t){if(e===t)return;v(t);try{i.getWallet(e,c()),i.renameWallet(e,t,c());return}catch(o){if(o instanceof Error&&!o.message.includes("not found"))throw o}let r=m(),n=r.find(o=>o.name===e);if(!n)throw new Error(`Wallet "${e}" not found`);n.name=t,g(r)}function it(e){return i.exportWallet(e,null,c())}function $e(e){v(e.name);let t=m();t.push(e),g(t)}function st(e,t){let r=m(),n=r.find(o=>o.name===e);if(!n)throw new Error(`Hardware wallet "${e}" not found`);n.addresses=t,g(r)}function at(e,t,r){return i.signTransaction(e,t,r,null,null,c())}function lt(e,t,r,n){return i.signMessage(e,t,r,null,n??null,null,c())}function ct(e,t,r){return i.signTypedData(e,t,r,null,null,c())}async function dt(e,t){if(e.type==="hardware")throw new Error(`Wallet "${e.name}" is a hardware wallet. Signing must happen on the device.`);let{moonpay:r}=await import("./client-S2OYW27G.js"),o=(await r.chain.retrieve({chain:t})).keyFamily,a=i.exportWallet(e.name,null,c());if(a.includes(" "))return z(a,o);let l;if(a.startsWith("{")){let p=JSON.parse(a);l=o==="solana"||o==="ton"?p.ed25519:p.secp256k1}else l=a;let f=Uint8Array.from(Buffer.from(l,"hex"));if(o==="solana"&&f.length===32){let p=q("tweetnacl");f=Uint8Array.from(p.sign.keyPair.fromSeed(f).secretKey)}return{privateKey:f,address:e.addresses[o]??""}}var Fe=ke,ft=Ee;function Be(e){if(e.type==="hardware"){$e(e);return}if(e.type==="hd"&&e.mnemonic){Se(e.name,e.mnemonic);return}if(e.type==="imported"&&e.privateKey){let t=e.privateKey;if(t.startsWith("0x"))t=t.slice(2);else if(!/^[0-9a-fA-F]+$/.test(t)){let r=Y.decode(t);t=Buffer.from(r.length===64?r.slice(0,32):r).toString("hex")}be(e.name,t);return}Ke(e.name)}function pt(e){for(let t of e)Be(t)}function ut(e){let t=Fe();e(t),g(t.filter(r=>r.type==="hardware"))}function v(e){try{throw i.getWallet(e,c()),new Error(`Wallet "${e}" already exists`)}catch(t){if(t instanceof Error&&t.message.includes("already exists"))throw t}if(m().some(t=>t.name===e))throw new Error(`Wallet "${e}" already exists`)}export{E as a,Ie as b,R as c,De as d,z as e,c as f,P as g,xe as h,Ke as i,Se as j,be as k,ke as l,Ae as m,nt as n,Ee as o,ot as p,it as q,$e as r,st as s,at as t,lt as u,ct as v,dt as w,Fe as x,ft as y,Be as z,pt as A,ut as B};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
process.noDeprecation = true; import { createRequire as __createRequire } from "module"; const require = __createRequire(import.meta.url);
|
|
2
|
-
import{b as a,c as b}from"./chunk-
|
|
2
|
+
import{b as a,c as b}from"./chunk-IBLWQCA2.js";import"./chunk-HKDLPDJU.js";import"./chunk-LMDE72OE.js";export{a as moonpay,b as resetClient};
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
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 J,b as K,c as R,d as C}from"./chunk-
|
|
3
|
+
import{a as J,b as K,c as R,d as C}from"./chunk-7VEPX3MI.js";import{b as N}from"./chunk-IBLWQCA2.js";import{m as A}from"./chunk-V4NDQ53W.js";import{e as v,g as H}from"./chunk-HKDLPDJU.js";import"./chunk-LMDE72OE.js";import{Command as se}from"commander";var W=!process.env.NO_COLOR&&process.stdout.isTTY===!0;function _(e){return n=>W?`${e}${n}\x1B[0m`:n}var d={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 n=typeof e;return n==="string"||n==="number"||n==="boolean"}function w(e){return e==null?"-":String(e)}function S(e,n=0){let t=" ".repeat(n);return O(e)?`${t}${w(e)}`:Array.isArray(e)?e.length===0?`${t}${d.dim("(empty)")}`:e.every(O)?e.map(s=>`${t}- ${w(s)}`).join(`
|
|
4
4
|
`):e.map(s=>{if(typeof s!="object"||s===null)return`${t}- ${w(s)}`;let r=Object.entries(s),c=[],[l,u]=r[0];O(u)?c.push(`${t}- ${d.bold(l)}: ${w(u)}`):(c.push(`${t}- ${d.bold(l)}:`),c.push(S(u,n+2)));for(let[p,g]of r.slice(1))O(g)?c.push(`${t} ${d.bold(p)}: ${w(g)}`):(c.push(`${t} ${d.bold(p)}:`),c.push(S(g,n+2)));return c.join(`
|
|
5
5
|
`)}).join(`
|
|
6
6
|
|
|
@@ -14,5 +14,5 @@ ${S(c,n+1)}`).join(`
|
|
|
14
14
|
|
|
15
15
|
Run \`mp skill install\` to install AI skills for Claude Code.
|
|
16
16
|
|
|
17
|
-
`+K).version(v).option("--json","Output as JSON instead of YAML");function ae(){return h.opts().json?"json":"yaml"}function U(e){console.log(F(e,ae()))}function M(){let e=ie();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
|
+
`+K).version(v).option("--json","Output as JSON instead of YAML");function ae(){return h.opts().json?"json":"yaml"}function U(e){console.log(F(e,ae()))}function M(){let e=ie();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-Q4CQRNQ2.js");await e()});function q(e,n){let t=e;for(let s of n){let r=t.commands.find(c=>c.name()===s);r||(r=t.command(s)),t=r}return t}function z(e,n=""){let t=[];for(let[s,r]of Object.entries(e)){let c=n?`${n}-${s}`:s,l=r;for(;l._def.typeName==="ZodEffects";)l=l._def.schema;let u=l;u._def.typeName==="ZodNullable"&&(u=u._def.innerType),u._def.typeName==="ZodObject"&&u.shape?t.push(...z(u.shape,c)):t.push({flatKey:c,field:r,path:c.split("-")})}return t}function ce(e,n){let t={};for(let{flatKey:s,path:r}of n){let c=s.replace(/-([a-z])/g,(u,p)=>p.toUpperCase()),l=c in e?e[c]:e[s];if(r.length===1)t[r[0]]=l;else{let u=t;for(let p=0;p<r.length-1;p++)(!u[r[p]]||typeof u[r[p]]!="object")&&(u[r[p]]={}),u=u[r[p]];u[r[r.length-1]]=l}}return t}function le(e,n){for(let t of n){let s=t.schema.name.split("_"),r=s.pop(),l=q(e,s).command(r).description(t.schema.description),u=t.schema.input.shape??{},p=z(u),g=[],b=[],k=[],$=[];for(let{flatKey:f,field:i}of p){let o=i.description??f,a=i;for(;a._def.typeName==="ZodEffects";)a=a._def.schema;let y=a._def.typeName,m=a;m._def.typeName==="ZodNullable"&&(m=m._def.innerType),m._def.typeName==="ZodNumber"&&b.push(f),m._def.typeName==="ZodRecord"&&k.push(f),m._def.typeName==="ZodBoolean"&&$.push(f),y==="ZodBoolean"?l.option(`--${f} [${f}]`,o,!1):y==="ZodNullable"?(l.option(`--${f} <${f}>`,o),g.push(f)):l.requiredOption(`--${f} <${f}>`,o)}l.action(async f=>{t.schema.name.startsWith("consent_")||await R.handler({});for(let o of g){let a=o.replace(/-([a-z])/g,(y,m)=>m.toUpperCase());f[a]===void 0&&(f[a]=null)}for(let o of b){let a=o.replace(/-([a-z])/g,(y,m)=>m.toUpperCase());f[a]!=null&&typeof f[a]=="string"&&(f[a]=Number(f[a]))}for(let o of $){let a=o.replace(/-([a-z])/g,(m,j)=>j.toUpperCase()),y=f[a];if(typeof y=="string"){let m=y.toLowerCase();m==="true"||m==="1"?f[a]=!0:(m==="false"||m==="0")&&(f[a]=!1)}}for(let o of k){let a=o.replace(/-([a-z])/g,(y,m)=>m.toUpperCase());if(typeof f[a]=="string")try{f[a]=JSON.parse(f[a])}catch{console.error(`Invalid JSON for --${o}`),process.exit(1)}}let i=ce(f,p);try{let o=await t.handler(i);U(o)}catch(o){console.error(Z(o)),process.exit(1)}})}}function fe(e){if(e.$ref&&e.definitions){let n=e.$ref.replace("#/definitions/","");return e.definitions[n]}return e}function ue(e){return Array.isArray(e.type)?e.type.includes("null"):e.anyOf?e.anyOf.some(n=>n.type==="null"):!1}function me(e){return Array.isArray(e.type)?e.type.includes("object"):e.anyOf?e.anyOf.some(n=>n.type==="object"):e.type==="object"}function pe(e){return Array.isArray(e.type)?e.type.some(n=>n==="number"||n==="integer"):e.anyOf?e.anyOf.some(n=>n.type==="number"||n.type==="integer"):e.type==="number"||e.type==="integer"}function de(e){return Array.isArray(e.type)?e.type.includes("boolean"):e.anyOf?e.anyOf.some(n=>n.type==="boolean"):e.type==="boolean"}var Y=new Set(["swaps_transaction_build","transaction_register","virtual-account_offramp_initiate","prediction-market_position_buy","prediction-market_position_sell","prediction-market_position_redeem","commerce_cart_update","commerce_checkout_start","commerce_checkout_pay","card_delegation_approve_transaction_build","card_delegation_revoke_transaction_build","card_delegation_token_retrieve","card_wallet_link","card_wallet_unlink"]);function ye(e,n){for(let t of n){if(Y.has(t.name))continue;let s=t.name.split("_"),r=s.pop(),c=q(e,s);if(c.commands.find(i=>i.name()===r))continue;let l=c.command(r).description(t.description),u=fe(t.inputSchema),p=u.properties??{},g=new Set(u.required??[]),b=[],k=[],$=[],f=[];for(let[i,o]of Object.entries(p)){let a=o.description??i,y=ue(o),m=me(o),j=pe(o),B=de(o);j&&k.push(i),B&&f.push(i),m?($.push(i),g.has(i)&&!y?l.requiredOption(`--${i} <json>`,`${a} (as JSON)`):(l.option(`--${i} <json>`,`${a} (as JSON)`),b.push(i))):y||!g.has(i)?(l.option(`--${i} <${i}>`,a),b.push(i)):l.requiredOption(`--${i} <${i}>`,a)}l.action(async i=>{await R.handler({});for(let o of b)i[o]===void 0&&(i[o]=null);for(let o of k)i[o]!=null&&typeof i[o]=="string"&&(i[o]=Number(i[o]));for(let o of f)if(typeof i[o]=="string"){let a=i[o].toLowerCase();a==="true"||a==="1"?i[o]=!0:(a==="false"||a==="0")&&(i[o]=!1)}for(let o of $)if(typeof i[o]=="string")try{i[o]=JSON.parse(i[o])}catch{console.error(`Invalid JSON for --${o}`),process.exit(1)}try{await I(i);let o=await N._call(t.name,i);U(o),M()}catch(o){console.error(Z(o)),process.exit(1)}})}}le(h,C);ye(h,J);h.command("tools").description("List available tools").action(()=>{let e=[...C.map(t=>({name:t.schema.name,description:t.schema.description})),...J.filter(t=>!C.some(s=>s.schema.name===t.name)&&!Y.has(t.name)).map(t=>({name:t.name,description:t.description}))].sort((t,s)=>t.name.localeCompare(s.name)),n=[];for(let t of e){let s=t.name.replace(/_/g," ");n.push(` ${d.green(s.padEnd(28))} ${d.dim(t.description)}`)}n.push(""),n.push(d.dim(`${e.length} tools`)),console.log(n.join(`
|
|
18
18
|
`)),M()});h.parse();
|
|
@@ -7,6 +7,6 @@ Run: npm i -g @moonpay/cli --include=optional`;function y(){try{let e=S("@ledger
|
|
|
7
7
|
`),p}async function U(){if(!p)return null;try{let e=y(),i=f().getDeviceSessionState({sessionId:p}),s=await e.firstValueFrom(i.pipe(e.take(1),e.timeout(3e3)));return s.sessionStateType>=1?s.currentApp?.name??null:null}catch{return null}}var M={evm:"Ethereum",solana:"Solana"};function _(e){let n=String(e);return n.includes("6807")||n.includes("6a15")||n.includes("UnknownDeviceExchangeError")}async function C(e){process.stderr.write(`Installing ${e} app on your Ledger...
|
|
8
8
|
`);let{OpenAppWithDependenciesDeviceAction:n}=y(),i=new n({input:{appName:e}}),t=f().executeDeviceAction({sessionId:E(),deviceAction:i});await m(t,`Install ${e}`,18e4),process.stderr.write(`Installed ${e} app
|
|
9
9
|
`)}async function R(e){let n=M[e];if(!n||await U()===n)return;process.stderr.write(`Opening ${n} app on your Ledger...
|
|
10
|
-
`);let{OpenAppDeviceAction:s}=y(),t=new s({input:{appName:n}}),u=f().executeDeviceAction({sessionId:E(),deviceAction:t});try{await m(u,`Open ${n}`)}catch(c){if(_(c)){await D(),await C(n),await D();return}if(!String(c).includes("isconnect"))throw c}await D()}async function D(){try{await f().disconnect({sessionId:p})}catch{}p=null,await new Promise(e=>setTimeout(e,500)),await P()}function $(e,n=0){switch(e){case"evm":return`44'/60'/${n}'/0/0`;case"solana":return`44'/501'/${n}'/0'`;default:throw new Error(`${e} derivation via Ledger is not supported.`)}}function k(e){return e.startsWith("0x")?e.slice(2):e}function T(e){return e.startsWith("0x")?e:`0x${e}`}async function x(e){let{moonpay:n}=await import("./client-
|
|
10
|
+
`);let{OpenAppDeviceAction:s}=y(),t=new s({input:{appName:n}}),u=f().executeDeviceAction({sessionId:E(),deviceAction:t});try{await m(u,`Open ${n}`)}catch(c){if(_(c)){await D(),await C(n),await D();return}if(!String(c).includes("isconnect"))throw c}await D()}async function D(){try{await f().disconnect({sessionId:p})}catch{}p=null,await new Promise(e=>setTimeout(e,500)),await P()}function $(e,n=0){switch(e){case"evm":return`44'/60'/${n}'/0/0`;case"solana":return`44'/501'/${n}'/0'`;default:throw new Error(`${e} derivation via Ledger is not supported.`)}}function k(e){return e.startsWith("0x")?e.slice(2):e}function T(e){return e.startsWith("0x")?e:`0x${e}`}async function x(e){let{moonpay:n}=await import("./client-S2OYW27G.js"),s=(await n.chain.retrieve({chain:e})).keyFamily;if(s==="bitcoin")throw new Error("Bitcoin address derivation via Ledger is not yet supported.");if(s==="tron")throw new Error("Tron address derivation via Ledger is not supported. The Ethereum signer cannot interact with the Tron Ledger app.");await R(s);let t=$(s),a=E(),u=f();switch(s){case"evm":{let{SignerEthBuilder:c}=I(),l=new c({dmk:u,sessionId:a}).build().getAddress(t,{skipOpenApp:!1});return(await m(l,"Get Ethereum address")).address}case"solana":{let{SignerSolanaBuilder:c}=L(),l=new c({dmk:u,sessionId:a}).build().getAddress(t,{skipOpenApp:!1});return await m(l,"Get Solana address")}default:throw new Error(`Ledger address derivation not supported for ${s}`)}}async function F(){let e={};try{e.ethereum=await x("ethereum")}catch(n){process.stderr.write(`Failed to get Ethereum address: ${n}
|
|
11
11
|
`)}try{e.solana=await x("solana")}catch(n){process.stderr.write(`Failed to get Solana address: ${n}
|
|
12
|
-
`)}if(!e.ethereum&&!e.solana)throw new Error("Could not derive any addresses from Ledger device");return e}async function H(e,n){let{moonpay:i}=await import("./client-
|
|
12
|
+
`)}if(!e.ethereum&&!e.solana)throw new Error("Could not derive any addresses from Ledger device");return e}async function H(e,n){let{moonpay:i}=await import("./client-S2OYW27G.js"),t=(await i.chain.retrieve({chain:e})).keyFamily;if(t==="bitcoin")throw new Error("Bitcoin transaction signing via Ledger is not yet supported. Use a software wallet for Bitcoin transactions.");if(t==="tron")throw new Error("Tron transaction signing via Ledger is not supported. Use a software wallet for Tron transactions.");await R(t);let a=$(t),u=E(),c=f();switch(t){case"evm":{let{SignerEthBuilder:d}=I(),l=new d({dmk:c,sessionId:u}).build(),w=T(n.startsWith("0x")?n:Buffer.from(n,"base64").toString("hex")),o=Uint8Array.from(Buffer.from(k(w),"hex")),r=l.signTransaction(a,o,{skipOpenApp:!1}),g=await m(r,"Sign transaction"),{parseTransaction:v,serializeTransaction:A}=await import("viem"),B=v(w);return{transaction:A(B,{r:T(k(g.r)),s:T(k(g.s)),v:BigInt(g.v)})}}case"solana":{let{SignerSolanaBuilder:d}=L(),l=new d({dmk:c,sessionId:u}).build(),{VersionedTransaction:w}=await import("@solana/web3.js"),o=Uint8Array.from(Buffer.from(n,"base64")),r=w.deserialize(o),g=r.message.serialize(),v=l.signTransaction(a,g,{skipOpenApp:!1}),A=await m(v,"Sign Solana transaction");return r.signatures[0]=A,{transaction:Buffer.from(r.serialize()).toString("base64")}}default:throw new Error(`Ledger transaction signing not supported for ${t}`)}}async function V(e,n){let{moonpay:i}=await import("./client-S2OYW27G.js"),t=(await i.chain.retrieve({chain:e})).keyFamily;if(t==="bitcoin")throw new Error("Bitcoin message signing via Ledger is not yet supported. Use a software wallet for Bitcoin message signing.");if(t==="tron")throw new Error("Tron message signing via Ledger is not supported. Use a software wallet for Tron message signing.");await R(t);let a=$(t),u=E(),c=f();switch(t){case"evm":{let{SignerEthBuilder:d}=I(),w=new d({dmk:c,sessionId:u}).build().signMessage(a,n,{skipOpenApp:!1}),o=await m(w,"Sign message"),r=k(o.r),g=k(o.s),v=o.v.toString(16).padStart(2,"0");return{signature:`0x${r}${g}${v}`}}case"solana":{let{SignerSolanaBuilder:d}=L(),l=new d({dmk:c,sessionId:u}).build(),w=Buffer.from(n,"utf8").toString("hex"),o=l.signMessage(a,w,{skipOpenApp:!1}),r=await m(o,"Sign Solana message");return{signature:(await import("bs58")).default.encode(r)}}default:throw new Error(`Ledger message signing not supported for ${t}`)}}async function q(){if(p){try{await f().disconnect({sessionId:p})}catch{}p=null}if(h){try{h.close()}catch{}h=null}}export{P as connectLedger,q as disconnectLedger,x as ledgerGetAddress,F as ledgerGetAllAddresses,V as ledgerSignMessage,H as ledgerSignTransaction};
|
|
@@ -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 f,d as u}from"./chunk-
|
|
2
|
+
import{a as f,d as u}from"./chunk-7VEPX3MI.js";import{b as d}from"./chunk-IBLWQCA2.js";import"./chunk-V4NDQ53W.js";import{e as l,g as R}from"./chunk-HKDLPDJU.js";import"./chunk-LMDE72OE.js";import{Server as N}from"@modelcontextprotocol/sdk/server/index.js";import{StdioServerTransport as O}from"@modelcontextprotocol/sdk/server/stdio.js";import{CallToolRequestSchema as T,ListToolsRequestSchema as x}from"@modelcontextprotocol/sdk/types.js";import{zodToJsonSchema as k}from"zod-to-json-schema";R();var y=new Map(u.map(s=>[s.schema.name,s]));function q(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 P(){let s=new N({name:"moonpay",version:l},{capabilities:{tools:{listChanged:!0}}}),n=u.map(e=>({name:e.schema.name,description:e.schema.description,inputSchema:k(e.schema.input)})),c=new Map;for(let e of f){if(y.has(e.name))continue;let t=q(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 h=new Map(n.map(e=>[e.name,e]));s.setRequestHandler(x,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(!h.has(t))return{content:[{type:"text",text:`Unknown tool: ${t}`}],isError:!0};try{let i=y.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 S=c.get(t)??{};for(let[p,r]of Object.entries(S))o[p]===void 0&&(Array.isArray(r.type)?r.type.includes("null"):r.anyOf?.some(w=>w.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 b=await d._call(t,o);return{content:[{type:"text",text:JSON.stringify(b,null,2)}]}}catch(i){return{content:[{type:"text",text:i instanceof Error?i.message:String(i)}],isError:!0}}});let g=new O;await s.connect(g)}export{P 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{A as v,B as w,f as a,g as b,h as c,i as d,j as e,k as f,l as g,m as h,n as i,o as j,p as k,q as l,r as m,s as n,t as o,u as p,v as q,w as r,x as s,y as t,z as u}from"./chunk-
|
|
2
|
+
import{A as v,B as w,f as a,g as b,h as c,i as d,j as e,k as f,l as g,m as h,n as i,o as j,p as k,q as l,r as m,s as n,t as o,u as p,v as q,w as r,x as s,y as t,z as u}from"./chunk-V4NDQ53W.js";import"./chunk-HKDLPDJU.js";import"./chunk-LMDE72OE.js";export{m as addHardwareWallet,u as addWallet,d as createWallet,j as deleteWallet,l as exportSecret,h as findWallet,i as findWalletOrThrow,a as getVaultPath,e as importMnemonic,f as importPrivateKey,g as listWallets,s as loadWallets,c as migrateWallets,w as mutateWallets,p as owsSignMessage,o as owsSignTransaction,q as owsSignTypedData,n as refreshHardwareAddresses,t as removeWallet,k as renameWallet,b as requireMigrationCheck,r as resolveSigningKey,v as saveWallets};
|
package/package.json
CHANGED
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: moonpay-buy-the-dip
|
|
3
|
+
description: Buy a fixed USD amount of a token any time the price drops sharply, with a cooldown so you don't catch the whole knife at once.
|
|
4
|
+
tags: [trading, automation, dca]
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Buy the dip
|
|
8
|
+
|
|
9
|
+
## Goal
|
|
10
|
+
|
|
11
|
+
Mechanical dip-buyer: fires a fixed USD buy when 24h drawdown exceeds a threshold, but only once per cooldown window so a multi-day slide doesn't drain the budget in 24 hours.
|
|
12
|
+
|
|
13
|
+
This skill works in two contexts:
|
|
14
|
+
- **Inside an automation harness** (MoonPay Agents desktop app): chat session memory holds last-fire timestamp and cumulative cost basis.
|
|
15
|
+
- **Headless via cron / launchd**: a JSON file at `~/.config/moonpay/state/buy-the-dip-<id>.json`.
|
|
16
|
+
|
|
17
|
+
## Prerequisites
|
|
18
|
+
|
|
19
|
+
- `mp` authenticated: `mp user retrieve`
|
|
20
|
+
- A funded wallet with the spending token (e.g. USDC) — `mp token balance list --wallet <addr> --chain <chain>`
|
|
21
|
+
- `jq` and `bc` installed
|
|
22
|
+
|
|
23
|
+
## Configuration
|
|
24
|
+
|
|
25
|
+
Captured on first run:
|
|
26
|
+
|
|
27
|
+
| Field | Notes |
|
|
28
|
+
|---|---|
|
|
29
|
+
| `token` | Token to buy. Resolve via `mp token search` |
|
|
30
|
+
| `chain` | e.g. `solana`, `ethereum`, `base` |
|
|
31
|
+
| `wallet` | Local wallet name |
|
|
32
|
+
| `usd_per_buy` | USD amount per fire. Default: 200 |
|
|
33
|
+
| `drawdown_pct` | Trigger threshold (24h price change). Default: 8 (interpreted as -8%) |
|
|
34
|
+
| `cooldown_days` | Days between fires. Default: 7 |
|
|
35
|
+
| `from_token` | What to spend. Default: USDC on the same chain |
|
|
36
|
+
|
|
37
|
+
State maintained:
|
|
38
|
+
|
|
39
|
+
| Field | Notes |
|
|
40
|
+
|---|---|
|
|
41
|
+
| `last_fire_at` | ISO timestamp of the last buy. Null until the first fire |
|
|
42
|
+
| `total_spent_usd` | Sum across all fires |
|
|
43
|
+
| `total_token_acquired` | Sum across all fires. Requires parsing the swap response for the actual filled token amount — the reference script below tracks USD only; if you want the token total, parse `mp token swap`'s output for the destination amount and update on each fire |
|
|
44
|
+
|
|
45
|
+
## Per-fire workflow
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
1. Get token data: price + 24h change.
|
|
49
|
+
data = mp --json token retrieve --token $TOKEN --chain $CHAIN
|
|
50
|
+
price = data.marketData.price
|
|
51
|
+
change_24h_pct = data.marketData.priceChangePercent."24h" * 100
|
|
52
|
+
2. cooldown_active = last_fire_at != null AND now < last_fire_at + cooldown_days
|
|
53
|
+
3. Decision:
|
|
54
|
+
- If change_24h_pct <= -drawdown_pct AND NOT cooldown_active:
|
|
55
|
+
BUY usd_per_buy worth of token via mp token swap (USDC → token)
|
|
56
|
+
Update last_fire_at = now
|
|
57
|
+
Update totals
|
|
58
|
+
Report fill price, amount bought, the 24h drop that triggered, next-eligible date
|
|
59
|
+
- Else if change_24h_pct <= -drawdown_pct AND cooldown_active:
|
|
60
|
+
Log "trigger hit but in cooldown — N days remaining"; exit
|
|
61
|
+
- Else:
|
|
62
|
+
Log "no dip — 24h change is X%"; exit
|
|
63
|
+
4. After any fire, optionally report cumulative stats: total_spent, average buy price, total token, current PnL on the dip-stack.
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Schedule
|
|
67
|
+
|
|
68
|
+
Hourly is the right cadence. Faster doesn't help — 24h change doesn't move that quickly within a single trading hour, and the cooldown gates fires anyway.
|
|
69
|
+
|
|
70
|
+
- Cron: `0 * * * * /path/to/script.sh # moonpay:buy-the-dip-<id>`
|
|
71
|
+
|
|
72
|
+
## Headless reference script
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
#!/bin/bash
|
|
76
|
+
set -euo pipefail
|
|
77
|
+
MP="$(which mp)"
|
|
78
|
+
ID="dip-buy-eth-main"
|
|
79
|
+
STATE="$HOME/.config/moonpay/state/${ID}.json"
|
|
80
|
+
LOG="$HOME/.config/moonpay/logs/trading.log"
|
|
81
|
+
mkdir -p "$(dirname "$STATE")" "$(dirname "$LOG")"
|
|
82
|
+
log() { echo "[$(date -u +%Y-%m-%dT%H:%M:%SZ)] $ID $*" >> "$LOG"; }
|
|
83
|
+
|
|
84
|
+
# --- Config ---
|
|
85
|
+
TOKEN="<token-address>"
|
|
86
|
+
CHAIN="ethereum"
|
|
87
|
+
WALLET="main"
|
|
88
|
+
USD_PER_BUY=200
|
|
89
|
+
DRAWDOWN_PCT=8
|
|
90
|
+
COOLDOWN_DAYS=7
|
|
91
|
+
FROM_TOKEN="0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48" # USDC on Ethereum
|
|
92
|
+
|
|
93
|
+
# Initialize state. total_token_acquired is omitted from the headless reference
|
|
94
|
+
# because parsing the actual filled amount out of `mp token swap`'s response is
|
|
95
|
+
# chain-dependent; track USD spent instead. Add token tracking back if you need
|
|
96
|
+
# average buy price — extract the destination amount from the swap response.
|
|
97
|
+
if [ ! -f "$STATE" ]; then
|
|
98
|
+
echo '{"last_fire_at": null, "total_spent_usd": 0}' > "$STATE"
|
|
99
|
+
fi
|
|
100
|
+
|
|
101
|
+
# --- Read price + 24h change ---
|
|
102
|
+
DATA=$("$MP" --json token retrieve --token "$TOKEN" --chain "$CHAIN")
|
|
103
|
+
PRICE=$(echo "$DATA" | jq '.marketData.price')
|
|
104
|
+
CHANGE=$(echo "$DATA" | jq '.marketData.priceChangePercent."24h" // 0')
|
|
105
|
+
CHANGE_PCT=$(echo "$CHANGE * 100" | bc -l)
|
|
106
|
+
|
|
107
|
+
# --- Cooldown check ---
|
|
108
|
+
LAST=$(jq -r '.last_fire_at // empty' "$STATE")
|
|
109
|
+
COOLDOWN_ACTIVE=false
|
|
110
|
+
if [ -n "$LAST" ]; then
|
|
111
|
+
# `last_fire_at` is stored in UTC (suffix Z). macOS `date -j` defaults to
|
|
112
|
+
# interpreting the parsed time as local — `-u` is required so UTC+9 users
|
|
113
|
+
# don't get a 9-hour-shorter cooldown than configured. GNU `date -d`
|
|
114
|
+
# parses the trailing Z natively.
|
|
115
|
+
LAST_EPOCH=$(date -u -j -f "%Y-%m-%dT%H:%M:%SZ" "$LAST" +%s 2>/dev/null || date -u -d "$LAST" +%s)
|
|
116
|
+
NOW=$(date +%s)
|
|
117
|
+
AGE_DAYS=$(echo "($NOW - $LAST_EPOCH) / 86400" | bc -l)
|
|
118
|
+
if (( $(echo "$AGE_DAYS < $COOLDOWN_DAYS" | bc -l) )); then COOLDOWN_ACTIVE=true; fi
|
|
119
|
+
fi
|
|
120
|
+
|
|
121
|
+
# --- Decide ---
|
|
122
|
+
TRIGGERED=$(echo "$CHANGE_PCT <= -$DRAWDOWN_PCT" | bc -l)
|
|
123
|
+
if [ "$TRIGGERED" = "1" ] && [ "$COOLDOWN_ACTIVE" = "false" ]; then
|
|
124
|
+
log "BUY: 24h $CHANGE_PCT% — buying \$$USD_PER_BUY of $TOKEN at $PRICE"
|
|
125
|
+
# Swap USDC -> token. USDC has 6 decimals on Solana/Ethereum/Base — adjust units.
|
|
126
|
+
USDC_AMOUNT="$USD_PER_BUY" # USDC ~ \$1
|
|
127
|
+
RESULT=$("$MP" --json token swap \
|
|
128
|
+
--wallet "$WALLET" --chain "$CHAIN" \
|
|
129
|
+
--from-token "$FROM_TOKEN" --from-amount "$USDC_AMOUNT" \
|
|
130
|
+
--to-token "$TOKEN" 2>&1) || { log "BUY FAILED: $RESULT"; exit 1; }
|
|
131
|
+
log "BUY OK: $RESULT"
|
|
132
|
+
jq --arg t "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
|
|
133
|
+
--argjson s "$USD_PER_BUY" \
|
|
134
|
+
'.last_fire_at = $t | .total_spent_usd += $s' \
|
|
135
|
+
"$STATE" > "$STATE.tmp" && mv "$STATE.tmp" "$STATE"
|
|
136
|
+
elif [ "$TRIGGERED" = "1" ]; then
|
|
137
|
+
log "trigger hit but in cooldown — last fire $LAST"
|
|
138
|
+
else
|
|
139
|
+
log "no dip — 24h change ${CHANGE_PCT}%"
|
|
140
|
+
fi
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## Inside an automation harness
|
|
144
|
+
|
|
145
|
+
When run inside the MoonPay Agents app, the harness chat session holds `last_fire_at` and the running totals. The agent reports cumulative stats (total spent, average buy price, current PnL on the dip-stack) on every fire — these come naturally from session memory rather than a state file.
|
|
146
|
+
|
|
147
|
+
## Common pitfalls
|
|
148
|
+
|
|
149
|
+
- **Treating `priceChangePercent."24h"` as already a percent**. The schema returns a decimal: `0.0327` for +3.27%. Multiply by 100 if comparing to a percent threshold.
|
|
150
|
+
- **No cooldown**. Without one, an 8% drop on day one is followed by another 5% drop on day two; without the gate, you fire again on the second drop's *cumulative* 24h change. The user wanted to feed the dip slowly, not all at once.
|
|
151
|
+
- **Hard-coded USDC decimals**. USDC has 6 decimals on Ethereum/Solana/Base/Polygon. The amount you pass to `mp token swap` is in token units, not raw decimals — `mp` handles decimals server-side based on the token address.
|
|
152
|
+
- **Forgetting to verify funds**. Before placing the buy, confirm `from_token` balance ≥ `usd_per_buy` via `mp token balance list`. If insufficient, log clearly and skip.
|
|
153
|
+
|
|
154
|
+
## Related skills
|
|
155
|
+
|
|
156
|
+
- **moonpay-trading-automation** — DCA / limit / stop patterns; this skill is the conditional-DCA cousin
|
|
157
|
+
- **moonpay-trailing-stop** — Pair this skill (entries) with that one (exits) for a full mechanical strategy
|
|
158
|
+
- **moonpay-discover-tokens** — Token resolution + price + 24h change from a single command
|
|
159
|
+
- **moonpay-swap-tokens** — Swap syntax
|
|
160
|
+
- **moonpay-check-wallet** — Verify funds before firing
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: moonpay-take-profit-ladder
|
|
3
|
+
description: Sell a position in chunks at preset price targets, hold the runner. Each rung sells a slice of the CURRENT remaining position when its target price is crossed.
|
|
4
|
+
tags: [trading, automation, take-profit]
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Take-profit ladder
|
|
8
|
+
|
|
9
|
+
## Goal
|
|
10
|
+
|
|
11
|
+
Lock in profit on a position progressively as price rises. The user defines rungs as `(price_multiplier, % of current position to sell)` pairs. As each rung is crossed, the strategy sells that slice and lets the rest ride.
|
|
12
|
+
|
|
13
|
+
This skill works in two contexts:
|
|
14
|
+
- **Inside an automation harness** (MoonPay Agents desktop app): chat session memory tracks fired/unfired rungs.
|
|
15
|
+
- **Headless via cron / launchd**: a JSON file at `~/.config/moonpay/state/take-profit-ladder-<id>.json`.
|
|
16
|
+
|
|
17
|
+
## Prerequisites
|
|
18
|
+
|
|
19
|
+
- `mp` authenticated: `mp user retrieve`
|
|
20
|
+
- The target position is held in a wallet `mp wallet list` knows about
|
|
21
|
+
- `jq` and `bc` installed
|
|
22
|
+
|
|
23
|
+
## Configuration
|
|
24
|
+
|
|
25
|
+
Captured on first run:
|
|
26
|
+
|
|
27
|
+
| Field | Notes |
|
|
28
|
+
|---|---|
|
|
29
|
+
| `token` | Token address. Resolve via `mp token search` if user gives a ticker |
|
|
30
|
+
| `chain` | e.g. `solana`, `ethereum`, `base` |
|
|
31
|
+
| `wallet` | Local wallet name |
|
|
32
|
+
| `entry_price` | Cost basis the rungs are computed off — required |
|
|
33
|
+
| `rungs` | Array of `{multiplier, sell_pct, fired}`. Default: `[{x: 1.5, sell: 25, fired: false}, {x: 2.0, sell: 25, fired: false}, {x: 3.0, sell: 25, fired: false}]` (hold remaining 25%) |
|
|
34
|
+
| `sell_into` | Default: USDC |
|
|
35
|
+
|
|
36
|
+
Compute absolute target prices once: `target = entry_price * multiplier`. Persist them so price math is consistent across fires.
|
|
37
|
+
|
|
38
|
+
## Per-fire workflow
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
1. price = mp --json token retrieve --token $TOKEN --chain $CHAIN | jq '.marketData.price'
|
|
42
|
+
2. balance = mp --json token balance list --wallet $WALLET_ADDR --chain $CHAIN
|
|
43
|
+
| jq --arg t $TOKEN '.items[] | select(.address==$t) | .balance.amount'
|
|
44
|
+
3. If balance == 0: mark all rungs as fired or strategy as complete; log "ladder complete"; exit.
|
|
45
|
+
4. crossable = rungs where fired==false AND price >= target
|
|
46
|
+
5. If crossable is empty: log "holding — price $price, next rung at $next_target ($gap_pct% away)"; exit.
|
|
47
|
+
6. For each crossable rung (in target order, lowest first):
|
|
48
|
+
a. sell_amount = current_balance * (rung.sell_pct / 100)
|
|
49
|
+
b. mp token swap --from-token $TOKEN --from-amount $sell_amount --to-token $SELL_INTO ...
|
|
50
|
+
c. Mark rung.fired = true. Update balance for next iteration.
|
|
51
|
+
7. Report: fill price for each rung, USD realized this fire, cumulative USD realized, % of original position remaining.
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
The sell command:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
mp --json token swap \
|
|
58
|
+
--wallet "$WALLET" \
|
|
59
|
+
--chain "$CHAIN" \
|
|
60
|
+
--from-token "$TOKEN" \
|
|
61
|
+
--from-amount "$SELL_AMOUNT" \
|
|
62
|
+
--to-token "$SELL_INTO"
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Schedule
|
|
66
|
+
|
|
67
|
+
15 minutes is a reasonable default. Volatile small-caps may want 5 minutes so a fast pump doesn't blow past multiple rungs unnoticed (the strategy handles gap-ups by firing all crossed rungs in one pass — but you'd rather fire each rung close to its actual price than fire all three at one mid-pump price).
|
|
68
|
+
|
|
69
|
+
## Headless reference script
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
#!/bin/bash
|
|
73
|
+
set -euo pipefail
|
|
74
|
+
MP="$(which mp)"
|
|
75
|
+
ID="tp-ladder-bonk-main"
|
|
76
|
+
STATE="$HOME/.config/moonpay/state/${ID}.json"
|
|
77
|
+
LOG="$HOME/.config/moonpay/logs/trading.log"
|
|
78
|
+
mkdir -p "$(dirname "$STATE")" "$(dirname "$LOG")"
|
|
79
|
+
log() { echo "[$(date -u +%Y-%m-%dT%H:%M:%SZ)] $ID $*" >> "$LOG"; }
|
|
80
|
+
|
|
81
|
+
# --- Config ---
|
|
82
|
+
TOKEN="<token-mint>"
|
|
83
|
+
CHAIN="solana"
|
|
84
|
+
WALLET="main"
|
|
85
|
+
WALLET_ADDR="<address>"
|
|
86
|
+
SELL_INTO="EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"
|
|
87
|
+
ENTRY_PRICE=0.000020 # user-provided
|
|
88
|
+
|
|
89
|
+
# Initialize state on first run.
|
|
90
|
+
# We compute targets via jq (not bc) because bc strips leading zeros on
|
|
91
|
+
# fractional results — bc would produce ".000030" for a 0.000020 entry × 1.5,
|
|
92
|
+
# which is invalid JSON. jq formats numbers correctly.
|
|
93
|
+
if [ ! -f "$STATE" ]; then
|
|
94
|
+
jq -n --argjson e "$ENTRY_PRICE" '
|
|
95
|
+
{
|
|
96
|
+
entry_price: $e,
|
|
97
|
+
rungs: [
|
|
98
|
+
{target: ($e * 1.5), sell_pct: 25, fired: false},
|
|
99
|
+
{target: ($e * 2.0), sell_pct: 25, fired: false},
|
|
100
|
+
{target: ($e * 3.0), sell_pct: 25, fired: false}
|
|
101
|
+
]
|
|
102
|
+
}
|
|
103
|
+
' > "$STATE"
|
|
104
|
+
log "initialized ladder at entry $ENTRY_PRICE"
|
|
105
|
+
fi
|
|
106
|
+
|
|
107
|
+
# --- Load price + balance ---
|
|
108
|
+
PRICE=$("$MP" --json token retrieve --token "$TOKEN" --chain "$CHAIN" | jq '.marketData.price')
|
|
109
|
+
BALANCE=$("$MP" --json token balance list --wallet "$WALLET_ADDR" --chain "$CHAIN" \
|
|
110
|
+
| jq --arg t "$TOKEN" '[.items[] | select(.address==$t) | .balance.amount][0] // 0')
|
|
111
|
+
|
|
112
|
+
if (( $(echo "$BALANCE <= 0" | bc -l) )); then
|
|
113
|
+
log "balance is zero, ladder complete"; exit 0
|
|
114
|
+
fi
|
|
115
|
+
|
|
116
|
+
# --- Iterate rungs in order ---
|
|
117
|
+
COUNT=$(jq '.rungs | length' "$STATE")
|
|
118
|
+
for i in $(seq 0 $((COUNT-1))); do
|
|
119
|
+
FIRED=$(jq -r ".rungs[$i].fired" "$STATE")
|
|
120
|
+
TARGET=$(jq -r ".rungs[$i].target" "$STATE")
|
|
121
|
+
PCT=$(jq -r ".rungs[$i].sell_pct" "$STATE")
|
|
122
|
+
if [ "$FIRED" = "true" ] || (( $(echo "$PRICE < $TARGET" | bc -l) )); then continue; fi
|
|
123
|
+
|
|
124
|
+
CURRENT=$("$MP" --json token balance list --wallet "$WALLET_ADDR" --chain "$CHAIN" \
|
|
125
|
+
| jq --arg t "$TOKEN" '[.items[] | select(.address==$t) | .balance.amount][0] // 0')
|
|
126
|
+
SELL=$(echo "scale=8; $CURRENT * $PCT / 100" | bc -l)
|
|
127
|
+
|
|
128
|
+
log "RUNG $i: price $PRICE >= target $TARGET — selling $SELL ($PCT% of $CURRENT)"
|
|
129
|
+
RESULT=$("$MP" --json token swap \
|
|
130
|
+
--wallet "$WALLET" --chain "$CHAIN" \
|
|
131
|
+
--from-token "$TOKEN" --from-amount "$SELL" \
|
|
132
|
+
--to-token "$SELL_INTO" 2>&1) || { log "RUNG $i FAILED: $RESULT"; exit 1; }
|
|
133
|
+
log "RUNG $i OK: $RESULT"
|
|
134
|
+
|
|
135
|
+
jq ".rungs[$i].fired = true" "$STATE" > "$STATE.tmp" && mv "$STATE.tmp" "$STATE"
|
|
136
|
+
done
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## Inside an automation harness
|
|
140
|
+
|
|
141
|
+
When this skill runs inside the MoonPay Agents desktop app, the harness's persistent chat session holds the rung state — no `state.json` needed. The agent reports each fire conversationally and continues to track unfired rungs across runs.
|
|
142
|
+
|
|
143
|
+
## Common pitfalls
|
|
144
|
+
|
|
145
|
+
- **Selling a fixed % of the original position instead of the current**. If rung 1 sold 25% of original and rung 2 also sells "25% of original," you're selling 33% of what's left. Always compute against the current balance at the moment of firing.
|
|
146
|
+
- **Storing only multipliers without absolute targets**. If you recompute `entry_price * multiplier` from memory each fire and entry_price drifts (say, the agent re-asks the user), you'll fire on different prices. Persist absolute target prices once.
|
|
147
|
+
- **Not handling gap-ups**. If price jumps from 1.4× entry to 2.5× entry between fires, both rung 1 and rung 2 should fire. The reference script iterates all unfired rungs — match that pattern.
|
|
148
|
+
|
|
149
|
+
## Related skills
|
|
150
|
+
|
|
151
|
+
- **moonpay-trading-automation** — General shell-script + cron patterns
|
|
152
|
+
- **moonpay-trailing-stop** — Companion strategy for the downside
|
|
153
|
+
- **moonpay-discover-tokens** — Resolve tickers to addresses
|
|
154
|
+
- **moonpay-swap-tokens** — Swap syntax
|