@coinbase/coinbase-cli 0.0.8 → 0.0.10

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/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- var L_=Object.defineProperty;var h_=(t=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(t,{get:(e,r)=>(typeof require<"u"?require:e)[r]}):t)(function(t){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+t+'" is not supported')});var S=(t,e)=>()=>(t&&(e=t(t=0)),e);var Zt=(t,e)=>{for(var r in e)L_(t,r,{get:e[r],enumerable:!0})};var O,u=S(()=>{O={live:{brokerageApi:"https://api.coinbase.com",agentApi:"https://agents.coinbase.com/api"}}});var m,d=S(()=>{m={production:"live"}});var v_,cn,Ie,En,un,pe=S(()=>{"use strict";u();d();v_="https://agents.coinbase.com/api",cn="@coinbase/coinbase-cli",Ie="https://registry.npmjs.org",En=typeof O<"u"?O:{live:{brokerageApi:"https://api.coinbase.com",agentApi:v_}},un=typeof m<"u"?m:{production:"live"}});function ht(t){return nr+Buffer.from(t,"utf8").toString("base64")}function Ut(t){return t.startsWith(nr)?Buffer.from(t.slice(nr.length),"base64").toString("utf8"):t}var nr,Te=S(()=>{"use strict";u();d();nr="b64:"});import{execFileSync as Re}from"node:child_process";var Oe,me,dn=S(()=>{"use strict";u();d();Te();Oe="/usr/bin/security",me=class{constructor(){try{Re(Oe,["list-keychains"],{stdio:["pipe","pipe","pipe"]})}catch{throw new Error("Keychain not accessible")}}get(e,r){try{let n=Re(Oe,["find-generic-password","-s",e,"-a",r,"-w"],{encoding:"utf8",stdio:["pipe","pipe","pipe"]}).trimEnd();return Ut(n)}catch{return null}}set(e,r,n){Re(Oe,["add-generic-password","-U","-s",e,"-a",r,"-w",ht(n)],{stdio:["pipe","pipe","pipe"]})}delete(e,r){try{Re(Oe,["delete-generic-password","-s",e,"-a",r],{stdio:["pipe","pipe","pipe"]})}catch{}}}});import{execFileSync as Ae}from"node:child_process";var Ne,gn=S(()=>{"use strict";u();d();Te();Ne=class{constructor(){try{Ae("which",["secret-tool"],{stdio:["pipe","pipe","pipe"]})}catch{throw new Error("secret-tool not found")}}get(e,r){try{let n=Ae("secret-tool",["lookup","service",e,"account",r],{encoding:"utf8",stdio:["pipe","pipe","pipe"]});return Ut(n.trimEnd())}catch{return null}}set(e,r,n){Ae("secret-tool",["store","--label",`${e}:${r}`,"service",e,"account",r],{input:ht(n),stdio:["pipe","pipe","pipe"]})}delete(e,r){try{Ae("secret-tool",["clear","service",e,"account",r],{stdio:["pipe","pipe","pipe"]})}catch{}}}});import{execFileSync as k_}from"node:child_process";function ir(t,e){return`${t}:${e}`}function Se(t){return t.replace(/'/g,"''")}function sr(t,e){let r=F_+t,n=Buffer.from(r,"utf16le").toString("base64"),i=e===void 0?process.env:{...process.env,[ln]:e};return k_("powershell.exe",["-NoProfile","-NonInteractive","-EncodedCommand",n],{encoding:"utf8",stdio:["pipe","pipe","pipe"],env:i}).trimEnd()}var F_,ln,Ce,In=S(()=>{"use strict";u();d();Te();F_=`
2
+ var h_=Object.defineProperty;var U_=(t=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(t,{get:(e,r)=>(typeof require<"u"?require:e)[r]}):t)(function(t){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+t+'" is not supported')});var S=(t,e)=>()=>(t&&(e=t(t=0)),e);var Zt=(t,e)=>{for(var r in e)h_(t,r,{get:e[r],enumerable:!0})};var O,u=S(()=>{O={live:{brokerageApi:"https://api.coinbase.com",agentApi:"https://agents.coinbase.com/api"}}});var m,d=S(()=>{m={production:"live"}});var k_,En,Ie,un,dn,pe=S(()=>{"use strict";u();d();k_="https://agents.coinbase.com/api",En="@coinbase/coinbase-cli",Ie="https://registry.npmjs.org",un=typeof O<"u"?O:{live:{brokerageApi:"https://api.coinbase.com",agentApi:k_}},dn=typeof m<"u"?m:{production:"live"}});function ht(t){return er+Buffer.from(t,"utf8").toString("base64")}function Ut(t){return t.startsWith(er)?Buffer.from(t.slice(er.length),"base64").toString("utf8"):t}var er,Te=S(()=>{"use strict";u();d();er="b64:"});import{execFileSync as Re}from"node:child_process";var Oe,me,gn=S(()=>{"use strict";u();d();Te();Oe="/usr/bin/security",me=class{constructor(){try{Re(Oe,["list-keychains"],{stdio:["pipe","pipe","pipe"]})}catch{throw new Error("Keychain not accessible")}}get(e,r){try{let n=Re(Oe,["find-generic-password","-s",e,"-a",r,"-w"],{encoding:"utf8",stdio:["pipe","pipe","pipe"]}).trimEnd();return Ut(n)}catch{return null}}set(e,r,n){Re(Oe,["add-generic-password","-U","-s",e,"-a",r,"-w",ht(n)],{stdio:["pipe","pipe","pipe"]})}delete(e,r){try{Re(Oe,["delete-generic-password","-s",e,"-a",r],{stdio:["pipe","pipe","pipe"]})}catch{}}}});import{execFileSync as Ae}from"node:child_process";var Ne,ln=S(()=>{"use strict";u();d();Te();Ne=class{constructor(){try{Ae("which",["secret-tool"],{stdio:["pipe","pipe","pipe"]})}catch{throw new Error("secret-tool not found")}}get(e,r){try{let n=Ae("secret-tool",["lookup","service",e,"account",r],{encoding:"utf8",stdio:["pipe","pipe","pipe"]});return Ut(n.trimEnd())}catch{return null}}set(e,r,n){Ae("secret-tool",["store","--label",`${e}:${r}`,"service",e,"account",r],{input:ht(n),stdio:["pipe","pipe","pipe"]})}delete(e,r){try{Ae("secret-tool",["clear","service",e,"account",r],{stdio:["pipe","pipe","pipe"]})}catch{}}}});import{execFileSync as F_}from"node:child_process";function rr(t,e){return`${t}:${e}`}function Se(t){return t.replace(/'/g,"''")}function nr(t,e){let r=V_+t,n=Buffer.from(r,"utf16le").toString("base64"),i=e===void 0?process.env:{...process.env,[In]:e};return F_("powershell.exe",["-NoProfile","-NonInteractive","-EncodedCommand",n],{encoding:"utf8",stdio:["pipe","pipe","pipe"],env:i}).trimEnd()}var V_,In,Ce,pn=S(()=>{"use strict";u();d();Te();V_=`
3
3
  if (-not ([System.Management.Automation.PSTypeName]'Win32.Cred').Type) {
4
4
  Add-Type -Namespace Win32 -Name Cred -MemberDefinition '
5
5
  [DllImport("advapi32.dll", SetLastError=true, CharSet=CharSet.Unicode)]
@@ -17,7 +17,7 @@ if (-not ([System.Management.Automation.PSTypeName]'Win32.Cred').Type) {
17
17
  public string TargetAlias; public string UserName;
18
18
  }'
19
19
  }
20
- `,ln="COINBASE_KEYRING_SECRET";Ce=class{get(e,r){try{let n=Se(ir(e,r)),i=sr(`
20
+ `,In="COINBASE_KEYRING_SECRET";Ce=class{get(e,r){try{let n=Se(rr(e,r)),i=nr(`
21
21
  $ptr = [IntPtr]::Zero
22
22
  if ([Win32.Cred]::CredRead('${n}', 1, 0, [ref]$ptr)) {
23
23
  $cred = [Runtime.InteropServices.Marshal]::PtrToStructure($ptr, [Type][Win32.Cred+CREDENTIAL])
@@ -25,8 +25,8 @@ if ([Win32.Cred]::CredRead('${n}', 1, 0, [ref]$ptr)) {
25
25
  [Runtime.InteropServices.Marshal]::Copy($cred.CredentialBlob, $bytes, 0, $cred.CredentialBlobSize)
26
26
  [Win32.Cred]::CredFree($ptr)
27
27
  [Text.Encoding]::UTF8.GetString($bytes)
28
- }`);return i?Ut(i):null}catch{return null}}set(e,r,n){let i=Se(ir(e,r)),s=Se(r);sr(`
29
- $sec = $env:${ln}
28
+ }`);return i?Ut(i):null}catch{return null}}set(e,r,n){let i=Se(rr(e,r)),s=Se(r);nr(`
29
+ $sec = $env:${In}
30
30
  $bytes = [Text.Encoding]::UTF8.GetBytes($sec)
31
31
  $blob = [Runtime.InteropServices.Marshal]::AllocHGlobal($bytes.Length)
32
32
  [Runtime.InteropServices.Marshal]::Copy($bytes, 0, $blob, $bytes.Length)
@@ -40,95 +40,95 @@ $cred.Persist = 2
40
40
  if (-not [Win32.Cred]::CredWrite([ref]$cred, 0)) {
41
41
  throw "CredWrite failed: $([Runtime.InteropServices.Marshal]::GetLastWin32Error())"
42
42
  }
43
- [Runtime.InteropServices.Marshal]::FreeHGlobal($blob)`,ht(n))}delete(e,r){try{sr(`[void][Win32.Cred]::CredDelete('${Se(ir(e,r))}', 1, 0)`)}catch{}}}});function Jt(){if(pt!==void 0)return pt;try{process.platform==="darwin"?pt=new me:process.platform==="linux"?pt=new Ne:process.platform==="win32"?pt=new Ce:pt=null}catch{pn||(process.stderr.write(`warning: OS keychain not accessible \u2014 secrets stored in keychain will not be available
44
- `),pn=!0),pt=null}return pt}function Tn(t){let e=Jt();if(!e)return null;try{return e.get(Pt,t)}catch{return null}}function Rn(t,e){let r=Jt();if(!r)return!1;try{return r.set(Pt,t,e),!0}catch{return!1}}function On(t){let e=Jt();if(e)try{e.delete(Pt,t)}catch{}}function mn(){return Jt()!==null}function An(){let t=Jt();if(!t)return!1;let e="__coinbase_cli_preflight__";try{t.set(Pt,e,"ok");let r=t.get(Pt,e);return t.delete(Pt,e),r==="ok"}catch{try{t.delete(Pt,e)}catch{}return!1}}var Pt,pt,pn,_r=S(()=>{"use strict";u();d();dn();gn();In();Pt="coinbase-cli",pn=!1});var Ln={};Zt(Ln,{activeEnvName:()=>Ft,activeEnvironment:()=>re,authIsViable:()=>Er,builtinEnvironments:()=>rt,clearEnvCredentialCache:()=>gr,clearEnvironmentSecretsFromKeychain:()=>ur,clearHistory:()=>ne,configDir:()=>Tt,configPath:()=>st,credentialsFor:()=>ee,envCredential:()=>te,getHistory:()=>pr,historyEnabled:()=>De,hydrateEnvironmentSecrets:()=>yn,isBuiltinURL:()=>fe,loadConfig:()=>tt,resolveAgentAPIURLForEnvironment:()=>Rt,resolveBrokerageURL:()=>nt,resolveURL:()=>x_,saveConfig:()=>ut,scrubbedEnv:()=>lr,setHistory:()=>Ir,setLockOptions:()=>K_,withConfigLock:()=>dr,writeEnvironmentSecretsToKeychain:()=>bn});import{readFileSync as Cn,writeFileSync as Pn,mkdirSync as fn,renameSync as V_,unlinkSync as or,openSync as G_,closeSync as w_,statSync as W_}from"node:fs";import{homedir as Nn}from"node:os";import{join as Pe}from"node:path";function Tt(){if(process.env.COINBASE_CONFIG_DIR)return process.env.COINBASE_CONFIG_DIR;if(process.platform==="win32"){let t=process.env.APPDATA??Pe(Nn(),"AppData","Roaming");return Pe(t,"coinbase")}return Pe(Nn(),".config","coinbase")}function st(){return Pe(Tt(),"config.json")}function Dn(t){if(rt[t])return rt[t];let e=Sn[t];if(e&&rt[e])return rt[e];let r={...rt};for(let[i,s]of Object.entries(Sn))rt[s]&&(r[i]=rt[s]);let n=Object.keys(r).find(i=>t.startsWith(i+"-"));return n?r[n]:void 0}function nt(t,e){return t.endpoints?.brokerageApi??t.url??Dn(e)?.brokerageApi??""}function x_(t,e){return nt(t,e)}function Rt(t,e){return t.endpoints?.agentApi??Dn(e)?.agentApi??""}function fe(t){return Object.values(rt).some(e=>e.brokerageApi&&t.startsWith(e.brokerageApi))}function B_(t,e){return Object.values(kt[e].secrets).map(r=>r(t))}function Er(t){if(!t)return!1;let e=kt[t.type];return e?Object.keys(e.secrets).every(r=>!!t[r]):!1}function yn(t,e){if(!e.auth)return e;let r=kt[e.auth.type];if(!r)return e;let n=e.auth,i={...n},s=!1,_=!1;for(let[o,a]of Object.entries(r.secrets)){if(n[o]){_=!0;continue}let E=Tn(a(t));E&&(i[o]=E,s=!0)}return Er(i)?{...e,auth:i,..._&&!s?{_plaintextBacked:!0}:{}}:{...e,auth:void 0}}function bn(t,e){if(!e.auth)return!0;if(!mn())return!1;let r=e.auth.type,n=kt[r];if(!n)return!0;if(!Er(e.auth)){let s=Object.keys(n.secrets).filter(_=>!e.auth[_]);throw new Error(`writeEnvironmentSecretsToKeychain: ${r} for "${t}" missing ${s.join(", ")}`)}let i=!0;for(let[s,_]of Object.entries(n.secrets))Rn(_(t),e.auth[s])||(i=!1);return i}function ur(t){for(let e of Object.keys(kt))for(let r of B_(t,e))On(r)}function te(t){return t.auth}function ee(t,e){if(e.auth?.type==="cdp_key")return{keyId:e.auth.key_id,keySecret:e.auth.key_secret};throw new Error(`environment "${t}" has no credentials. Run: coinbase env ${t} --key-file path/to/key.json`)}function tt(){let t={env:"",environments:{},history:{}};try{let e=Cn(st(),"utf8"),r=JSON.parse(e);t.env=r.env??"";let n=r.environments??{};for(let[i,s]of Object.entries(n))t.environments[i]=yn(i,s);return t.history=r.history??{},r.settings&&(t.settings=r.settings),t}catch(e){if(e.code!=="ENOENT")throw e instanceof SyntaxError?new Error(`invalid config JSON: ${e.message}`):new Error(`reading config: ${e.message}`)}return t}function ut(t,e={}){let r=Tt();fn(r,{recursive:!0,mode:448});let n={},i=[];for(let[a,E]of Object.entries(t.environments)){let g={};if(E.url!==void 0&&(g.url=E.url),E.endpoints!==void 0&&(g.endpoints={...E.endpoints}),!E.auth){n[a]=g;continue}let c=bn(a,E),l=e.allowPlaintext===!0||E._plaintextBacked===!0;if(!c){if(!l){i.push(a);continue}g.auth=E.auth,n[a]=g;continue}let p=kt[E.auth.type];p&&(g.auth=p.metadataOnly(E.auth)),n[a]=g}if(i.length)throw new Error(`OS keychain unavailable; refusing to persist secrets for environment(s): ${i.join(", ")}.
45
- Re-run the env-setup command with --allow-plaintext-secrets to write secrets to ${st()} (file is mode 0600), or install/unlock your OS keychain (macOS Keychain, libsecret on Linux, Windows Credential Manager).`);let s={env:t.env,environments:n};Object.keys(t.history).length>0&&(s.history=t.history),t.settings&&(s.settings=t.settings);let _=st(),o=`${_}.${process.pid}.${Date.now()}.tmp`;try{Pn(o,JSON.stringify(s,null,2)+`
46
- `,{mode:384}),V_(o,_)}catch(a){try{or(o)}catch{}throw a}}function K_(t){Mt={...Mt,...t}}function vt(){return st()+H_}function Y_(t){let e=Date.now()+t;for(;Date.now()<e;);}function q_(){try{let t=G_(vt(),"wx",384);return Pn(t,String(process.pid)),t}catch(t){if(t.code!=="EEXIST")throw t;return null}}function z_(){try{let t=W_(vt());if(Date.now()-t.mtimeMs<Mt.staleAfterMs)return!1;let e=Cn(vt(),"utf8").trim(),r=Number(e);if(!Number.isInteger(r)||r<=0)return!0;try{return process.kill(r,0),!1}catch(n){return n.code==="ESRCH"}}catch{return!1}}function dr(t){fn(Tt(),{recursive:!0,mode:448});let e=null;for(let r=0;r<Mt.retries&&(e=q_(),e===null);r++){if(z_()){try{or(vt())}catch{}continue}Y_(Mt.baseDelayMs*(1+Math.random()))}if(e===null)throw new Error(`could not acquire config lock after ${Mt.retries} attempts: ${vt()}`);try{return t()}finally{try{w_(e)}catch{}try{or(vt())}catch{}}}function gr(){ar=void 0,cr=void 0}function $_(){return process.env.COINBASE_KEY_ID&&(ar=process.env.COINBASE_KEY_ID,delete process.env.COINBASE_KEY_ID),process.env.COINBASE_KEY_SECRET&&(cr=process.env.COINBASE_KEY_SECRET,delete process.env.COINBASE_KEY_SECRET),{keyId:ar,keySecret:cr}}function Ft(t,e){return e||process.env.COINBASE_ENV||t.env}function re(t,e){let r=Ft(t,e);if(!r)throw new Error("no environment configured. Run: coinbase env <name>");let n={...t.environments[r]},{keyId:i,keySecret:s}=$_();if(i||s){let a=n.auth?.type==="cdp_key"?n.auth:void 0,E=i??a?.key_id??"",g=s??a?.key_secret??"";E&&g&&(n.auth={type:"cdp_key",key_id:E,key_secret:g})}if(process.env.COINBASE_URL){let a=process.env.COINBASE_URL;n.endpoints={...n.endpoints,brokerageApi:a},n.url=a,fe(a)||process.stderr.write(`warning: COINBASE_URL overrides to non-standard endpoint: ${a}
47
- `)}let _=nt(n,r),o=Rt(n,r);if(!_&&!o)throw new Error(`no REST endpoint for environment "${r}". Set a brokerage URL, an Agent API URL, or use a built-in environment name`);if(!n.auth)throw new Error(`no credentials for "${r}". Run: coinbase env ${r} --key-file path/to/key.json`);return{name:r,env:n}}function lr(){let t={...process.env};for(let e of j_)delete t[e];return t}function De(t){return process.env.COINBASE_NO_HISTORY?!1:t.settings?.history?.enabled!==!1}function Ir(t,e,r,n){t.history[e]||(t.history[e]={}),t.history[e][r]={last_used:new Date().toISOString(),values:n}}function pr(t,e,r){return t.history[e]?.[r]}function ne(t,e,r){if(e&&r)return t.history[e]?.[r]?(delete t.history[e][r],Object.keys(t.history[e]).length===0&&delete t.history[e],1):0;if(e){let i=Object.keys(t.history[e]??{}).length;return delete t.history[e],i}let n=Object.values(t.history).reduce((i,s)=>i+Object.keys(s).length,0);return t.history={},n}var rt,Sn,kt,H_,Mt,ar,cr,j_,it=S(()=>{"use strict";u();d();pe();_r();rt=En,Sn=un;kt={cdp_key:{secrets:{key_secret:t=>`${t}:cdp:key_secret`},metadataOnly:t=>({type:"cdp_key",key_id:t.key_id})}};H_=".lock",Mt={retries:50,baseDelayMs:20,staleAfterMs:5e3};j_=["COINBASE_KEY_SECRET","COINBASE_KEY_ID"]});function Un(t,e,r){let n=new Date(Date.UTC(t,e-1,r));return n.getUTCFullYear()===t&&n.getUTCMonth()===e-1&&n.getUTCDate()===r}var X,Z,Mn,vn,kn,ft=S(()=>{"use strict";u();d();X=[{name:"api-key",actions:[{id:"api_key_permissions",name:"permissions",method:"GET",path:"/api-key/permissions",summary:"Get Current API Key Permissions",description:"Returns the authoritative permissions and portfolio association for the API key used to authenticate this request. It accepts no key or customer identifier and always inspects the current credential.",pathParams:[],params:[],streamable:!1,watchFields:null,watch:null,template:{},responseFields:{fields:["can_view","can_trade","can_transfer","portfolio_uuid","portfolio_type"]},annotations:{readOnlyHint:!0},agentApi:"eligible",noInput:!0,history:"disabled"}]},{name:"convert",actions:[{id:"convert_quote",name:"quote",method:"POST",path:"/convert/quote",summary:"Get Convert Quote",description:"Quotes stablecoin\u2194fiat and stablecoin\u2194stablecoin conversions, returning rate, fees, and a quote ID. It does not support BTC, ETH, or other non-stablecoin assets; use an order to trade those assets. Pass the ID to convert_execute promptly because quotes expire.",pathParams:[],params:[{name:"from",in:"body",type:"string",required:!0,description:"Source currency",example:"USDC"},{name:"to",in:"body",type:"string",required:!0,description:"Target currency",example:"USD"},{name:"amount",in:"body",type:"string",required:!0,description:"Amount to convert",example:"100.00"}],streamable:!1,watchFields:null,watch:null,template:{from:"USDC",to:"USD",amount:"100.00"},responseFields:{fields:["trade"],nested:{trade:{fields:["id","status","amount","subtotal","total","total_fee","exchange_rate","source_currency","target_currency"]}}},annotations:{readOnlyHint:!1,destructiveHint:!1},agentApi:"eligible"},{id:"convert_execute",name:"execute",method:"POST",path:"/convert/execute/{quote_id}",summary:"Execute Convert Trade",description:"Executes a previously quoted conversion using the quote_id from convert_quote. This moves funds at the quoted rate \u2014 get a fresh quote first since quotes expire. The from/to currencies must match the original quote.",pathParams:["quote_id"],params:[{name:"quote_id",in:"path",type:"string",required:!0,description:"Quote ID from convert quote response"},{name:"from",in:"body",type:"string",required:!0,description:"Source currency",example:"USDC"},{name:"to",in:"body",type:"string",required:!0,description:"Target currency",example:"USD"}],streamable:!1,watchFields:null,watch:null,template:{from:"USDC",to:"USD"},responseFields:{fields:["trade"],nested:{trade:{fields:["id","status"]}}},annotations:{destructiveHint:!0},agentApi:"eligible"},{id:"convert_get",name:"get",method:"GET",path:"/convert/get/{quote_id}",summary:"Get Convert Status",description:"Check status of a conversion by quote ID.",pathParams:["quote_id"],params:[{name:"quote_id",in:"path",type:"string",required:!0,description:"Quote ID"},{name:"from",in:"query",type:"string",required:!0,description:"Source currency"},{name:"to",in:"query",type:"string",required:!0,description:"Target currency"}],streamable:!1,watchFields:null,watch:null,template:{},responseFields:{fields:["id","status","source_currency","target_currency","exchange_rate"]},annotations:{readOnlyHint:!0},agentApi:"eligible"}]},{name:"orders",actions:[{id:"orders_list",name:"list",method:"GET",path:"/orders",summary:"List Orders",description:"Lists orders with optional filters by status, product, side, and time range. Use status=OPEN to find resting orders that can be edited or cancelled.",pathParams:[],params:[{name:"portfolio_id",in:"query",type:"string",required:!1,description:"Scope to a specific portfolio (defaults to all portfolios the caller can access)"},{name:"status",in:"query",type:"string",required:!1,description:"Filter by status"},{name:"product_ids",in:"query",type:"string",required:!1,description:"Filter by product (e.g. BTC-USD). Comma-separated for multiple."},{name:"side",in:"query",type:"string",required:!1,description:"Filter by side",enum:["BUY","SELL"],example:"BUY"},{name:"product_type",in:"query",type:"string",required:!1,description:"Filter by product type",enum:["SPOT","FUTURE","EQUITY"],example:"SPOT"},{name:"start",in:"query",type:"string",required:!1,description:"Start date (RFC 3339 with timezone, e.g. 2024-01-01T00:00:00Z)",format:"date-time"},{name:"end",in:"query",type:"string",required:!1,description:"End date (RFC 3339 with timezone, e.g. 2024-12-31T23:59:59Z)",format:"date-time"},{name:"limit",in:"query",type:"integer",required:!1,description:"Results per page"},{name:"cursor",in:"query",type:"string",required:!1,description:"Pagination cursor"}],streamable:!0,watchFields:{status:{type:"string",enum:["pending","open","filled","cancelled","failed","expired","cancel_queued"],description:"Order status"},side:{type:"string",enum:["buy","sell"],description:"Order side"},price:{type:"string",format:"decimal",description:"Average filled price"},filled_size:{type:"string",format:"decimal",description:"Filled quantity"},fees:{type:"string",format:"decimal",description:"Total fees"},product_id:{type:"string",description:"Trading pair"},order_id:{type:"string",description:"Order ID"}},watch:{channel:"user",endpoint:"user",requiresAuth:!0,coalesce:!1},template:{},responseFields:{fields:["orders","has_next","cursor"],nested:{orders:{fields:["order_id","product_id","side","status","order_configuration","created_time","completion_percentage","filled_size","average_filled_price","total_fees","total_value_after_fees","number_of_fills"]}}},annotations:{readOnlyHint:!0},agentApi:"eligible"},{id:"orders_create",name:"create",method:"POST",path:"/orders",summary:"Create Order",description:"Place a requested market, limit, or stop-limit order. Preview first for fee or slippage estimates. Set exactly one size: for limit and market SELL, quote_size is converted to base_size; market BUY spends quote_size; stop_limit uses base_size. A FUTURE order rejected on eligibility grounds means the account isn't approved for futures. Send the user to\u2026",pathParams:[],params:[{name:"product_id",in:"body",type:"string",required:!0,description:`Trading pair (BASE-QUOTE, e.g. BTC-USD or BTC-USDC) for spot crypto, a dated-futures contract code for CFM. For equities, use TICKER-QUOTE (e.g. AAPL-USD or AAPL-USDC). If the user names a quote currency (e.g. "use my USDC"), use that pair \u2014 never default to USD instead. If they don't say, check the balance for this request's portfolio_id (or the default portfolio if omitted) and use whichever of USD/USDC they hold there; if both, prefer the USDC pair. If the resulting pair doesn't exist, tell the user rather than silently substituting a different one.`,example:"BTC-USDC"},{name:"side",in:"body",type:"string",required:!0,description:"BUY or SELL",enum:["BUY","SELL"],example:"BUY"},{name:"type",in:"body",type:"string",required:!0,description:"market (fill at current price), limit (fill at specified price or better), stop_limit (trigger limit order when price crosses stop_price)",enum:["market","limit","stop_limit"],example:"market"},{name:"quote_size",in:"body",type:"string",required:!1,description:"Quote-currency amount (e.g. $100 USD). Mutually exclusive with base_size. Market BUYs spend this amount; limit and market SELL convert it to base_size. Not supported for stop_limit. Max 15,000 USD notional.",oneOf:"base_size|quote_size",example:"100.00"},{name:"base_size",in:"body",type:"string",required:!1,description:"Base currency amount (e.g. buy 0.001 BTC). Any side/type. Keep order notional at or below 15,000 USD (quote-currency equivalent).",oneOf:"base_size|quote_size",example:"0.001"},{name:"limit_price",in:"body",type:"string",required:!1,description:"Limit price (limit/stop_limit orders)",example:"65000.00"},{name:"stop_price",in:"body",type:"string",required:!1,description:"Stop price (stop_limit orders)",example:"60000.00"},{name:"stop_direction",in:"body",type:"string",required:!1,description:"up = trigger when price rises above stop_price. down = trigger when falls below.",enum:["up","down"],example:"down"},{name:"post_only",in:"body",type:"boolean",required:!1,description:"Post-only mode (limit orders). Rejects if would take liquidity."},{name:"time_in_force",in:"body",type:"string",required:!1,description:"GTC=good til cancelled. IOC=immediate or cancel. FOK=fill or kill.",enum:["GTC","IOC","FOK","GTD"],example:"GTC"},{name:"end_time",in:"body",type:"string",required:!1,description:"Expiry time for GTD orders (RFC 3339). Required when time_in_force=GTD.",format:"date-time",example:"2024-12-31T23:59:59Z"},{name:"reduce_only",in:"body",type:"boolean",required:!1,description:"Only reduce existing position. Rejects if would increase exposure."},{name:"portfolio_id",in:"body",type:"string",required:!1,description:"The optional UUID of a portfolio containing accounts with which to trade. Defaults to the default portfolio when no portfolio_id is provided."},{name:"client_order_id",in:"body",type:"string",required:!1,description:"Idempotency key (auto-generated if omitted)"},{name:"equity_trading_session",in:"body",type:"string",required:!1,description:"Equity orders only. Trading session for the order. Ignored for crypto and futures.",enum:["NORMAL","PRE_MARKET","AFTER_HOURS","OVERNIGHT","MULTI_SESSION"]},{name:"equity_order_date",in:"body",type:"string",required:!1,description:"Equity orders only. Trade date for the order (YYYY-MM-DD). Ignored for crypto and futures.",format:"date"}],streamable:!1,watchFields:null,watch:null,template:{product_id:"BTC-USDC",side:"BUY",type:"market",quote_size:"100.00",base_size:"0.001",limit_price:"65000.00",stop_price:"60000.00",stop_direction:"down",post_only:!1,time_in_force:"GTC",end_time:"2024-12-31T23:59:59Z",reduce_only:!1,portfolio_id:"<string>",client_order_id:"<string>",equity_trading_session:"NORMAL",equity_order_date:"<string>"},responseFields:{fields:["order_id","product_id","side","client_order_id"]},annotations:{destructiveHint:!0},agentApi:"eligible"},{id:"orders_preview",name:"preview",method:"POST",path:"/orders/preview",summary:"Preview Order",description:"Estimate fees, fill price, and slippage for an order without placing it. For futures orders, also returns this order's margin/leverage/liquidation impact (order_margin_total, margin_ratio_data's current vs projected ratio, current vs projected liquidation buffer) \u2014 use this to check whether a specific order is safe before placing it. Optional \u2014 use it when the user wants an estimate before\u2026",pathParams:[],params:[{name:"product_id",in:"body",type:"string",required:!0,description:`Trading pair (BASE-QUOTE, e.g. BTC-USD or BTC-USDC) for spot crypto, a dated-futures contract code for CFM. For equities, use TICKER-QUOTE (e.g. AAPL-USD or AAPL-USDC). If the user names a quote currency (e.g. "use my USDC"), use that pair \u2014 never default to USD instead. If they don't say, check the balance for this request's portfolio_id (or the default portfolio if omitted) and use whichever of USD/USDC they hold there; if both, prefer the USDC pair. If the resulting pair doesn't exist, tell the user rather than silently substituting a different one.`,example:"BTC-USDC"},{name:"side",in:"body",type:"string",required:!0,description:"BUY or SELL",enum:["BUY","SELL"],example:"BUY"},{name:"type",in:"body",type:"string",required:!0,description:"market (fill at current price), limit (fill at specified price or better), stop_limit (trigger limit order when price crosses stop_price)",enum:["market","limit","stop_limit"],example:"market"},{name:"quote_size",in:"body",type:"string",required:!1,description:"Quote currency amount (e.g. spend $100 USD). Mutually exclusive with base_size.",oneOf:"base_size|quote_size",example:"100.00"},{name:"base_size",in:"body",type:"string",required:!1,description:"Base currency amount (e.g. 0.001 BTC). Mutually exclusive with quote_size.",oneOf:"base_size|quote_size",example:"0.001"},{name:"limit_price",in:"body",type:"string",required:!1,description:"Limit price (for limit/stop_limit previews)",example:"65000.00"},{name:"stop_price",in:"body",type:"string",required:!1,description:"Stop price (for stop_limit previews)",example:"60000.00"},{name:"stop_direction",in:"body",type:"string",required:!1,description:"up = trigger when price rises above stop_price. down = trigger when falls below.",enum:["up","down"],example:"down"},{name:"portfolio_id",in:"body",type:"string",required:!1,description:"The optional UUID of a portfolio containing accounts with which to trade. Defaults to the default portfolio when no portfolio_id is provided."},{name:"equity_trading_session",in:"body",type:"string",required:!1,description:"Equity orders only. Trading session for the order. Ignored for crypto and futures.",enum:["NORMAL","PRE_MARKET","AFTER_HOURS","OVERNIGHT","MULTI_SESSION"]},{name:"equity_order_date",in:"body",type:"string",required:!1,description:"Equity orders only. Trade date for the order (YYYY-MM-DD). Ignored for crypto and futures.",format:"date"}],streamable:!1,watchFields:null,watch:null,template:{product_id:"BTC-USDC",side:"BUY",type:"market",quote_size:"100.00",base_size:"0.001",limit_price:"65000.00",stop_price:"60000.00",stop_direction:"down",portfolio_id:"<string>",equity_trading_session:"NORMAL",equity_order_date:"<string>"},responseFields:{fields:["order_total","commission_total","slippage","est_average_filled_price","base_size","quote_size","best_bid","best_ask","leverage","long_leverage","short_leverage","max_leverage","position_notional_limit","available_buying_power","order_margin_total","current_liquidation_buffer","projected_liquidation_buffer","predicted_liquidation_price","margin_ratio_data"],nested:{margin_ratio_data:{fields:["current_margin_ratio","projected_margin_ratio"]}}},annotations:{readOnlyHint:!0},agentApi:"eligible"},{id:"orders_edit",name:"edit",method:"POST",path:"/orders/{order_id}/edit",summary:"Edit Order",description:"Atomically update an open order's price or size without cancelling. Avoids the cancel+replace exposure window.",pathParams:["order_id"],params:[{name:"order_id",in:"path",type:"string",required:!0,description:"Order to edit"},{name:"base_size",in:"body",type:"string",required:!1,description:"New base size",example:"0.002"},{name:"limit_price",in:"body",type:"string",required:!1,description:"New limit price",example:"64000.00"}],streamable:!1,watchFields:null,watch:null,template:{base_size:"0.002",limit_price:"64000.00"},responseFields:{fields:["order_id","status"]},annotations:{destructiveHint:!0},agentApi:"eligible"},{id:"orders_edit_preview",name:"edit-preview",method:"POST",path:"/orders/edit-preview",summary:"Preview Order Edit",description:"Estimate the result, fees, fill price, and slippage for replacing an open order's size or limit price without editing or otherwise executing the order. This is read-only in side-effect semantics, but upstream authorization currently requires mcp:orders:create for hosted OAuth callers; mcp:orders:read alone is denied. CDP API-key callers may use rat#view where supported by the upstream path.\u2026",pathParams:[],params:[{name:"order_id",in:"body",type:"string",required:!0,description:"Open order UUID to preview editing"},{name:"base_size",in:"body",type:"string",required:!1,description:"Positive decimal replacement base size",example:"0.002"},{name:"limit_price",in:"body",type:"string",required:!1,description:"Positive decimal replacement limit price",example:"64000.00"}],streamable:!1,watchFields:null,watch:null,template:{order_id:"<string>",base_size:"0.002",limit_price:"64000.00"},responseFields:{fields:["slippage","order_total","commission_total","quote_size","base_size","best_bid","best_ask","average_filled_price","order_margin_total","commission_detail_total","pnl_configuration"],nested:{commission_detail_total:{fields:["total_commission","gst_commission","withholding_commission","client_commission","venue_commission","regulatory_commission","clearing_commission"]},pnl_configuration:{fields:["trigger_bracket_pnl"],nested:{trigger_bracket_pnl:{fields:["take_profit_pnl","stop_loss_pnl"]}}}}},anyOf:[["base_size"],["limit_price"]],annotations:{readOnlyHint:!0,destructiveHint:!1},agentApi:"eligible"},{id:"orders_get",name:"get",method:"GET",path:"/orders/{order_id}",summary:"Get Order",description:"Retrieves the full status and fill details of a single order by ID. Use after creating an order to confirm execution.",pathParams:["order_id"],params:[{name:"order_id",in:"path",type:"string",required:!0,description:"Order ID"}],streamable:!1,watchFields:null,watch:null,template:{},responseFields:{fields:["order_id","product_id","side","status","order_configuration","created_time","completion_percentage","filled_size","average_filled_price","total_fees","total_value_after_fees","number_of_fills"]},annotations:{readOnlyHint:!0},agentApi:"eligible"},{id:"orders_cancel",name:"cancel",method:"POST",path:"/orders/cancel",summary:"Cancel Orders",description:"Cancels one or more open orders by ID. Removes resting orders from the book so reserved funds are released; already-filled portions are unaffected. Returns per-order success so a partial batch can fail.",pathParams:[],params:[{name:"order_ids",in:"body",type:"array",required:!0,description:"Order IDs to cancel"}],streamable:!1,watchFields:null,watch:null,template:{order_ids:[]},responseFields:{fields:["results"],nested:{results:{fields:["success","order_id"]}}},annotations:{destructiveHint:!0},agentApi:"eligible"},{id:"orders_close_position",name:"close-position",method:"POST",path:"/orders/close-position",summary:"Close Position",description:"Places a market order to flatten an open position for a product, moving funds immediately. Omit size for a full close or set it for a partial close. Preview the equivalent order first if fee or slippage impact matters.",pathParams:[],params:[{name:"client_order_id",in:"body",type:"string",required:!0,description:"Idempotency key"},{name:"product_id",in:"body",type:"string",required:!0,description:"Product to close",example:"BTC-PERP"},{name:"size",in:"body",type:"string",required:!1,description:"Partial close size (omit for full close)",example:"0.001"}],streamable:!1,watchFields:null,watch:null,template:{client_order_id:"<string>",product_id:"BTC-PERP",size:"0.001"},responseFields:{fields:["success","order_id","product_id"]},annotations:{destructiveHint:!0},agentApi:"eligible"},{id:"orders_fills",name:"fills",method:"GET",path:"/orders/fills",summary:"List Fills",description:"Lists individual trade executions with commissions and maker/taker indicator, filterable by product, order, side, and time range. Use this to reconcile actual fill prices and fees paid.",pathParams:[],params:[{name:"portfolio_id",in:"query",type:"string",required:!1,description:"Scope to a specific portfolio (defaults to all portfolios the caller can access)"},{name:"product_ids",in:"query",type:"string",required:!1,description:"Filter by product (e.g. BTC-USD)"},{name:"order_ids",in:"query",type:"array",required:!1,description:"Filter by order ID"},{name:"side",in:"query",type:"string",required:!1,description:"Filter by side",enum:["BUY","SELL"],example:"BUY"},{name:"start",in:"query",type:"string",required:!1,description:"Start time (RFC 3339 with timezone, e.g. 2024-01-01T00:00:00Z)",format:"date-time"},{name:"end",in:"query",type:"string",required:!1,description:"End time (RFC 3339 with timezone, e.g. 2024-12-31T23:59:59Z)",format:"date-time"},{name:"limit",in:"query",type:"integer",required:!1,description:"Results per page"},{name:"cursor",in:"query",type:"string",required:!1,description:"Pagination cursor"}],streamable:!1,watchFields:null,watch:null,template:{},responseFields:{fields:["fills","cursor"],nested:{fills:{fields:["trade_id","order_id","trade_time","price","size","commission","product_id","side","liquidity_indicator"]}}},annotations:{readOnlyHint:!0},agentApi:"eligible"}]},{name:"portfolios",actions:[{id:"portfolios_list",name:"list",method:"GET",path:"/portfolios",summary:"List Portfolios",description:"Lists all portfolios on the account, including their UUIDs and types. Use this to find the portfolio_id needed for orders, transfers, and balance queries.",pathParams:[],params:[{name:"portfolio_type",in:"query",type:"string",required:!1,description:"Filter by type (DEFAULT, CONSUMER)",enum:["DEFAULT","CONSUMER"]}],streamable:!1,watchFields:null,watch:null,template:{},responseFields:{fields:["portfolios"],nested:{portfolios:{fields:["uuid","name","type","deleted"]}}},annotations:{readOnlyHint:!0},agentApi:"eligible"},{id:"portfolios_create",name:"create",method:"POST",path:"/portfolios",summary:"Create Portfolio",description:"Creates a new named portfolio for segregating funds and positions. Does not move any funds; use transfer afterward to fund it.",pathParams:[],params:[{name:"name",in:"body",type:"string",required:!0,description:"Portfolio name",example:"agent-1"}],streamable:!1,watchFields:null,watch:null,template:{name:"agent-1"},responseFields:{fields:["uuid","name","type","deleted"]},annotations:{destructiveHint:!1},agentApi:"eligible"},{id:"portfolios_get",name:"get",method:"GET",path:"/portfolios/{portfolio_id}",summary:"Get Portfolio Breakdown",description:"Returns portfolio metadata, balances, and positions.",pathParams:["portfolio_id"],params:[{name:"portfolio_id",in:"path",type:"string",required:!0,description:"Portfolio UUID"},{name:"currency",in:"query",type:"string",required:!1,description:"Currency for balance denomination"}],streamable:!1,watchFields:null,watch:null,template:{},responseFields:{fields:["portfolio","portfolio_balances","spot_positions","futures_positions","equity_positions"],nested:{portfolio:{fields:["uuid","name","type","deleted"]},portfolio_balances:{fields:["total_balance","total_crypto_balance","total_cash_equivalent_balance","total_equities_balance"],nested:{total_balance:{fields:["value","currency"]},total_crypto_balance:{fields:["value","currency"]},total_cash_equivalent_balance:{fields:["value","currency"]},total_equities_balance:{fields:["value","currency"]}}},spot_positions:{fields:["asset","account_uuid","total_balance_fiat","total_balance_crypto","available_to_trade_fiat","allocation","is_cash"]},futures_positions:{fields:["product_id","contract_size","side","amount","avg_entry_price","current_price","unrealized_pnl","expiry","underlying_asset","product_name","venue","notional_value"]},equity_positions:{fields:["asset","account_uuid","total_balance_fiat","total_balance_equity","available_to_trade_equity","available_to_trade_fiat","account_type","allocation","cost_basis","average_entry_price","unrealized_pnl"]}}},annotations:{readOnlyHint:!0},agentApi:"eligible"},{id:"portfolios_edit",name:"edit",method:"PUT",path:"/portfolios/{portfolio_id}",summary:"Edit Portfolio",description:"Renames an existing portfolio. Does not affect balances or positions.",pathParams:["portfolio_id"],params:[{name:"portfolio_id",in:"path",type:"string",required:!0,description:"Portfolio UUID"},{name:"name",in:"body",type:"string",required:!1,description:"New portfolio name"}],streamable:!1,watchFields:null,watch:null,template:{name:"<string>"},responseFields:{fields:["uuid","name","type","deleted"]},annotations:{destructiveHint:!1},agentApi:"eligible"},{id:"portfolios_delete",name:"delete",method:"DELETE",path:"/portfolios/{portfolio_id}",summary:"Delete Portfolio",description:"Permanently deletes a portfolio. The portfolio must be empty first \u2014 transfer out any remaining funds and close all positions before deleting. The DEFAULT portfolio cannot be deleted.",pathParams:["portfolio_id"],params:[{name:"portfolio_id",in:"path",type:"string",required:!0,description:"Portfolio UUID"}],streamable:!1,watchFields:null,watch:null,template:{},responseFields:null,annotations:{destructiveHint:!0},agentApi:"eligible"}]},{name:"products",actions:[{id:"products_list",name:"list",method:"GET",path:"/products",summary:"List Products",description:"Viewing products, including FUTURE ones, doesn't require any special account approval. Trading them is a separate matter \u2014 see the product_type field description.",pathParams:[],params:[{name:"product_type",in:"query",type:"string",required:!1,description:"Product type filter",enum:["SPOT","FUTURE","EQUITY"],example:"SPOT"},{name:"product_ids",in:"query",type:"string",required:!1,description:"Comma-separated product IDs"},{name:"symbol",in:"query",type:"string",required:!1,description:"Filter products by symbol, matches base or quote side (e.g. USD, BTC). For a specific product use products_get (e.g. BTC-USD). Pagination ignored when set.",pattern:"^[A-Za-z0-9]+$"},{name:"limit",in:"query",type:"integer",required:!1,description:"Results per page"},{name:"cursor",in:"query",type:"string",required:!1,description:"Pagination cursor"}],streamable:!1,watchFields:null,watch:null,template:{},responseFields:{fields:["products","cursor","has_next","num_products"],nested:{products:{fields:["product_id","price","price_percentage_change_24h","volume_24h","product_type","quote_currency_id","base_currency_id","base_increment","quote_increment","base_min_size","base_max_size","quote_min_size","quote_max_size","status","future_product_details","fcm_trading_session_details"],nested:{future_product_details:{fields:["contract_expiry_type","contract_size","contract_expiry","time_to_expiry_ms","open_interest","funding_rate","funding_interval","funding_time","intraday_margin_rate","overnight_margin_rate"],nested:{intraday_margin_rate:{fields:["long_margin_rate","short_margin_rate"]},overnight_margin_rate:{fields:["long_margin_rate","short_margin_rate"]}}},fcm_trading_session_details:{fields:["is_session_open","open_time","close_time","session_state"]}}}}},annotations:{readOnlyHint:!0},agentApi:"eligible"},{id:"products_best_bid_ask",name:"best-bid-ask",method:"GET",path:"/products/best-bid-ask",summary:"Best Bid/Ask for Multiple Products",description:"Returns best bid and ask for one or more products in a single call. Omit product_ids to return pricebooks for all products. Not currently available for equities.",pathParams:[],params:[{name:"product_ids",in:"query",type:"array",required:!1,description:"Product IDs (e.g. BTC-USD and ETH-USD). Omit to return all products."}],streamable:!1,watchFields:null,watch:null,template:{},responseFields:{fields:["pricebooks"],nested:{pricebooks:{fields:["product_id","bids","asks","time"],nested:{bids:{fields:["price","size"]},asks:{fields:["price","size"]}}}}},annotations:{readOnlyHint:!0},agentApi:"eligible"},{id:"products_get",name:"get",method:"GET",path:"/products/{product_id}",summary:"Get Product",description:"Viewing a product, including a FUTURE one, doesn't require any special account approval. Trading it is a separate matter \u2014 see the product_type field description.",pathParams:["product_id"],params:[{name:"product_id",in:"path",type:"string",required:!0,description:"Product ID (e.g. BTC-USD)"}],streamable:!1,watchFields:null,watch:null,template:{},responseFields:{fields:["product_id","price","price_percentage_change_24h","volume_24h","product_type","quote_currency_id","base_currency_id","base_increment","quote_increment","base_min_size","base_max_size","quote_min_size","quote_max_size","status","future_product_details","fcm_trading_session_details"],nested:{future_product_details:{fields:["contract_expiry_type","contract_size","contract_expiry","time_to_expiry_ms","open_interest","funding_rate","funding_interval","funding_time","intraday_margin_rate","overnight_margin_rate"],nested:{intraday_margin_rate:{fields:["long_margin_rate","short_margin_rate"]},overnight_margin_rate:{fields:["long_margin_rate","short_margin_rate"]}}},fcm_trading_session_details:{fields:["is_session_open","open_time","close_time","session_state"]}}},annotations:{readOnlyHint:!0},agentApi:"eligible"},{id:"products_ticker",name:"ticker",method:"GET",path:"/products/{product_id}/ticker",summary:"Get Ticker",description:"Returns recent trade prints plus the current best bid/ask for a product. Use for a quick spot-price snapshot before previewing or placing an order. Not currently available for equities.",pathParams:["product_id"],params:[{name:"product_id",in:"path",type:"string",required:!0,description:"Trading pair (e.g. BTC-USD)"},{name:"limit",in:"query",type:"integer",required:!1,description:"Number of trades. Defaults to 100."}],streamable:!0,watchFields:{price:{type:"string",format:"decimal",description:"Last trade price"},bid:{type:"string",format:"decimal",description:"Best bid"},ask:{type:"string",format:"decimal",description:"Best ask"},bid_size:{type:"string",format:"decimal",description:"Size at best bid"},ask_size:{type:"string",format:"decimal",description:"Size at best ask"},volume:{type:"string",format:"decimal",description:"24h volume"},high:{type:"string",format:"decimal",description:"24h high"},low:{type:"string",format:"decimal",description:"24h low"},pct_24h:{type:"string",format:"decimal",description:"24h price change %"},product_id:{type:"string",description:"Trading pair"}},watch:{channel:"ticker",endpoint:"public",requiresAuth:!1,coalesce:!0},template:{},responseFields:{fields:["trades","best_bid","best_ask"],nested:{trades:{fields:["trade_id","product_id","price","size","time","side"]}}},annotations:{readOnlyHint:!0},agentApi:"eligible"},{id:"products_book",name:"book",method:"GET",path:"/products/{product_id}/book",summary:"Get Order Book",description:"Returns the current bid/ask order book for a product. Use to gauge available liquidity and likely slippage before sizing a market order. Not currently available for equities.",pathParams:["product_id"],params:[{name:"product_id",in:"path",type:"string",required:!0,description:"Product ID"},{name:"limit",in:"query",type:"integer",required:!1,description:"Number of levels"}],streamable:!0,watchFields:{spread:{type:"string",format:"decimal",description:"Bid-ask spread"},mid:{type:"string",format:"decimal",description:"Midpoint price"},product_id:{type:"string",description:"Trading pair"}},watch:{channel:"level2",wireName:"l2_data",endpoint:"public",requiresAuth:!1,coalesce:!0},template:{},responseFields:{fields:["pricebook"],nested:{pricebook:{fields:["product_id","bids","asks","time"],nested:{bids:{fields:["price","size"]},asks:{fields:["price","size"]}}}}},annotations:{readOnlyHint:!0},agentApi:"eligible"},{id:"products_candles",name:"candles",method:"GET",path:"/products/{product_id}/candles",summary:"Get Candles",description:"Returns historical OHLCV candles for a product at a chosen granularity and time range. Use for price history and technical analysis. Not currently available for equities.",pathParams:["product_id"],params:[{name:"product_id",in:"path",type:"string",required:!0,description:"Trading pair (e.g. BTC-USD)"},{name:"start",in:"query",type:"string",required:!1,description:"Start time (RFC 3339, e.g. 2024-01-01T00:00:00Z). Defaults to 60 candles before end.",format:"date-time"},{name:"end",in:"query",type:"string",required:!1,description:"End time (RFC 3339, e.g. 2024-01-01T00:00:00Z). Defaults to now.",format:"date-time"},{name:"granularity",in:"query",type:"string",required:!1,description:"Candle interval: 1m, 5m, 15m, 30m, 1h, 2h, 4h, 6h, 1d. Defaults to 1h.",enum:["1m","5m","15m","30m","1h","2h","4h","6h","1d"],default:"1h"},{name:"limit",in:"query",type:"integer",required:!1,description:"Max candles"}],streamable:!1,watchFields:null,watch:null,template:{},responseFields:{fields:["candles","truncated"],nested:{candles:{fields:["start","low","high","open","close","volume"]}}},annotations:{readOnlyHint:!0},agentApi:"eligible"}]},{name:"x402",actions:[{id:"x402_resources",name:"resources",method:"GET",path:"/x402/resources",summary:"Discover x402 Resources",description:"Discover curated x402 resources: paid on-chain and market metrics, wallet and entity intelligence, and derivatives data. Discovery spends nothing. An optional keyword q filters the catalog; omit it to list all. Each result carries the resource URL, its advisory price, and its input and output schemas. A result's inputSchema is coinbase_x402_fetch's input verbatim: pass those properties flat; do\u2026",pathParams:[],params:[{name:"q",in:"query",type:"string",required:!1,description:"Optional keyword filter. Matched against each resource's description, provider name, and tags using case-insensitive token search. Omit to return the full catalog."}],streamable:!1,watchFields:null,watch:null,template:{},responseFields:{fields:["resources"],nested:{resources:{fields:["resource","description","accepts","inputSchema","outputSchema"],nested:{accepts:{fields:["amount"]}}}}},annotations:{readOnlyHint:!0},agentApi:"only"},{id:"x402_pay",name:"pay",method:"POST",path:"/x402/pay",summary:"Pay an x402 Payment Requirement",description:"Turns an x402 PaymentRequirements challenge into a ready-to-send payment header by placing a pre-authorized hold on the caller's USDC balance (Base / EIP-3009 exact scheme, v0). Attach the returned header as X-PAYMENT for v1 or PAYMENT-SIGNATURE for v2. This authorizes moving funds up to max_amount \u2014 pass the smallest amount that satisfies the requirement. Funds-touching and gated internal-only\u2026",pathParams:[],params:[{name:"scheme",in:"body",type:"string",required:!0,description:'x402 payment scheme. Only "exact" is supported in v0.'},{name:"network",in:"body",type:"string",required:!0,description:'x402 network as a CAIP-2 chain id. Only "eip155:8453" (Base mainnet) is supported in v0.'},{name:"asset",in:"body",type:"string",required:!0,description:"USDC asset contract address on the network (the x402 asset field)."},{name:"pay_to",in:"body",type:"string",required:!0,description:"Recipient address the payment authorizes (the x402 payTo field)."},{name:"amount",in:"body",type:"string",required:!0,description:"The amount the resource requires, in atomic units of the asset. Decimal string; never truncated."},{name:"max_amount",in:"body",type:"string",required:!0,description:"Caller-set spend cap in atomic units. The hold is rejected if amount exceeds this. Decimal string."},{name:"max_timeout_seconds",in:"body",type:"integer",required:!0,description:"Validity window for the signed authorization, in seconds (the x402 maxTimeoutSeconds field). Must be between 1 and 300; the server caps how long the authorization stays valid. Pass a value no greater than the resource's advertised maxTimeoutSeconds (a shorter window is valid, and settlement is near-instant); requests above 300 are rejected."},{name:"x402_version",in:"body",type:"integer",required:!1,description:"x402 protocol version from the resource's 402 challenge. Pass the value the resource advertised. Optional; defaults to 1."},{name:"extra",in:"body",type:"object",required:!1,description:"Full extra object from the resource's 402 PaymentRequirements. Required when x402_version is 2; name and version must match the Base USDC EIP-712 domain."},{name:"portfolio_id",in:"body",type:"string",required:!1,description:'Optional UUID of the consumer portfolio to pay from. Omit only when exactly one accessible non-deleted consumer portfolio is available and the caller has portfolio listing permission. If discovery is not authorized, provide portfolio_id explicitly. For OAuth, ask the user to reconnect and select "View your trading portfolios" in Coinbase consent. For an API key, ask the user to edit it, open Advanced Settings, and enable "View (read-only)" for every portfolio the agent needs. If multiple consumer portfolios are available, call coinbase_portfolios_list, select the funding portfolio with the use'},{name:"account_id",in:"body",type:"string",required:!1,description:"Optional UUID of the USDC account to debit, within the chosen portfolio. Omit to use that portfolio's single USDC account; the tool returns an error (it does NOT guess) when the portfolio has zero or multiple USDC accounts."},{name:"idempotency_key",in:"body",type:"string",required:!1,description:"Optional caller-supplied idempotency key; must be a UUID. Omit it on a first attempt \u2014 one is generated and returned to you. Reuse the SAME key when retrying an outcome-unknown payment so a duplicate hold is not placed. If the tool reports a terminal rejection, do not reuse that key; start a new payment attempt with a new key."}],streamable:!1,watchFields:null,watch:null,template:{scheme:"<string>",network:"<string>",asset:"<string>",pay_to:"<string>",amount:"<string>",max_amount:"<string>",max_timeout_seconds:0,x402_version:0,extra:{name:"<string>",version:"<string>"},portfolio_id:"<string>",account_id:"<string>",idempotency_key:"<string>"},responseFields:{fields:["payment_header","payment_id","idempotency_key","expires_at"]},annotations:{destructiveHint:!0},agentApi:"only"},{id:"x402_fetch",name:"fetch",method:"POST",path:"/x402/fetch",summary:"Pay For and Fetch x402 Resource",description:"Fetches a resource returned by x402_resources. On a 402 challenge, pays from the caller's custodial USDC via a pre-authorized hold, then retries with PAYMENT-SIGNATURE \u2014 no manual challenge handling. This tool accepts only resource URLs returned by x402_resources. max_amount is the spend control; when the user has requested the data or stated a budget, proceed in a single call rather than\u2026",pathParams:[],params:[{name:"resource",in:"body",type:"string",required:!0,description:"Resource URL returned by coinbase_x402_resources, with any path parameters substituted. Any URL that does not match a catalog resource is rejected."},{name:"input",in:"body",type:"object",required:!1,description:"Request parameters, exactly as described by the resource's inputSchema from coinbase_x402_resources \u2014 pass those properties flat, at the top level. The tool routes them to the query string or the request body per the resource's HTTP method; you do not construct the HTTP envelope. Validated strictly as a closed allowlist; unknown keys are rejected."},{name:"max_amount",in:"body",type:"string",required:!1,description:"Optional caller-set spend cap, in atomic units of the resource's asset. Defaults to the catalog advisory ceiling for the resource; when supplied the effective cap is min(max_amount, advisory ceiling). Never derived from the live 402 challenge."},{name:"portfolio_id",in:"body",type:"string",required:!1,description:'Optional UUID of the consumer portfolio to pay from. Omit only when exactly one accessible non-deleted consumer portfolio is available and the caller has portfolio listing permission. If discovery is not authorized, provide portfolio_id explicitly. For OAuth, ask the user to reconnect and select "View your trading portfolios" in Coinbase consent. For an API key, ask the user to edit it, open Advanced Settings, and enable "View (read-only)" for every portfolio the agent needs. If multiple consumer portfolios are available, call coinbase_portfolios_list, select the funding portfolio with the use'},{name:"account_id",in:"body",type:"string",required:!1,description:"Optional UUID of the USDC account to debit, within the chosen portfolio. Omit to use that portfolio's single USDC account; an error (not a guess) is returned when the portfolio has zero or multiple USDC accounts."},{name:"idempotency_key",in:"body",type:"string",required:!1,description:"Optional caller-supplied idempotency key for the payment; must be a UUID. Omit it on a first attempt \u2014 one is generated and returned to you. Reuse the SAME key when retrying an outcome-unknown fetch so a duplicate hold is not placed. If the tool reports a terminal rejection, do not reuse that key; start a new payment attempt with a new key."}],streamable:!1,watchFields:null,watch:null,template:{resource:"<string>",input:{},max_amount:"<string>",portfolio_id:"<string>",account_id:"<string>",idempotency_key:"<string>"},responseFields:{fields:["data","paid","payment_id","idempotency_key","expires_at"]},annotations:{destructiveHint:!0},agentApi:"only"}]}],Z={balance:{id:"balance",name:"balance",method:"GET",path:"/balance",summary:"View Balances",description:"Returns account balances for exactly one portfolio. If portfolio_id is omitted, only the default portfolio is returned. Results are not aggregated across portfolios; use coinbase_portfolios_list and query each portfolio for a complete multi-portfolio view. The response portfolio_id identifies the effective portfolio queried. Balances show available funds and amounts on hold; available_balance\u2026",pathParams:[],params:[{name:"portfolio_id",in:"query",type:"string",required:!1,description:"UUID of the single portfolio to query. Omit to query only the default portfolio."},{name:"show_zero",in:"query",type:"boolean",required:!1,description:"Include zero-balance accounts (default false)"},{name:"limit",in:"query",type:"integer",required:!1,description:"Results per page"},{name:"cursor",in:"query",type:"string",required:!1,description:"Pagination cursor"}],streamable:!1,watchFields:null,watch:null,template:{},responseFields:{fields:["portfolio_id","accounts","has_next","cursor","size"],nested:{accounts:{fields:["uuid","name","currency","available_balance","hold","type","active","ready"],nested:{available_balance:{fields:["value","currency"]},hold:{fields:["value","currency"]}}}}},annotations:{readOnlyHint:!0},agentApi:"eligible"},fees:{id:"fees",name:"fees",method:"GET",path:"/fees",summary:"Fee Tier and Volume",description:"Fee tier, maker/taker rates, and 30-day volume.",pathParams:[],params:[{name:"product_type",in:"query",type:"string",required:!1,description:"Filter by product type",enum:["SPOT","FUTURE","EQUITY"],example:"SPOT"}],streamable:!1,watchFields:null,watch:null,template:{},responseFields:{fields:["total_fees","fee_tier","margin_rate","advanced_trade_only_volume","advanced_trade_only_fees","coinbase_pro_volume","coinbase_pro_fees","total_balance","has_cost_plus_commission"],nested:{fee_tier:{fields:["pricing_tier","taker_fee_rate","maker_fee_rate"]},margin_rate:{fields:["value"]}}},annotations:{readOnlyHint:!0},agentApi:"eligible"},transfer:{id:"transfer",name:"transfer",method:"POST",path:"/transfer",summary:"Move Funds Between Portfolios",description:"Moves funds of a single currency from one portfolio to another. This executes immediately and moves money \u2014 verify the source has sufficient available balance first. Both portfolio UUIDs come from portfolios_list.",pathParams:[],params:[{name:"amount",in:"body",type:"string",required:!0,description:"Amount to transfer",example:"100.00"},{name:"currency",in:"body",type:"string",required:!0,description:"Currency",example:"USD"},{name:"from",in:"body",type:"string",required:!0,description:"Source portfolio UUID",example:"d17b3486-8f2c-4a1e-9b30-5c7e1f2a4d61"},{name:"to",in:"body",type:"string",required:!0,description:"Target portfolio UUID",example:"a44ef7a8-3c95-4d18-bf62-90ad7e5c1b04"}],streamable:!1,watchFields:null,watch:null,template:{amount:"100.00",currency:"USD",from:"d17b3486-8f2c-4a1e-9b30-5c7e1f2a4d61",to:"a44ef7a8-3c95-4d18-bf62-90ad7e5c1b04"},responseFields:{fields:["source_portfolio_uuid","target_portfolio_uuid"]},annotations:{destructiveHint:!0},agentApi:"eligible"}},Mn=new Set(["balance","fees","transfer"]),vn={date:/^\d{4}-\d{2}-\d{2}$/,"date-time":/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?(Z|[+-]\d{2}:\d{2})$/};kn={date:t=>{let e=t.match(/^(\d{4})-(\d{2})-(\d{2})$/);return!!e&&Un(+e[1],+e[2],+e[3])},"date-time":t=>{let e=t.match(/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})/);if(!e)return!1;let[,r,n,i,s,_,o]=e;return Un(+r,+n,+i)&&+s<24&&+_<60&&+o<61}}});function ye(t){return typeof t=="object"&&"endpoint"in t}function F(t,e){return{endpoint:t,...e}}var Dt=S(()=>{"use strict";u();d()});var Fn,Vn,Gn,wn,Wn,xn,Bn,Hn,Kn,Yn,qn,zn,$n,jn,Qn,Gt=S(()=>{"use strict";u();d();Fn={origin:"RetailBrokerageApi_CancelOrders",method:"POST",path:"/api/v3/brokerage/orders/batch_cancel"},Vn={origin:"RetailBrokerageApi_ClosePosition",method:"POST",path:"/api/v3/brokerage/orders/close_position"},Gn={origin:"RetailBrokerageApi_CommitConvertTrade",method:"POST",path:"/api/v3/brokerage/convert/trade/{trade_id}"},wn={origin:"RetailBrokerageApi_CreatePortfolio",method:"POST",path:"/api/v3/brokerage/portfolios"},Wn={origin:"RetailBrokerageApi_DeletePortfolio",method:"DELETE",path:"/api/v3/brokerage/portfolios/{portfolio_uuid}"},xn={origin:"RetailBrokerageApi_EditPortfolio",method:"PUT",path:"/api/v3/brokerage/portfolios/{portfolio_uuid}"},Bn={origin:"RetailBrokerageApi_GetBestBidAsk",method:"GET",path:"/api/v3/brokerage/best_bid_ask"},Hn={origin:"RetailBrokerageApi_GetConvertTrade",method:"GET",path:"/api/v3/brokerage/convert/trade/{trade_id}"},Kn={origin:"RetailBrokerageApi_GetFills",method:"GET",path:"/api/v3/brokerage/orders/historical/fills"},Yn={origin:"RetailBrokerageApi_GetHistoricalOrder",method:"GET",path:"/api/v3/brokerage/orders/historical/{order_id}"},qn={origin:"RetailBrokerageApi_GetHistoricalOrders",method:"GET",path:"/api/v3/brokerage/orders/historical/batch"},zn={origin:"RetailBrokerageApi_GetPortfolios",method:"GET",path:"/api/v3/brokerage/portfolios"},$n={origin:"RetailBrokerageApi_GetProduct",method:"GET",path:"/api/v3/brokerage/products/{product_id}"},jn={origin:"RetailBrokerageApi_GetPublicProductBook",method:"GET",path:"/api/v3/brokerage/market/product_book"},Qn={origin:"RetailBrokerageApi_GetTransactionSummary",method:"GET",path:"/api/v3/brokerage/transaction_summary"}});function ro(t,e){let r={...e},n=t;for(let[i,s]of Object.entries(r)){let _="{"+i+"}";s!=null&&n.includes(_)&&(n=n.replaceAll(_,encodeURIComponent(String(s))),delete r[i])}return{url:n,remaining:r}}async function et(t,e,r,n){let{url:i,remaining:s}=ro(r,n),_=e==="POST"||e==="PUT"||e==="DELETE"||e==="PATCH",o,a=null;if(_)o=t.baseURL+i,Object.keys(s).length>0&&(a=new TextEncoder().encode(JSON.stringify(s)));else{let l=Object.entries(s).filter(([,p])=>p!=null).flatMap(([p,A])=>(Array.isArray(A)?A:[A]).map(T=>encodeURIComponent(p)+"="+encodeURIComponent(String(T)))).join("&");o=t.baseURL+i+(l?"?"+l:"")}let E=await t.doRequest({method:e,url:o,body:a}),g=new TextDecoder().decode(E.body),c;try{c=JSON.parse(g)}catch{c=g}if(E.status>=400){let l=c,p=l?.error_response?.message??l?.error_response?.error_details??l?.message??l?.error_details??g.slice(0,200);throw new _t(p,E.status,c)}return{status:E.status,data:c}}function Xn(t,e){return et(t,"POST","/api/v3/brokerage/convert/quote",e)}function Zn(t,e){return et(t,"POST","/api/v3/brokerage/orders/edit",e)}function Jn(t,e){return et(t,"GET","/api/v3/brokerage/accounts",e)}function ti(t,e){return et(t,"GET","/api/v3/brokerage/key_permissions",e)}function ei(t,e){return et(t,"GET","/api/v3/brokerage/products/{product_id}/candles",e)}function ri(t,e){return et(t,"GET","/api/v3/brokerage/products/{product_id}/ticker",e)}function ni(t,e){return et(t,"GET","/api/v3/brokerage/portfolios/{portfolio_uuid}",e)}function Or(t,e){return et(t,"GET","/api/v3/brokerage/products",e)}function ii(t,e){return et(t,"POST","/api/v3/brokerage/portfolios/move_funds",e)}function si(t,e){return et(t,"POST","/api/v3/brokerage/orders",e)}function _i(t,e){return et(t,"POST","/api/v3/brokerage/orders/edit_preview",e)}function oi(t,e){return et(t,"POST","/api/v3/brokerage/orders/preview",e)}var _t,dt=S(()=>{"use strict";u();d();_t=class extends Error{status;data;constructor(e,r,n){super(e),this.status=r,this.data=n}}});function so(t,e,r){if(!(!t||t===r))return e[t]??t}function oo(t){if(typeof t=="number")return t;if(t&&typeof t=="object"&&"value"in t){let e=Number(t.value);return Number.isFinite(e)?e:void 0}}var no,io,_o,ao,ai,ci=S(()=>{"use strict";u();d();Dt();Gt();dt();no={FUTURES_POSITION_SIDE_LONG:"LONG",FUTURES_POSITION_SIDE_SHORT:"SHORT"},io="FUTURES_POSITION_SIDE_UNSPECIFIED";_o=["total_balance_fiat","total_balance_equity","available_to_trade_equity","available_to_trade_fiat","cost_basis","average_entry_price","unrealized_pnl"];ao=async(t,e)=>{let n=(await ni(e,{portfolio_uuid:t.portfolio_id,currency:t.currency})).data.breakdown??{},i=(n.futures_positions??[]).map(_=>({..._,side:so(_.side,no,io)})),s=(n.equity_positions??[]).map(_=>{let o={..._};for(let a of _o)a in o&&(o[a]=oo(o[a]));return o});return{...n,futures_positions:i,equity_positions:s}},ai={portfolios_list:F(zn),portfolios_get:ao,portfolios_create:F(wn,{responseUnwrap:"portfolio"}),portfolios_edit:F(xn,{requestMap:{portfolio_id:"portfolio_uuid"},responseUnwrap:"portfolio"}),portfolios_delete:F(Wn,{requestMap:{portfolio_id:"portfolio_uuid"}})}});var P,Ot=S(()=>{"use strict";u();d();P=class t extends Error{status;correlationId;traceId;code;constructor(e,r,n){super(e),this.status=r,this.correlationId=n?.correlationId,this.traceId=n?.traceId,this.code=n?.code}static stripGrpcPrefix(e){let r=e.match(/^rpc error: code = \w+ desc = (.+)$/s);return r?r[1]:e}static fromResponse(e,r,n){let i=new TextDecoder().decode(e),s,_;try{let a=JSON.parse(i);a.errorType&&a.errorMessage?s=`${a.errorType} \u2014 ${a.errorMessage}`:a.message?s=t.stripGrpcPrefix(a.message):s=i.length>200?i.slice(0,200)+"...":i,_=a.correlationId||a.correlation_id||void 0}catch{s=i.length>200?i.slice(0,200)+"...":i}let o=n?.get("trace-id")??void 0;return new t(s,r,{correlationId:_,traceId:o})}}});function Ei(t){return String(t).replace(/^(NEW_ORDER_FAILURE_REASON_|PREVIEW_|EDIT_ORDER_FAILURE_REASON_)/,"").replace(/_/g," ").toLowerCase()}function mr(t){if(t?.success===!1){let e=t.error_response,r=t.errors?.[0]?.edit_failure_reason,n=e?.new_order_failure_reason??e?.preview_failure_reason??e?.error,i=n?Ei(n):void 0;throw new P(e?.message||e?.error_details||i||(r?Ei(r):void 0)||"Operation failed",400)}}var ui=S(()=>{"use strict";u();d();Ot()});var be,Ar,yt,wt,di=S(()=>{"use strict";u();d();be={MARKET:"market",LIMIT:"limit",STOP_LIMIT:"stop_limit"},Ar={UP:"up",DOWN:"down"},yt={GTC:"GTC",IOC:"IOC",FOK:"FOK",GTD:"GTD"},wt={NORMAL:"NORMAL",PRE_MARKET:"PRE_MARKET",AFTER_HOURS:"AFTER_HOURS",OVERNIGHT:"OVERNIGHT",MULTI_SESSION:"MULTI_SESSION"}});import{randomUUID as co}from"node:crypto";function gi(t){let e=t.type;if(e===be.MARKET)return{market_market_ioc:{...t.quote_size&&{quote_size:t.quote_size},...t.base_size&&{base_size:t.base_size}}};if(e===be.LIMIT){let r=t.time_in_force??yt.GTC,n={...t.quote_size&&{quote_size:t.quote_size},...t.base_size&&{base_size:t.base_size},limit_price:t.limit_price,...t.post_only&&{post_only:!0}};return r===yt.IOC?{sor_limit_ioc:n}:r===yt.FOK?{limit_limit_fok:n}:r===yt.GTD?{limit_limit_gtd:{...n,...t.end_time&&{end_time:t.end_time}}}:{limit_limit_gtc:n}}else if(e===be.STOP_LIMIT){let r=t.stop_direction===Ar.UP?"STOP_DIRECTION_STOP_UP":t.stop_direction===Ar.DOWN?"STOP_DIRECTION_STOP_DOWN":(()=>{throw new P("stop_direction is required for stop_limit orders (up or down)",400)})(),n=t.time_in_force??yt.GTC,i={base_size:t.base_size,limit_price:t.limit_price,stop_price:t.stop_price,stop_direction:r};return n===yt.GTD?{stop_limit_stop_limit_gtd:{...i,...t.end_time&&{end_time:t.end_time}}}:{stop_limit_stop_limit_gtc:i}}throw new P(`Unknown order type: ${e}. Use market, limit, or stop_limit.`,400)}function li(t){if(!t.equity_trading_session&&!t.equity_order_date)return;let e={};if(t.equity_trading_session){let r=Eo[t.equity_trading_session];if(!r)throw new P(`Unknown equity_trading_session: ${t.equity_trading_session}`,400);e.equity_trading_session=r}if(t.equity_order_date){let r=t.equity_order_date.match(uo);if(!r)throw new P("equity_order_date must be YYYY-MM-DD",400);e.equity_order_date={year:Number(r[1]),month:Number(r[2]),day:Number(r[3])}}return e}function go(t){let e={client_order_id:t.client_order_id??co(),product_id:t.product_id,side:t.side,order_configuration:gi(t)};t.portfolio_id&&(e.retail_portfolio_id=t.portfolio_id),t.reduce_only&&(e.reduce_only=!0);let r=li(t);return r&&(e.equity_order_metadata=r),e}function To(t){let e=new Set,r=new Set,n=0,i=!0;for(let s=0;s<t.length;s++){let _=t[s];if(_==='"'){let o=s;for(s++;s<t.length;s++)if(t[s]==="\\")s++;else if(t[s]==='"')break;if(n===1&&i){let a=JSON.parse(t.slice(o,s+1));e.has(a)&&r.add(a),e.add(a),i=!1}}else _==="{"||_==="["?n++:_==="}"||_==="]"?n--:_===","&&n===1&&(i=!0)}return[...r]}function Ii(t){if(!t||typeof t!="object"||Array.isArray(t))throw new P("Malformed order edit preview response",502,{code:"MALFORMED_RESPONSE"});let e=t;if(e.errors!==void 0&&!Array.isArray(e.errors))throw new P("Malformed order edit preview response",502,{code:"MALFORMED_RESPONSE"});let r=e.errors;if(r?.some(_=>!_||typeof _!="object"||Array.isArray(_)))throw new P("Malformed order edit preview response",502,{code:"MALFORMED_RESPONSE"});if(r?.length){let _=r[0],o=_?.edit_failure_reason??_?.preview_failure_reason,a=typeof o=="string"&&/^[A-Z0-9_]+$/.test(o)&&!o.startsWith("UNKNOWN_")?o.slice(o.indexOf("FAILURE_REASON_")>=0?o.indexOf("FAILURE_REASON_")+15:0).replaceAll("_"," ").toLowerCase():"operation failed";throw new P(`Order edit preview rejected: ${a}`,400,{code:"UPSTREAM_REJECTION"})}for(let _ of["slippage","order_total","commission_total","quote_size","base_size","best_bid","best_ask","average_filled_price","order_margin_total"])if(e[_]!==void 0&&typeof e[_]!="string")throw new P("Malformed order edit preview response",502,{code:"MALFORMED_RESPONSE"});for(let _ of["commission_detail_total","pnl_configuration"])if(e[_]!==void 0&&(!e[_]||typeof e[_]!="object"||Array.isArray(e[_])))throw new P("Malformed order edit preview response",502,{code:"MALFORMED_RESPONSE"});let n=e.commission_detail_total;for(let _ of["total_commission","gst_commission","withholding_commission","client_commission","venue_commission","regulatory_commission","clearing_commission"])if(n?.[_]!==void 0&&typeof n[_]!="string")throw new P("Malformed order edit preview response",502,{code:"MALFORMED_RESPONSE"});let s=e.pnl_configuration?.trigger_bracket_pnl;if(s!==void 0&&(!s||typeof s!="object"||Array.isArray(s)))throw new P("Malformed order edit preview response",502,{code:"MALFORMED_RESPONSE"});for(let _ of["take_profit_pnl","stop_loss_pnl"])if(s&&s[_]!==void 0&&typeof s[_]!="string")throw new P("Malformed order edit preview response",502,{code:"MALFORMED_RESPONSE"})}function pi(t){if(!t||typeof t!="object"||Array.isArray(t))return{error:"ORDER_EDIT_PREVIEW_FAILED",message:"Order edit preview failed"};let e=t,r=s=>String(s).replace(/Bearer\s+\S+/gi,"Bearer [REDACTED]").replace(/-----BEGIN [^-]+-----[\s\S]*?-----END [^-]+-----/g,"[REDACTED PRIVATE KEY]").slice(0,500),n=s=>typeof s=="string"&&/^[A-Z][A-Z0-9_]*$/.test(s)?s:"ORDER_EDIT_PREVIEW_FAILED";if(typeof e.errorType=="string"&&typeof e.errorMessage=="string")return{errorType:n(e.errorType),errorMessage:r(e.errorMessage),...typeof e.correlationId=="string"?{correlationId:e.correlationId}:{}};let i=e.message??e.errorMessage??e.error_response?.message??e.error_response?.error_details??e.error_details??"Order edit preview failed";return{error:n(e.error??e.errorType),...typeof e.code=="number"?{code:e.code}:{},message:r(i),...typeof e.correlationId=="string"?{correlationId:e.correlationId}:{},...typeof e.correlation_id=="string"?{correlation_id:e.correlation_id}:{}}}var Eo,uo,lo,Io,po,Ro,Oo,mo,Ti,Ri=S(()=>{"use strict";u();d();Dt();Ot();ui();di();Gt();dt();Eo={[wt.NORMAL]:"EQUITY_TRADING_SESSION_NORMAL",[wt.PRE_MARKET]:"EQUITY_TRADING_SESSION_PRE_MARKET",[wt.AFTER_HOURS]:"EQUITY_TRADING_SESSION_AFTER_HOURS",[wt.OVERNIGHT]:"EQUITY_TRADING_SESSION_OVERNIGHT",[wt.MULTI_SESSION]:"EQUITY_TRADING_SESSION_MULTI_SESSION"},uo=new RegExp("^(\\d{4})-(\\d{2})-(\\d{2})$");lo=async(t,e)=>{let r=go(t),n=await si(e,r);return mr(n.data),n.data.success_response??n.data},Io=async(t,e)=>{let r=li(t),n=await oi(e,{product_id:t.product_id,side:t.side,order_configuration:gi(t),...t.portfolio_id&&{retail_portfolio_id:t.portfolio_id},...r&&{equity_order_metadata:r}}),i=n.data;if(i.errs?.length>0)throw new P(i.errs[0].replace(/^PREVIEW_/,"").replace(/_/g," ").toLowerCase(),400);return n.data},po=async(t,e)=>{if(!t.base_size&&!t.limit_price)throw new P("Provide base_size and/or limit_price to edit",400);let r={order_id:t.order_id,size:t.base_size??"",price:t.limit_price??""},n=await Zn(e,r);return mr(n.data),{order_id:t.order_id,status:"EDITED"}};Ro=({body:t,query:e,path:r,headers:n,rawBody:i,originalParams:s,structured:_})=>{let o=(T,N)=>{throw new P(N,400,{code:T})},a=["order_id","base_size","limit_price"];if(_){for(let T of["body","query","path","headers"]){let N=s[T];N!==void 0&&(!N||typeof N!="object"||Array.isArray(N))&&o(T==="body"?"INVALID_BODY":"INVALID_PARAMETERS",`${T} must be an object.`)}i!==null&&!(i instanceof Uint8Array)&&o("INVALID_BODY","Raw request body must be bytes containing a JSON object.")}let E={};if(i){let T=new TextDecoder().decode(i),N;try{N=JSON.parse(T)}catch{o("INVALID_BODY","Request body must be valid JSON.")}(!N||typeof N!="object"||Array.isArray(N))&&o("INVALID_BODY","Request body must be a JSON object."),E=N;let f=[...new Set([...To(T),...Object.keys(E).filter(M=>Object.hasOwn(t,M))])];f.length>0&&o("AMBIGUOUS_FIELDS",`Field(s) supplied more than once: ${f.join(", ")}`)}if(_){let T=["body","query","path","headers","rawBody"],N=Object.keys(s).filter(v=>!T.includes(v)),f=N.filter(v=>!a.includes(v));f.length>0&&o("UNKNOWN_FIELDS",`Unknown field(s): ${f.join(", ")}`);let M=N.filter(v=>Object.hasOwn(t,v)||Object.hasOwn(E,v));M.length>0&&o("AMBIGUOUS_FIELDS",`Field(s) supplied more than once: ${M.join(", ")}`),N.length>0&&o("INVALID_PARAMETER_LOCATION",`Body field(s) cannot be supplied outside the body in structured input: ${N.join(", ")}`)}let g=Object.keys(n),c=g.filter(T=>!a.includes(T));c.length>0&&o("UNKNOWN_FIELDS",`Unknown header field(s): ${c.join(", ")}`),g.length>0&&o("INVALID_PARAMETER_LOCATION",`Body field(s) cannot be supplied as headers: ${g.join(", ")}`);let l={...r,...t,...E,...e};(l.order_id===void 0||l.order_id==="")&&o("MISSING_FIELDS","Missing required field(s): order_id");let p=Object.keys(_?l:s).filter(T=>!a.includes(T));p.length>0&&o("UNKNOWN_FIELDS",`Unknown field(s): ${p.join(", ")}`);let A=a.filter(T=>Object.hasOwn(e,T)||Object.hasOwn(r,T));A.length>0&&o("INVALID_PARAMETER_LOCATION",`Body field(s) cannot be supplied as query or path parameters: ${A.join(", ")}`),[l.base_size,l.limit_price].every(T=>T===void 0||T==="")&&o("MISSING_FIELDS","One of base_size, or limit_price is required.");for(let T of a){let N=l[T];if(N===void 0)continue;if(typeof N!="string"&&o("INVALID_VALUE",`Invalid value for ${T}. Expected a string.`),!(T==="order_id"?/^(?!00000000-0000-0000-0000-000000000000$)[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/:/^(?=.*[1-9])[0-9]+(?:\.[0-9]+)?$/).test(N)){let M=T==="order_id"?"Open order canonical non-nil UUID to preview editing":`Positive decimal replacement ${T==="base_size"?"base size":"limit price"}; at least one replacement is required`;o("INVALID_VALUE",`Invalid value for ${T}: "${String(N).slice(0,80)}". ${M}.`)}}};Oo=async(t,e)=>{let r={order_id:t.order_id,size:t.base_size??"",price:t.limit_price??""};try{let n=await _i(e,r);return Ii(n.data),n.data}catch(n){if(n instanceof _t){let i=pi(n.data),s=i.message??i.errorMessage??i.error??"Order edit preview failed";throw new P(String(s),n.status,{code:"UPSTREAM_REQUEST_FAILED"})}throw n}},mo={status:"order_status",side:"order_side",start:"start_date",end:"end_date",portfolio_id:"retail_portfolio_id"},Ti={orders_list:F(qn,{requestMap:mo}),orders_get:F(Yn,{responseUnwrap:"order"}),orders_create:lo,orders_preview:Io,orders_edit_preview:Object.assign(Oo,{validateInput:Ro,validateResponse:Ii,sanitizeError:pi}),orders_edit:po,orders_cancel:F(Fn),orders_close_position:F(Vn),orders_fills:F(Kn,{requestMap:{side:"order_side",start:"start_sequence_timestamp",end:"end_sequence_timestamp",portfolio_id:"retail_portfolio_id"}})}});function Oi(t){return String(Math.floor(new Date(t).getTime()/1e3))}var Ao,No,So,Co,Po,fo,mi,Ai=S(()=>{"use strict";u();d();Dt();Ot();Gt();dt();Ao={"1m":"ONE_MINUTE","5m":"FIVE_MINUTE","15m":"FIFTEEN_MINUTE","30m":"THIRTY_MINUTE","1h":"ONE_HOUR","2h":"TWO_HOUR","4h":"FOUR_HOUR","6h":"SIX_HOUR","1d":"ONE_DAY"},No={"1m":60,"5m":300,"15m":900,"30m":1800,"1h":3600,"2h":7200,"4h":14400,"6h":21600,"1d":86400},So=60,Co=async(t,e)=>{let{symbol:r,limit:n,cursor:i,...s}=t;if(r){let o=r.toUpperCase(),g=((await Or(e,s)).data.products??[]).filter(l=>l.base_currency_id===o||l.quote_currency_id===o),c=n!==void 0&&n>0?g.slice(0,n):g;return{products:c,num_products:c.length}}return(await Or(e,{...s,limit:n,cursor:i})).data};Po=async(t,e)=>{if(!t.granularity)throw new P("granularity is required (expected execute() to apply its default)",500);let r=t.granularity,n=Ao[r],i=No[r],s=Math.floor(Date.now()/1e3),_=t.end?Oi(t.end):String(s),o=t.start?Oi(t.start):String(Number(_)-So*i);return(await ei(e,{...t,granularity:n,start:o,end:_})).data},fo=async(t,e)=>{let r=t.limit??100;return(await ri(e,{...t,limit:r})).data},mi={products_list:Co,products_get:F($n),products_ticker:fo,products_book:F(jn),products_candles:Po,products_best_bid_ask:F(Bn)}});var Do,Ni,Si=S(()=>{"use strict";u();d();Dt();Gt();dt();Ot();Do=async(t,e)=>{let{from:r,to:n,...i}=t,s=await Xn(e,{...i,from_account:r,to_account:n});if(!s.data?.trade?.id)throw new P(`Convert quote returned no trade for ${t.from} \u2192 ${t.to}. Verify balance, supported pair, and account eligibility.`,422);return s.data},Ni={convert_quote:Do,convert_execute:F(Gn,{requestMap:{quote_id:"trade_id",from:"from_account",to:"to_account"}}),convert_get:F(Hn,{requestMap:{quote_id:"trade_id",from:"from_account",to:"to_account"},responseUnwrap:"trade"})}});var yo,Ci,Pi=S(()=>{"use strict";u();d();dt();yo=async(t,e)=>{let r={};t.portfolio_id&&(r.retail_portfolio_id=t.portfolio_id),t.limit&&(r.limit=t.limit),t.cursor&&(r.cursor=t.cursor);let i=(await Jn(e,r)).data,s=i.accounts??[],_=t.show_zero?s:s.filter(o=>parseFloat(o.available_balance?.value??"0")!==0||parseFloat(o.hold?.value??"0")!==0);return{accounts:_,has_next:i.has_next,cursor:i.cursor,size:_.length}},Ci={balance:yo}});var bo,fi,Di=S(()=>{"use strict";u();d();Ot();dt();bo=async(t,e)=>{let r={funds:{value:t.amount,currency:t.currency},source_portfolio_uuid:t.from,target_portfolio_uuid:t.to},i=(await ii(e,r)).data;if(!i?.source_portfolio_uuid)throw new P("Transfer failed \u2014 check amount, currency, and portfolio UUIDs",400);return i},fi={transfer:bo}});var yi,bi=S(()=>{"use strict";u();d();Dt();Gt();yi={fees:F(Qn)}});var Li,hi=S(()=>{"use strict";u();d();Li={x402_resources:{endpoint:{origin:"AgentAPI_X402Resources",method:"GET",path:"/x402/resources"}},x402_pay:{endpoint:{origin:"AgentAPI_X402Pay",method:"POST",path:"/x402/pay"}},x402_fetch:{endpoint:{origin:"AgentAPI_X402Fetch",method:"POST",path:"/x402/fetch"}}}});function Ui(t){let e=t&&typeof t=="object"?t:{},r={};return typeof e.can_view=="boolean"&&(r.can_view=e.can_view),typeof e.can_trade=="boolean"&&(r.can_trade=e.can_trade),typeof e.can_transfer=="boolean"&&(r.can_transfer=e.can_transfer),typeof e.portfolio_uuid=="string"&&(r.portfolio_uuid=e.portfolio_uuid),(e.portfolio_type==="UNDEFINED"||e.portfolio_type==="DEFAULT"||e.portfolio_type==="CONSUMER"||e.portfolio_type==="INTX")&&(r.portfolio_type=e.portfolio_type),r}function Mi(t){let e=t===401?"AUTHENTICATION_FAILED":t===403?"PERMISSION_INTROSPECTION_FORBIDDEN":"BROKERAGE_REQUEST_FAILED",r=t===401?"Authentication failed for the current API key. Coinbase Advanced Trade requires an ECDSA key; if this environment uses Ed25519, create an ECDSA key and update the environment credentials.":t===403?"The current API key is not authorized to inspect its permissions.":`Brokerage API permission introspection failed with HTTP ${t}.`;return new _t(r,t,{error:e,code:t,message:r})}var Nr,vi,ki=S(()=>{"use strict";u();d();dt();Nr=async(t,e)=>{try{let{data:r}=await ti(e,{});return Ui(r)}catch(r){throw r instanceof _t?Mi(r.status):r}};Nr.normalizeResponse=Ui;Nr.errorResponse=t=>Mi(t).data;vi={api_key_permissions:Nr}});function Le(t){return Lo[t]}var Lo,Sr=S(()=>{"use strict";u();d();ci();Ri();Ai();Si();Pi();Di();bi();hi();ki();Lo={...ai,...Ti,...mi,...Ni,...Ci,...fi,...yi,...Li,...vi}});function Cr(t,e){if(!e)return t;let r={};for(let[n,i]of Object.entries(t)){let s=e[n]??n;r[s]=i}return r}function Fi(t,e){if(!e||typeof t!="object"||t===null||Array.isArray(t))return t;let r={};for(let[n,i]of Object.entries(t)){let s=e[n]??n;r[s]=i}return r}var Vi=S(()=>{"use strict";u();d()});function ho(t,e){let r={...e},n=t;for(let[i,s]of Object.entries(e)){if(s==null||s==="")continue;let _=`{${i}}`;n.includes(_)&&(n=n.replaceAll(_,encodeURIComponent(String(s))),delete r[i])}return{resolvedPath:n,remainingParams:r}}function Uo(t){let e=[];for(let[r,n]of Object.entries(t))if(n!=null)if(Array.isArray(n))for(let i of n)e.push(`${encodeURIComponent(r)}=${encodeURIComponent(String(i))}`);else e.push(`${encodeURIComponent(r)}=${encodeURIComponent(String(n))}`);return e.length>0?"?"+e.join("&"):""}function vo(t,e){for(let[r,n]of Object.entries(e))for(let i of t){let s=i[r];if(s!=null){if(n==="join-comma"&&Array.isArray(s))i[r]=s.join(",");else if(n==="split-comma"){let _=Array.isArray(s)?s:[s];i[r]=_.flatMap(o=>String(o).split(",").map(a=>a.trim()).filter(Boolean))}}}}function Gi(t,e){return`${t.replace(/\/+$/,"")}${e}`}function ko(t){return t===408||t===429||t>=500}function Fo(t){return t instanceof TypeError||t instanceof Error&&(t.name==="AbortError"||t.name==="TimeoutError")}function Vo(t,e){if(t&&typeof t=="object"&&!Array.isArray(t)){let r=typeof t.hint=="string"&&t.hint?`${t.hint} `:"";return{...t,hint:`${r}${Pr}`}}return{error:"AGENT_API_REQUEST_FAILED",code:e,message:typeof t=="string"&&t?t:`Agent API request failed with HTTP ${e}.`,hint:Pr}}function wi(t,e){return{status:400,data:{error:"REST_ENDPOINT_UNAVAILABLE",code:400,message:`${e} endpoint is not configured for environment "${t.envName}". Configure the endpoint for this environment before retrying.`}}}function Go(t,e){let r=e.split("."),n=t;for(let i of r){if(n==null||typeof n!="object")return t;n=n[i]}return n!==void 0?n:t}function wo(t){return t&&typeof t=="object"&&("body"in t||"query"in t||"path"in t||"rawBody"in t)}function ie(t,e){if(t==null||typeof t!="object")return t;if(Array.isArray(t))return t.map(n=>ie(n,e));let r={};for(let n of e.fields){if(!(n in t))continue;let i=e.nested?.[n];i&&Array.isArray(t[n])?r[n]=t[n].map(s=>ie(s,i)):i&&typeof t[n]=="object"&&t[n]!==null?r[n]=ie(t[n],i):r[n]=t[n]}return r}function Wo(t,e){let r=fr[t];if(!r)return;if(!e)return r;let n=r;for(let i of e.split(".")){let s=n?.nested?.[i];if(!s)return r;n=s}return n}async function Wt(t,e,r){let n=wo(e),i=n?e.body??{}:{},s=n?e.query??{}:{},_=n?e.path??{}:{},o=n?e.headers??{}:{},a=n?e.rawBody??null:null,E=!1,g=Le(t);if(!g)return{status:404,data:{error:"UNKNOWN_OPERATION",code:404,message:`No route for ${t}`}};let c=Wi.find(I=>I.id===t),l=ye(g)?void 0:g;if(!n)for(let[I,R]of Object.entries(e)){let L=c?.params.find(H=>H.name===I),b=L?.in==="query"?s:L?.in==="path"?_:i;b[I]=R}if(c?.noInput&&([...Object.keys(i),...Object.keys(s),...Object.keys(_),...Object.keys(o)].length>0||(a?.length??0)>0))return{status:400,data:{error:"UNEXPECTED_FIELDS",code:400,message:`${t} does not accept input fields; it always inspects the current credential.`}};if(r.transport==="agent"&&!c?.agentApi)return{status:400,data:{error:"AGENT_API_ROUTE_UNAVAILABLE",code:400,message:`${t} is not available through the Agent API. Set COINBASE_TRANSPORT=brokerage to use direct brokerage.`}};let p=c?.agentApi?Rt(r.env,r.envName):"",A=c?.agentApi==="only"||r.transport==="agent"||c?.agentApi==="eligible"&&r.transport!=="brokerage"&&!!p;if(l?.validateInput)try{l.validateInput({body:i,query:s,path:_,headers:o,rawBody:a,originalParams:e,structured:n})}catch(I){if(!(I instanceof P))throw I;return{status:I.status,data:{error:I.code??"INVALID_VALUE",code:I.status,message:I.message}}}if(c?.params){if(a)try{let I=JSON.parse(new TextDecoder().decode(a));if(I&&typeof I=="object"&&!Array.isArray(I)){if(c.closedInput){let R=Object.keys(I).filter(L=>Object.hasOwn(i,L));if(R.length>0)return{status:400,data:{error:"AMBIGUOUS_FIELDS",code:400,message:`Field(s) supplied more than once: ${R.join(", ")}`}}}E=!0,Object.assign(i,I)}else if(c.closedInput)return{status:400,data:{error:"INVALID_BODY",code:400,message:"Request body must be a JSON object."}}}catch{if(c.closedInput)return{status:400,data:{error:"INVALID_BODY",code:400,message:"Request body must be valid JSON."}}}for(let I of c.params){if(I.default===void 0||I.required||_[I.name]!==void 0||i[I.name]!==void 0||s[I.name]!==void 0)continue;let R=I.in==="query"?s:I.in==="path"?_:i;R[I.name]=I.default}{let I=c.params.filter(b=>(b.in==="body"||!ye(g)&&b.in==="path")&&b.required),R={..._,...i,...s},L=I.filter(b=>R[b.name]===void 0||R[b.name]==="");if(L.length>0)return{status:400,data:{error:"MISSING_FIELDS",code:400,message:`Missing required field(s): ${L.map(H=>H.name).join(", ")}`}}}{let I={..._,...i,...s},R={},L={};for(let b of c.params)if(b.oneOf&&(L[b.oneOf]||(L[b.oneOf]=[]),L[b.oneOf].push(b.name),I[b.name]!==void 0&&I[b.name]!=="")){if(R[b.oneOf])return{status:400,data:{error:"CONFLICTING_FIELDS",code:400,message:`${R[b.oneOf]} and ${b.name} are mutually exclusive. Provide one, not both.`}};R[b.oneOf]=b.name}for(let[b,H]of Object.entries(L))if(!R[b])return{status:400,data:{error:"MISSING_FIELDS",code:400,message:`One of ${H.join(", ")} is required.`}}}{let I={..._,...i,...s};if(c.closedInput){let R=new Set(c.params.map(H=>H.name)),L=Object.keys(I).filter(H=>!R.has(H));if(L.length>0)return{status:400,data:{error:"UNKNOWN_FIELDS",code:400,message:`Unknown field(s): ${L.join(", ")}`}};let b=c.params.filter(H=>H.in==="body"&&(Object.hasOwn(s,H.name)||Object.hasOwn(_,H.name))).map(H=>H.name);if(b.length>0)return{status:400,data:{error:"INVALID_PARAMETER_LOCATION",code:400,message:`Body field(s) cannot be supplied as query or path parameters: ${b.join(", ")}`}}}if(c.anyOf&&!c.anyOf.some(R=>R.every(L=>I[L]!==void 0&&I[L]!=="")))return{status:400,data:{error:"MISSING_FIELDS",code:400,message:`One of ${c.anyOf.map(L=>L.join(" and ")).join(", or ")} is required.`}}}for(let I of c.params)for(let R of[i,s,_]){if(R[I.name]===void 0)continue;if(c.closedInput&&I.type==="string"&&typeof R[I.name]!="string")return{status:400,data:{error:"INVALID_VALUE",code:400,message:`Invalid value for ${I.name}. Expected a string.`}};if(I.type==="array"&&typeof R[I.name]=="string"?R[I.name]=R[I.name].split(",").map(Et=>Et.trim()).filter(Boolean):I.type==="string"&&Array.isArray(R[I.name])&&(R[I.name]=R[I.name].join(",")),I.type==="boolean"){if(typeof R[I.name]!="boolean"&&(typeof R[I.name]!="string"||R[I.name]!=="true"&&R[I.name]!=="false"))return{status:400,data:{error:"INVALID_VALUE",code:400,message:`Invalid value for ${I.name}: "${R[I.name]}". Expected "true" or "false".`}};typeof R[I.name]=="string"&&(R[I.name]=R[I.name]==="true")}else if((I.type==="integer"||I.type==="number")&&typeof R[I.name]=="string"){let Et=Number(R[I.name]);if(!Number.isFinite(Et))return{status:400,data:{error:"INVALID_VALUE",code:400,message:`Invalid value for ${I.name}: "${R[I.name]}". Expected a number.`}};R[I.name]=Et}if(I.enum&&!I.enum.includes(String(R[I.name])))return{status:400,data:{error:"INVALID_VALUE",code:400,message:`Invalid value for ${I.name}: "${R[I.name]}". Expected one of: ${I.enum.join(", ")}`}};let L=I.pattern?xi.get(I.pattern):void 0,b=I.format?vn[I.format]:void 0,H=L??b;if(H&&typeof R[I.name]=="string"){let Et=R[I.name],on=I.format?kn[I.format]:void 0;if(!(H.test(Et)&&(!L||!b||b.test(Et))&&(!on||on(Et)))){let an=(I.description??"").split(/\.\s/)[0].replace(/\.?\s*$/,""),b_=an?`. ${an}.`:".";return{status:400,data:{error:"INVALID_VALUE",code:400,message:`Invalid value for ${I.name}: "${String(Et).slice(0,80)}"${b_}`}}}}}}if(!A&&!r.baseURL)return wi(r,"Brokerage API");let T=Mo[t];if(!A&&T&&vo([i,s,_],T),!A&&!ye(g)){let I={...i,...s,..._};try{let R=await g(I,r),L=fr[t];return L&&(R=ie(R,L)),{status:200,data:R}}catch(R){if(R instanceof _t)return{status:R.status,data:R.data};let L=R instanceof P?R.status:500,b=P.stripGrpcPrefix(R instanceof Error?R.message:String(R));return{status:L,data:{error:R instanceof P&&R.code?R.code:"HANDLER_ERROR",code:L,message:b}}}}let N=g,f=A?{origin:"AgentAPI",method:c.method,path:c.path}:N.endpoint,M=A?void 0:N.requestMap,v=A?void 0:N.responseMap,Q=A?void 0:N.responseUnwrap,y={...i,..._},h=Cr(y,M),{resolvedPath:x,remainingParams:$}=ho(f.path,h);if(x.includes("{"))return{status:400,data:{error:"MISSING_PATH_PARAMS",code:400,message:`Missing required param(s): ${(x.match(/\{([^}]+)\}/g)?.map(R=>R.slice(1,-1))??[]).join(", ")}`}};let at=f.method==="POST"||f.method==="PUT"||f.method==="DELETE"||f.method==="PATCH",ct,Lt=a??null,U={...A?s:Cr(s,M)},D=A?p:f.baseURL??r.baseURL;if(!D)return wi(r,A?"Agent API":"Brokerage API");at?(ct=Gi(D,x),a&&E&&(Object.keys(_).length>0||c?.closedInput||l?.validateInput)?Lt=new TextEncoder().encode(JSON.stringify($)):!Lt&&Object.keys($).length>0&&(Lt=new TextEncoder().encode(JSON.stringify($)))):(Object.assign(U,$),ct=Gi(D,x));let V=Uo(U);V&&(ct+=V);let B;try{B=await r.doRequest({method:f.method,url:ct,body:Lt,headers:Object.keys(o).length>0?o:void 0})}catch(I){if(!A||c?.agentApi!=="eligible"||!Fo(I))throw I;let R=I instanceof Error?I.message:String(I);throw new Error(`${R}
48
- Hint: ${Pr}`)}let Ct=new TextDecoder().decode(B.body),G;try{G=JSON.parse(Ct)}catch{G=Ct}if(B.status>=400){let I=N.sanitizeError?N.sanitizeError(G):G,R=l?.errorResponse?.(B.status)??(A&&c?.agentApi==="eligible"&&ko(B.status)?Vo(I,B.status):I);return{status:B.status,data:R,headers:B.headers}}if(N.validateResponse)try{N.validateResponse(G)}catch(I){let R=I instanceof P?I.status:502,L=P.stripGrpcPrefix(I instanceof Error?I.message:String(I));return{status:R,data:{error:R===502?"MALFORMED_RESPONSE":"UPSTREAM_REJECTION",code:R,message:L},headers:B.headers}}Q&&(G=Go(G,Q)),v&&(G=Fi(G,v)),l?.normalizeResponse&&(G=l.normalizeResponse(G));let It=Wo(t,Q);return It&&(G=ie(G,It)),{status:B.status,data:G,headers:B.headers}}var Wi,fr,xi,Mo,Pr,he=S(()=>{"use strict";u();d();Dt();Sr();Vi();Ot();dt();ft();it();Wi=[...X.flatMap(t=>t.actions),...Object.values(Z)],fr={},xi=new Map;for(let t of Wi){fr[t.id]=t.responseFields;for(let e of t.params)e.pattern&&xi.set(e.pattern,new RegExp(e.pattern))}Mo={orders_list:{product_ids:"split-comma"},orders_fills:{product_ids:"split-comma"},products_list:{product_ids:"split-comma"}};Pr="To bypass the Agent API temporarily, retry with COINBASE_TRANSPORT=brokerage."});import{readFileSync as xo,writeFileSync as Bo,mkdirSync as Ho}from"node:fs";import{join as Hi}from"node:path";function Bi(t){let e=t.replace(/^v/,"").split("-")[0],[r,n,i]=e.split(".").map(Number);return{major:r??0,minor:n??0,patch:i??0}}function Yo(t,e){let r=Bi(t),n=Bi(e);return n.major!==r.major?n.major>r.major:n.minor!==r.minor?n.minor>r.minor:n.patch>r.patch}function zo(t,e){let r=Ie===qo?"":` --registry ${Ie}`;return`
43
+ [Runtime.InteropServices.Marshal]::FreeHGlobal($blob)`,ht(n))}delete(e,r){try{nr(`[void][Win32.Cred]::CredDelete('${Se(rr(e,r))}', 1, 0)`)}catch{}}}});function Jt(){if(It!==void 0)return It;try{process.platform==="darwin"?It=new me:process.platform==="linux"?It=new Ne:process.platform==="win32"?It=new Ce:It=null}catch{Tn||(process.stderr.write(`warning: OS keychain not accessible \u2014 secrets stored in keychain will not be available
44
+ `),Tn=!0),It=null}return It}function Rn(t){let e=Jt();if(!e)return null;try{return e.get(Pt,t)}catch{return null}}function On(t,e){let r=Jt();if(!r)return!1;try{return r.set(Pt,t,e),!0}catch{return!1}}function mn(t){let e=Jt();if(e)try{e.delete(Pt,t)}catch{}}function An(){return Jt()!==null}function Nn(){let t=Jt();if(!t)return!1;let e="__coinbase_cli_preflight__";try{t.set(Pt,e,"ok");let r=t.get(Pt,e);return t.delete(Pt,e),r==="ok"}catch{try{t.delete(Pt,e)}catch{}return!1}}var Pt,It,Tn,ir=S(()=>{"use strict";u();d();gn();ln();pn();Pt="coinbase-cli",Tn=!1});var hn={};Zt(hn,{activeEnvName:()=>Ft,activeEnvironment:()=>re,authIsViable:()=>ar,builtinEnvironments:()=>rt,clearEnvCredentialCache:()=>ur,clearEnvironmentSecretsFromKeychain:()=>cr,clearHistory:()=>ne,configDir:()=>pt,configPath:()=>st,credentialsFor:()=>ee,envCredential:()=>te,getHistory:()=>lr,historyEnabled:()=>De,hydrateEnvironmentSecrets:()=>bn,isBuiltinURL:()=>fe,loadConfig:()=>J,resolveAgentAPIURLForEnvironment:()=>Tt,resolveBrokerageURL:()=>nt,resolveURL:()=>B_,saveConfig:()=>Et,scrubbedEnv:()=>dr,setHistory:()=>gr,setLockOptions:()=>Y_,withConfigLock:()=>Er,writeEnvironmentSecretsToKeychain:()=>Ln});import{readFileSync as Pn,writeFileSync as fn,mkdirSync as Dn,renameSync as G_,unlinkSync as sr,openSync as w_,closeSync as W_,statSync as x_}from"node:fs";import{homedir as Sn}from"node:os";import{join as Pe}from"node:path";function pt(){if(process.env.COINBASE_CONFIG_DIR)return process.env.COINBASE_CONFIG_DIR;if(process.platform==="win32"){let t=process.env.APPDATA??Pe(Sn(),"AppData","Roaming");return Pe(t,"coinbase")}return Pe(Sn(),".config","coinbase")}function st(){return Pe(pt(),"config.json")}function yn(t){if(rt[t])return rt[t];let e=Cn[t];if(e&&rt[e])return rt[e];let r={...rt};for(let[i,s]of Object.entries(Cn))rt[s]&&(r[i]=rt[s]);let n=Object.keys(r).find(i=>t.startsWith(i+"-"));return n?r[n]:void 0}function nt(t,e){return t.endpoints?.brokerageApi??t.url??yn(e)?.brokerageApi??""}function B_(t,e){return nt(t,e)}function Tt(t,e){return t.endpoints?.agentApi??yn(e)?.agentApi??""}function fe(t){return Object.values(rt).some(e=>e.brokerageApi&&t.startsWith(e.brokerageApi))}function H_(t,e){return Object.values(kt[e].secrets).map(r=>r(t))}function ar(t){if(!t)return!1;let e=kt[t.type];return e?Object.keys(e.secrets).every(r=>!!t[r]):!1}function bn(t,e){if(!e.auth)return e;let r=kt[e.auth.type];if(!r)return e;let n=e.auth,i={...n},s=!1,_=!1;for(let[o,a]of Object.entries(r.secrets)){if(n[o]){_=!0;continue}let E=Rn(a(t));E&&(i[o]=E,s=!0)}return ar(i)?{...e,auth:i,..._&&!s?{_plaintextBacked:!0}:{}}:{...e,auth:void 0}}function Ln(t,e){if(!e.auth)return!0;if(!An())return!1;let r=e.auth.type,n=kt[r];if(!n)return!0;if(!ar(e.auth)){let s=Object.keys(n.secrets).filter(_=>!e.auth[_]);throw new Error(`writeEnvironmentSecretsToKeychain: ${r} for "${t}" missing ${s.join(", ")}`)}let i=!0;for(let[s,_]of Object.entries(n.secrets))On(_(t),e.auth[s])||(i=!1);return i}function cr(t){for(let e of Object.keys(kt))for(let r of H_(t,e))mn(r)}function te(t){return t.auth}function ee(t,e){if(e.auth?.type==="cdp_key")return{keyId:e.auth.key_id,keySecret:e.auth.key_secret};throw new Error(`environment "${t}" has no credentials. Run: coinbase env ${t} --key-file path/to/key.json`)}function J(){let t={env:"",environments:{},history:{}};try{let e=Pn(st(),"utf8"),r=JSON.parse(e);t.env=r.env??"";let n=r.environments??{};for(let[i,s]of Object.entries(n))t.environments[i]=bn(i,s);return t.history=r.history??{},r.settings&&(t.settings=r.settings),t}catch(e){if(e.code!=="ENOENT")throw e instanceof SyntaxError?new Error(`invalid config JSON: ${e.message}`):new Error(`reading config: ${e.message}`)}return t}function Et(t,e={}){let r=pt();Dn(r,{recursive:!0,mode:448});let n={},i=[];for(let[a,E]of Object.entries(t.environments)){let g={};if(E.url!==void 0&&(g.url=E.url),E.endpoints!==void 0&&(g.endpoints={...E.endpoints}),!E.auth){n[a]=g;continue}let c=Ln(a,E),l=e.allowPlaintext===!0||E._plaintextBacked===!0;if(!c){if(!l){i.push(a);continue}g.auth=E.auth,n[a]=g;continue}let p=kt[E.auth.type];p&&(g.auth=p.metadataOnly(E.auth)),n[a]=g}if(i.length)throw new Error(`OS keychain unavailable; refusing to persist secrets for environment(s): ${i.join(", ")}.
45
+ Re-run the env-setup command with --allow-plaintext-secrets to write secrets to ${st()} (file is mode 0600), or install/unlock your OS keychain (macOS Keychain, libsecret on Linux, Windows Credential Manager).`);let s={env:t.env,environments:n};Object.keys(t.history).length>0&&(s.history=t.history),t.settings&&(s.settings=t.settings);let _=st(),o=`${_}.${process.pid}.${Date.now()}.tmp`;try{fn(o,JSON.stringify(s,null,2)+`
46
+ `,{mode:384}),G_(o,_)}catch(a){try{sr(o)}catch{}throw a}}function Y_(t){Mt={...Mt,...t}}function vt(){return st()+K_}function q_(t){let e=Date.now()+t;for(;Date.now()<e;);}function z_(){try{let t=w_(vt(),"wx",384);return fn(t,String(process.pid)),t}catch(t){if(t.code!=="EEXIST")throw t;return null}}function $_(){try{let t=x_(vt());if(Date.now()-t.mtimeMs<Mt.staleAfterMs)return!1;let e=Pn(vt(),"utf8").trim(),r=Number(e);if(!Number.isInteger(r)||r<=0)return!0;try{return process.kill(r,0),!1}catch(n){return n.code==="ESRCH"}}catch{return!1}}function Er(t){Dn(pt(),{recursive:!0,mode:448});let e=null;for(let r=0;r<Mt.retries&&(e=z_(),e===null);r++){if($_()){try{sr(vt())}catch{}continue}q_(Mt.baseDelayMs*(1+Math.random()))}if(e===null)throw new Error(`could not acquire config lock after ${Mt.retries} attempts: ${vt()}`);try{return t()}finally{try{W_(e)}catch{}try{sr(vt())}catch{}}}function ur(){_r=void 0,or=void 0}function j_(){return process.env.COINBASE_KEY_ID&&(_r=process.env.COINBASE_KEY_ID,delete process.env.COINBASE_KEY_ID),process.env.COINBASE_KEY_SECRET&&(or=process.env.COINBASE_KEY_SECRET,delete process.env.COINBASE_KEY_SECRET),{keyId:_r,keySecret:or}}function Ft(t,e){return e||process.env.COINBASE_ENV||t.env}function re(t,e){let r=Ft(t,e);if(!r)throw new Error("no environment configured. Run: coinbase env <name>");let n={...t.environments[r]},{keyId:i,keySecret:s}=j_();if(i||s){let a=n.auth?.type==="cdp_key"?n.auth:void 0,E=i??a?.key_id??"",g=s??a?.key_secret??"";E&&g&&(n.auth={type:"cdp_key",key_id:E,key_secret:g})}if(process.env.COINBASE_URL){let a=process.env.COINBASE_URL;n.endpoints={...n.endpoints,brokerageApi:a},n.url=a,fe(a)||process.stderr.write(`warning: COINBASE_URL overrides to non-standard endpoint: ${a}
47
+ `)}let _=nt(n,r),o=Tt(n,r);if(!_&&!o)throw new Error(`no REST endpoint for environment "${r}". Set a brokerage URL, an Agent API URL, or use a built-in environment name`);if(!n.auth)throw new Error(`no credentials for "${r}". Run: coinbase env ${r} --key-file path/to/key.json`);return{name:r,env:n}}function dr(){let t={...process.env};for(let e of Q_)delete t[e];return t}function De(t){return process.env.COINBASE_NO_HISTORY?!1:t.settings?.history?.enabled!==!1}function gr(t,e,r,n){t.history[e]||(t.history[e]={}),t.history[e][r]={last_used:new Date().toISOString(),values:n}}function lr(t,e,r){return t.history[e]?.[r]}function ne(t,e,r){if(e&&r)return t.history[e]?.[r]?(delete t.history[e][r],Object.keys(t.history[e]).length===0&&delete t.history[e],1):0;if(e){let i=Object.keys(t.history[e]??{}).length;return delete t.history[e],i}let n=Object.values(t.history).reduce((i,s)=>i+Object.keys(s).length,0);return t.history={},n}var rt,Cn,kt,K_,Mt,_r,or,Q_,it=S(()=>{"use strict";u();d();pe();ir();rt=un,Cn=dn;kt={cdp_key:{secrets:{key_secret:t=>`${t}:cdp:key_secret`},metadataOnly:t=>({type:"cdp_key",key_id:t.key_id})}};K_=".lock",Mt={retries:50,baseDelayMs:20,staleAfterMs:5e3};Q_=["COINBASE_KEY_SECRET","COINBASE_KEY_ID"]});function Mn(t,e,r){let n=new Date(Date.UTC(t,e-1,r));return n.getUTCFullYear()===t&&n.getUTCMonth()===e-1&&n.getUTCDate()===r}var j,Q,vn,kn,Fn,Rt=S(()=>{"use strict";u();d();j=[{name:"api-key",actions:[{id:"api_key_permissions",name:"permissions",method:"GET",path:"/api-key/permissions",summary:"Get Current API Key Permissions",description:"Returns the authoritative permissions and portfolio association for the API key used to authenticate this request. It accepts no key or customer identifier and always inspects the current credential.",pathParams:[],params:[],streamable:!1,watchFields:null,watch:null,template:{},responseFields:{fields:["can_view","can_trade","can_transfer","portfolio_uuid","portfolio_type"]},annotations:{readOnlyHint:!0},agentApi:"eligible",noInput:!0,history:"disabled"}]},{name:"convert",actions:[{id:"convert_quote",name:"quote",method:"POST",path:"/convert/quote",summary:"Get Convert Quote",description:"Quotes USD\u2194USDC conversions only, returning rate, fees, and a quote ID. For other currency pairs, use an order instead. Pass the ID to convert_execute promptly because quotes expire.",pathParams:[],params:[{name:"from",in:"body",type:"string",required:!0,description:"Source currency",example:"USDC"},{name:"to",in:"body",type:"string",required:!0,description:"Target currency",example:"USD"},{name:"amount",in:"body",type:"string",required:!0,description:"Amount to convert",example:"100.00"}],streamable:!1,watchFields:null,watch:null,template:{from:"USDC",to:"USD",amount:"100.00"},responseFields:{fields:["trade"],nested:{trade:{fields:["id","status","amount","subtotal","total","total_fee","exchange_rate","source_currency","target_currency"]}}},annotations:{readOnlyHint:!1,destructiveHint:!1},agentApi:"eligible"},{id:"convert_execute",name:"execute",method:"POST",path:"/convert/execute/{quote_id}",summary:"Execute Convert Trade",description:"Executes a previously quoted USD\u2194USDC conversion using the quote_id from convert_quote. This moves funds at the quoted rate \u2014 get a fresh quote first since quotes expire. The from/to currencies must match the original quote; use orders for other pairs.",pathParams:["quote_id"],params:[{name:"quote_id",in:"path",type:"string",required:!0,description:"Quote ID from convert quote response"},{name:"from",in:"body",type:"string",required:!0,description:"Source currency",example:"USDC"},{name:"to",in:"body",type:"string",required:!0,description:"Target currency",example:"USD"}],streamable:!1,watchFields:null,watch:null,template:{from:"USDC",to:"USD"},responseFields:{fields:["trade"],nested:{trade:{fields:["id","status"]}}},annotations:{destructiveHint:!0},agentApi:"eligible"},{id:"convert_get",name:"get",method:"GET",path:"/convert/get/{quote_id}",summary:"Get Convert Status",description:"Check status of a USD\u2194USDC conversion by quote ID. For other pairs, use orders instead.",pathParams:["quote_id"],params:[{name:"quote_id",in:"path",type:"string",required:!0,description:"Quote ID"},{name:"from",in:"query",type:"string",required:!0,description:"Source currency"},{name:"to",in:"query",type:"string",required:!0,description:"Target currency"}],streamable:!1,watchFields:null,watch:null,template:{},responseFields:{fields:["id","status","source_currency","target_currency","exchange_rate"]},annotations:{readOnlyHint:!0},agentApi:"eligible"}]},{name:"orders",actions:[{id:"orders_list",name:"list",method:"GET",path:"/orders",summary:"List Orders",description:"Lists orders with optional filters by status, product, side, and time range. Use status=OPEN to find resting orders that can be edited or cancelled. For EQUITY orders, product_id is TICKER-QUOTE (e.g. AAPL-USD), the same form orders_create expects.",pathParams:[],params:[{name:"portfolio_id",in:"query",type:"string",required:!1,description:"Scope to a specific portfolio (defaults to all portfolios the caller can access)"},{name:"status",in:"query",type:"string",required:!1,description:"Filter by status"},{name:"product_ids",in:"query",type:"string",required:!1,description:"Filter by product (e.g. BTC-USD). Comma-separated for multiple."},{name:"side",in:"query",type:"string",required:!1,description:"Filter by side",enum:["BUY","SELL"],example:"BUY"},{name:"product_type",in:"query",type:"string",required:!1,description:"Filter by product type",enum:["SPOT","FUTURE","EQUITY"],example:"SPOT"},{name:"start",in:"query",type:"string",required:!1,description:"Start date (RFC 3339 with timezone, e.g. 2024-01-01T00:00:00Z)",format:"date-time"},{name:"end",in:"query",type:"string",required:!1,description:"End date (RFC 3339 with timezone, e.g. 2024-12-31T23:59:59Z)",format:"date-time"},{name:"limit",in:"query",type:"integer",required:!1,description:"Results per page"},{name:"cursor",in:"query",type:"string",required:!1,description:"Pagination cursor"}],streamable:!0,watchFields:{status:{type:"string",enum:["pending","open","filled","cancelled","failed","expired","cancel_queued"],description:"Order status"},side:{type:"string",enum:["buy","sell"],description:"Order side"},price:{type:"string",format:"decimal",description:"Average filled price"},filled_size:{type:"string",format:"decimal",description:"Filled quantity"},fees:{type:"string",format:"decimal",description:"Total fees"},product_id:{type:"string",description:"Trading pair"},order_id:{type:"string",description:"Order ID"}},watch:{channel:"user",endpoint:"user",requiresAuth:!0,coalesce:!1},template:{},responseFields:{fields:["orders","has_next","cursor"],nested:{orders:{fields:["order_id","product_id","side","status","order_configuration","attached_order_id","attached_order_configuration","created_time","last_fill_time","completion_percentage","filled_size","average_filled_price","total_fees","total_value_after_fees","number_of_fills"]}}},annotations:{readOnlyHint:!0},agentApi:"eligible"},{id:"orders_create",name:"create",method:"POST",path:"/orders",summary:"Create Order",description:"Place a market, limit, stop_limit, bracket, twap, or scaled order, subject to venue eligibility. Equities: use market or limit. Spot brackets require SELL; for entry, use market/limit BUY with attached exits. Futures brackets support BUY/SELL. Bracket stops become aggressive limit exits; fills and loss limits are not guaranteed. TWAP requires base_size, start_time, end_time, and a positive limit_price; slice count is automatic. Use orders_preview for optional fee, fill, and execution-plan estimates. Set exactly one size: limit and market SELL convert quote_size to base_size; market BUY spends quote_size; stop_limit/bracket/twap/scaled require base_size. Attached exits require market/limit parents and activate as the parent fills, including partial fills. If a FUTURE order is rejected for account eligibility, direct the user to https://help.coinbase.com/en/coinbase/trading-and-funding/derivatives/futures-intro to apply.",pathParams:[],params:[{name:"product_id",in:"body",type:"string",required:!0,description:`Trading pair (BASE-QUOTE, e.g. BTC-USD or BTC-USDC) for spot crypto, a dated-futures contract code for CFM. For equities, use TICKER-QUOTE (e.g. AAPL-USD or AAPL-USDC). If the user names a quote currency (e.g. "use my USDC"), use that pair \u2014 never default to USD instead. If they don't say, check the balance for this request's portfolio_id (or the default portfolio if omitted) and use whichever of USD/USDC they hold there; if both, prefer the USDC pair. If the resulting pair doesn't exist, tell the user rather than silently substituting a different one.`,example:"BTC-USDC"},{name:"side",in:"body",type:"string",required:!0,description:"BUY or SELL",enum:["BUY","SELL"],example:"BUY"},{name:"type",in:"body",type:"string",required:!0,description:"market: current price. limit: specified price or better. stop_limit: stop triggers a limit order. bracket: take-profit limit and stop-triggered aggressive limit exit; fills and loss limits are not guaranteed; spot SELL or eligible futures BUY/SELL. twap: split base_size over start_time/end_time with a positive limit_price and automatic slice count; requires GTD. scaled: 2 to 20 limit child orders between positive min_price/max_price. Equities: use market/limit. Other types depend on venue eligibility.",enum:["market","limit","stop_limit","bracket","twap","scaled"],example:"market"},{name:"quote_size",in:"body",type:"string",required:!1,description:"Quote-currency amount (e.g. $100 USD). Mutually exclusive with base_size. Market BUYs spend this amount; limit and market SELL convert it to base_size. Not supported for stop_limit, bracket, twap, or scaled \u2014 use base_size for those. Max 15,000 USD notional.",oneOf:"base_size|quote_size",example:"100.00"},{name:"base_size",in:"body",type:"string",required:!1,description:"Base currency amount (e.g. 0.001 BTC). Mutually exclusive with quote_size. Required for stop_limit, bracket, twap, and scaled. Max 15,000 USD notional.",oneOf:"base_size|quote_size",example:"0.001"},{name:"limit_price",in:"body",type:"string",required:!1,description:"Required limit price for limit/stop_limit/bracket/twap. Bracket take-profit and TWAP execution price ceiling/floor must be strictly positive decimals.",example:"65000.00"},{name:"stop_price",in:"body",type:"string",required:!1,description:"Stop trigger for stop_limit. For bracket, required positive decimal: above limit_price for futures BUY, below for SELL. Bracket stops become aggressive limit exits; no guaranteed fill or loss cap.",example:"60000.00"},{name:"stop_direction",in:"body",type:"string",required:!1,description:"stop_limit only. Bracket direction is implied by side.",enum:["up","down"],example:"down"},{name:"post_only",in:"body",type:"boolean",required:!1,description:"Post-only limit order: rejects if it would take liquidity. true is rejected for non-limit types."},{name:"time_in_force",in:"body",type:"string",required:!1,description:"GTC=good til cancelled for crypto. IOC=immediate or cancel. FOK=fill or kill. GTD=good til date; requires end_time. Crypto stop_limit, bracket, and scaled support GTC/GTD. twap requires GTD. Equities only support market (IOC or omitted time_in_force) and limit (GTC or omitted time_in_force) orders, with no end_time. Equity limits are good for day. Extended-hours equities require whole-share base-sized limit orders; the selected session determines expiry.",enum:["GTC","IOC","FOK","GTD"],example:"GTC"},{name:"end_time",in:"body",type:"string",required:!1,description:"Expiry or execution end time (RFC 3339). Required for GTD and twap. The TWAP schedule may be adjusted.",format:"date-time",example:"2024-12-31T23:59:59Z"},{name:"reduce_only",in:"body",type:"boolean",required:!1,description:"Restrict the order to reducing existing exposure. Supported for INTX perpetuals; US dated futures, spot, and equities may reject it. Not supported for scaled."},{name:"attached_take_profit_price",in:"body",type:"string",required:!1,description:"Positive decimal take-profit limit exit, activated as a market/limit parent fills (including partial fills). May combine with attached_stop_loss_price. Spot: BUY parent only. Futures: BUY/SELL subject to venue eligibility. Not equities. No guaranteed fill.",example:"70000.00"},{name:"attached_stop_loss_price",in:"body",type:"string",required:!1,description:"Positive decimal stop trigger, activated as a market/limit parent fills (including partial fills). Becomes an aggressive limit exit, not a guaranteed fill or loss cap. May combine with attached_take_profit_price. Spot: BUY parent only. Futures: BUY/SELL subject to venue eligibility. Not equities.",example:"58000.00"},{name:"start_time",in:"body",type:"string",required:!1,description:"Requested execution start (RFC 3339). Required for twap. Slice count is automatic.",format:"date-time",example:"2024-12-31T14:00:00Z"},{name:"num_orders",in:"body",type:"integer",required:!1,description:"Number of limit child orders, from 2 to 20. Required for scaled.",example:5},{name:"min_price",in:"body",type:"string",required:!1,description:"Lowest child limit price. Required for scaled. Must be positive and below max_price.",example:"58000.00"},{name:"max_price",in:"body",type:"string",required:!1,description:"Highest child limit price. Required for scaled. Must be positive and above min_price.",example:"62000.00"},{name:"price_distribution",in:"body",type:"string",required:!1,description:"Scaled price spacing. Defaults to FLAT (evenly spaced prices).",enum:["FLAT","LINEAR_INCREASING","LINEAR_DECREASING"],example:"FLAT"},{name:"size_distribution",in:"body",type:"string",required:!1,description:"Scaled size distribution. Defaults to an even split across child orders.",enum:["INCREASING","DECREASING","EVENLY_SPLIT"],example:"EVENLY_SPLIT"},{name:"portfolio_id",in:"body",type:"string",required:!1,description:"The optional UUID of a portfolio containing accounts with which to trade. Defaults to the default portfolio when no portfolio_id is provided."},{name:"client_order_id",in:"body",type:"string",required:!1,description:"Idempotency key (auto-generated if omitted)"},{name:"equity_trading_session",in:"body",type:"string",required:!1,description:"Equity trading session. Ignored for crypto and futures.",enum:["NORMAL","PRE_MARKET","AFTER_HOURS","OVERNIGHT","MULTI_SESSION"]},{name:"equity_order_date",in:"body",type:"string",required:!1,description:"Optional equity trade date (YYYY-MM-DD); brokerage populates it when omitted. Ignored for crypto and futures.",format:"date"}],streamable:!1,watchFields:null,watch:null,template:{product_id:"BTC-USDC",side:"BUY",type:"market",quote_size:"100.00",base_size:"0.001",limit_price:"65000.00",stop_price:"60000.00",stop_direction:"down",post_only:!1,time_in_force:"GTC",end_time:"2024-12-31T23:59:59Z",reduce_only:!1,attached_take_profit_price:"70000.00",attached_stop_loss_price:"58000.00",start_time:"2024-12-31T14:00:00Z",num_orders:5,min_price:"58000.00",max_price:"62000.00",price_distribution:"FLAT",size_distribution:"EVENLY_SPLIT",portfolio_id:"<string>",client_order_id:"<string>",equity_trading_session:"NORMAL",equity_order_date:"<string>"},responseFields:{fields:["order_id","product_id","side","client_order_id"]},annotations:{destructiveHint:!0},agentApi:"eligible"},{id:"orders_preview",name:"preview",method:"POST",path:"/orders/preview",summary:"Preview Order",description:"Estimate fees, fill price, slippage, and execution plans without placing an order. Optional before orders_create; the same order-type and asset-class restrictions apply. Futures previews also estimate margin, leverage, and liquidation impact: compare current and projected margin ratios and liquidation buffers. If a FUTURE preview is rejected for account eligibility, direct the user to https://help.coinbase.com/en/coinbase/trading-and-funding/derivatives/futures-intro to apply.",pathParams:[],params:[{name:"product_id",in:"body",type:"string",required:!0,description:`Trading pair (BASE-QUOTE, e.g. BTC-USD or BTC-USDC) for spot crypto, a dated-futures contract code for CFM. For equities, use TICKER-QUOTE (e.g. AAPL-USD or AAPL-USDC). If the user names a quote currency (e.g. "use my USDC"), use that pair \u2014 never default to USD instead. If they don't say, check the balance for this request's portfolio_id (or the default portfolio if omitted) and use whichever of USD/USDC they hold there; if both, prefer the USDC pair. If the resulting pair doesn't exist, tell the user rather than silently substituting a different one.`,example:"BTC-USDC"},{name:"side",in:"body",type:"string",required:!0,description:"BUY or SELL",enum:["BUY","SELL"],example:"BUY"},{name:"type",in:"body",type:"string",required:!0,description:"market: current price. limit: specified price or better. stop_limit: stop triggers a limit order. bracket: take-profit limit and stop-triggered aggressive limit exit; fills and loss limits are not guaranteed; spot SELL or eligible futures BUY/SELL. twap: split base_size over start_time/end_time with a positive limit_price and automatic slice count; requires GTD. scaled: 2 to 20 limit child orders between positive min_price/max_price. Equities: use market/limit. Other types depend on venue eligibility.",enum:["market","limit","stop_limit","bracket","twap","scaled"],example:"market"},{name:"quote_size",in:"body",type:"string",required:!1,description:"Quote currency amount (e.g. spend $100 USD). Mutually exclusive with base_size. Not supported for stop_limit, bracket, twap, or scaled \u2014 use base_size for those.",oneOf:"base_size|quote_size",example:"100.00"},{name:"base_size",in:"body",type:"string",required:!1,description:"Base currency amount (e.g. 0.001 BTC). Mutually exclusive with quote_size. Required for stop_limit, bracket, twap, and scaled.",oneOf:"base_size|quote_size",example:"0.001"},{name:"limit_price",in:"body",type:"string",required:!1,description:"Required limit price for limit/stop_limit/bracket/twap. Bracket take-profit and TWAP execution price ceiling/floor must be strictly positive decimals.",example:"65000.00"},{name:"stop_price",in:"body",type:"string",required:!1,description:"Stop trigger for stop_limit. For bracket, required positive decimal: above limit_price for futures BUY, below for SELL. Bracket stops become aggressive limit exits; no guaranteed fill or loss cap.",example:"60000.00"},{name:"stop_direction",in:"body",type:"string",required:!1,description:"stop_limit only. Bracket direction is implied by side.",enum:["up","down"],example:"down"},{name:"post_only",in:"body",type:"boolean",required:!1,description:"Post-only limit order: rejects if it would take liquidity. true is rejected for non-limit types."},{name:"time_in_force",in:"body",type:"string",required:!1,description:"GTC=good til cancelled for crypto. IOC=immediate or cancel. FOK=fill or kill. GTD=good til date; requires end_time. Crypto stop_limit, bracket, and scaled support GTC/GTD. twap requires GTD. Equities only support market (IOC or omitted time_in_force) and limit (GTC or omitted time_in_force) orders, with no end_time. Equity limits are good for day. Extended-hours equities require whole-share base-sized limit orders; the selected session determines expiry.",enum:["GTC","IOC","FOK","GTD"],example:"GTC"},{name:"end_time",in:"body",type:"string",required:!1,description:"Expiry or execution end time (RFC 3339). Required for GTD and twap. The TWAP schedule may be adjusted.",format:"date-time",example:"2024-12-31T23:59:59Z"},{name:"reduce_only",in:"body",type:"boolean",required:!1,description:"Restrict the order to reducing existing exposure. Supported for INTX perpetuals; US dated futures, spot, and equities may reject it. Not supported for scaled."},{name:"attached_take_profit_price",in:"body",type:"string",required:!1,description:"Positive decimal take-profit limit exit, activated as a market/limit parent fills (including partial fills). May combine with attached_stop_loss_price. Spot: BUY parent only. Futures: BUY/SELL subject to venue eligibility. Not equities. No guaranteed fill.",example:"70000.00"},{name:"attached_stop_loss_price",in:"body",type:"string",required:!1,description:"Positive decimal stop trigger, activated as a market/limit parent fills (including partial fills). Becomes an aggressive limit exit, not a guaranteed fill or loss cap. May combine with attached_take_profit_price. Spot: BUY parent only. Futures: BUY/SELL subject to venue eligibility. Not equities.",example:"58000.00"},{name:"start_time",in:"body",type:"string",required:!1,description:"Requested execution start (RFC 3339). Required for twap. Slice count is automatic.",format:"date-time",example:"2024-12-31T14:00:00Z"},{name:"num_orders",in:"body",type:"integer",required:!1,description:"Number of limit child orders, from 2 to 20. Required for scaled.",example:5},{name:"min_price",in:"body",type:"string",required:!1,description:"Lowest child limit price. Required for scaled. Must be positive and below max_price.",example:"58000.00"},{name:"max_price",in:"body",type:"string",required:!1,description:"Highest child limit price. Required for scaled. Must be positive and above min_price.",example:"62000.00"},{name:"price_distribution",in:"body",type:"string",required:!1,description:"Scaled price spacing. Defaults to FLAT (evenly spaced prices).",enum:["FLAT","LINEAR_INCREASING","LINEAR_DECREASING"],example:"FLAT"},{name:"size_distribution",in:"body",type:"string",required:!1,description:"Scaled size distribution. Defaults to an even split across child orders.",enum:["INCREASING","DECREASING","EVENLY_SPLIT"],example:"EVENLY_SPLIT"},{name:"portfolio_id",in:"body",type:"string",required:!1,description:"The optional UUID of a portfolio containing accounts with which to trade. Defaults to the default portfolio when no portfolio_id is provided."},{name:"equity_trading_session",in:"body",type:"string",required:!1,description:"Equity trading session. Ignored for crypto and futures.",enum:["NORMAL","PRE_MARKET","AFTER_HOURS","OVERNIGHT","MULTI_SESSION"]},{name:"equity_order_date",in:"body",type:"string",required:!1,description:"Optional equity trade date (YYYY-MM-DD); brokerage populates it when omitted. Ignored for crypto and futures.",format:"date"}],streamable:!1,watchFields:null,watch:null,template:{product_id:"BTC-USDC",side:"BUY",type:"market",quote_size:"100.00",base_size:"0.001",limit_price:"65000.00",stop_price:"60000.00",stop_direction:"down",post_only:!1,time_in_force:"GTC",end_time:"2024-12-31T23:59:59Z",reduce_only:!1,attached_take_profit_price:"70000.00",attached_stop_loss_price:"58000.00",start_time:"2024-12-31T14:00:00Z",num_orders:5,min_price:"58000.00",max_price:"62000.00",price_distribution:"FLAT",size_distribution:"EVENLY_SPLIT",portfolio_id:"<string>",equity_trading_session:"NORMAL",equity_order_date:"<string>"},responseFields:{fields:["order_total","commission_total","slippage","est_average_filled_price","warning","twap_bucket_metadata","scaled_metadata","base_size","quote_size","best_bid","best_ask","leverage","long_leverage","short_leverage","max_leverage","position_notional_limit","available_buying_power","order_margin_total","current_liquidation_buffer","projected_liquidation_buffer","predicted_liquidation_price","margin_ratio_data"],nested:{twap_bucket_metadata:{fields:["bucket_duration","bucket_size","number_buckets","start_time","end_time"]},scaled_metadata:{fields:["scaled_order_distribution"],nested:{scaled_order_distribution:{fields:["size","price","errs","warning"]}}},margin_ratio_data:{fields:["current_margin_ratio","projected_margin_ratio"]}}},annotations:{readOnlyHint:!0},agentApi:"eligible"},{id:"orders_edit",name:"edit",method:"POST",path:"/orders/{order_id}/edit",summary:"Edit Order",description:"Atomically update an open order's price or size without cancelling. Omit attached fields to keep existing exits. Attach or change exits only on eligible unfilled limit orders: spot BUY or futures BUY/SELL, not equities. Exits activate as the parent fills, including partial fills. Stops become aggressive limit exits; fills and loss limits are not guaranteed. Attached updates replace both legs: send attached_take_profit_price and attached_stop_loss_price to keep both, even when changing one. Read orders_get first: attached_order_configuration.trigger_bracket_gtc.limit_price maps to attached_take_profit_price; stop_trigger_price maps to attached_stop_loss_price. cancel_attached_order removes both legs, but may be rejected after an exit activates.",pathParams:["order_id"],params:[{name:"order_id",in:"path",type:"string",required:!0,description:"Order to edit"},{name:"base_size",in:"body",type:"string",required:!1,description:"New base size",example:"0.002"},{name:"limit_price",in:"body",type:"string",required:!1,description:"New limit price",example:"64000.00"},{name:"attached_take_profit_price",in:"body",type:"string",required:!1,description:"Positive take-profit limit price for an eligible unfilled limit order. Send both attached prices to keep both legs. Spot BUY or eligible futures BUY/SELL; not equities.",example:"70000.00"},{name:"attached_stop_loss_price",in:"body",type:"string",required:!1,description:"Positive stop trigger for an eligible unfilled limit order. Send both attached prices to keep both legs. Triggers an aggressive limit exit; fills and loss limits are not guaranteed. Spot BUY or eligible futures BUY/SELL; not equities.",example:"58000.00"},{name:"cancel_attached_order",in:"body",type:"boolean",required:!1,description:"Remove both attached exit legs while keeping the parent order. Cannot be combined with attached_take_profit_price or attached_stop_loss_price. May be rejected after an exit activates."}],streamable:!1,watchFields:null,watch:null,template:{base_size:"0.002",limit_price:"64000.00",attached_take_profit_price:"70000.00",attached_stop_loss_price:"58000.00",cancel_attached_order:!1},responseFields:{fields:["order_id","status"]},annotations:{destructiveHint:!0},agentApi:"eligible"},{id:"orders_edit_preview",name:"edit-preview",method:"POST",path:"/orders/edit-preview",summary:"Preview Order Edit",description:"Estimate the result, fees, fill price, and slippage of changing an open order's size or limit price without editing it. Hosted OAuth requires mcp:orders:create. CDP API-key callers may use rat#view where supported. Unsupported replacements return errors.",pathParams:[],params:[{name:"order_id",in:"body",type:"string",required:!0,description:"Open order UUID to preview editing"},{name:"base_size",in:"body",type:"string",required:!1,description:"Positive decimal replacement base size",example:"0.002"},{name:"limit_price",in:"body",type:"string",required:!1,description:"Positive decimal replacement limit price",example:"64000.00"}],streamable:!1,watchFields:null,watch:null,template:{order_id:"<string>",base_size:"0.002",limit_price:"64000.00"},responseFields:{fields:["slippage","order_total","commission_total","quote_size","base_size","best_bid","best_ask","average_filled_price","order_margin_total","commission_detail_total","pnl_configuration"],nested:{commission_detail_total:{fields:["total_commission","gst_commission","withholding_commission","client_commission","venue_commission","regulatory_commission","clearing_commission"]},pnl_configuration:{fields:["trigger_bracket_pnl"],nested:{trigger_bracket_pnl:{fields:["take_profit_pnl","stop_loss_pnl"]}}}}},anyOf:[["base_size"],["limit_price"]],annotations:{readOnlyHint:!0,destructiveHint:!1},agentApi:"eligible"},{id:"orders_get",name:"get",method:"GET",path:"/orders/{order_id}",summary:"Get Order",description:"Retrieves the full status and fill details of a single order by ID. Use after creating an order to confirm execution, and before orders_edit to see the current attached take-profit/stop-loss (attached_order_id / attached_order_configuration). For EQUITY orders, product_id is TICKER-QUOTE (e.g. AAPL-USD), the same form orders_create expects.",pathParams:["order_id"],params:[{name:"order_id",in:"path",type:"string",required:!0,description:"Order ID"}],streamable:!1,watchFields:null,watch:null,template:{},responseFields:{fields:["order_id","product_id","side","status","order_configuration","attached_order_id","attached_order_configuration","created_time","last_fill_time","completion_percentage","filled_size","average_filled_price","total_fees","total_value_after_fees","number_of_fills"]},annotations:{readOnlyHint:!0},agentApi:"eligible"},{id:"orders_cancel",name:"cancel",method:"POST",path:"/orders/cancel",summary:"Cancel Orders",description:"Cancels one or more open orders by ID. Removes resting orders from the book so reserved funds are released; already-filled portions are unaffected. Returns per-order success so a partial batch can fail.",pathParams:[],params:[{name:"order_ids",in:"body",type:"array",required:!0,description:"Order IDs to cancel"}],streamable:!1,watchFields:null,watch:null,template:{order_ids:[]},responseFields:{fields:["results"],nested:{results:{fields:["success","order_id"]}}},annotations:{destructiveHint:!0},agentApi:"eligible"},{id:"orders_close_position",name:"close-position",method:"POST",path:"/orders/close-position",summary:"Close Position",description:"Places a market order to flatten an open position for a product, moving funds immediately. Omit size for a full close or set it for a partial close. Preview the equivalent order first if fee or slippage impact matters.",pathParams:[],params:[{name:"client_order_id",in:"body",type:"string",required:!0,description:"Idempotency key"},{name:"product_id",in:"body",type:"string",required:!0,description:"Product to close",example:"BTC-PERP"},{name:"size",in:"body",type:"string",required:!1,description:"Partial close size (omit for full close)",example:"0.001"}],streamable:!1,watchFields:null,watch:null,template:{client_order_id:"<string>",product_id:"BTC-PERP",size:"0.001"},responseFields:{fields:["success","order_id","product_id"]},annotations:{destructiveHint:!0},agentApi:"eligible"},{id:"orders_fills",name:"fills",method:"GET",path:"/orders/fills",summary:"List Fills",description:"Lists individual trade executions with commissions and maker/taker indicator, filterable by product, order, side, and time range. Use this to reconcile actual fill prices and fees paid. For EQUITY fills, product_id is TICKER-QUOTE (e.g. AAPL-USD), the same form orders_create expects.",pathParams:[],params:[{name:"portfolio_id",in:"query",type:"string",required:!1,description:"Scope to a specific portfolio (defaults to all portfolios the caller can access)"},{name:"product_ids",in:"query",type:"string",required:!1,description:"Filter by product (e.g. BTC-USD)"},{name:"order_ids",in:"query",type:"array",required:!1,description:"Filter by order ID"},{name:"side",in:"query",type:"string",required:!1,description:"Filter by side",enum:["BUY","SELL"],example:"BUY"},{name:"start",in:"query",type:"string",required:!1,description:"Start time (RFC 3339 with timezone, e.g. 2024-01-01T00:00:00Z)",format:"date-time"},{name:"end",in:"query",type:"string",required:!1,description:"End time (RFC 3339 with timezone, e.g. 2024-12-31T23:59:59Z)",format:"date-time"},{name:"limit",in:"query",type:"integer",required:!1,description:"Results per page"},{name:"cursor",in:"query",type:"string",required:!1,description:"Pagination cursor"}],streamable:!1,watchFields:null,watch:null,template:{},responseFields:{fields:["fills","cursor"],nested:{fills:{fields:["trade_id","order_id","trade_time","price","size","commission","product_id","side","liquidity_indicator"]}}},annotations:{readOnlyHint:!0},agentApi:"eligible"}]},{name:"portfolios",actions:[{id:"portfolios_list",name:"list",method:"GET",path:"/portfolios",summary:"List Portfolios",description:"Lists all portfolios on the account, including their UUIDs and types. Use this to find the portfolio_id needed for orders, transfers, and balance queries.",pathParams:[],params:[{name:"portfolio_type",in:"query",type:"string",required:!1,description:"Filter by type (DEFAULT, CONSUMER)",enum:["DEFAULT","CONSUMER"]}],streamable:!1,watchFields:null,watch:null,template:{},responseFields:{fields:["portfolios"],nested:{portfolios:{fields:["uuid","name","type","deleted"]}}},annotations:{readOnlyHint:!0},agentApi:"eligible"},{id:"portfolios_create",name:"create",method:"POST",path:"/portfolios",summary:"Create Portfolio",description:"Creates a new named portfolio for segregating funds and positions. Does not move any funds; use transfer afterward to fund it.",pathParams:[],params:[{name:"name",in:"body",type:"string",required:!0,description:"Portfolio name",example:"agent-1"}],streamable:!1,watchFields:null,watch:null,template:{name:"agent-1"},responseFields:{fields:["uuid","name","type","deleted"]},annotations:{destructiveHint:!1},agentApi:"eligible"},{id:"portfolios_get",name:"get",method:"GET",path:"/portfolios/{portfolio_id}",summary:"Get Portfolio Breakdown",description:"Returns portfolio metadata, balances, and positions.",pathParams:["portfolio_id"],params:[{name:"portfolio_id",in:"path",type:"string",required:!0,description:"Portfolio UUID"},{name:"currency",in:"query",type:"string",required:!1,description:"Currency for balance denomination"}],streamable:!1,watchFields:null,watch:null,template:{},responseFields:{fields:["portfolio","portfolio_balances","spot_positions","futures_positions","equity_positions"],nested:{portfolio:{fields:["uuid","name","type","deleted"]},portfolio_balances:{fields:["total_balance","total_crypto_balance","total_cash_equivalent_balance","total_equities_balance"],nested:{total_balance:{fields:["value","currency"]},total_crypto_balance:{fields:["value","currency"]},total_cash_equivalent_balance:{fields:["value","currency"]},total_equities_balance:{fields:["value","currency"]}}},spot_positions:{fields:["asset","account_uuid","total_balance_fiat","total_balance_crypto","available_to_trade_fiat","allocation","is_cash"]},futures_positions:{fields:["product_id","contract_size","side","amount","avg_entry_price","current_price","unrealized_pnl","expiry","underlying_asset","product_name","venue","notional_value"]},equity_positions:{fields:["asset","account_uuid","total_balance_fiat","total_balance_equity","available_to_trade_equity","available_to_trade_fiat","account_type","allocation","cost_basis","average_entry_price","unrealized_pnl"]}}},annotations:{readOnlyHint:!0},agentApi:"eligible"},{id:"portfolios_edit",name:"edit",method:"PUT",path:"/portfolios/{portfolio_id}",summary:"Edit Portfolio",description:"Renames an existing portfolio. Does not affect balances or positions.",pathParams:["portfolio_id"],params:[{name:"portfolio_id",in:"path",type:"string",required:!0,description:"Portfolio UUID"},{name:"name",in:"body",type:"string",required:!1,description:"New portfolio name"}],streamable:!1,watchFields:null,watch:null,template:{name:"<string>"},responseFields:{fields:["uuid","name","type","deleted"]},annotations:{destructiveHint:!1},agentApi:"eligible"},{id:"portfolios_delete",name:"delete",method:"DELETE",path:"/portfolios/{portfolio_id}",summary:"Delete Portfolio",description:"Permanently deletes a portfolio. The portfolio must be empty first \u2014 transfer out any remaining funds and close all positions before deleting. The DEFAULT portfolio cannot be deleted.",pathParams:["portfolio_id"],params:[{name:"portfolio_id",in:"path",type:"string",required:!0,description:"Portfolio UUID"}],streamable:!1,watchFields:null,watch:null,template:{},responseFields:null,annotations:{destructiveHint:!0},agentApi:"eligible"}]},{name:"products",actions:[{id:"products_list",name:"list",method:"GET",path:"/products",summary:"List Products",description:"Viewing products, including FUTURE ones, doesn't require any special account approval. Trading them is a separate matter \u2014 see the product_type field description.",pathParams:[],params:[{name:"product_type",in:"query",type:"string",required:!1,description:"Product type filter",enum:["SPOT","FUTURE","EQUITY"],example:"SPOT"},{name:"product_ids",in:"query",type:"string",required:!1,description:"Comma-separated product IDs"},{name:"symbol",in:"query",type:"string",required:!1,description:"Filter products by symbol, matches base or quote side (e.g. USD, BTC). For a specific product use products_get (e.g. BTC-USD). Pagination ignored when set.",pattern:"^[A-Za-z0-9]+$"},{name:"limit",in:"query",type:"integer",required:!1,description:"Results per page"},{name:"cursor",in:"query",type:"string",required:!1,description:"Pagination cursor"}],streamable:!1,watchFields:null,watch:null,template:{},responseFields:{fields:["products","cursor","has_next","num_products"],nested:{products:{fields:["product_id","price","price_percentage_change_24h","volume_24h","product_type","quote_currency_id","base_currency_id","base_increment","quote_increment","base_min_size","base_max_size","quote_min_size","quote_max_size","status","future_product_details","fcm_trading_session_details"],nested:{future_product_details:{fields:["contract_expiry_type","contract_size","contract_expiry","time_to_expiry_ms","open_interest","funding_rate","funding_interval","funding_time","intraday_margin_rate","overnight_margin_rate"],nested:{intraday_margin_rate:{fields:["long_margin_rate","short_margin_rate"]},overnight_margin_rate:{fields:["long_margin_rate","short_margin_rate"]}}},fcm_trading_session_details:{fields:["is_session_open","open_time","close_time","session_state"]}}}}},annotations:{readOnlyHint:!0},agentApi:"eligible"},{id:"products_best_bid_ask",name:"best-bid-ask",method:"GET",path:"/products/best-bid-ask",summary:"Best Bid/Ask for Multiple Products",description:"Returns best bid and ask for one or more products in a single call. Omit product_ids to return pricebooks for all products. Not currently available for equities.",pathParams:[],params:[{name:"product_ids",in:"query",type:"array",required:!1,description:"Product IDs (e.g. BTC-USD and ETH-USD). Omit to return all products."}],streamable:!1,watchFields:null,watch:null,template:{},responseFields:{fields:["pricebooks"],nested:{pricebooks:{fields:["product_id","bids","asks","time"],nested:{bids:{fields:["price","size"]},asks:{fields:["price","size"]}}}}},annotations:{readOnlyHint:!0},agentApi:"eligible"},{id:"products_get",name:"get",method:"GET",path:"/products/{product_id}",summary:"Get Product",description:"Viewing a product, including a FUTURE one, doesn't require any special account approval. Trading it is a separate matter \u2014 see the product_type field description.",pathParams:["product_id"],params:[{name:"product_id",in:"path",type:"string",required:!0,description:"Product ID (e.g. BTC-USD)"}],streamable:!1,watchFields:null,watch:null,template:{},responseFields:{fields:["product_id","price","price_percentage_change_24h","volume_24h","product_type","quote_currency_id","base_currency_id","base_increment","quote_increment","base_min_size","base_max_size","quote_min_size","quote_max_size","status","future_product_details","fcm_trading_session_details"],nested:{future_product_details:{fields:["contract_expiry_type","contract_size","contract_expiry","time_to_expiry_ms","open_interest","funding_rate","funding_interval","funding_time","intraday_margin_rate","overnight_margin_rate"],nested:{intraday_margin_rate:{fields:["long_margin_rate","short_margin_rate"]},overnight_margin_rate:{fields:["long_margin_rate","short_margin_rate"]}}},fcm_trading_session_details:{fields:["is_session_open","open_time","close_time","session_state"]}}},annotations:{readOnlyHint:!0},agentApi:"eligible"},{id:"products_ticker",name:"ticker",method:"GET",path:"/products/{product_id}/ticker",summary:"Get Ticker",description:"Returns recent trade prints plus the current best bid/ask for a product. Use for a quick spot-price snapshot before previewing or placing an order. Not currently available for equities.",pathParams:["product_id"],params:[{name:"product_id",in:"path",type:"string",required:!0,description:"Trading pair (e.g. BTC-USD)"},{name:"limit",in:"query",type:"integer",required:!1,description:"Number of trades. Defaults to 100."}],streamable:!0,watchFields:{price:{type:"string",format:"decimal",description:"Last trade price"},bid:{type:"string",format:"decimal",description:"Best bid"},ask:{type:"string",format:"decimal",description:"Best ask"},bid_size:{type:"string",format:"decimal",description:"Size at best bid"},ask_size:{type:"string",format:"decimal",description:"Size at best ask"},volume:{type:"string",format:"decimal",description:"24h volume"},high:{type:"string",format:"decimal",description:"24h high"},low:{type:"string",format:"decimal",description:"24h low"},pct_24h:{type:"string",format:"decimal",description:"24h price change %"},product_id:{type:"string",description:"Trading pair"}},watch:{channel:"ticker",endpoint:"public",requiresAuth:!1,coalesce:!0},template:{},responseFields:{fields:["trades","best_bid","best_ask"],nested:{trades:{fields:["trade_id","product_id","price","size","time","side"]}}},annotations:{readOnlyHint:!0},agentApi:"eligible"},{id:"products_book",name:"book",method:"GET",path:"/products/{product_id}/book",summary:"Get Order Book",description:"Returns the current bid/ask order book for a product. Use to gauge available liquidity and likely slippage before sizing a market order. Not currently available for equities.",pathParams:["product_id"],params:[{name:"product_id",in:"path",type:"string",required:!0,description:"Product ID"},{name:"limit",in:"query",type:"integer",required:!1,description:"Number of levels"}],streamable:!0,watchFields:{spread:{type:"string",format:"decimal",description:"Bid-ask spread"},mid:{type:"string",format:"decimal",description:"Midpoint price"},product_id:{type:"string",description:"Trading pair"}},watch:{channel:"level2",wireName:"l2_data",endpoint:"public",requiresAuth:!1,coalesce:!0},template:{},responseFields:{fields:["pricebook"],nested:{pricebook:{fields:["product_id","bids","asks","time"],nested:{bids:{fields:["price","size"]},asks:{fields:["price","size"]}}}}},annotations:{readOnlyHint:!0},agentApi:"eligible"},{id:"products_candles",name:"candles",method:"GET",path:"/products/{product_id}/candles",summary:"Get Candles",description:"Returns historical OHLCV candles for a product at a chosen granularity and time range. Use for price history and technical analysis. Not currently available for equities.",pathParams:["product_id"],params:[{name:"product_id",in:"path",type:"string",required:!0,description:"Trading pair (e.g. BTC-USD)"},{name:"start",in:"query",type:"string",required:!1,description:"Start time (RFC 3339, e.g. 2024-01-01T00:00:00Z). Defaults to 60 candles before end.",format:"date-time"},{name:"end",in:"query",type:"string",required:!1,description:"End time (RFC 3339, e.g. 2024-01-01T00:00:00Z). Defaults to now.",format:"date-time"},{name:"granularity",in:"query",type:"string",required:!1,description:"Candle interval: 1m, 5m, 15m, 30m, 1h, 2h, 4h, 6h, 1d. Defaults to 1h.",enum:["1m","5m","15m","30m","1h","2h","4h","6h","1d"],default:"1h"},{name:"limit",in:"query",type:"integer",required:!1,description:"Max candles"}],streamable:!1,watchFields:null,watch:null,template:{},responseFields:{fields:["candles","truncated"],nested:{candles:{fields:["start","low","high","open","close","volume"]}}},annotations:{readOnlyHint:!0},agentApi:"eligible"}]},{name:"x402",actions:[{id:"x402_resources",name:"resources",method:"GET",path:"/x402/resources",summary:"Discover x402 Resources",description:`Discover curated x402 resources: paid on-chain and market metrics, wallet and entity intelligence, and derivatives data. Discovery spends nothing. An optional keyword q filters the catalog; omit it to list all. Each result carries the resource URL, its advisory price, and its input and output schemas. All currently supported x402 purchases through this connector use Base USDC. accepts[].amount and coinbase_x402_fetch's max_amount use USDC's 6-decimal atomic units; for example, "50000" means "0.05 USDC". A result's inputSchema is coinbase_x402_fetch's input verbatim: pass those properties flat; do not build an HTTP envelope. The live 402 challenge sets the exact amount.`,pathParams:[],params:[{name:"q",in:"query",type:"string",required:!1,description:"Optional keyword filter. Matched against each resource's description, provider name, and tags using case-insensitive token search. Omit to return the full catalog."}],streamable:!1,watchFields:null,watch:null,template:{},responseFields:{fields:["resources"],nested:{resources:{fields:["resource","description","accepts","inputSchema","outputSchema"],nested:{accepts:{fields:["amount"]}}}}},annotations:{readOnlyHint:!0},agentApi:"only"},{id:"x402_pay",name:"pay",method:"POST",path:"/x402/pay",summary:"Pay an x402 Payment Requirement",description:`Turns an x402 PaymentRequirements challenge into a ready-to-send payment header by placing a pre-authorized hold on the caller's Base USDC balance (EIP-3009 exact scheme, v0). All currently supported x402 purchases through this connector use Base USDC, and amount and max_amount use its 6-decimal atomic units; for example, "50000" means "0.05 USDC". Attach the returned header as X-PAYMENT for v1 or PAYMENT-SIGNATURE for v2. This authorizes moving funds up to max_amount \u2014 pass the smallest amount that satisfies the requirement. Funds-touching and gated internal-only behind a default-off feature flag.`,pathParams:[],params:[{name:"scheme",in:"body",type:"string",required:!0,description:'x402 payment scheme. Only "exact" is supported in v0.'},{name:"network",in:"body",type:"string",required:!0,description:'x402 network as a CAIP-2 chain id. Only "eip155:8453" (Base mainnet) is supported in v0.'},{name:"asset",in:"body",type:"string",required:!0,description:"USDC asset contract address on the network (the x402 asset field)."},{name:"pay_to",in:"body",type:"string",required:!0,description:"Recipient address the payment authorizes (the x402 payTo field)."},{name:"amount",in:"body",type:"string",required:!0,description:`The amount the resource requires, in Base USDC's 6-decimal atomic units; for example, "50000" means "0.05 USDC". Decimal string; never truncated.`},{name:"max_amount",in:"body",type:"string",required:!0,description:`Caller-set spend cap in Base USDC's 6-decimal atomic units; for example, "50000" means "0.05 USDC". The hold is rejected if amount exceeds this. Decimal string.`},{name:"max_timeout_seconds",in:"body",type:"integer",required:!0,description:"Validity window for the signed authorization, in seconds (the x402 maxTimeoutSeconds field). Must be between 1 and 300; the server caps how long the authorization stays valid. Pass a value no greater than the resource's advertised maxTimeoutSeconds (a shorter window is valid, and settlement is near-instant); requests above 300 are rejected."},{name:"x402_version",in:"body",type:"integer",required:!1,description:"x402 protocol version from the resource's 402 challenge. Pass the value the resource advertised. Optional; defaults to 1."},{name:"extra",in:"body",type:"object",required:!1,description:"Full extra object from the resource's 402 PaymentRequirements. Required when x402_version is 2; name and version must match the Base USDC EIP-712 domain."},{name:"portfolio_id",in:"body",type:"string",required:!1,description:'Optional UUID of the consumer portfolio to pay from. Omit only when exactly one accessible non-deleted consumer portfolio is available and the caller has portfolio listing permission. If discovery is not authorized, provide portfolio_id explicitly. For OAuth, ask the user to reconnect and select "View your trading portfolios" in Coinbase consent. For an API key, ask the user to edit it, open Advanced Settings, and enable "View (read-only)" for every portfolio the agent needs. If multiple consumer portfolios are available, call coinbase_portfolios_list, select the funding portfolio with the use'},{name:"account_id",in:"body",type:"string",required:!1,description:"Optional UUID of the USDC account to debit, within the chosen portfolio. Omit to use that portfolio's single USDC account; the tool returns an error (it does NOT guess) when the portfolio has zero or multiple USDC accounts."},{name:"idempotency_key",in:"body",type:"string",required:!1,description:"Optional caller-supplied idempotency key; must be a UUID. Omit it on a first attempt \u2014 one is generated and returned to you. Reuse the SAME key when retrying an outcome-unknown payment so a duplicate hold is not placed. If the tool reports a terminal rejection, do not reuse that key; start a new payment attempt with a new key."}],streamable:!1,watchFields:null,watch:null,template:{scheme:"<string>",network:"<string>",asset:"<string>",pay_to:"<string>",amount:"<string>",max_amount:"<string>",max_timeout_seconds:0,x402_version:0,extra:{name:"<string>",version:"<string>"},portfolio_id:"<string>",account_id:"<string>",idempotency_key:"<string>"},responseFields:{fields:["payment_header","payment_id","idempotency_key","expires_at"]},annotations:{destructiveHint:!0},agentApi:"only"},{id:"x402_fetch",name:"fetch",method:"POST",path:"/x402/fetch",summary:"Pay For and Fetch x402 Resource",description:`Fetches a resource returned by x402_resources. On a 402 challenge, pays from the caller's custodial Base USDC via a pre-authorized hold, then retries with PAYMENT-SIGNATURE \u2014 no manual challenge handling. All currently supported x402 purchases through this connector use Base USDC, and max_amount uses its 6-decimal atomic units; for example, "50000" means "0.05 USDC". This tool accepts only resource URLs returned by x402_resources. max_amount is the spend control; when the user has requested the data or stated a budget, proceed in a single call rather than re-confirming. Protocol v2 only; v1 challenges are rejected.`,pathParams:[],params:[{name:"resource",in:"body",type:"string",required:!0,description:"Resource URL returned by coinbase_x402_resources, with any path parameters substituted. Any URL that does not match a catalog resource is rejected."},{name:"input",in:"body",type:"object",required:!1,description:"Request parameters, exactly as described by the resource's inputSchema from coinbase_x402_resources \u2014 pass those properties flat, at the top level. The tool routes them to the query string or the request body per the resource's HTTP method; you do not construct the HTTP envelope. Validated against the returned schema; unknown keys are rejected unless that schema explicitly permits additional properties."},{name:"max_amount",in:"body",type:"string",required:!1,description:`Optional caller-set spend cap in Base USDC's 6-decimal atomic units; for example, "50000" means "0.05 USDC". Defaults to the catalog advisory ceiling for the resource; when supplied the effective cap is min(max_amount, advisory ceiling). Never derived from the live 402 challenge.`},{name:"portfolio_id",in:"body",type:"string",required:!1,description:'Optional UUID of the consumer portfolio to pay from. Omit only when exactly one accessible non-deleted consumer portfolio is available and the caller has portfolio listing permission. If discovery is not authorized, provide portfolio_id explicitly. For OAuth, ask the user to reconnect and select "View your trading portfolios" in Coinbase consent. For an API key, ask the user to edit it, open Advanced Settings, and enable "View (read-only)" for every portfolio the agent needs. If multiple consumer portfolios are available, call coinbase_portfolios_list, select the funding portfolio with the use'},{name:"account_id",in:"body",type:"string",required:!1,description:"Optional UUID of the USDC account to debit, within the chosen portfolio. Omit to use that portfolio's single USDC account; an error (not a guess) is returned when the portfolio has zero or multiple USDC accounts."},{name:"idempotency_key",in:"body",type:"string",required:!1,description:"Optional caller-supplied idempotency key for the payment; must be a UUID. Omit it on a first attempt \u2014 one is generated and returned to you. Reuse the SAME key when retrying an outcome-unknown fetch so a duplicate hold is not placed. If the tool reports a terminal rejection, do not reuse that key; start a new payment attempt with a new key."}],streamable:!1,watchFields:null,watch:null,template:{resource:"<string>",input:{},max_amount:"<string>",portfolio_id:"<string>",account_id:"<string>",idempotency_key:"<string>"},responseFields:{fields:["data","paid","payment_id","idempotency_key","expires_at"]},annotations:{destructiveHint:!0},agentApi:"only"}]}],Q={balance:{id:"balance",name:"balance",method:"GET",path:"/balance",summary:"View Balances",description:"Returns account balances for exactly one portfolio. If portfolio_id is omitted, only the default portfolio is returned. Results are not aggregated across portfolios; use coinbase_portfolios_list and query each portfolio for a complete multi-portfolio view. The response portfolio_id identifies the effective portfolio queried. Balances show available funds and amounts on hold; available_balance excludes funds held by open orders. Use before trading or transferring to confirm available funds.",pathParams:[],params:[{name:"portfolio_id",in:"query",type:"string",required:!1,description:"UUID of the single portfolio to query. Omit to query only the default portfolio."},{name:"show_zero",in:"query",type:"boolean",required:!1,description:"Include zero-balance accounts (default false)"},{name:"limit",in:"query",type:"integer",required:!1,description:"Results per page"},{name:"cursor",in:"query",type:"string",required:!1,description:"Pagination cursor"}],streamable:!1,watchFields:null,watch:null,template:{},responseFields:{fields:["portfolio_id","accounts","has_next","cursor","size"],nested:{accounts:{fields:["uuid","name","currency","available_balance","hold","type","active","ready"],nested:{available_balance:{fields:["value","currency"]},hold:{fields:["value","currency"]}}}}},annotations:{readOnlyHint:!0},agentApi:"eligible"},fees:{id:"fees",name:"fees",method:"GET",path:"/fees",summary:"Fee Tier and Volume",description:"Fee tier, maker/taker rates, and 30-day volume.",pathParams:[],params:[{name:"product_type",in:"query",type:"string",required:!1,description:"Filter by product type",enum:["SPOT","FUTURE","EQUITY"],example:"SPOT"}],streamable:!1,watchFields:null,watch:null,template:{},responseFields:{fields:["total_fees","fee_tier","margin_rate","advanced_trade_only_volume","advanced_trade_only_fees","coinbase_pro_volume","coinbase_pro_fees","total_balance","has_cost_plus_commission"],nested:{fee_tier:{fields:["pricing_tier","taker_fee_rate","maker_fee_rate"]},margin_rate:{fields:["value"]}}},annotations:{readOnlyHint:!0},agentApi:"eligible"},transfer:{id:"transfer",name:"transfer",method:"POST",path:"/transfer",summary:"Move Funds Between Portfolios",description:"Moves funds of a single currency from one portfolio to another. This executes immediately and moves money \u2014 verify the source has sufficient available balance first. Both portfolio UUIDs come from portfolios_list.",pathParams:[],params:[{name:"amount",in:"body",type:"string",required:!0,description:"Amount to transfer",example:"100.00"},{name:"currency",in:"body",type:"string",required:!0,description:"Currency",example:"USD"},{name:"from",in:"body",type:"string",required:!0,description:"Source portfolio UUID",example:"d17b3486-8f2c-4a1e-9b30-5c7e1f2a4d61"},{name:"to",in:"body",type:"string",required:!0,description:"Target portfolio UUID",example:"a44ef7a8-3c95-4d18-bf62-90ad7e5c1b04"}],streamable:!1,watchFields:null,watch:null,template:{amount:"100.00",currency:"USD",from:"d17b3486-8f2c-4a1e-9b30-5c7e1f2a4d61",to:"a44ef7a8-3c95-4d18-bf62-90ad7e5c1b04"},responseFields:{fields:["source_portfolio_uuid","target_portfolio_uuid"]},annotations:{destructiveHint:!0},agentApi:"eligible"},feedback:{id:"feedback_submit",name:"feedback",method:"POST",path:"/feedback",summary:"Send Feedback About Coinbase Tools",description:"Submit one feedback observation about Coinbase tools. In about three sentences, describe what you tried, what happened or was missing, and what you expected. Include a short error code or reproduction detail when useful. Leave out credentials, account details and transcripts. Show agent-drafted feedback to the user and obtain approval before sending it. Do not interrupt the user's task or repeat an offer they declined. Do not retry automatically: an unconfirmed delivery may already have been received.",pathParams:[],params:[{name:"note",in:"body",type:"string",required:!0,description:"The observation: what you tried, what happened or was missing, and what you expected. 1 to 2000 characters after trimming. Never include credentials, account details or transcripts.",example:"coinbase_orders_preview returned invalid_argument for a SOL-USDC limit order with limit_price 150. I expected a fee estimate. The same order previewed fine with base_size."},{name:"tool_name",in:"body",type:"string",required:!1,description:"Optional tool the feedback is about, e.g. coinbase_orders_preview. Omit for cross-cutting feedback or missing capabilities."}],streamable:!1,watchFields:null,watch:null,template:{note:"coinbase_orders_preview returned invalid_argument for a SOL-USDC limit order with limit_price 150. I expected a fee estimate. The same order previewed fine with base_size.",tool_name:"<string>"},responseFields:{fields:["feedback_id","status","additional_feedback"]},closedInput:!0,annotations:{readOnlyHint:!1,destructiveHint:!1},agentApi:"only"}},vn=new Set(["balance","fees","transfer","feedback"]),kn={date:/^\d{4}-\d{2}-\d{2}$/,"date-time":/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?(Z|[+-]\d{2}:\d{2})$/};Fn={date:t=>{let e=t.match(/^(\d{4})-(\d{2})-(\d{2})$/);return!!e&&Mn(+e[1],+e[2],+e[3])},"date-time":t=>{let e=t.match(/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})/);if(!e)return!1;let[,r,n,i,s,_,o]=e;return Mn(+r,+n,+i)&&+s<24&&+_<60&&+o<61}}});function ye(t){return typeof t=="object"&&"endpoint"in t}function G(t,e){return{endpoint:t,...e}}var ft=S(()=>{"use strict";u();d()});var Vn,Gn,wn,Wn,xn,Bn,Hn,Kn,Yn,qn,zn,$n,jn,Qn,Xn,Gt=S(()=>{"use strict";u();d();Vn={origin:"RetailBrokerageApi_CancelOrders",method:"POST",path:"/api/v3/brokerage/orders/batch_cancel"},Gn={origin:"RetailBrokerageApi_ClosePosition",method:"POST",path:"/api/v3/brokerage/orders/close_position"},wn={origin:"RetailBrokerageApi_CommitConvertTrade",method:"POST",path:"/api/v3/brokerage/convert/trade/{trade_id}"},Wn={origin:"RetailBrokerageApi_CreatePortfolio",method:"POST",path:"/api/v3/brokerage/portfolios"},xn={origin:"RetailBrokerageApi_DeletePortfolio",method:"DELETE",path:"/api/v3/brokerage/portfolios/{portfolio_uuid}"},Bn={origin:"RetailBrokerageApi_EditPortfolio",method:"PUT",path:"/api/v3/brokerage/portfolios/{portfolio_uuid}"},Hn={origin:"RetailBrokerageApi_GetBestBidAsk",method:"GET",path:"/api/v3/brokerage/best_bid_ask"},Kn={origin:"RetailBrokerageApi_GetConvertTrade",method:"GET",path:"/api/v3/brokerage/convert/trade/{trade_id}"},Yn={origin:"RetailBrokerageApi_GetFills",method:"GET",path:"/api/v3/brokerage/orders/historical/fills"},qn={origin:"RetailBrokerageApi_GetHistoricalOrder",method:"GET",path:"/api/v3/brokerage/orders/historical/{order_id}"},zn={origin:"RetailBrokerageApi_GetHistoricalOrders",method:"GET",path:"/api/v3/brokerage/orders/historical/batch"},$n={origin:"RetailBrokerageApi_GetPortfolios",method:"GET",path:"/api/v3/brokerage/portfolios"},jn={origin:"RetailBrokerageApi_GetProduct",method:"GET",path:"/api/v3/brokerage/products/{product_id}"},Qn={origin:"RetailBrokerageApi_GetPublicProductBook",method:"GET",path:"/api/v3/brokerage/market/product_book"},Xn={origin:"RetailBrokerageApi_GetTransactionSummary",method:"GET",path:"/api/v3/brokerage/transaction_summary"}});function no(t,e){let r={...e},n=t;for(let[i,s]of Object.entries(r)){let _="{"+i+"}";s!=null&&n.includes(_)&&(n=n.replaceAll(_,encodeURIComponent(String(s))),delete r[i])}return{url:n,remaining:r}}async function tt(t,e,r,n){let{url:i,remaining:s}=no(r,n),_=e==="POST"||e==="PUT"||e==="DELETE"||e==="PATCH",o,a=null;if(_)o=t.baseURL+i,Object.keys(s).length>0&&(a=new TextEncoder().encode(JSON.stringify(s)));else{let l=Object.entries(s).filter(([,p])=>p!=null).flatMap(([p,A])=>(Array.isArray(A)?A:[A]).map(R=>encodeURIComponent(p)+"="+encodeURIComponent(String(R)))).join("&");o=t.baseURL+i+(l?"?"+l:"")}let E=await t.doRequest({method:e,url:o,body:a}),g=new TextDecoder().decode(E.body),c;try{c=JSON.parse(g)}catch{c=g}if(E.status>=400){let l=c,p=l?.error_response?.message??l?.error_response?.error_details??l?.message??l?.error_details??g.slice(0,200);throw new _t(p,E.status,c)}return{status:E.status,data:c}}function Zn(t,e){return tt(t,"POST","/api/v3/brokerage/convert/quote",e)}function Jn(t,e){return tt(t,"POST","/api/v3/brokerage/orders/edit",e)}function ti(t,e){return tt(t,"GET","/api/v3/brokerage/accounts",e)}function ei(t,e){return tt(t,"GET","/api/v3/brokerage/key_permissions",e)}function ri(t,e){return tt(t,"GET","/api/v3/brokerage/products/{product_id}/candles",e)}function ni(t,e){return tt(t,"GET","/api/v3/brokerage/products/{product_id}/ticker",e)}function ii(t,e){return tt(t,"GET","/api/v3/brokerage/portfolios/{portfolio_uuid}",e)}function Tr(t,e){return tt(t,"GET","/api/v3/brokerage/products",e)}function si(t,e){return tt(t,"POST","/api/v3/brokerage/portfolios/move_funds",e)}function _i(t,e){return tt(t,"POST","/api/v3/brokerage/orders",e)}function oi(t,e){return tt(t,"POST","/api/v3/brokerage/orders/edit_preview",e)}function ai(t,e){return tt(t,"POST","/api/v3/brokerage/orders/preview",e)}var _t,ut=S(()=>{"use strict";u();d();_t=class extends Error{status;data;constructor(e,r,n){super(e),this.status=r,this.data=n}}});function _o(t,e,r){if(!(!t||t===r))return e[t]??t}function ao(t){if(typeof t=="number")return t;if(t&&typeof t=="object"&&"value"in t){let e=Number(t.value);return Number.isFinite(e)?e:void 0}}var io,so,oo,co,ci,Ei=S(()=>{"use strict";u();d();ft();Gt();ut();io={FUTURES_POSITION_SIDE_LONG:"LONG",FUTURES_POSITION_SIDE_SHORT:"SHORT"},so="FUTURES_POSITION_SIDE_UNSPECIFIED";oo=["total_balance_fiat","total_balance_equity","available_to_trade_equity","available_to_trade_fiat","cost_basis","average_entry_price","unrealized_pnl"];co=async(t,e)=>{let n=(await ii(e,{portfolio_uuid:t.portfolio_id,currency:t.currency})).data.breakdown??{},i=(n.futures_positions??[]).map(_=>({..._,side:_o(_.side,io,so)})),s=(n.equity_positions??[]).map(_=>{let o={..._};for(let a of oo)a in o&&(o[a]=ao(o[a]));return o});return{...n,futures_positions:i,equity_positions:s}},ci={portfolios_list:G($n),portfolios_get:co,portfolios_create:G(Wn,{responseUnwrap:"portfolio"}),portfolios_edit:G(Bn,{requestMap:{portfolio_id:"portfolio_uuid"},responseUnwrap:"portfolio"}),portfolios_delete:G(xn,{requestMap:{portfolio_id:"portfolio_uuid"}})}});var P,Ot=S(()=>{"use strict";u();d();P=class t extends Error{status;correlationId;traceId;code;constructor(e,r,n){super(e),this.status=r,this.correlationId=n?.correlationId,this.traceId=n?.traceId,this.code=n?.code}static stripGrpcPrefix(e){let r=e.match(/^rpc error: code = \w+ desc = (.+)$/s);return r?r[1]:e}static fromResponse(e,r,n){let i=new TextDecoder().decode(e),s,_;try{let a=JSON.parse(i);a.errorType&&a.errorMessage?s=`${a.errorType} \u2014 ${a.errorMessage}`:a.message?s=t.stripGrpcPrefix(a.message):s=i.length>200?i.slice(0,200)+"...":i,_=a.correlationId||a.correlation_id||void 0}catch{s=i.length>200?i.slice(0,200)+"...":i}let o=n?.get("trace-id")??void 0;return new t(s,r,{correlationId:_,traceId:o})}}});function ui(t){return String(t).replace(/^(NEW_ORDER_FAILURE_REASON_|PREVIEW_|EDIT_ORDER_FAILURE_REASON_)/,"").replace(/_/g," ").toLowerCase()}function Rr(t){if(t?.success===!1){let e=t.error_response,r=t.errors?.[0]?.edit_failure_reason,n=e?.new_order_failure_reason??e?.preview_failure_reason??e?.error,i=n?ui(n):void 0;throw new P(e?.message||e?.error_details||i||(r?ui(r):void 0)||"Operation failed",400)}}var di=S(()=>{"use strict";u();d();Ot()});var Dt,Or,yt,wt,gi=S(()=>{"use strict";u();d();Dt={MARKET:"market",LIMIT:"limit",STOP_LIMIT:"stop_limit",BRACKET:"bracket",TWAP:"twap",SCALED:"scaled"},Or={UP:"up",DOWN:"down"},yt={GTC:"GTC",IOC:"IOC",FOK:"FOK",GTD:"GTD"},wt={NORMAL:"NORMAL",PRE_MARKET:"PRE_MARKET",AFTER_HOURS:"AFTER_HOURS",OVERNIGHT:"OVERNIGHT",MULTI_SESSION:"MULTI_SESSION"}});import{randomUUID as Eo}from"node:crypto";function li(t){let e=t.type;if(e===Dt.BRACKET||e===Dt.TWAP||e===Dt.SCALED)throw new P(`Order type "${e}" requires the Agent API.`,400,{code:"AGENT_API_REQUIRED"});if(e===Dt.MARKET)return{market_market_ioc:{...t.quote_size&&{quote_size:t.quote_size},...t.base_size&&{base_size:t.base_size}}};if(e===Dt.LIMIT){let r=t.time_in_force??yt.GTC,n={...t.quote_size&&{quote_size:t.quote_size},...t.base_size&&{base_size:t.base_size},limit_price:t.limit_price,...t.post_only&&{post_only:!0}};return r===yt.IOC?{sor_limit_ioc:n}:r===yt.FOK?{limit_limit_fok:n}:r===yt.GTD?{limit_limit_gtd:{...n,...t.end_time&&{end_time:t.end_time}}}:{limit_limit_gtc:n}}else if(e===Dt.STOP_LIMIT){let r=t.stop_direction===Or.UP?"STOP_DIRECTION_STOP_UP":t.stop_direction===Or.DOWN?"STOP_DIRECTION_STOP_DOWN":(()=>{throw new P("stop_direction is required for stop_limit orders (up or down)",400)})(),n=t.time_in_force??yt.GTC,i={base_size:t.base_size,limit_price:t.limit_price,stop_price:t.stop_price,stop_direction:r};return n===yt.GTD?{stop_limit_stop_limit_gtd:{...i,...t.end_time&&{end_time:t.end_time}}}:{stop_limit_stop_limit_gtc:i}}throw new P(`Unknown order type: ${e}. Use market, limit, or stop_limit.`,400)}function Ii(t){if(!t.equity_trading_session&&!t.equity_order_date)return;let e={};if(t.equity_trading_session){let r=uo[t.equity_trading_session];if(!r)throw new P(`Unknown equity_trading_session: ${t.equity_trading_session}`,400);e.equity_trading_session=r}if(t.equity_order_date){let r=t.equity_order_date.match(go);if(!r)throw new P("equity_order_date must be YYYY-MM-DD",400);e.equity_order_date={year:Number(r[1]),month:Number(r[2]),day:Number(r[3])}}return e}function lo(t){let e={client_order_id:t.client_order_id??Eo(),product_id:t.product_id,side:t.side,order_configuration:li(t)};t.portfolio_id&&(e.retail_portfolio_id=t.portfolio_id),t.reduce_only&&(e.reduce_only=!0);let r=Ii(t);return r&&(e.equity_order_metadata=r),e}function mr(t,e){let r=e.filter(n=>Object.hasOwn(t,n));if(r.length>0)throw new P(`Field(s) ${r.join(", ")} require the Agent API.`,400,{code:"AGENT_API_REQUIRED"})}function Oo(t){let e=new Set,r=new Set,n=0,i=!0;for(let s=0;s<t.length;s++){let _=t[s];if(_==='"'){let o=s;for(s++;s<t.length;s++)if(t[s]==="\\")s++;else if(t[s]==='"')break;if(n===1&&i){let a=JSON.parse(t.slice(o,s+1));e.has(a)&&r.add(a),e.add(a),i=!1}}else _==="{"||_==="["?n++:_==="}"||_==="]"?n--:_===","&&n===1&&(i=!0)}return[...r]}function Ti(t){if(!t||typeof t!="object"||Array.isArray(t))throw new P("Malformed order edit preview response",502,{code:"MALFORMED_RESPONSE"});let e=t;if(e.errors!==void 0&&!Array.isArray(e.errors))throw new P("Malformed order edit preview response",502,{code:"MALFORMED_RESPONSE"});let r=e.errors;if(r?.some(_=>!_||typeof _!="object"||Array.isArray(_)))throw new P("Malformed order edit preview response",502,{code:"MALFORMED_RESPONSE"});if(r?.length){let _=r[0],o=_?.edit_failure_reason??_?.preview_failure_reason,a=typeof o=="string"&&/^[A-Z0-9_]+$/.test(o)&&!o.startsWith("UNKNOWN_")?o.slice(o.indexOf("FAILURE_REASON_")>=0?o.indexOf("FAILURE_REASON_")+15:0).replaceAll("_"," ").toLowerCase():"operation failed";throw new P(`Order edit preview rejected: ${a}`,400,{code:"UPSTREAM_REJECTION"})}for(let _ of["slippage","order_total","commission_total","quote_size","base_size","best_bid","best_ask","average_filled_price","order_margin_total"])if(e[_]!==void 0&&typeof e[_]!="string")throw new P("Malformed order edit preview response",502,{code:"MALFORMED_RESPONSE"});for(let _ of["commission_detail_total","pnl_configuration"])if(e[_]!==void 0&&(!e[_]||typeof e[_]!="object"||Array.isArray(e[_])))throw new P("Malformed order edit preview response",502,{code:"MALFORMED_RESPONSE"});let n=e.commission_detail_total;for(let _ of["total_commission","gst_commission","withholding_commission","client_commission","venue_commission","regulatory_commission","clearing_commission"])if(n?.[_]!==void 0&&typeof n[_]!="string")throw new P("Malformed order edit preview response",502,{code:"MALFORMED_RESPONSE"});let s=e.pnl_configuration?.trigger_bracket_pnl;if(s!==void 0&&(!s||typeof s!="object"||Array.isArray(s)))throw new P("Malformed order edit preview response",502,{code:"MALFORMED_RESPONSE"});for(let _ of["take_profit_pnl","stop_loss_pnl"])if(s&&s[_]!==void 0&&typeof s[_]!="string")throw new P("Malformed order edit preview response",502,{code:"MALFORMED_RESPONSE"})}function Ri(t){if(!t||typeof t!="object"||Array.isArray(t))return{error:"ORDER_EDIT_PREVIEW_FAILED",message:"Order edit preview failed"};let e=t,r=s=>String(s).replace(/Bearer\s+\S+/gi,"Bearer [REDACTED]").replace(/-----BEGIN [^-]+-----[\s\S]*?-----END [^-]+-----/g,"[REDACTED PRIVATE KEY]").slice(0,500),n=s=>typeof s=="string"&&/^[A-Z][A-Z0-9_]*$/.test(s)?s:"ORDER_EDIT_PREVIEW_FAILED";if(typeof e.errorType=="string"&&typeof e.errorMessage=="string")return{errorType:n(e.errorType),errorMessage:r(e.errorMessage),...typeof e.correlationId=="string"?{correlationId:e.correlationId}:{}};let i=e.message??e.errorMessage??e.error_response?.message??e.error_response?.error_details??e.error_details??"Order edit preview failed";return{error:n(e.error??e.errorType),...typeof e.code=="number"?{code:e.code}:{},message:r(i),...typeof e.correlationId=="string"?{correlationId:e.correlationId}:{},...typeof e.correlation_id=="string"?{correlation_id:e.correlation_id}:{}}}var uo,go,pi,Io,po,To,Ro,mo,Ao,No,Oi,mi=S(()=>{"use strict";u();d();ft();Ot();di();gi();Gt();ut();uo={[wt.NORMAL]:"EQUITY_TRADING_SESSION_NORMAL",[wt.PRE_MARKET]:"EQUITY_TRADING_SESSION_PRE_MARKET",[wt.AFTER_HOURS]:"EQUITY_TRADING_SESSION_AFTER_HOURS",[wt.OVERNIGHT]:"EQUITY_TRADING_SESSION_OVERNIGHT",[wt.MULTI_SESSION]:"EQUITY_TRADING_SESSION_MULTI_SESSION"},go=new RegExp("^(\\d{4})-(\\d{2})-(\\d{2})$");pi=["attached_take_profit_price","attached_stop_loss_price","start_time","num_orders","min_price","max_price","price_distribution","size_distribution"],Io=["attached_take_profit_price","attached_stop_loss_price","cancel_attached_order"];po=async(t,e)=>{mr(t,pi);let r=lo(t),n=await _i(e,r);return Rr(n.data),n.data.success_response??n.data},To=async(t,e)=>{mr(t,[...pi,"reduce_only"]);let r=Ii(t),n=await ai(e,{product_id:t.product_id,side:t.side,order_configuration:li(t),...t.portfolio_id&&{retail_portfolio_id:t.portfolio_id},...r&&{equity_order_metadata:r}}),i=n.data;if(i.errs?.length>0)throw new P(i.errs[0].replace(/^PREVIEW_/,"").replace(/_/g," ").toLowerCase(),400);return n.data},Ro=async(t,e)=>{if(mr(t,Io),!t.base_size&&!t.limit_price)throw new P("Provide base_size and/or limit_price to edit",400);let r={order_id:t.order_id,size:t.base_size??"",price:t.limit_price??""},n=await Jn(e,r);return Rr(n.data),{order_id:t.order_id,status:"EDITED"}};mo=({body:t,query:e,path:r,headers:n,rawBody:i,originalParams:s,structured:_})=>{let o=(R,N)=>{throw new P(N,400,{code:R})},a=["order_id","base_size","limit_price"];if(_){for(let R of["body","query","path","headers"]){let N=s[R];N!==void 0&&(!N||typeof N!="object"||Array.isArray(N))&&o(R==="body"?"INVALID_BODY":"INVALID_PARAMETERS",`${R} must be an object.`)}i!==null&&!(i instanceof Uint8Array)&&o("INVALID_BODY","Raw request body must be bytes containing a JSON object.")}let E={};if(i){let R=new TextDecoder().decode(i),N;try{N=JSON.parse(R)}catch{o("INVALID_BODY","Request body must be valid JSON.")}(!N||typeof N!="object"||Array.isArray(N))&&o("INVALID_BODY","Request body must be a JSON object."),E=N;let f=[...new Set([...Oo(R),...Object.keys(E).filter(M=>Object.hasOwn(t,M))])];f.length>0&&o("AMBIGUOUS_FIELDS",`Field(s) supplied more than once: ${f.join(", ")}`)}if(_){let R=["body","query","path","headers","rawBody"],N=Object.keys(s).filter(k=>!R.includes(k)),f=N.filter(k=>!a.includes(k));f.length>0&&o("UNKNOWN_FIELDS",`Unknown field(s): ${f.join(", ")}`);let M=N.filter(k=>Object.hasOwn(t,k)||Object.hasOwn(E,k));M.length>0&&o("AMBIGUOUS_FIELDS",`Field(s) supplied more than once: ${M.join(", ")}`),N.length>0&&o("INVALID_PARAMETER_LOCATION",`Body field(s) cannot be supplied outside the body in structured input: ${N.join(", ")}`)}let g=Object.keys(n),c=g.filter(R=>!a.includes(R));c.length>0&&o("UNKNOWN_FIELDS",`Unknown header field(s): ${c.join(", ")}`),g.length>0&&o("INVALID_PARAMETER_LOCATION",`Body field(s) cannot be supplied as headers: ${g.join(", ")}`);let l={...r,...t,...E,...e};(l.order_id===void 0||l.order_id==="")&&o("MISSING_FIELDS","Missing required field(s): order_id");let p=Object.keys(_?l:s).filter(R=>!a.includes(R));p.length>0&&o("UNKNOWN_FIELDS",`Unknown field(s): ${p.join(", ")}`);let A=a.filter(R=>Object.hasOwn(e,R)||Object.hasOwn(r,R));A.length>0&&o("INVALID_PARAMETER_LOCATION",`Body field(s) cannot be supplied as query or path parameters: ${A.join(", ")}`),[l.base_size,l.limit_price].every(R=>R===void 0||R==="")&&o("MISSING_FIELDS","One of base_size, or limit_price is required.");for(let R of a){let N=l[R];if(N===void 0)continue;if(typeof N!="string"&&o("INVALID_VALUE",`Invalid value for ${R}. Expected a string.`),!(R==="order_id"?/^(?!00000000-0000-0000-0000-000000000000$)[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/:/^(?=.*[1-9])[0-9]+(?:\.[0-9]+)?$/).test(N)){let M=R==="order_id"?"Open order canonical non-nil UUID to preview editing":`Positive decimal replacement ${R==="base_size"?"base size":"limit price"}; at least one replacement is required`;o("INVALID_VALUE",`Invalid value for ${R}: "${String(N).slice(0,80)}". ${M}.`)}}};Ao=async(t,e)=>{let r={order_id:t.order_id,size:t.base_size??"",price:t.limit_price??""};try{let n=await oi(e,r);return Ti(n.data),n.data}catch(n){if(n instanceof _t){let i=Ri(n.data),s=i.message??i.errorMessage??i.error??"Order edit preview failed";throw new P(String(s),n.status,{code:"UPSTREAM_REQUEST_FAILED"})}throw n}},No={status:"order_status",side:"order_side",start:"start_date",end:"end_date",portfolio_id:"retail_portfolio_id"},Oi={orders_list:G(zn,{requestMap:No}),orders_get:G(qn,{responseUnwrap:"order"}),orders_create:po,orders_preview:To,orders_edit_preview:Object.assign(Ao,{validateInput:mo,validateResponse:Ti,sanitizeError:Ri}),orders_edit:Ro,orders_cancel:G(Vn),orders_close_position:G(Gn),orders_fills:G(Yn,{requestMap:{side:"order_side",start:"start_sequence_timestamp",end:"end_sequence_timestamp",portfolio_id:"retail_portfolio_id"}})}});function Ai(t){return String(Math.floor(new Date(t).getTime()/1e3))}var So,Co,Po,fo,Do,yo,Ni,Si=S(()=>{"use strict";u();d();ft();Ot();Gt();ut();So={"1m":"ONE_MINUTE","5m":"FIVE_MINUTE","15m":"FIFTEEN_MINUTE","30m":"THIRTY_MINUTE","1h":"ONE_HOUR","2h":"TWO_HOUR","4h":"FOUR_HOUR","6h":"SIX_HOUR","1d":"ONE_DAY"},Co={"1m":60,"5m":300,"15m":900,"30m":1800,"1h":3600,"2h":7200,"4h":14400,"6h":21600,"1d":86400},Po=60,fo=async(t,e)=>{let{symbol:r,limit:n,cursor:i,...s}=t;if(r){let o=r.toUpperCase(),g=((await Tr(e,s)).data.products??[]).filter(l=>l.base_currency_id===o||l.quote_currency_id===o),c=n!==void 0&&n>0?g.slice(0,n):g;return{products:c,num_products:c.length}}return(await Tr(e,{...s,limit:n,cursor:i})).data};Do=async(t,e)=>{if(!t.granularity)throw new P("granularity is required (expected execute() to apply its default)",500);let r=t.granularity,n=So[r],i=Co[r],s=Math.floor(Date.now()/1e3),_=t.end?Ai(t.end):String(s),o=t.start?Ai(t.start):String(Number(_)-Po*i);return(await ri(e,{...t,granularity:n,start:o,end:_})).data},yo=async(t,e)=>{let r=t.limit??100;return(await ni(e,{...t,limit:r})).data},Ni={products_list:fo,products_get:G(jn),products_ticker:yo,products_book:G(Qn),products_candles:Do,products_best_bid_ask:G(Hn)}});var bo,Ci,Pi=S(()=>{"use strict";u();d();ft();Gt();ut();Ot();bo=async(t,e)=>{let{from:r,to:n,...i}=t,s=await Zn(e,{...i,from_account:r,to_account:n});if(!s.data?.trade?.id)throw new P(`Convert quote returned no trade for ${t.from} \u2192 ${t.to}. Verify balance, supported pair, and account eligibility.`,422);return s.data},Ci={convert_quote:bo,convert_execute:G(wn,{requestMap:{quote_id:"trade_id",from:"from_account",to:"to_account"}}),convert_get:G(Kn,{requestMap:{quote_id:"trade_id",from:"from_account",to:"to_account"},responseUnwrap:"trade"})}});var Lo,fi,Di=S(()=>{"use strict";u();d();ut();Lo=async(t,e)=>{let r={};t.portfolio_id&&(r.retail_portfolio_id=t.portfolio_id),t.limit&&(r.limit=t.limit),t.cursor&&(r.cursor=t.cursor);let i=(await ti(e,r)).data,s=i.accounts??[],_=t.show_zero?s:s.filter(o=>parseFloat(o.available_balance?.value??"0")!==0||parseFloat(o.hold?.value??"0")!==0);return{accounts:_,has_next:i.has_next,cursor:i.cursor,size:_.length}},fi={balance:Lo}});var ho,yi,bi=S(()=>{"use strict";u();d();Ot();ut();ho=async(t,e)=>{let r={funds:{value:t.amount,currency:t.currency},source_portfolio_uuid:t.from,target_portfolio_uuid:t.to},i=(await si(e,r)).data;if(!i?.source_portfolio_uuid)throw new P("Transfer failed \u2014 check amount, currency, and portfolio UUIDs",400);return i},yi={transfer:ho}});var Li,hi=S(()=>{"use strict";u();d();ft();Gt();Li={fees:G(Xn)}});function Ui(t){let e=t&&typeof t=="object"?t:{},r={};return typeof e.can_view=="boolean"&&(r.can_view=e.can_view),typeof e.can_trade=="boolean"&&(r.can_trade=e.can_trade),typeof e.can_transfer=="boolean"&&(r.can_transfer=e.can_transfer),typeof e.portfolio_uuid=="string"&&(r.portfolio_uuid=e.portfolio_uuid),(e.portfolio_type==="UNDEFINED"||e.portfolio_type==="DEFAULT"||e.portfolio_type==="CONSUMER"||e.portfolio_type==="INTX")&&(r.portfolio_type=e.portfolio_type),r}function Mi(t){let e=t===401?"AUTHENTICATION_FAILED":t===403?"PERMISSION_INTROSPECTION_FORBIDDEN":"BROKERAGE_REQUEST_FAILED",r=t===401?"Authentication failed for the current API key. Coinbase Advanced Trade requires an ECDSA key; if this environment uses Ed25519, create an ECDSA key and update the environment credentials.":t===403?"The current API key is not authorized to inspect its permissions.":`Brokerage API permission introspection failed with HTTP ${t}.`;return new _t(r,t,{error:e,code:t,message:r})}var Ar,vi,ki=S(()=>{"use strict";u();d();ut();Ar=async(t,e)=>{try{let{data:r}=await ei(e,{});return Ui(r)}catch(r){throw r instanceof _t?Mi(r.status):r}};Ar.normalizeResponse=Ui;Ar.errorResponse=t=>Mi(t).data;vi={api_key_permissions:Ar}});function Nr(t){return Uo[t]}function Fi(t){return Nr(t)!==void 0||Mo.has(t)}var Uo,Mo,Sr=S(()=>{"use strict";u();d();Rt();Ei();mi();Si();Pi();Di();bi();hi();ki();Uo={...ci,...Oi,...Ni,...Ci,...fi,...yi,...Li,...vi};Mo=new Set([...j.flatMap(t=>t.actions),...Object.values(Q)].filter(t=>t.agentApi).map(t=>t.id))});function Cr(t,e){if(!e)return t;let r={};for(let[n,i]of Object.entries(t)){let s=e[n]??n;r[s]=i}return r}function Vi(t,e){if(!e||typeof t!="object"||t===null||Array.isArray(t))return t;let r={};for(let[n,i]of Object.entries(t)){let s=e[n]??n;r[s]=i}return r}var Gi=S(()=>{"use strict";u();d()});function vo(t,e){let r={...e},n=t;for(let[i,s]of Object.entries(e)){if(s==null||s==="")continue;let _=`{${i}}`;n.includes(_)&&(n=n.replaceAll(_,encodeURIComponent(String(s))),delete r[i])}return{resolvedPath:n,remainingParams:r}}function ko(t){let e=[];for(let[r,n]of Object.entries(t))if(n!=null)if(Array.isArray(n))for(let i of n)e.push(`${encodeURIComponent(r)}=${encodeURIComponent(String(i))}`);else e.push(`${encodeURIComponent(r)}=${encodeURIComponent(String(n))}`);return e.length>0?"?"+e.join("&"):""}function Vo(t,e){for(let[r,n]of Object.entries(e))for(let i of t){let s=i[r];if(s!=null){if(n==="join-comma"&&Array.isArray(s))i[r]=s.join(",");else if(n==="split-comma"){let _=Array.isArray(s)?s:[s];i[r]=_.flatMap(o=>String(o).split(",").map(a=>a.trim()).filter(Boolean))}}}}function wi(t,e){return`${t.replace(/\/+$/,"")}${e}`}function Go(t){return t===408||t===429||t>=500}function wo(t){return t instanceof TypeError||t instanceof Error&&(t.name==="AbortError"||t.name==="TimeoutError")}function Wo(t,e){if(t&&typeof t=="object"&&!Array.isArray(t)){let r=typeof t.hint=="string"&&t.hint?`${t.hint} `:"";return{...t,hint:`${r}${Pr}`}}return{error:"AGENT_API_REQUEST_FAILED",code:e,message:typeof t=="string"&&t?t:`Agent API request failed with HTTP ${e}.`,hint:Pr}}function Wi(t,e){return{status:400,data:{error:"REST_ENDPOINT_UNAVAILABLE",code:400,message:`${e} endpoint is not configured for environment "${t.envName}". Configure the endpoint for this environment before retrying.`}}}function xo(t,e){let r=e.split("."),n=t;for(let i of r){if(n==null||typeof n!="object")return t;n=n[i]}return n!==void 0?n:t}function Bo(t){return t&&typeof t=="object"&&("body"in t||"query"in t||"path"in t||"rawBody"in t)}function ie(t,e){if(t==null||typeof t!="object")return t;if(Array.isArray(t))return t.map(n=>ie(n,e));let r={};for(let n of e.fields){if(!(n in t))continue;let i=e.nested?.[n];i&&Array.isArray(t[n])?r[n]=t[n].map(s=>ie(s,i)):i&&typeof t[n]=="object"&&t[n]!==null?r[n]=ie(t[n],i):r[n]=t[n]}return r}function Ho(t,e){let r=fr[t];if(!r)return;if(!e)return r;let n=r;for(let i of e.split(".")){let s=n?.nested?.[i];if(!s)return r;n=s}return n}async function Wt(t,e,r){let n=Bo(e),i=n?e.body??{}:{},s=n?e.query??{}:{},_=n?e.path??{}:{},o=n?e.headers??{}:{},a=n?e.rawBody??null:null,E=!1,g=Nr(t),c=xi.find(I=>I.id===t);if(!g&&!c?.agentApi)return{status:404,data:{error:"UNKNOWN_OPERATION",code:404,message:`No route for ${t}`}};let l=g&&!ye(g)?g:void 0;if(!n)for(let[I,T]of Object.entries(e)){let h=c?.params.find(B=>B.name===I),y=h?.in==="query"?s:h?.in==="path"?_:i;y[I]=T}if(c?.noInput&&([...Object.keys(i),...Object.keys(s),...Object.keys(_),...Object.keys(o)].length>0||(a?.length??0)>0))return{status:400,data:{error:"UNEXPECTED_FIELDS",code:400,message:`${t} does not accept input fields; it always inspects the current credential.`}};if(r.transport==="agent"&&!c?.agentApi)return{status:400,data:{error:"AGENT_API_ROUTE_UNAVAILABLE",code:400,message:`${t} is not available through the Agent API. Set COINBASE_TRANSPORT=brokerage to use direct brokerage.`}};let p=c?.agentApi?Tt(r.env,r.envName):"",A=c?.agentApi==="only"||r.transport==="agent"||c?.agentApi==="eligible"&&r.transport!=="brokerage"&&!!p;if(!g&&!A)return{status:400,data:{error:"BROKERAGE_ROUTE_UNAVAILABLE",code:400,message:`${t} is only available through the Agent API. Unset COINBASE_TRANSPORT=brokerage to use it.`}};if(l?.validateInput)try{l.validateInput({body:i,query:s,path:_,headers:o,rawBody:a,originalParams:e,structured:n})}catch(I){if(!(I instanceof P))throw I;return{status:I.status,data:{error:I.code??"INVALID_VALUE",code:I.status,message:I.message}}}if(c?.params){if(a)try{let I=JSON.parse(new TextDecoder().decode(a));if(I&&typeof I=="object"&&!Array.isArray(I)){if(c.closedInput){let T=Object.keys(I).filter(h=>Object.hasOwn(i,h));if(T.length>0)return{status:400,data:{error:"AMBIGUOUS_FIELDS",code:400,message:`Field(s) supplied more than once: ${T.join(", ")}`}}}E=!0,Object.assign(i,I)}else if(c.closedInput)return{status:400,data:{error:"INVALID_BODY",code:400,message:"Request body must be a JSON object."}}}catch{if(c.closedInput)return{status:400,data:{error:"INVALID_BODY",code:400,message:"Request body must be valid JSON."}}}for(let I of c.params){if(I.default===void 0||I.required||_[I.name]!==void 0||i[I.name]!==void 0||s[I.name]!==void 0)continue;let T=I.in==="query"?s:I.in==="path"?_:i;T[I.name]=I.default}{let I=c.params.filter(y=>(y.in==="body"||g!==void 0&&!ye(g)&&y.in==="path")&&y.required),T={..._,...i,...s},h=I.filter(y=>T[y.name]===void 0||T[y.name]==="");if(h.length>0)return{status:400,data:{error:"MISSING_FIELDS",code:400,message:`Missing required field(s): ${h.map(B=>B.name).join(", ")}`}}}{let I={..._,...i,...s},T={},h={};for(let y of c.params)if(y.oneOf&&(h[y.oneOf]||(h[y.oneOf]=[]),h[y.oneOf].push(y.name),I[y.name]!==void 0&&I[y.name]!=="")){if(T[y.oneOf])return{status:400,data:{error:"CONFLICTING_FIELDS",code:400,message:`${T[y.oneOf]} and ${y.name} are mutually exclusive. Provide one, not both.`}};T[y.oneOf]=y.name}for(let[y,B]of Object.entries(h))if(!T[y])return{status:400,data:{error:"MISSING_FIELDS",code:400,message:`One of ${B.join(", ")} is required.`}}}{let I={..._,...i,...s};if(c.closedInput){let T=new Set(c.params.map(B=>B.name)),h=Object.keys(I).filter(B=>!T.has(B));if(h.length>0)return{status:400,data:{error:"UNKNOWN_FIELDS",code:400,message:`Unknown field(s): ${h.join(", ")}`}};let y=c.params.filter(B=>B.in==="body"&&(Object.hasOwn(s,B.name)||Object.hasOwn(_,B.name))).map(B=>B.name);if(y.length>0)return{status:400,data:{error:"INVALID_PARAMETER_LOCATION",code:400,message:`Body field(s) cannot be supplied as query or path parameters: ${y.join(", ")}`}}}if(c.anyOf&&!c.anyOf.some(T=>T.every(h=>I[h]!==void 0&&I[h]!=="")))return{status:400,data:{error:"MISSING_FIELDS",code:400,message:`One of ${c.anyOf.map(h=>h.join(" and ")).join(", or ")} is required.`}}}for(let I of c.params)for(let T of[i,s,_]){if(T[I.name]===void 0)continue;if(c.closedInput&&I.type==="string"&&typeof T[I.name]!="string")return{status:400,data:{error:"INVALID_VALUE",code:400,message:`Invalid value for ${I.name}. Expected a string.`}};if(I.type==="array"&&typeof T[I.name]=="string"?T[I.name]=T[I.name].split(",").map(ct=>ct.trim()).filter(Boolean):I.type==="string"&&Array.isArray(T[I.name])&&(T[I.name]=T[I.name].join(",")),I.type==="boolean"){if(typeof T[I.name]!="boolean"&&(typeof T[I.name]!="string"||T[I.name]!=="true"&&T[I.name]!=="false"))return{status:400,data:{error:"INVALID_VALUE",code:400,message:`Invalid value for ${I.name}: "${T[I.name]}". Expected "true" or "false".`}};typeof T[I.name]=="string"&&(T[I.name]=T[I.name]==="true")}else if((I.type==="integer"||I.type==="number")&&typeof T[I.name]=="string"){let ct=Number(T[I.name]);if(!Number.isFinite(ct))return{status:400,data:{error:"INVALID_VALUE",code:400,message:`Invalid value for ${I.name}: "${T[I.name]}". Expected a number.`}};T[I.name]=ct}if(I.enum&&!I.enum.includes(String(T[I.name])))return{status:400,data:{error:"INVALID_VALUE",code:400,message:`Invalid value for ${I.name}: "${T[I.name]}". Expected one of: ${I.enum.join(", ")}`}};let h=I.pattern?Bi.get(I.pattern):void 0,y=I.format?kn[I.format]:void 0,B=h??y;if(B&&typeof T[I.name]=="string"){let ct=T[I.name],an=I.format?Fn[I.format]:void 0;if(!(B.test(ct)&&(!h||!y||y.test(ct))&&(!an||an(ct)))){let cn=(I.description??"").split(/\.\s/)[0].replace(/\.?\s*$/,""),L_=cn?`. ${cn}.`:".";return{status:400,data:{error:"INVALID_VALUE",code:400,message:`Invalid value for ${I.name}: "${String(ct).slice(0,80)}"${L_}`}}}}}}if(!A&&!r.baseURL)return Wi(r,"Brokerage API");let R=Fo[t];if(!A&&R&&Vo([i,s,_],R),!A&&g&&!ye(g)){let I={...i,...s,..._};try{let T=await g(I,r),h=fr[t];return h&&(T=ie(T,h)),{status:200,data:T}}catch(T){if(T instanceof _t)return{status:T.status,data:T.data};let h=T instanceof P?T.status:500,y=P.stripGrpcPrefix(T instanceof Error?T.message:String(T));return{status:h,data:{error:T instanceof P&&T.code?T.code:"HANDLER_ERROR",code:h,message:y}}}}let N=g??{},f=A?{origin:"AgentAPI",method:c.method,path:c.path}:N.endpoint,M=A?void 0:N.requestMap,k=A?void 0:N.responseMap,q=A?void 0:N.responseUnwrap,b={...i,..._},U=Cr(b,M),{resolvedPath:V,remainingParams:$}=vo(f.path,U);if(V.includes("{"))return{status:400,data:{error:"MISSING_PATH_PARAMS",code:400,message:`Missing required param(s): ${(V.match(/\{([^}]+)\}/g)?.map(T=>T.slice(1,-1))??[]).join(", ")}`}};let lt=f.method==="POST"||f.method==="PUT"||f.method==="DELETE"||f.method==="PATCH",et,Lt=a??null,C={...A?s:Cr(s,M)},L=A?p:f.baseURL??r.baseURL;if(!L)return Wi(r,A?"Agent API":"Brokerage API");lt?(et=wi(L,V),a&&E&&(Object.keys(_).length>0||c?.closedInput||l?.validateInput)?Lt=new TextEncoder().encode(JSON.stringify($)):!Lt&&Object.keys($).length>0&&(Lt=new TextEncoder().encode(JSON.stringify($)))):(Object.assign(C,$),et=wi(L,V));let D=ko(C);D&&(et+=D);let v;try{v=await r.doRequest({method:f.method,url:et,body:Lt,headers:Object.keys(o).length>0?o:void 0})}catch(I){if(!A||c?.agentApi!=="eligible"||!wo(I))throw I;let T=I instanceof Error?I.message:String(I);throw new Error(`${T}
48
+ Hint: ${Pr}`)}let at=new TextDecoder().decode(v.body),w;try{w=JSON.parse(at)}catch{w=at}if(v.status>=400){let I=N.sanitizeError?N.sanitizeError(w):w,T=l?.errorResponse?.(v.status)??(A&&c?.agentApi==="eligible"&&Go(v.status)?Wo(I,v.status):I);return{status:v.status,data:T,headers:v.headers}}if(N.validateResponse)try{N.validateResponse(w)}catch(I){let T=I instanceof P?I.status:502,h=P.stripGrpcPrefix(I instanceof Error?I.message:String(I));return{status:T,data:{error:T===502?"MALFORMED_RESPONSE":"UPSTREAM_REJECTION",code:T,message:h},headers:v.headers}}q&&(w=xo(w,q)),k&&(w=Vi(w,k)),l?.normalizeResponse&&(w=l.normalizeResponse(w));let Ct=Ho(t,q);return Ct&&(w=ie(w,Ct)),{status:v.status,data:w,headers:v.headers}}var xi,fr,Bi,Fo,Pr,be=S(()=>{"use strict";u();d();ft();Sr();Gi();Ot();ut();Rt();it();xi=[...j.flatMap(t=>t.actions),...Object.values(Q)],fr={},Bi=new Map;for(let t of xi){fr[t.id]=t.responseFields;for(let e of t.params)e.pattern&&Bi.set(e.pattern,new RegExp(e.pattern))}Fo={orders_list:{product_ids:"split-comma"},orders_fills:{product_ids:"split-comma"},products_list:{product_ids:"split-comma"}};Pr="To bypass the Agent API temporarily, retry with COINBASE_TRANSPORT=brokerage."});import{readFileSync as Ko,writeFileSync as Yo,mkdirSync as qo}from"node:fs";import{join as Ki}from"node:path";function Hi(t){let e=t.replace(/^v/,"").split("-")[0],[r,n,i]=e.split(".").map(Number);return{major:r??0,minor:n??0,patch:i??0}}function $o(t,e){let r=Hi(t),n=Hi(e);return n.major!==r.major?n.major>r.major:n.minor!==r.minor?n.minor>r.minor:n.patch>r.patch}function Qo(t,e){let r=Ie===jo?"":` --registry ${Ie}`;return`
49
49
  Update available: ${t} \u2192 ${e}
50
- Run: npm i -g ${Ue}${r}
51
- `}function qi(){return Tt()}function jo(){try{return JSON.parse(xo(Hi(qi(),Yi),"utf8"))}catch{return null}}function Qo(t){try{let e=qi();Ho(e,{recursive:!0}),Bo(Hi(e,Yi),JSON.stringify(t))}catch{}}async function Xo(){try{let t=new AbortController,e=setTimeout(()=>t.abort(),3e3),r=await fetch(Ko,{signal:t.signal,headers:{Accept:"application/json"}});return clearTimeout(e),r.ok?(await r.json())?.["dist-tags"]?.latest??null:null}catch{return null}}async function zi(){if(process.env.CI||process.env.COINBASE_NO_UPDATE_CHECK)return"";let t=jo();if(t&&Date.now()-t.checkedAt<$o)return"";let e=await Xo();return e?(Qo({checkedAt:Date.now(),latestVersion:e}),Yo(gt,e)?zo(gt,e):""):""}var Ki,gt,Ue,Ko,Yi,qo,$o,Me=S(()=>{"use strict";u();d();pe();it();Ki="0.0.8";gt=Ki,Ue=cn,Ko=`${Ie}/${encodeURIComponent(Ue)}`,Yi="version-check.json";qo="https://registry.npmjs.org";$o=1440*60*1e3});import{createSign as Zo,createPrivateKey as Jo,sign as ta,randomBytes as ea}from"node:crypto";function Dr(t){return Buffer.from(t).toString("base64url")}function ve(t){return Dr(Buffer.from(JSON.stringify(t)))}function ra(){return ea(16).toString("hex")}function ji(t){return t.includes("-----BEGIN EC PRIVATE KEY-----")}function Qi(t){let e=Buffer.from(t,"base64");return e.length===32||e.length===64}function yr(t,e,r,n,i){let s=Math.floor(Date.now()/1e3),_=ra(),o={sub:t,iss:"cdp",nbf:s,iat:s,exp:s+120},a=`${r} ${n}${i}`;if(r&&n&&i&&(o.uris=[a]),ji(e))return ia(t,e,o,_);if(Qi(e))return sa(t,e,o,_);throw new Error("invalid key format - must be either PEM EC key or base64 Ed25519 key")}function na(t,e,r){let n=`${ve(t)}.${ve(e)}`,i=Zo("SHA256");i.update(n);let s=i.sign(r);return`${n}.${Dr(_a(s))}`}function ia(t,e,r,n){return na({alg:"ES256",typ:"JWT",kid:t,nonce:n},r,e)}function sa(t,e,r,n){let s=`${ve({alg:"EdDSA",typ:"JWT",kid:t,nonce:n})}.${ve(r)}`,_=Buffer.from(e,"base64"),o=Jo({key:Buffer.concat([Buffer.from("302e020100300506032b657004220420","hex"),_.subarray(0,32)]),format:"der",type:"pkcs8"}),a=ta(null,Buffer.from(s),o);return`${s}.${Dr(a)}`}function _a(t){let e=2;if(t[e]!==2)throw new Error("invalid DER signature");e++;let r=t[e];e++;let n=t.subarray(e,e+r);if(e+=r,t[e]!==2)throw new Error("invalid DER signature");e++;let i=t[e];e++;let s=t.subarray(e,e+i);return n=$i(n,32),s=$i(s,32),Buffer.concat([n,s])}function $i(t,e){if(t.length===e)return Buffer.from(t);if(t.length>e)return Buffer.from(t.subarray(t.length-e));let r=Buffer.alloc(e);return r.set(t,e-t.length),r}function oa(t){return ji(t)?"ecdsa":Qi(t)?"ed25519":"unknown"}async function ke(t){let e;if(t.keyId&&t.keySecret){let _=new URL(t.url);e=`Bearer ${yr(t.keyId,t.keySecret,t.method,_.host,_.pathname)}`}else throw new Error("doAuthenticatedRequest: must supply keyId+keySecret");let r={Authorization:e,"Content-Type":"application/json","Correlation-Context":`sdk_version=${encodeURIComponent(gt)},sdk_language=typescript,source=${encodeURIComponent(Ue)}`,...t.headers},n=await fetch(t.url,{method:t.method,headers:r,body:t.body?Buffer.from(t.body):void 0}),s={body:new Uint8Array(await n.arrayBuffer()),status:n.status,headers:n.headers};return n.status===401&&t.keySecret&&oa(t.keySecret)==="ed25519"&&(s.hint="CDP key is Ed25519 but Coinbase Advanced Trade requires ECDSA. Create an ECDSA key at https://portal.cdp.coinbase.com/projects/api-keys (set Signature algorithm to ECDSA at key creation), then `coinbase env <name> --key-file ...`."),s}var Fe=S(()=>{"use strict";u();d();Me()});function ba(t,e){return t.FORCE_HYPERLINK==="0"?!1:t.FORCE_HYPERLINK?!0:!e||t.CI?!1:!!(/ghostty|iterm|wezterm|hyper/i.test(t.TERM_PROGRAM||"")||t.WT_SESSION||parseInt(t.VTE_VERSION||"",10)>=5e3)}function mt(t){return t.replace(/\x1b\]8;;[^\x07]*\x07/g,"").replace(/\x1b\[[0-9;]*m/g,"").length}var Rs,Ge=S(()=>{"use strict";u();d();Rs=ba(process.env,!!process.stdout.isTTY)});function ha(t){let e=[],r=0;for(;r<t.length;){if(t[r]===" "||t[r]===" "){r++;continue}let n=r;if(t[r]==="("){e.push({type:12,value:"(",pos:n}),r++;continue}if(t[r]===")"){e.push({type:13,value:")",pos:n}),r++;continue}if(r+1<t.length){let i=t[r]+t[r+1];if(i==="=="){e.push({type:3,value:"==",pos:n}),r+=2;continue}if(i==="!="){e.push({type:4,value:"!=",pos:n}),r+=2;continue}if(i===">="){e.push({type:7,value:">=",pos:n}),r+=2;continue}if(i==="<="){e.push({type:8,value:"<=",pos:n}),r+=2;continue}if(i==="&&"){e.push({type:9,value:"&&",pos:n}),r+=2;continue}if(i==="||"){e.push({type:10,value:"||",pos:n}),r+=2;continue}}if(t[r]===">"){e.push({type:5,value:">",pos:n}),r++;continue}if(t[r]==="<"){e.push({type:6,value:"<",pos:n}),r++;continue}if(t[r]==='"'){r++;let i="";for(;r<t.length&&t[r]!=='"';)t[r]==="\\"&&r+1<t.length&&r++,i+=t[r],r++;if(r>=t.length)throw new Error(`Unterminated string at position ${n}`);r++,e.push({type:2,value:i,pos:n});continue}if(t[r]==="-"||t[r]>="0"&&t[r]<="9"){let i="";if(t[r]==="-")if(r+1<t.length&&t[r+1]>="0"&&t[r+1]<="9")i+=t[r],r++;else throw new Error(`Unexpected character '-' at position ${n}`);for(;r<t.length&&t[r]>="0"&&t[r]<="9";)i+=t[r],r++;if(r<t.length&&t[r]===".")for(i+=".",r++;r<t.length&&t[r]>="0"&&t[r]<="9";)i+=t[r],r++;let s=r<t.length?t[r]:"",_=s.toLowerCase()in vr&&(r+1>=t.length||t[r+1]===" "||t[r+1]===" "||t[r+1]===")"||t[r+1]==="&"||t[r+1]==="|");if(s&&!_&&(s>="a"&&s<="z"||s>="A"&&s<="Z"||s==="-"))r=n;else{let o=parseFloat(i);r<t.length&&t[r].toLowerCase()in vr&&(o*=vr[t[r].toLowerCase()],r++),e.push({type:1,value:o,pos:n});continue}}if(t[r]>="a"&&t[r]<="z"||t[r]>="A"&&t[r]<="Z"||t[r]==="_"||t[r]>="0"&&t[r]<="9"){let i="";for(;r<t.length&&(t[r]>="a"&&t[r]<="z"||t[r]>="A"&&t[r]<="Z"||t[r]>="0"&&t[r]<="9"||t[r]==="_"||t[r]==="-");)i+=t[r],r++;e.push({type:0,value:i,pos:n});continue}throw new Error(`Unexpected character '${t[r]}' at position ${n}`)}return e.push({type:11,value:"",pos:r}),e}function Ua(t){return t>=3&&t<=8}function Vr(t){let e=t.trim();if(e.length===0)throw new Error("Empty predicate");return new kr(ha(e)).parse()}function ae(t){switch(t.type){case"comparison":return t.product?[t.product]:[];case"and":case"or":return[...ae(t.left),...ae(t.right)]}}function Fr(t){return t.format==="decimal"}function As(t,e){let r=[];function n(i){switch(i.type){case"comparison":{let s=e[i.field];if(!s){r.push({field:i.field,message:`Unknown field '${i.field}'`});return}let _=Fr(s);!_&&typeof i.value=="number"&&r.push({field:i.field,message:`'${i.field}' is a string field \u2014 use "${i.value}" not ${i.value}`}),_&&typeof i.value=="string"&&r.push({field:i.field,message:`'${i.field}' is a numeric field \u2014 use ${i.value} not "${i.value}"`}),!_&&(i.op===">"||i.op==="<"||i.op===">="||i.op==="<=")&&r.push({field:i.field,message:`'${i.field}' is a string field \u2014 only == and != are supported`}),s.enum&&typeof i.value=="string"&&!s.enum.includes(i.value)&&r.push({field:i.field,message:`'${i.value}' is not valid for '${i.field}' \u2014 expected: ${s.enum.join(", ")}`});break}case"and":case"or":n(i.left),n(i.right);break}}return n(t),r}function Ma(t,e){let r=e.split("."),n=t;for(let i of r){if(n==null||typeof n!="object")return;n=n[i]}return n}function ka(t,e){if(typeof e=="number"){if(typeof t=="number")return[t,e];if(typeof t=="string"&&va.test(t))return[parseFloat(t),e]}return null}function Fa(t,e,r){let n=t.product&&r?r.get(t.product)??e:e;if(t.product&&n.product_id!==t.product)return!1;let i=Ma(n,t.field);if(i==null)return!1;let s=ka(i,t.value);switch(t.op){case"==":return s?s[0]===s[1]:i===t.value;case"!=":return s?s[0]!==s[1]:i!==t.value;case">":return s?s[0]>s[1]:!1;case"<":return s?s[0]<s[1]:!1;case">=":return s?s[0]>=s[1]:!1;case"<=":return s?s[0]<=s[1]:!1}}function xt(t,e,r){switch(t.type){case"comparison":return Fa(t,e,r);case"and":return xt(t.left,e,r)&&xt(t.right,e,r);case"or":return xt(t.left,e,r)||xt(t.right,e,r)}}function Ns(t){let e=[];e.push(" --until <predicate> Exit when predicate matches"),e.push(""),e.push(" Predicate: field [product] op value [&& | || ...]"),e.push(" Operators: == != > < >= <="),e.push(" Grouping: ( )"),e.push(" Suffixes: k (1,000) m (1,000,000) b (1,000,000,000)"),e.push(""),e.push(" Fields:");let r=Math.max(...Object.keys(t).map(s=>s.length));for(let[s,_]of Object.entries(t)){let o=_.enum?_.enum.join("|"):Fr(_)?"number":_.type;e.push(` ${s.padEnd(r)} ${o.padEnd(12)} ${_.description}`)}let n=Object.entries(t).filter(([,s])=>Fr(s)).map(([s])=>s),i=Object.entries(t).filter(([,s])=>s.enum).map(([s,_])=>({k:s,vals:_.enum}));if(e.push(""),e.push(" Examples:"),n.length>0&&e.push(` --until "${n[0]} > 70k"`),n.length>1&&e.push(` --until "${n[0]} >= 70k && ${n[0]} <= 75k"`),i.length>0){let s=i[0];e.push(` --until "${s.k} == \\"${s.vals[0]}\\""`)}return n.length>0&&e.push(` --until "(${n[0]} > 72k || ${n[0]} < 68k)"`),e.join(`
52
- `)}var vr,kr,va,Gr=S(()=>{"use strict";u();d();vr={k:1e3,m:1e6,b:1e9};kr=class{tokens;pos=0;constructor(e){this.tokens=e}parse(){let e=this.parseOr();if(this.current().type!==11)throw new Error(`Unexpected token '${this.current().value}' at position ${this.current().pos}`);return e}parseOr(){let e=this.parseAnd();for(;this.current().type===10;)this.advance(),e={type:"or",left:e,right:this.parseAnd()};return e}parseAnd(){let e=this.parseAtom();for(;this.current().type===9;)this.advance(),e={type:"and",left:e,right:this.parseAtom()};return e}parseAtom(){if(this.current().type===12){this.advance();let e=this.parseOr();if(this.current().type!==13)throw new Error(`Expected ')' at position ${this.current().pos}`);return this.advance(),e}return this.parseComparison()}parseComparison(){let r=this.expect(0,"field name").value,n;this.current().type===0&&this.pos+1<this.tokens.length&&Ua(this.tokens[this.pos+1].type)&&(n=this.advance().value);let i=this.parseOp(),s;if(this.current().type===1)s=this.advance().value;else if(this.current().type===2)s=this.advance().value;else throw new Error(`Expected number or string at position ${this.current().pos}, got '${this.current().value}'`);return{type:"comparison",field:r,product:n,op:i,value:s}}parseOp(){let e=this.current();switch(e.type){case 3:return this.advance(),"==";case 4:return this.advance(),"!=";case 5:return this.advance(),">";case 6:return this.advance(),"<";case 7:return this.advance(),">=";case 8:return this.advance(),"<=";default:throw new Error(`Expected operator at position ${e.pos}, got '${e.value}'`)}}current(){return this.tokens[this.pos]}advance(){return this.tokens[this.pos++]}expect(e,r){let n=this.current();if(n.type!==e)throw new Error(`Expected ${r} at position ${n.pos}, got '${n.value}'`);return this.advance()}};va=/^-?(\d+\.?\d*|\.\d+)([eE][+-]?\d+)?$/});function ot(t){return Ss[t]??null}var Va,Ga,wa,Wa,Ss,ce=S(()=>{"use strict";u();d();ft();Va="wss://advanced-trade-ws.coinbase.com",Ga="wss://advanced-trade-ws-user.coinbase.com",wa={public:Va,user:Ga},Wa=[...X.flatMap(t=>t.actions),...Object.values(Z)],Ss={};for(let t of Wa)t.watch&&(Ss[t.id]={name:t.watch.channel,...t.watch.wireName?{wireName:t.watch.wireName}:{},endpoint:wa[t.watch.endpoint],requiresAuth:t.watch.requiresAuth,coalesce:t.watch.coalesce})});var K,xa,Ba,We,xe=S(()=>{"use strict";u();d();K={CONNECTING:"CONNECTING",CONNECTED:"CONNECTED",SUBSCRIBED:"SUBSCRIBED",RECONNECTING:"RECONNECTING",FAILED:"FAILED"},xa=3e4,Ba=1e3,We=class{url;opts;ws=null;_state=K.CONNECTING;heartbeatTimer=null;reconnectTimer=null;retryCount=0;closed=!1;WSClass;heartbeatTimeoutMs;maxRetries;now;lastActivityTime=0;wasReconnecting=!1;constructor(e,r){this.url=e,this.opts=r,this.WSClass=r.WebSocketClass??globalThis.WebSocket,this.heartbeatTimeoutMs=r.heartbeatTimeoutMs??5e3,this.maxRetries=r.maxRetries??1/0,this.now=r.now??Date.now}get state(){return this._state}connect(){if(!this.closed){this.clearReconnectTimer(),this.teardownSocket(),this.setState(K.CONNECTING);try{this.ws=new this.WSClass(this.url)}catch{this.scheduleReconnect();return}this.resetHeartbeat(),this.ws.onopen=()=>{this.lastActivityTime=this.now(),this.setState(K.CONNECTED),this.resetHeartbeat()},this.ws.onmessage=e=>{let r=this.now();if(this.lastActivityTime>0&&r-this.lastActivityTime>this.heartbeatTimeoutMs*2){this.forceClose();return}this.lastActivityTime=r,this.resetHeartbeat();let n;try{n=typeof e.data=="string"?JSON.parse(e.data):e.data}catch{return}this.opts.onMessage(n)},this.ws.onclose=()=>{this.clearHeartbeat(),this.closed||this.scheduleReconnect()},this.ws.onerror=()=>{}}}send(e){this.ws&&this.ws.readyState===1&&this.ws.send(e)}markSubscribed(){this.setState(K.SUBSCRIBED),this.retryCount=0}close(){this.closed=!0,this.clearHeartbeat(),this.clearReconnectTimer(),this.teardownSocket()}teardownSocket(){this.ws&&(this.ws.onopen=null,this.ws.onclose=null,this.ws.onmessage=null,this.ws.onerror=null,this.ws.readyState<2&&this.ws.close(1e3,"teardown"),this.ws=null)}forceClose(){this.ws&&(this.clearHeartbeat(),this.teardownSocket(),this.scheduleReconnect())}setState(e){this._state=e,e===K.RECONNECTING&&!this.wasReconnecting&&(this.wasReconnecting=!0,this.opts.onDisconnect?.()),e===K.CONNECTED&&this.wasReconnecting&&(this.wasReconnecting=!1,this.opts.onReconnect?.()),this.opts.onStateChange?.(e)}resetHeartbeat(){this.clearHeartbeat(),this.heartbeatTimer=setTimeout(()=>{this.forceClose()},this.heartbeatTimeoutMs)}clearHeartbeat(){this.heartbeatTimer&&(clearTimeout(this.heartbeatTimer),this.heartbeatTimer=null)}clearReconnectTimer(){this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=null)}scheduleReconnect(){if(this.closed)return;if(this.clearReconnectTimer(),this.retryCount>=this.maxRetries){this.setState(K.FAILED);return}this.setState(K.RECONNECTING);let e=Math.min(Ba*Math.pow(2,this.retryCount),xa),r=500+Math.random()*(e-500);this.retryCount++,this.reconnectTimer=setTimeout(()=>{this.connect()},r)}}});var Be,Cs=S(()=>{"use strict";u();d();xe();Be=class{conn;channel;productIds=[];jwt;lastSeq;hasSubscribed=!1;wasReconnecting=!1;eventHandler;gapHandler;heartbeatHandler;errorHandler;reconnectedHandler;refreshJWTFn;constructor(e){this.channel=e.channel,this.eventHandler=e.onEvent,this.gapHandler=e.onSequenceGap,this.heartbeatHandler=e.onHeartbeat,this.errorHandler=e.onError,this.reconnectedHandler=e.onReconnected,this.refreshJWTFn=e.refreshJWT;let r={onMessage:n=>this.handleMessage(n),onStateChange:n=>{n===K.CONNECTED&&this.hasSubscribed&&(this.refreshJWTFn&&this.wasReconnecting&&(this.jwt=this.refreshJWTFn()),this.lastSeq=void 0,this.sendSubscribe()),e.onStateChange?.(n)},onDisconnect:()=>{this.wasReconnecting=!0,e.onDisconnect?.()},onReconnect:()=>{e.onReconnect?.()},heartbeatTimeoutMs:e.heartbeatTimeoutMs,maxRetries:e.maxRetries,WebSocketClass:e.WebSocketClass,now:e.now};this.conn=new We(e.channel.endpoint,r)}connect(){this.conn.connect()}subscribe(e,r){this.productIds=e,this.jwt=r,this.hasSubscribed=!0,this.lastSeq=void 0,(this.conn.state===K.CONNECTED||this.conn.state===K.SUBSCRIBED)&&this.sendSubscribe()}unsubscribe(e){let r={type:"unsubscribe",channel:this.channel.name};e.length>0&&(r.product_ids=e),this.jwt&&(r.jwt=this.jwt),this.conn.send(JSON.stringify(r));let n={type:"unsubscribe",channel:"heartbeats"};e.length>0&&(n.product_ids=e),this.jwt&&(n.jwt=this.jwt),this.conn.send(JSON.stringify(n)),this.productIds=this.productIds.filter(i=>!e.includes(i))}updateJWT(e){this.jwt=e}close(){this.conn.close()}get state(){return this.conn.state}get subscribedProducts(){return[...this.productIds]}sendSubscribe(){let e={type:"subscribe",channel:this.channel.name};this.productIds.length>0&&(e.product_ids=this.productIds),this.jwt&&(e.jwt=this.jwt),this.conn.send(JSON.stringify(e));let r={type:"subscribe",channel:"heartbeats"};this.productIds.length>0&&(r.product_ids=this.productIds),this.jwt&&(r.jwt=this.jwt),this.conn.send(JSON.stringify(r))}handleMessage(e){if(typeof e!="object"||e===null)return;let r=e;if(r.type==="error"){this.errorHandler?.(String(r.message??r.reason??"unknown error"));return}if(r.type==="subscriptions"||r.channel==="subscriptions"){typeof r.sequence_num=="number"&&(this.lastSeq===void 0||r.sequence_num>this.lastSeq)&&(this.lastSeq=r.sequence_num),this.conn.markSubscribed(),this.wasReconnecting&&(this.wasReconnecting=!1,this.reconnectedHandler?.());return}if(typeof r.sequence_num=="number"){let i=r.sequence_num;if(this.lastSeq!==void 0&&i<=this.lastSeq)return;this.lastSeq!==void 0&&i>this.lastSeq+1&&this.gapHandler?.(this.lastSeq+1,i),(this.lastSeq===void 0||i>this.lastSeq)&&(this.lastSeq=i)}if(r.channel==="heartbeats"){this.heartbeatHandler?.();return}let n=this.channel.wireName??this.channel.name;r.channel===n&&this.eventHandler(e)}}});function He(t,e){return yr(t,e,"","","")}var wr=S(()=>{"use strict";u();d();Fe()});var Ke,Ps=S(()=>{"use strict";u();d();Ke=class{snapshots=new Map;timestamps=new Map;now;constructor(e){this.now=e??Date.now}update(e,r){this.snapshots.set(e,r),this.timestamps.set(e,this.now())}get(e){return this.snapshots.get(e)}all(){return this.snapshots}isStale(e,r){let n=this.timestamps.get(e);return n===void 0?!1:this.now()-n>r}staleProducts(e,r){let n=new Set;for(let i of e)this.isStale(i,r)&&n.add(i);return n}hasSeen(e){return this.timestamps.has(e)}age(e){let r=this.timestamps.get(e);if(r!==void 0)return this.now()-r}}});function Wr(t,e,r){if(!r||t===0)return"";let n=t>0?Ht:Kt;return e?`${Bt}${n}`:n}function hs(t,e,r){if(!r)return"";let n=t==="bid"||t==="BUY"?Ht:Kt;return e?`${Bt}${n}`:n}var z,Bt,Ht,Kt,fs,Y,Ds,ys,bs,Ls,Yt=S(()=>{"use strict";u();d();z="\x1B[2m",Bt="\x1B[1m",Ht="\x1B[32m",Kt="\x1B[31m",fs="\x1B[33m",Y="\x1B[0m",Ds="\x1B[?25l",ys="\x1B[?25h",bs="\x1B[?1049h",Ls="\x1B[?1049l"});var qt,Us=S(()=>{"use strict";u();d();Yt();qt=class{out;inAltScreen=!1;cursorHidden=!1;scrollRegionSet=!1;cleanedUp=!1;resizeHandlers=[];sigwinchHandler=null;sigintHandler=null;sigtermHandler=null;stdinHandler=null;constructor(e){this.out=e??process.stdout}enterAltScreen(){this.out.write(bs),this.inAltScreen=!0}exitAltScreen(){this.out.write(Ls),this.inAltScreen=!1}hideCursor(){this.out.write(Ds),this.cursorHidden=!0}showCursor(){this.out.write(ys),this.cursorHidden=!1}setScrollRegion(e,r){this.out.write(`\x1B[${e};${r}r`),this.scrollRegionSet=!0}resetScrollRegion(){this.out.write("\x1B[r"),this.scrollRegionSet=!1}moveTo(e,r){this.out.write(`\x1B[${e};${r}H`)}clearLine(){this.out.write("\x1B[K")}insertLine(){this.out.write("\x1B[L")}write(e){this.out.write(e)}get cols(){return this.out.columns??80}get rows(){return this.out.rows??24}onResize(e){this.resizeHandlers.push(e),this.sigwinchHandler||(this.sigwinchHandler=()=>{let r=this.cols,n=this.rows;for(let i of this.resizeHandlers)i(r,n)},process.on("SIGWINCH",this.sigwinchHandler))}installSignalHandlers(e){let r=e??(()=>process.exit(0));process.stdin.isTTY&&typeof process.stdin.setRawMode=="function"&&(process.stdin.setRawMode(!0),process.stdin.resume(),this.stdinHandler=n=>{n[0]===3&&(this.cleanup(),r())},process.stdin.on("data",this.stdinHandler)),this.sigintHandler=()=>{this.cleanup(),r()},this.sigtermHandler=()=>{this.cleanup(),r()},process.on("SIGINT",this.sigintHandler),process.on("SIGTERM",this.sigtermHandler)}cleanup(){this.cleanedUp||(this.cleanedUp=!0,process.stdin.isTTY&&typeof process.stdin.setRawMode=="function"&&process.stdin.setRawMode(!1),this.scrollRegionSet&&this.resetScrollRegion(),this.cursorHidden&&this.showCursor(),this.inAltScreen&&this.exitAltScreen(),this.out.write(Y),this.removeListeners())}removeListeners(){this.stdinHandler&&(process.stdin.removeListener("data",this.stdinHandler),this.stdinHandler=null,process.stdin.isTTY&&process.stdin.pause()),this.sigwinchHandler&&(process.removeListener("SIGWINCH",this.sigwinchHandler),this.sigwinchHandler=null),this.sigintHandler&&(process.removeListener("SIGINT",this.sigintHandler),this.sigintHandler=null),this.sigtermHandler&&(process.removeListener("SIGTERM",this.sigtermHandler),this.sigtermHandler=null)}}});var Ee,Ms=S(()=>{"use strict";u();d();Ee=class{flashes=new Map;offsets=new Map;now;constructor(e){this.now=e??Date.now}flash(e,r=600){this.flashes.set(e,this.now()+r)}isFlashing(e){let r=this.flashes.get(e);return r===void 0?!1:this.now()<r}expired(){let e=this.now(),r=[];for(let[n,i]of this.flashes)e>=i&&(r.push(n),this.flashes.delete(n),this.offsets.delete(n));return r}flashWithOffset(e,r,n=1500){let i=this.now()+n;this.flashes.set(e,i),this.offsets.set(e,{indexAtCreation:r,durationMs:n,expiry:i})}getRow(e,r,n){let i=this.offsets.get(e);if(!i)return null;if(this.now()>=i.expiry)return this.offsets.delete(e),null;let s=r-i.indexAtCreation-1;return n+s}clear(){this.flashes.clear(),this.offsets.clear()}}});function W(t,e){let r=mt(t);return r>=e?t.slice(0,t.length-(r-e)):t+" ".repeat(e-r)}function k(t,e){let r=mt(t);return r>=e?t.slice(0,t.length-(r-e)):" ".repeat(e-r)+t}function At(t,e){let r="\u2500".repeat(t);return e?`${z}${r}${Y}`:r}function zt(t,e,r){let n=mt(t),i=mt(e);if(n+1+i>r){let o=r-i-1;return o>0?`${t.slice(0,o)} ${e}`:e.slice(0,r)}let _=r-n-i;return _<0?W(`${t} ${e}`,r):`${t}${" ".repeat(_)}${e}`}function $t(t,e){return e?t?`${Bt}\xB7${Y}`:`${z}\xB7${Y}`:""}function J(){let t=new Date,e=String(t.getHours()).padStart(2,"0"),r=String(t.getMinutes()).padStart(2,"0"),n=String(t.getSeconds()).padStart(2,"0");return`${e}:${r}:${n}`}var ue=S(()=>{"use strict";u();d();Ge();Yt()});function j(t){let e=Math.abs(t);return e>=1e3?t.toLocaleString("en-US",{minimumFractionDigits:2,maximumFractionDigits:2}):e>=1?t.toFixed(2):t.toFixed(4)}function jt(t){let e=Math.abs(t);return e>=100?t.toFixed(1):e>=10?t.toFixed(2):e>=1?t.toFixed(3):e>=.01?t.toFixed(4):e>=1e-4?t.toFixed(6):t===0?"0":t.toFixed(8)}function vs(t){return t>=1e9?`${(t/1e9).toFixed(1)}B`:t>=1e6?`${(t/1e6).toFixed(0)}M`:t>=1e3?`${(t/1e3).toFixed(0)}K`:t.toFixed(0)}function ks(t){return`${t>=0?"+":""}${t.toFixed(2)}%`}function Fs(t){let e=new Date(t);if(isNaN(e.getTime()))return t;let r=String(e.getHours()).padStart(2,"0"),n=String(e.getMinutes()).padStart(2,"0"),i=String(e.getSeconds()).padStart(2,"0"),s=String(e.getMilliseconds()).padStart(3,"0");return`${r}:${n}:${i}.${s}`}var Ye=S(()=>{"use strict";u();d()});function ws(t){let e=[],r=0;for(let n of Ha){if(r+n.width+1>t){let i=t-r-1;i>=4&&n.key==="id"&&e.push({...n,width:i});break}e.push(n),r+=n.width+1}return e}function Ws(){return{events:[],positions:new Map,openOrders:new Set,totalFees:0,lastClock:J(),netCash:0,fillCount:0,accounted:new Map,prependCount:0,heartbeat:!1,updateCount:0}}function Ka(t){let e=t.order_configuration;if(e)for(let r of Object.values(e)){if(r&&typeof r=="object"&&"base_size"in r)return String(r.base_size);if(r&&typeof r=="object"&&"quote_size"in r)return`$${String(r.quote_size)}`}}function Ya(t,e){let r=e.creation_time?Date.parse(e.creation_time):NaN;if(Number.isNaN(r))return 0;for(let n=0;n<t.length;n++){let i=t[n].creation_time?Date.parse(t[n].creation_time):NaN;if(!Number.isNaN(i)&&i<r)return n}return t.length}function xr(t,e,r="live"){let n=t.events;if(!n)return{inserts:[],updates:[]};let i=[],s=[];for(let _ of n){let o=_.orders;if(o)for(let a of o){let E={order_id:String(a.order_id??""),status:String(a.status??""),product_id:String(a.product_id??""),order_side:String(a.order_side??a.side??""),order_type:a.order_type?String(a.order_type):void 0,average_filled_price:String(a.average_filled_price??a.avg_price??"0"),total_fees:String(a.total_fees??"0"),filled_size:String(a.filled_size??a.cumulative_quantity??"0"),base_size:Ka(a),creation_time:a.creation_time?String(a.creation_time):a.created_time?String(a.created_time):void 0},g=e.events.findIndex(c=>c.order_id===E.order_id);if(g>=0){let c=e.events[g],l=c.status!==E.status||c.filled_size!==E.filled_size||c.total_fees!==E.total_fees||c.average_filled_price!==E.average_filled_price;c.status=E.status,c.average_filled_price=E.average_filled_price,c.filled_size=E.filled_size,c.total_fees=E.total_fees,l&&(Vs(e,E),s.push(c));continue}r==="backfill"?e.events.splice(Ya(e.events,E),0,E):e.events.unshift(E),e.prependCount++,Vs(e,E),i.push(E),e.events.length>1e4&&e.events.pop()}}return{inserts:i,updates:s}}function Vs(t,e){t.updateCount++,t.lastClock=J();let r=e.status.toUpperCase();r==="OPEN"||r==="PENDING"?t.openOrders.add(e.order_id):t.openOrders.delete(e.order_id);let n=parseFloat(e.total_fees??"0")||0,i=parseFloat(e.filled_size??"0")||0,s=parseFloat(e.average_filled_price??"0")||0,_=i*s,o=t.accounted.get(e.order_id)??{fees:0,size:0,value:0},a=n-o.fees,E=i-o.size,g=_-o.value;(E!==0||a!==0)&&(o.size===0&&i>0&&t.fillCount++,t.totalFees+=a,e.order_side==="BUY"?(t.netCash-=g,t.positions.set(e.product_id,(t.positions.get(e.product_id)??0)+E)):(t.netCash+=g,t.positions.set(e.product_id,(t.positions.get(e.product_id)??0)-E)),t.accounted.set(e.order_id,{fees:n,size:i,value:_}))}function qa(t,e,r,n,i){let s=e.order_side==="BUY"?"BUY":"SELL",_=hs(s,n,i),o=e.status.toUpperCase(),a=i?Y:"",E=parseFloat(e.average_filled_price??"0"),g=parseFloat(e.filled_size??"0");switch(t){case"time":return W(Fs(e.creation_time??new Date().toISOString()),r);case"status":return`${(o==="OPEN"||o==="PENDING")&&i?fs:""}${W(o,r)}${a}`;case"product":return W(e.product_id,r);case"side":return`${_}${W(s,r)}${a}`;case"size":{let c=g>0?jt(g):e.base_size??"-";return`${_}${k(c,r)}${a}`}case"price":return`${_}${k(E>0?j(E):"-",r)}${a}`;case"fee":{let c=parseFloat(e.total_fees??"0");return k(c>0?j(c):"-",r)}case"id":return`${i?z:""}${W(e.order_id.slice(0,r),r)}${a}`;default:return W("",r)}}function de(t,e,r,n=80){return ws(n).map(i=>qa(i.key,t,i.width,e,r)).join(" ")}function za(t,e=80){let r=new Set(["size","price","fee"]),i=ws(e).map(s=>r.has(s.key)?k(s.header,s.width):W(s.header,s.width)).join(" ");return t?`${z}${i}${Y}`:i}function $a(t,e,r){let n=t.netCash>=0?r?Ht:"":r?Kt:"",i=r?Y:"",s=`Fills:${t.fillCount}`,_=`Open:${t.openOrders.size}`,o=`Fees:${j(t.totalFees)}`,a=`Net:${t.netCash>=0?"+":""}${j(t.netCash)}`,E=`${n}${a}${i}`,c=`${$t(t.heartbeat,r)} ${t.lastClock}`,l=`\xB7 ${t.lastClock}`,p=`${s} ${_} ${o} ${a}`,A=`${s} ${_} ${o} ${E}`,T=new Map;for(let[y,h]of t.positions){if(Math.abs(h)<1e-9)continue;let $=(y.match(/-/g)??[]).length===1?y.slice(0,y.indexOf("-")):y;T.set($,(T.get($)??0)+h)}let N=[],f=[];for(let[y,h]of T){if(Math.abs(h)<1e-9)continue;let x=`${y}:${jt(h)}`;N.push(x),f.push(x)}let M=e-p.length-l.length-6,v="";if(N.length>0&&M>8){let y="",h=0,x=0;for(let $=0;$<N.length;$++){let at=x>0?" ":"";if(h+at.length+f[$].length>M){let ct=N.length-x;ct>0&&(y+=` +${ct}`);break}y+=at+N[$],h+=at.length+f[$].length,x++}v=y}let Q=v?`${A} ${v}`:A;return zt(Q,c,e)}function xs(t,e,r,n,i){let s=i??e.events,_=t.cols,o=t.rows,a=o,E=o-1,g=o-2;n.inserts.forEach((c,l)=>{r.flashWithOffset(c.order_id,e.prependCount-1-l,1500),t.moveTo(qe,1),t.insertLine(),t.write(de(c,!0,!0,t.cols)+"\x1B[K")});for(let c of n.updates){let l=s.indexOf(c);if(l>=0){let p=qe+l;p<=g&&(r.flash(c.order_id,1500),t.moveTo(p,1),t.write(de(c,!0,!0,t.cols)+"\x1B[K"))}}for(let c of r.expired()){let l=s.findIndex(p=>p.order_id===c);if(l>=0){let p=qe+l;p<=g&&(t.moveTo(p,1),t.write(de(s[l],!1,!0,t.cols)+"\x1B[K"))}}t.moveTo(E,1),t.write(At(_,!0)),t.moveTo(a,1),t.write($a(e,_-1,!0)+"\x1B[K")}function Br(t){t.enterAltScreen(),t.hideCursor();let e=t.rows;t.setScrollRegion(qe,e-2),t.moveTo(1,1),t.write(za(!0,t.cols)+"\x1B[K"),t.moveTo(2,1),t.write(At(t.cols,!0))}function Gs(t){return t?.toLowerCase()}function ze(t,e,r){return{_ch:"user",_seq:e,_ts:r,order_id:t.order_id,status:Gs(t.status),product_id:t.product_id,side:Gs(t.order_side),filled_size:t.filled_size??null,price:t.average_filled_price??null,fees:t.total_fees??null}}function Bs(t,e,r){return JSON.stringify(ze(t,e,r))}var qe,Ha,Hs=S(()=>{"use strict";u();d();ue();Yt();Ye();qe=3,Ha=[{header:"TIME",width:13,key:"time"},{header:"STATUS",width:10,key:"status"},{header:"PRODUCT",width:10,key:"product"},{header:"SIDE",width:5,key:"side"},{header:"SIZE",width:12,key:"size"},{header:"PRICE",width:12,key:"price"},{header:"FEE",width:8,key:"fee"},{header:"ORDER ID",width:12,key:"id"}]});function Ks(t,e,r,n=8){let i=r-e;if(i<=0)return"\u2500".repeat(n);let s=Math.max(0,Math.min(1,(t-e)/i)),_=Math.round(s*(n-1)),o="";for(let a=0;a<n;a++)o+=a===_?"\u25CF":"\u2500";return o}function Ys(t,e,r){if(e<=0||t<=0)return"";let n=Math.max(0,Math.round(t/e*r));return"\u2588".repeat(n)}var Hr=S(()=>{"use strict";u();d()});function $s(t){let e=[],r=0;for(let n of Xa){if(r+n.width+1>t)break;e.push(n),r+=n.width+1}return e}function js(){return{products:new Map,prevPrices:new Map,productOrder:[],heartbeat:!1,updateCount:0,lastClock:J()}}function Qs(t,e){let r=t.events;if(!r)return[];let n=[];for(let i of r){let s=i.tickers;if(s)for(let _ of s){let o={product_id:String(_.product_id??""),price:String(_.price??"0"),volume_24_h:String(_.volume_24_h??"0"),price_percent_chg_24_h:String(_.price_percent_chg_24_h??"0"),best_bid:String(_.best_bid??"0"),best_bid_quantity:String(_.best_bid_quantity??"0"),best_ask:String(_.best_ask??"0"),best_ask_quantity:String(_.best_ask_quantity??"0"),high_24_h:String(_.high_24_h??"0"),low_24_h:String(_.low_24_h??"0")},a=e.prevPrices.get(o.product_id),E=parseFloat(o.price),g=0;a!==void 0&&(E>a?g=1:E<a&&(g=-1)),e.prevPrices.set(o.product_id,E),e.products.set(o.product_id,o),e.productOrder.includes(o.product_id)||e.productOrder.push(o.product_id),e.updateCount++,e.lastClock=J(),n.push({ticker:o,direction:g})}}return n}function Za(t,e,r,n,i,s){let _=parseFloat(e.price),o=s?Y:"";switch(t){case"symbol":return W(e.product_id,r);case"price":return`${Wr(n,i,s)}${k(j(_),r)}${o}`;case"pct":{let a=parseFloat(e.price_percent_chg_24_h),E=a>0?1:a<0?-1:0;return`${Wr(E,!1,s)}${k(ks(a),r)}${o}`}case"bid":return k(j(parseFloat(e.best_bid)),r);case"ask":return k(j(parseFloat(e.best_ask)),r);case"bidSz":return`${s?z:""}${k(jt(parseFloat(e.best_bid_quantity)),r)}${o}`;case"askSz":return`${s?z:""}${k(jt(parseFloat(e.best_ask_quantity)),r)}${o}`;case"low":return`${s?z:""}${k(j(parseFloat(e.low_24_h)),r)}${o}`;case"high":return`${s?z:""}${k(j(parseFloat(e.high_24_h)),r)}${o}`;case"range":return W(Ks(_,parseFloat(e.low_24_h),parseFloat(e.high_24_h),r),r);case"vol":return`${s?z:""}${k(vs(parseFloat(e.volume_24_h)),r)}${o}`;default:return W("",r)}}function zs(t,e,r,n,i=80){return $s(i).map(_=>Za(_.key,t,_.width,e,r,n)).join(" ")}function Ja(t,e=80){let n=$s(e).map(i=>i.key==="symbol"||i.key==="range"?W(i.header,i.width):k(i.header,i.width)).join(" ");return t?`${z}${n}${Y}`:n}function tc(t,e,r){let n=`${t.products.size} product${t.products.size!==1?"s":""}`,s=`${$t(t.heartbeat,r)} ${t.lastClock}`;return zt(n,s,e)}function Kr(t){t.enterAltScreen(),t.hideCursor(),t.moveTo(ja,1),t.write(Ja(!0,t.cols)+"\x1B[K"),t.moveTo(Qa,1),t.write(At(t.cols,!0))}function Xs(t,e,r,n,i){let s=t.cols,_=t.rows,o=_,a=_-1;for(let{ticker:E,direction:g}of n){let c=e.productOrder.indexOf(E.product_id);if(c<0)continue;let l=qs+c;if(l>=a)continue;let p=i?.has(E.product_id)??!1,A=!p&&r.isFlashing(E.product_id);t.moveTo(l,1);let T=zs(E,p?0:g,A,!0,s);t.write((p?z+T+Y:T)+"\x1B[K")}for(let E of r.expired()){let g=e.productOrder.indexOf(E);if(g<0)continue;let c=qs+g;if(c>=a)continue;let l=e.products.get(E);l&&(t.moveTo(c,1),t.write(zs(l,0,!1,!0,s)+"\x1B[K"))}t.moveTo(a,1),t.write(At(s,!0)),t.moveTo(o,1),t.write(tc(e,s-1,!0)+"\x1B[K")}function Yr(t,e,r){return{_ch:"ticker",_seq:e,_ts:r,product_id:t.product_id,price:t.price,pct_24h:t.price_percent_chg_24_h,bid:t.best_bid,bid_size:t.best_bid_quantity,ask:t.best_ask,ask_size:t.best_ask_quantity,volume:t.volume_24_h,high:t.high_24_h,low:t.low_24_h}}function Zs(t,e,r){return JSON.stringify(Yr(t,e,r))}var ja,Qa,qs,Xa,Js=S(()=>{"use strict";u();d();ue();Yt();Ye();Hr();ja=1,Qa=2,qs=3,Xa=[{header:"SYMBOL",width:10,key:"symbol"},{header:"PRICE",width:12,key:"price"},{header:"%24h",width:8,key:"pct"},{header:"BID",width:11,key:"bid"},{header:"ASK",width:11,key:"ask"},{header:"LOW",width:11,key:"low"},{header:"RANGE",width:10,key:"range"},{header:"HIGH",width:11,key:"high"},{header:"BIDSZ",width:7,key:"bidSz"},{header:"ASKSZ",width:7,key:"askSz"},{header:"VOL",width:6,key:"vol"}]});function t_(t,e){if(!t)return 0n;if(!ec.test(t))throw new Error(`invalid decimal: ${t}`);let r=t.startsWith("-"),[n,i=""]=(r?t.slice(1):t).split(".");if(i.length>e)throw new Error(`too many decimal places (max ${e}): ${t}`);let s=BigInt(n||"0")*10n**BigInt(e)+BigInt(i.padEnd(e,"0")||"0");return r?-s:s}function $e(t,e){let r=t<0n,n=(r?-t:t).toString().padStart(e+1,"0"),i=n.slice(0,n.length-e),s=n.slice(n.length-e).replace(/0+$/,"");return`${r?"-":""}${i}${s?`.${s}`:""}`}var ec,e_=S(()=>{"use strict";u();d();ec=/^-?(?:\d+(?:\.\d*)?|\.\d+)$/});function n_(t,e=0){return{productId:t,bids:new Map,asks:new Map,heartbeat:!1,updateCount:0,msgCount:0,lastMsgTime:Date.now(),msgRate:0,depth:e,lastClock:J()}}function i_(t,e){let r=t.events;if(!r)return;e.msgCount++;let n=Date.now(),i=(n-e.lastMsgTime)/1e3;i>=1&&(e.msgRate=Math.round(e.msgCount/i),e.msgCount=0,e.lastMsgTime=n);for(let s of r){let _=s.type,o=s.updates;if(_==="snapshot"&&(e.bids.clear(),e.asks.clear()),!!o){for(let a of o){let E=String(a.side??"").toLowerCase(),g;try{g=t_(String(a.price_level??"0"),je)}catch{continue}let c=parseFloat(String(a.new_quantity??"0"));if(g<=0n)continue;let l=E==="bid"?e.bids:e.asks;c<=0?l.delete(g):l.set(g,c)}e.updateCount++,e.lastClock=J()}}}function Xe(t){let e=[];for(let[r,n]of t.bids)e.push({price:r,size:n});return e.sort((r,n)=>r.price<n.price?1:r.price>n.price?-1:0),e}function Ze(t){let e=[];for(let[r,n]of t.asks)e.push({price:r,size:n});return e.sort((r,n)=>r.price<n.price?-1:r.price>n.price?1:0),e}function Qe(t){return Number($e(t,je))}function s_(t,e){if(t.length===0||e.length===0)return null;let r=t[0].price,n=e[0].price;return{spread:$e(n-r,je),mid:$e(5n*(n+r),je+1)}}function r_(t,e,r,n,i,s,_){let o=_?i==="bid"?Ht:Kt:"",a=_?Y:"",E=Ys(r,n,s),g=`${o}${E}${a}`;return[`${o}${k(j(t),Nt[0])}${a}`,k(e.toFixed(4),Nt[1]),k(r.toFixed(4),Nt[2]),g].join(" ")}function ic(t,e,r){let n=s_(Xe(t),Ze(t)),i=r?z:"",s=r?Y:"";if(!n)return`${i}${W(" Waiting for data...",e)}${s}`;let _=Number(n.spread),o=Number(n.mid),a=_/o*100,E=` Spread: ${j(_).padStart(10)} (${a.toFixed(3).padStart(6)}%) Mid: ${j(o).padStart(12)}`;return`${i}${W(E,e)}${s}`}function sc(t,e,r){let n=nc.map((a,E)=>E===3?W(a,Nt[E]):k(a,Nt[E])).join(" "),i=r?z:"",s=r?Bt:"",_=r?Y:"",o=`${s}${t.productId}${_}`;return`${W(o,e)}
53
- ${i}${n}${_}`}function _c(t,e,r){let n=Xe(t).reduce((g,c)=>g+c.size,0),i=Ze(t).reduce((g,c)=>g+c.size,0),s=i>0?(n/i).toFixed(2):"-",o=`${t.depth?`Depth:${t.depth} `:""}B/A:${s} Rate:${t.msgRate}/s`,E=`${$t(t.heartbeat,r)} ${t.lastClock}`;return zt(o,E,e)}function qr(t,e){t.enterAltScreen(),t.hideCursor(),zr(t,e)}function zr(t,e){let r=t.cols,n=t.rows;if(n<4)return;let i=Nt[0]+Nt[1]+Nt[2]+3,s=Math.max(4,r-i),_=Ze(e),o=Xe(e),a=n-1,E=n,g=Math.max(0,n-4),c=Math.floor(g/2),l=g>c*2||c>0,p=e.depth?Math.min(c,e.depth):c,A=_.slice(0,p),T=o.slice(0,p),N=0,f=[];for(let h of A)N+=h.size,f.push(N);let M=0,v=[];for(let h of T)M+=h.size,v.push(M);let Q=Math.max(N,M),y=1;t.moveTo(y,1),t.write(sc(e,r,!0)+"\x1B[K"),y=rc;for(let h=0;h<p&&y<a;h++,y++)if(t.moveTo(y,1),h<A.length){let x=A.length-1-h;t.write(r_(Qe(A[x].price),A[x].size,f[x],Q,"ask",s,!0)+"\x1B[K")}else t.clearLine();l&&y<a&&(t.moveTo(y,1),t.write(ic(e,r,!0)+"\x1B[K"),y++);for(let h=0;h<p&&y<a;h++,y++)t.moveTo(y,1),h<T.length?t.write(r_(Qe(T[h].price),T[h].size,v[h],Q,"bid",s,!0)+"\x1B[K"):t.clearLine();for(;y<a;)t.moveTo(y,1),t.clearLine(),y++;t.moveTo(a,1),t.write(At(r,!0)),t.moveTo(E,1),t.write(_c(e,r-1,!0)+"\x1B[K")}function $r(t,e,r){let n=Xe(t),i=Ze(t),s=s_(n,i);return{_ch:"level2",_seq:e,_ts:r,product_id:t.productId,spread:s?s.spread:null,mid:s?s.mid:null,bids:n.map(_=>({price:Qe(_.price),size:_.size})),asks:i.map(_=>({price:Qe(_.price),size:_.size}))}}function __(t,e,r){return JSON.stringify($r(t,e,r))}var rc,Nt,nc,je,o_=S(()=>{"use strict";u();d();ue();Yt();Ye();Hr();e_();rc=3,Nt=[14,12,12,16],nc=["PRICE","SIZE","TOTAL","DEPTH"],je=12});function a_(t,e,r,n,i){return new jr(t,e,r,n,i)}function c_(t,e,r){return new Qr(t,e,r)}function E_(t,e,r,n){return new Xr(t,e,r,n)}var jr,Qr,Xr,u_=S(()=>{"use strict";u();d();xe();wr();Us();Ms();ue();Hs();Js();o_();he();jr=class{productIds=[];screen;refreshJWT;state=Ws();flash=new Ee;queryFilter;context;jwt;until;liveness=!1;connected=!1;constructor(e,r,n,i,s){this.context=r,this.jwt=n,this.until=s,this.queryFilter=e.flags.query,e.isTTY&&!e.untilActive&&(this.screen=new qt(e.out),Br(this.screen),this.screen.onResize(()=>{Br(this.screen),this.repaintFrame()})),i.requiresAuth&&(this.refreshJWT=()=>this.freshJWT())}freshJWT(){let e=this.context.env;return e?.auth?.key_id&&e?.auth?.key_secret?He(e.auth.key_id,e.auth.key_secret):this.jwt}matchesFilter(e){let r=this.queryFilter;return r?!(r.status&&e.status.toUpperCase()!==String(r.status).toUpperCase()||r.product_ids&&!String(r.product_ids).split(",").includes(e.product_id)||r.side&&e.order_side.toUpperCase()!==String(r.side).toUpperCase()):!0}visibleEvents(){return this.queryFilter?this.state.events.filter(e=>this.matchesFilter(e)):void 0}syncHeartbeat(){this.state.heartbeat=this.connected&&this.liveness}render(e){this.screen&&(this.syncHeartbeat(),xs(this.screen,this.state,this.flash,e,this.visibleEvents()))}repaintFrame(){if(!this.screen)return;let e=this.queryFilter?this.state.events.filter(i=>this.matchesFilter(i)):this.state.events,r=this.screen.rows-4,n=Math.min(e.length,r);for(let i=n-1;i>=0;i--)this.screen.moveTo(3+i,1),this.screen.write(de(e[i],!1,!0,this.screen.cols)+"\x1B[K");for(let i=n;i<r;i++)this.screen.moveTo(3+i,1),this.screen.write("\x1B[K");this.render({inserts:[],updates:[]})}onData(e,r,n){let i=this.queryFilter?this.visibleEvents().map(a=>a.order_id):void 0,s=xr(e,this.state);this.liveness=!this.liveness;let _={inserts:s.inserts.filter(a=>this.matchesFilter(a)),updates:s.updates.filter(a=>this.matchesFilter(a))};if(i){let a=this.visibleEvents().map(g=>g.order_id);a.length!==i.length||a.some((g,c)=>g!==i[c])?this.repaintFrame():this.render(_)}else this.render(_);return[..._.inserts,..._.updates].map(a=>({obj:ze(a,r,n),line:Bs(a,r,n)}))}onHeartbeat(){this.liveness=!this.liveness,this.state.lastClock=J(),this.render({inserts:[],updates:[]})}onConnState(e){this.connected=e===K.SUBSCRIBED,this.repaintFrame()}onGap(){this.backfill().catch(()=>{})}onReconnected(){this.backfill().catch(()=>{})}setup(){return this.backfill()}cleanup(){this.screen?.cleanup()}async backfill(){try{let e=await Wt("orders_list",{query:{limit:100,...this.queryFilter}},this.context);if(e.status<400&&e.data?.orders){let r=e.data.orders;for(let n of r.reverse()){let s=xr({events:[{orders:[n]}]},this.state,"backfill");if(this.until.active)for(let _ of[...s.inserts,...s.updates]){let o=String(n.created_time??new Date().toISOString());if(this.until.check(ze(_,0,o)))return}}}}catch{}this.repaintFrame()}};Qr=class{productIds;screen;state=js();flash=new Ee;until;liveness=!1;connected=!1;constructor(e,r,n){this.until=n,this.productIds=r,e.isTTY&&!e.untilActive&&(this.screen=new qt(e.out),Kr(this.screen),this.screen.onResize(()=>{Kr(this.screen),this.repaintFrame()}))}syncHeartbeat(){this.state.heartbeat=this.connected&&this.liveness}render(e){this.screen&&(this.syncHeartbeat(),Xs(this.screen,this.state,this.flash,e,this.until.active?this.until.stale:void 0))}repaintFrame(){if(!this.screen)return;let e=this.state.productOrder.map(r=>this.state.products.get(r)).filter(r=>!!r).map(r=>({ticker:r,direction:0}));this.render(e)}onData(e,r,n){let i=Qs(e,this.state);this.liveness=!this.liveness;for(let{ticker:s}of i)this.flash.flash(s.product_id,600);return this.render(i),i.map(({ticker:s})=>({obj:Yr(s,r,n),line:Zs(s,r,n)}))}onHeartbeat(){this.liveness=!this.liveness,this.state.lastClock=J(),this.render([])}onConnState(e){this.connected=e===K.SUBSCRIBED,this.render([])}onGap(){}onReconnected(){}async setup(){}cleanup(){this.screen?.cleanup()}};Xr=class{productIds;screen;state;productId;liveness=!1;connected=!1;constructor(e,r,n,i){this.productId=r,this.productIds=[r],this.state=n_(r,e.flags.depth??0),e.isTTY&&!e.untilActive&&(this.screen=new qt(e.out),qr(this.screen,this.state),this.screen.onResize(()=>{qr(this.screen,this.state),this.render()}))}syncHeartbeat(){this.state.heartbeat=this.connected&&this.liveness}render(){this.screen&&(this.syncHeartbeat(),zr(this.screen,this.state))}onData(e,r,n){return i_(e,this.state),this.liveness=!this.liveness,this.render(),[{obj:$r(this.state,r,n),line:__(this.state,r,n)}]}onHeartbeat(){this.liveness=!this.liveness,this.state.lastClock=J(),this.render()}onConnState(e){this.connected=e===K.SUBSCRIBED,this.render()}onGap(){return this.state.bids.clear(),this.state.asks.clear(),this.render(),{resubscribe:[this.productId]}}onReconnected(){}async setup(){}cleanup(){this.screen?.cleanup()}}});var d_={};Zt(d_,{applyJQ:()=>Zr});import{execFileSync as oc}from"node:child_process";function Zr(t,e){try{return oc("jq",["-r",e],{input:t,encoding:"utf8",maxBuffer:10*1024*1024,env:lr()}).trimEnd()}catch(r){if(r.code==="ENOENT")throw new Error("jq is not installed. Install it: https://jqlang.github.io/jq/download/");let n=(r.stderr??r.message??"").toString().trim();throw new Error(`jq: ${n}`)}}var Jr=S(()=>{"use strict";u();d();it()});var tn={};Zt(tn,{UntilController:()=>Qt,__test:()=>gc,startWatch:()=>dc,surfaceForChannel:()=>St});function cc(t){return ac.find(e=>e.id===t)}function St(t){switch(t.name){case"user":return"blotter";case"ticker":return"watchlist";case"level2":return"ladder";default:return null}}async function uc(t,e){if(!e.requiresAuth)return;let n=t.env?.auth;if(!n)throw new Error("WebSocket channel requires authentication. Run: coinbase env <name> --key-file key.json");if(n.type==="oauth")throw new Error(`The --watch blotter requires CDP API key auth (WebSocket does not support OAuth).
54
- Set up a CDP key: coinbase env <name> --key-file key.json`);if(n.type==="cdp_key"&&n.key_id&&n.key_secret)return He(n.key_id,n.key_secret);throw new Error("Unsupported auth type for WebSocket")}async function dc(t,e,r,n){let i=ot(t);if(!i)throw new Error(`--watch is not supported for "${t.replace(/_/g," ")}"`);let s=St(i);if(!s)throw new Error(`--watch is not yet implemented for channel "${i.name}"`);if(n.until){let a;try{a=Vr(n.until)}catch(c){throw new Error(`Invalid --until predicate: ${c.message}`)}let E=cc(t);if(E?.watchFields){let c=As(a,E.watchFields);if(c.length>0){let l=Object.keys(E.watchFields).join(", ");throw new Error(c.map(p=>p.message).join(`
50
+ Run: npm i -g ${Le}${r}
51
+ `}function zi(){return pt()}function Zo(){try{return JSON.parse(Ko(Ki(zi(),qi),"utf8"))}catch{return null}}function Jo(t){try{let e=zi();qo(e,{recursive:!0}),Yo(Ki(e,qi),JSON.stringify(t))}catch{}}async function ta(){try{let t=new AbortController,e=setTimeout(()=>t.abort(),3e3),r=await fetch(zo,{signal:t.signal,headers:{Accept:"application/json"}});return clearTimeout(e),r.ok?(await r.json())?.["dist-tags"]?.latest??null:null}catch{return null}}async function $i(){if(process.env.CI||process.env.COINBASE_NO_UPDATE_CHECK)return"";let t=Zo();if(t&&Date.now()-t.checkedAt<Xo)return"";let e=await ta();return e?(Jo({checkedAt:Date.now(),latestVersion:e}),$o(dt,e)?Qo(dt,e):""):""}var Yi,dt,Le,zo,qi,jo,Xo,he=S(()=>{"use strict";u();d();pe();it();Yi="0.0.10";dt=Yi,Le=En,zo=`${Ie}/${encodeURIComponent(Le)}`,qi="version-check.json";jo="https://registry.npmjs.org";Xo=1440*60*1e3});import{createSign as ea,createPrivateKey as ra,sign as na,randomBytes as ia}from"node:crypto";function Dr(t){return Buffer.from(t).toString("base64url")}function Ue(t){return Dr(Buffer.from(JSON.stringify(t)))}function sa(){return ia(16).toString("hex")}function Qi(t){return t.includes("-----BEGIN EC PRIVATE KEY-----")}function Xi(t){let e=Buffer.from(t,"base64");return e.length===32||e.length===64}function yr(t,e,r,n,i){let s=Math.floor(Date.now()/1e3),_=sa(),o={sub:t,iss:"cdp",nbf:s,iat:s,exp:s+120},a=`${r} ${n}${i}`;if(r&&n&&i&&(o.uris=[a]),Qi(e))return oa(t,e,o,_);if(Xi(e))return aa(t,e,o,_);throw new Error("invalid key format - must be either PEM EC key or base64 Ed25519 key")}function _a(t,e,r){let n=`${Ue(t)}.${Ue(e)}`,i=ea("SHA256");i.update(n);let s=i.sign(r);return`${n}.${Dr(ca(s))}`}function oa(t,e,r,n){return _a({alg:"ES256",typ:"JWT",kid:t,nonce:n},r,e)}function aa(t,e,r,n){let s=`${Ue({alg:"EdDSA",typ:"JWT",kid:t,nonce:n})}.${Ue(r)}`,_=Buffer.from(e,"base64"),o=ra({key:Buffer.concat([Buffer.from("302e020100300506032b657004220420","hex"),_.subarray(0,32)]),format:"der",type:"pkcs8"}),a=na(null,Buffer.from(s),o);return`${s}.${Dr(a)}`}function ca(t){let e=2;if(t[e]!==2)throw new Error("invalid DER signature");e++;let r=t[e];e++;let n=t.subarray(e,e+r);if(e+=r,t[e]!==2)throw new Error("invalid DER signature");e++;let i=t[e];e++;let s=t.subarray(e,e+i);return n=ji(n,32),s=ji(s,32),Buffer.concat([n,s])}function ji(t,e){if(t.length===e)return Buffer.from(t);if(t.length>e)return Buffer.from(t.subarray(t.length-e));let r=Buffer.alloc(e);return r.set(t,e-t.length),r}function Ea(t){return Qi(t)?"ecdsa":Xi(t)?"ed25519":"unknown"}async function Me(t){let e;if(t.keyId&&t.keySecret){let _=new URL(t.url);e=`Bearer ${yr(t.keyId,t.keySecret,t.method,_.host,_.pathname)}`}else throw new Error("doAuthenticatedRequest: must supply keyId+keySecret");let r={Authorization:e,"Content-Type":"application/json","Correlation-Context":`sdk_version=${encodeURIComponent(dt)},sdk_language=typescript,source=${encodeURIComponent(Le)}`,...t.headers},n=await fetch(t.url,{method:t.method,headers:r,body:t.body?Buffer.from(t.body):void 0}),s={body:new Uint8Array(await n.arrayBuffer()),status:n.status,headers:n.headers};return n.status===401&&t.keySecret&&Ea(t.keySecret)==="ed25519"&&(s.hint="CDP key is Ed25519 but Coinbase Advanced Trade requires ECDSA. Create an ECDSA key at https://portal.cdp.coinbase.com/projects/api-keys (set Signature algorithm to ECDSA at key creation), then `coinbase env <name> --key-file ...`."),s}var ve=S(()=>{"use strict";u();d();he()});function Ua(t,e){return t.FORCE_HYPERLINK==="0"?!1:t.FORCE_HYPERLINK?!0:!e||t.CI?!1:!!(/ghostty|iterm|wezterm|hyper/i.test(t.TERM_PROGRAM||"")||t.WT_SESSION||parseInt(t.VTE_VERSION||"",10)>=5e3)}function mt(t){return t.replace(/\x1b\]8;;[^\x07]*\x07/g,"").replace(/\x1b\[[0-9;]*m/g,"").length}var Os,Fe=S(()=>{"use strict";u();d();Os=Ua(process.env,!!process.stdout.isTTY)});function va(t){let e=[],r=0;for(;r<t.length;){if(t[r]===" "||t[r]===" "){r++;continue}let n=r;if(t[r]==="("){e.push({type:12,value:"(",pos:n}),r++;continue}if(t[r]===")"){e.push({type:13,value:")",pos:n}),r++;continue}if(r+1<t.length){let i=t[r]+t[r+1];if(i==="=="){e.push({type:3,value:"==",pos:n}),r+=2;continue}if(i==="!="){e.push({type:4,value:"!=",pos:n}),r+=2;continue}if(i===">="){e.push({type:7,value:">=",pos:n}),r+=2;continue}if(i==="<="){e.push({type:8,value:"<=",pos:n}),r+=2;continue}if(i==="&&"){e.push({type:9,value:"&&",pos:n}),r+=2;continue}if(i==="||"){e.push({type:10,value:"||",pos:n}),r+=2;continue}}if(t[r]===">"){e.push({type:5,value:">",pos:n}),r++;continue}if(t[r]==="<"){e.push({type:6,value:"<",pos:n}),r++;continue}if(t[r]==='"'){r++;let i="";for(;r<t.length&&t[r]!=='"';)t[r]==="\\"&&r+1<t.length&&r++,i+=t[r],r++;if(r>=t.length)throw new Error(`Unterminated string at position ${n}`);r++,e.push({type:2,value:i,pos:n});continue}if(t[r]==="-"||t[r]>="0"&&t[r]<="9"){let i="";if(t[r]==="-")if(r+1<t.length&&t[r+1]>="0"&&t[r+1]<="9")i+=t[r],r++;else throw new Error(`Unexpected character '-' at position ${n}`);for(;r<t.length&&t[r]>="0"&&t[r]<="9";)i+=t[r],r++;if(r<t.length&&t[r]===".")for(i+=".",r++;r<t.length&&t[r]>="0"&&t[r]<="9";)i+=t[r],r++;let s=r<t.length?t[r]:"",_=s.toLowerCase()in vr&&(r+1>=t.length||t[r+1]===" "||t[r+1]===" "||t[r+1]===")"||t[r+1]==="&"||t[r+1]==="|");if(s&&!_&&(s>="a"&&s<="z"||s>="A"&&s<="Z"||s==="-"))r=n;else{let o=parseFloat(i);r<t.length&&t[r].toLowerCase()in vr&&(o*=vr[t[r].toLowerCase()],r++),e.push({type:1,value:o,pos:n});continue}}if(t[r]>="a"&&t[r]<="z"||t[r]>="A"&&t[r]<="Z"||t[r]==="_"||t[r]>="0"&&t[r]<="9"){let i="";for(;r<t.length&&(t[r]>="a"&&t[r]<="z"||t[r]>="A"&&t[r]<="Z"||t[r]>="0"&&t[r]<="9"||t[r]==="_"||t[r]==="-");)i+=t[r],r++;e.push({type:0,value:i,pos:n});continue}throw new Error(`Unexpected character '${t[r]}' at position ${n}`)}return e.push({type:11,value:"",pos:r}),e}function ka(t){return t>=3&&t<=8}function Vr(t){let e=t.trim();if(e.length===0)throw new Error("Empty predicate");return new kr(va(e)).parse()}function ae(t){switch(t.type){case"comparison":return t.product?[t.product]:[];case"and":case"or":return[...ae(t.left),...ae(t.right)]}}function Fr(t){return t.format==="decimal"}function Ns(t,e){let r=[];function n(i){switch(i.type){case"comparison":{let s=e[i.field];if(!s){r.push({field:i.field,message:`Unknown field '${i.field}'`});return}let _=Fr(s);!_&&typeof i.value=="number"&&r.push({field:i.field,message:`'${i.field}' is a string field \u2014 use "${i.value}" not ${i.value}`}),_&&typeof i.value=="string"&&r.push({field:i.field,message:`'${i.field}' is a numeric field \u2014 use ${i.value} not "${i.value}"`}),!_&&(i.op===">"||i.op==="<"||i.op===">="||i.op==="<=")&&r.push({field:i.field,message:`'${i.field}' is a string field \u2014 only == and != are supported`}),s.enum&&typeof i.value=="string"&&!s.enum.includes(i.value)&&r.push({field:i.field,message:`'${i.value}' is not valid for '${i.field}' \u2014 expected: ${s.enum.join(", ")}`});break}case"and":case"or":n(i.left),n(i.right);break}}return n(t),r}function Fa(t,e){let r=e.split("."),n=t;for(let i of r){if(n==null||typeof n!="object")return;n=n[i]}return n}function Ga(t,e){if(typeof e=="number"){if(typeof t=="number")return[t,e];if(typeof t=="string"&&Va.test(t))return[parseFloat(t),e]}return null}function wa(t,e,r){let n=t.product&&r?r.get(t.product)??e:e;if(t.product&&n.product_id!==t.product)return!1;let i=Fa(n,t.field);if(i==null)return!1;let s=Ga(i,t.value);switch(t.op){case"==":return s?s[0]===s[1]:i===t.value;case"!=":return s?s[0]!==s[1]:i!==t.value;case">":return s?s[0]>s[1]:!1;case"<":return s?s[0]<s[1]:!1;case">=":return s?s[0]>=s[1]:!1;case"<=":return s?s[0]<=s[1]:!1}}function xt(t,e,r){switch(t.type){case"comparison":return wa(t,e,r);case"and":return xt(t.left,e,r)&&xt(t.right,e,r);case"or":return xt(t.left,e,r)||xt(t.right,e,r)}}function Ss(t){let e=[];e.push(" --until <predicate> Exit when predicate matches"),e.push(""),e.push(" Predicate: field [product] op value [&& | || ...]"),e.push(" Operators: == != > < >= <="),e.push(" Grouping: ( )"),e.push(" Suffixes: k (1,000) m (1,000,000) b (1,000,000,000)"),e.push(""),e.push(" Fields:");let r=Math.max(...Object.keys(t).map(s=>s.length));for(let[s,_]of Object.entries(t)){let o=_.enum?_.enum.join("|"):Fr(_)?"number":_.type;e.push(` ${s.padEnd(r)} ${o.padEnd(12)} ${_.description}`)}let n=Object.entries(t).filter(([,s])=>Fr(s)).map(([s])=>s),i=Object.entries(t).filter(([,s])=>s.enum).map(([s,_])=>({k:s,vals:_.enum}));if(e.push(""),e.push(" Examples:"),n.length>0&&e.push(` --until "${n[0]} > 70k"`),n.length>1&&e.push(` --until "${n[0]} >= 70k && ${n[0]} <= 75k"`),i.length>0){let s=i[0];e.push(` --until "${s.k} == \\"${s.vals[0]}\\""`)}return n.length>0&&e.push(` --until "(${n[0]} > 72k || ${n[0]} < 68k)"`),e.join(`
52
+ `)}var vr,kr,Va,Gr=S(()=>{"use strict";u();d();vr={k:1e3,m:1e6,b:1e9};kr=class{tokens;pos=0;constructor(e){this.tokens=e}parse(){let e=this.parseOr();if(this.current().type!==11)throw new Error(`Unexpected token '${this.current().value}' at position ${this.current().pos}`);return e}parseOr(){let e=this.parseAnd();for(;this.current().type===10;)this.advance(),e={type:"or",left:e,right:this.parseAnd()};return e}parseAnd(){let e=this.parseAtom();for(;this.current().type===9;)this.advance(),e={type:"and",left:e,right:this.parseAtom()};return e}parseAtom(){if(this.current().type===12){this.advance();let e=this.parseOr();if(this.current().type!==13)throw new Error(`Expected ')' at position ${this.current().pos}`);return this.advance(),e}return this.parseComparison()}parseComparison(){let r=this.expect(0,"field name").value,n;this.current().type===0&&this.pos+1<this.tokens.length&&ka(this.tokens[this.pos+1].type)&&(n=this.advance().value);let i=this.parseOp(),s;if(this.current().type===1)s=this.advance().value;else if(this.current().type===2)s=this.advance().value;else throw new Error(`Expected number or string at position ${this.current().pos}, got '${this.current().value}'`);return{type:"comparison",field:r,product:n,op:i,value:s}}parseOp(){let e=this.current();switch(e.type){case 3:return this.advance(),"==";case 4:return this.advance(),"!=";case 5:return this.advance(),">";case 6:return this.advance(),"<";case 7:return this.advance(),">=";case 8:return this.advance(),"<=";default:throw new Error(`Expected operator at position ${e.pos}, got '${e.value}'`)}}current(){return this.tokens[this.pos]}advance(){return this.tokens[this.pos++]}expect(e,r){let n=this.current();if(n.type!==e)throw new Error(`Expected ${r} at position ${n.pos}, got '${n.value}'`);return this.advance()}};Va=/^-?(\d+\.?\d*|\.\d+)([eE][+-]?\d+)?$/});function ot(t){return Cs[t]??null}var Wa,xa,Ba,Ha,Cs,ce=S(()=>{"use strict";u();d();Rt();Wa="wss://advanced-trade-ws.coinbase.com",xa="wss://advanced-trade-ws-user.coinbase.com",Ba={public:Wa,user:xa},Ha=[...j.flatMap(t=>t.actions),...Object.values(Q)],Cs={};for(let t of Ha)t.watch&&(Cs[t.id]={name:t.watch.channel,...t.watch.wireName?{wireName:t.watch.wireName}:{},endpoint:Ba[t.watch.endpoint],requiresAuth:t.watch.requiresAuth,coalesce:t.watch.coalesce})});var H,Ka,Ya,Ge,we=S(()=>{"use strict";u();d();H={CONNECTING:"CONNECTING",CONNECTED:"CONNECTED",SUBSCRIBED:"SUBSCRIBED",RECONNECTING:"RECONNECTING",FAILED:"FAILED"},Ka=3e4,Ya=1e3,Ge=class{url;opts;ws=null;_state=H.CONNECTING;heartbeatTimer=null;reconnectTimer=null;retryCount=0;closed=!1;WSClass;heartbeatTimeoutMs;maxRetries;now;lastActivityTime=0;wasReconnecting=!1;constructor(e,r){this.url=e,this.opts=r,this.WSClass=r.WebSocketClass??globalThis.WebSocket,this.heartbeatTimeoutMs=r.heartbeatTimeoutMs??5e3,this.maxRetries=r.maxRetries??1/0,this.now=r.now??Date.now}get state(){return this._state}connect(){if(!this.closed){this.clearReconnectTimer(),this.teardownSocket(),this.setState(H.CONNECTING);try{this.ws=new this.WSClass(this.url)}catch{this.scheduleReconnect();return}this.resetHeartbeat(),this.ws.onopen=()=>{this.lastActivityTime=this.now(),this.setState(H.CONNECTED),this.resetHeartbeat()},this.ws.onmessage=e=>{let r=this.now();if(this.lastActivityTime>0&&r-this.lastActivityTime>this.heartbeatTimeoutMs*2){this.forceClose();return}this.lastActivityTime=r,this.resetHeartbeat();let n;try{n=typeof e.data=="string"?JSON.parse(e.data):e.data}catch{return}this.opts.onMessage(n)},this.ws.onclose=()=>{this.clearHeartbeat(),this.closed||this.scheduleReconnect()},this.ws.onerror=()=>{}}}send(e){this.ws&&this.ws.readyState===1&&this.ws.send(e)}markSubscribed(){this.setState(H.SUBSCRIBED),this.retryCount=0}close(){this.closed=!0,this.clearHeartbeat(),this.clearReconnectTimer(),this.teardownSocket()}teardownSocket(){this.ws&&(this.ws.onopen=null,this.ws.onclose=null,this.ws.onmessage=null,this.ws.onerror=null,this.ws.readyState<2&&this.ws.close(1e3,"teardown"),this.ws=null)}forceClose(){this.ws&&(this.clearHeartbeat(),this.teardownSocket(),this.scheduleReconnect())}setState(e){this._state=e,e===H.RECONNECTING&&!this.wasReconnecting&&(this.wasReconnecting=!0,this.opts.onDisconnect?.()),e===H.CONNECTED&&this.wasReconnecting&&(this.wasReconnecting=!1,this.opts.onReconnect?.()),this.opts.onStateChange?.(e)}resetHeartbeat(){this.clearHeartbeat(),this.heartbeatTimer=setTimeout(()=>{this.forceClose()},this.heartbeatTimeoutMs)}clearHeartbeat(){this.heartbeatTimer&&(clearTimeout(this.heartbeatTimer),this.heartbeatTimer=null)}clearReconnectTimer(){this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=null)}scheduleReconnect(){if(this.closed)return;if(this.clearReconnectTimer(),this.retryCount>=this.maxRetries){this.setState(H.FAILED);return}this.setState(H.RECONNECTING);let e=Math.min(Ya*Math.pow(2,this.retryCount),Ka),r=500+Math.random()*(e-500);this.retryCount++,this.reconnectTimer=setTimeout(()=>{this.connect()},r)}}});var We,Ps=S(()=>{"use strict";u();d();we();We=class{conn;channel;productIds=[];jwt;lastSeq;hasSubscribed=!1;wasReconnecting=!1;eventHandler;gapHandler;heartbeatHandler;errorHandler;reconnectedHandler;refreshJWTFn;constructor(e){this.channel=e.channel,this.eventHandler=e.onEvent,this.gapHandler=e.onSequenceGap,this.heartbeatHandler=e.onHeartbeat,this.errorHandler=e.onError,this.reconnectedHandler=e.onReconnected,this.refreshJWTFn=e.refreshJWT;let r={onMessage:n=>this.handleMessage(n),onStateChange:n=>{n===H.CONNECTED&&this.hasSubscribed&&(this.refreshJWTFn&&this.wasReconnecting&&(this.jwt=this.refreshJWTFn()),this.lastSeq=void 0,this.sendSubscribe()),e.onStateChange?.(n)},onDisconnect:()=>{this.wasReconnecting=!0,e.onDisconnect?.()},onReconnect:()=>{e.onReconnect?.()},heartbeatTimeoutMs:e.heartbeatTimeoutMs,maxRetries:e.maxRetries,WebSocketClass:e.WebSocketClass,now:e.now};this.conn=new Ge(e.channel.endpoint,r)}connect(){this.conn.connect()}subscribe(e,r){this.productIds=e,this.jwt=r,this.hasSubscribed=!0,this.lastSeq=void 0,(this.conn.state===H.CONNECTED||this.conn.state===H.SUBSCRIBED)&&this.sendSubscribe()}unsubscribe(e){let r={type:"unsubscribe",channel:this.channel.name};e.length>0&&(r.product_ids=e),this.jwt&&(r.jwt=this.jwt),this.conn.send(JSON.stringify(r));let n={type:"unsubscribe",channel:"heartbeats"};e.length>0&&(n.product_ids=e),this.jwt&&(n.jwt=this.jwt),this.conn.send(JSON.stringify(n)),this.productIds=this.productIds.filter(i=>!e.includes(i))}updateJWT(e){this.jwt=e}close(){this.conn.close()}get state(){return this.conn.state}get subscribedProducts(){return[...this.productIds]}sendSubscribe(){let e={type:"subscribe",channel:this.channel.name};this.productIds.length>0&&(e.product_ids=this.productIds),this.jwt&&(e.jwt=this.jwt),this.conn.send(JSON.stringify(e));let r={type:"subscribe",channel:"heartbeats"};this.productIds.length>0&&(r.product_ids=this.productIds),this.jwt&&(r.jwt=this.jwt),this.conn.send(JSON.stringify(r))}handleMessage(e){if(typeof e!="object"||e===null)return;let r=e;if(r.type==="error"){this.errorHandler?.(String(r.message??r.reason??"unknown error"));return}if(r.type==="subscriptions"||r.channel==="subscriptions"){typeof r.sequence_num=="number"&&(this.lastSeq===void 0||r.sequence_num>this.lastSeq)&&(this.lastSeq=r.sequence_num),this.conn.markSubscribed(),this.wasReconnecting&&(this.wasReconnecting=!1,this.reconnectedHandler?.());return}if(typeof r.sequence_num=="number"){let i=r.sequence_num;if(this.lastSeq!==void 0&&i<=this.lastSeq)return;this.lastSeq!==void 0&&i>this.lastSeq+1&&this.gapHandler?.(this.lastSeq+1,i),(this.lastSeq===void 0||i>this.lastSeq)&&(this.lastSeq=i)}if(r.channel==="heartbeats"){this.heartbeatHandler?.();return}let n=this.channel.wireName??this.channel.name;r.channel===n&&this.eventHandler(e)}}});function xe(t,e){return yr(t,e,"","","")}var wr=S(()=>{"use strict";u();d();ve()});var Be,fs=S(()=>{"use strict";u();d();Be=class{snapshots=new Map;timestamps=new Map;now;constructor(e){this.now=e??Date.now}update(e,r){this.snapshots.set(e,r),this.timestamps.set(e,this.now())}get(e){return this.snapshots.get(e)}all(){return this.snapshots}isStale(e,r){let n=this.timestamps.get(e);return n===void 0?!1:this.now()-n>r}staleProducts(e,r){let n=new Set;for(let i of e)this.isStale(i,r)&&n.add(i);return n}hasSeen(e){return this.timestamps.has(e)}age(e){let r=this.timestamps.get(e);if(r!==void 0)return this.now()-r}}});function Wr(t,e,r){if(!r||t===0)return"";let n=t>0?Ht:Kt;return e?`${Bt}${n}`:n}function Us(t,e,r){if(!r)return"";let n=t==="bid"||t==="BUY"?Ht:Kt;return e?`${Bt}${n}`:n}var z,Bt,Ht,Kt,Ds,K,ys,bs,Ls,hs,Yt=S(()=>{"use strict";u();d();z="\x1B[2m",Bt="\x1B[1m",Ht="\x1B[32m",Kt="\x1B[31m",Ds="\x1B[33m",K="\x1B[0m",ys="\x1B[?25l",bs="\x1B[?25h",Ls="\x1B[?1049h",hs="\x1B[?1049l"});var qt,Ms=S(()=>{"use strict";u();d();Yt();qt=class{out;inAltScreen=!1;cursorHidden=!1;scrollRegionSet=!1;cleanedUp=!1;resizeHandlers=[];sigwinchHandler=null;sigintHandler=null;sigtermHandler=null;stdinHandler=null;constructor(e){this.out=e??process.stdout}enterAltScreen(){this.out.write(Ls),this.inAltScreen=!0}exitAltScreen(){this.out.write(hs),this.inAltScreen=!1}hideCursor(){this.out.write(ys),this.cursorHidden=!0}showCursor(){this.out.write(bs),this.cursorHidden=!1}setScrollRegion(e,r){this.out.write(`\x1B[${e};${r}r`),this.scrollRegionSet=!0}resetScrollRegion(){this.out.write("\x1B[r"),this.scrollRegionSet=!1}moveTo(e,r){this.out.write(`\x1B[${e};${r}H`)}clearLine(){this.out.write("\x1B[K")}insertLine(){this.out.write("\x1B[L")}write(e){this.out.write(e)}get cols(){return this.out.columns??80}get rows(){return this.out.rows??24}onResize(e){this.resizeHandlers.push(e),this.sigwinchHandler||(this.sigwinchHandler=()=>{let r=this.cols,n=this.rows;for(let i of this.resizeHandlers)i(r,n)},process.on("SIGWINCH",this.sigwinchHandler))}installSignalHandlers(e){let r=e??(()=>process.exit(0));process.stdin.isTTY&&typeof process.stdin.setRawMode=="function"&&(process.stdin.setRawMode(!0),process.stdin.resume(),this.stdinHandler=n=>{n[0]===3&&(this.cleanup(),r())},process.stdin.on("data",this.stdinHandler)),this.sigintHandler=()=>{this.cleanup(),r()},this.sigtermHandler=()=>{this.cleanup(),r()},process.on("SIGINT",this.sigintHandler),process.on("SIGTERM",this.sigtermHandler)}cleanup(){this.cleanedUp||(this.cleanedUp=!0,process.stdin.isTTY&&typeof process.stdin.setRawMode=="function"&&process.stdin.setRawMode(!1),this.scrollRegionSet&&this.resetScrollRegion(),this.cursorHidden&&this.showCursor(),this.inAltScreen&&this.exitAltScreen(),this.out.write(K),this.removeListeners())}removeListeners(){this.stdinHandler&&(process.stdin.removeListener("data",this.stdinHandler),this.stdinHandler=null,process.stdin.isTTY&&process.stdin.pause()),this.sigwinchHandler&&(process.removeListener("SIGWINCH",this.sigwinchHandler),this.sigwinchHandler=null),this.sigintHandler&&(process.removeListener("SIGINT",this.sigintHandler),this.sigintHandler=null),this.sigtermHandler&&(process.removeListener("SIGTERM",this.sigtermHandler),this.sigtermHandler=null)}}});var Ee,vs=S(()=>{"use strict";u();d();Ee=class{flashes=new Map;offsets=new Map;now;constructor(e){this.now=e??Date.now}flash(e,r=600){this.flashes.set(e,this.now()+r)}isFlashing(e){let r=this.flashes.get(e);return r===void 0?!1:this.now()<r}expired(){let e=this.now(),r=[];for(let[n,i]of this.flashes)e>=i&&(r.push(n),this.flashes.delete(n),this.offsets.delete(n));return r}flashWithOffset(e,r,n=1500){let i=this.now()+n;this.flashes.set(e,i),this.offsets.set(e,{indexAtCreation:r,durationMs:n,expiry:i})}getRow(e,r,n){let i=this.offsets.get(e);if(!i)return null;if(this.now()>=i.expiry)return this.offsets.delete(e),null;let s=r-i.indexAtCreation-1;return n+s}clear(){this.flashes.clear(),this.offsets.clear()}}});function x(t,e){let r=mt(t);return r>=e?t.slice(0,t.length-(r-e)):t+" ".repeat(e-r)}function F(t,e){let r=mt(t);return r>=e?t.slice(0,t.length-(r-e)):" ".repeat(e-r)+t}function At(t,e){let r="\u2500".repeat(t);return e?`${z}${r}${K}`:r}function zt(t,e,r){let n=mt(t),i=mt(e);if(n+1+i>r){let o=r-i-1;return o>0?`${t.slice(0,o)} ${e}`:e.slice(0,r)}let _=r-n-i;return _<0?x(`${t} ${e}`,r):`${t}${" ".repeat(_)}${e}`}function $t(t,e){return e?t?`${Bt}\xB7${K}`:`${z}\xB7${K}`:""}function Z(){let t=new Date,e=String(t.getHours()).padStart(2,"0"),r=String(t.getMinutes()).padStart(2,"0"),n=String(t.getSeconds()).padStart(2,"0");return`${e}:${r}:${n}`}var ue=S(()=>{"use strict";u();d();Fe();Yt()});function X(t){let e=Math.abs(t);return e>=1e3?t.toLocaleString("en-US",{minimumFractionDigits:2,maximumFractionDigits:2}):e>=1?t.toFixed(2):t.toFixed(4)}function jt(t){let e=Math.abs(t);return e>=100?t.toFixed(1):e>=10?t.toFixed(2):e>=1?t.toFixed(3):e>=.01?t.toFixed(4):e>=1e-4?t.toFixed(6):t===0?"0":t.toFixed(8)}function ks(t){return t>=1e9?`${(t/1e9).toFixed(1)}B`:t>=1e6?`${(t/1e6).toFixed(0)}M`:t>=1e3?`${(t/1e3).toFixed(0)}K`:t.toFixed(0)}function Fs(t){return`${t>=0?"+":""}${t.toFixed(2)}%`}function Vs(t){let e=new Date(t);if(isNaN(e.getTime()))return t;let r=String(e.getHours()).padStart(2,"0"),n=String(e.getMinutes()).padStart(2,"0"),i=String(e.getSeconds()).padStart(2,"0"),s=String(e.getMilliseconds()).padStart(3,"0");return`${r}:${n}:${i}.${s}`}var He=S(()=>{"use strict";u();d()});function Ws(t){let e=[],r=0;for(let n of qa){if(r+n.width+1>t){let i=t-r-1;i>=4&&n.key==="id"&&e.push({...n,width:i});break}e.push(n),r+=n.width+1}return e}function xs(){return{events:[],positions:new Map,openOrders:new Set,totalFees:0,lastClock:Z(),netCash:0,fillCount:0,accounted:new Map,prependCount:0,heartbeat:!1,updateCount:0}}function za(t){let e=t.order_configuration;if(e)for(let r of Object.values(e)){if(r&&typeof r=="object"&&"base_size"in r)return String(r.base_size);if(r&&typeof r=="object"&&"quote_size"in r)return`$${String(r.quote_size)}`}}function $a(t,e){let r=e.creation_time?Date.parse(e.creation_time):NaN;if(Number.isNaN(r))return 0;for(let n=0;n<t.length;n++){let i=t[n].creation_time?Date.parse(t[n].creation_time):NaN;if(!Number.isNaN(i)&&i<r)return n}return t.length}function xr(t,e,r="live"){let n=t.events;if(!n)return{inserts:[],updates:[]};let i=[],s=[];for(let _ of n){let o=_.orders;if(o)for(let a of o){let E={order_id:String(a.order_id??""),status:String(a.status??""),product_id:String(a.product_id??""),order_side:String(a.order_side??a.side??""),order_type:a.order_type?String(a.order_type):void 0,average_filled_price:String(a.average_filled_price??a.avg_price??"0"),total_fees:String(a.total_fees??"0"),filled_size:String(a.filled_size??a.cumulative_quantity??"0"),base_size:za(a),creation_time:a.creation_time?String(a.creation_time):a.created_time?String(a.created_time):void 0},g=e.events.findIndex(c=>c.order_id===E.order_id);if(g>=0){let c=e.events[g],l=c.status!==E.status||c.filled_size!==E.filled_size||c.total_fees!==E.total_fees||c.average_filled_price!==E.average_filled_price;c.status=E.status,c.average_filled_price=E.average_filled_price,c.filled_size=E.filled_size,c.total_fees=E.total_fees,l&&(Gs(e,E),s.push(c));continue}r==="backfill"?e.events.splice($a(e.events,E),0,E):e.events.unshift(E),e.prependCount++,Gs(e,E),i.push(E),e.events.length>1e4&&e.events.pop()}}return{inserts:i,updates:s}}function Gs(t,e){t.updateCount++,t.lastClock=Z();let r=e.status.toUpperCase();r==="OPEN"||r==="PENDING"?t.openOrders.add(e.order_id):t.openOrders.delete(e.order_id);let n=parseFloat(e.total_fees??"0")||0,i=parseFloat(e.filled_size??"0")||0,s=parseFloat(e.average_filled_price??"0")||0,_=i*s,o=t.accounted.get(e.order_id)??{fees:0,size:0,value:0},a=n-o.fees,E=i-o.size,g=_-o.value;(E!==0||a!==0)&&(o.size===0&&i>0&&t.fillCount++,t.totalFees+=a,e.order_side==="BUY"?(t.netCash-=g,t.positions.set(e.product_id,(t.positions.get(e.product_id)??0)+E)):(t.netCash+=g,t.positions.set(e.product_id,(t.positions.get(e.product_id)??0)-E)),t.accounted.set(e.order_id,{fees:n,size:i,value:_}))}function ja(t,e,r,n,i){let s=e.order_side==="BUY"?"BUY":"SELL",_=Us(s,n,i),o=e.status.toUpperCase(),a=i?K:"",E=parseFloat(e.average_filled_price??"0"),g=parseFloat(e.filled_size??"0");switch(t){case"time":return x(Vs(e.creation_time??new Date().toISOString()),r);case"status":return`${(o==="OPEN"||o==="PENDING")&&i?Ds:""}${x(o,r)}${a}`;case"product":return x(e.product_id,r);case"side":return`${_}${x(s,r)}${a}`;case"size":{let c=g>0?jt(g):e.base_size??"-";return`${_}${F(c,r)}${a}`}case"price":return`${_}${F(E>0?X(E):"-",r)}${a}`;case"fee":{let c=parseFloat(e.total_fees??"0");return F(c>0?X(c):"-",r)}case"id":return`${i?z:""}${x(e.order_id.slice(0,r),r)}${a}`;default:return x("",r)}}function de(t,e,r,n=80){return Ws(n).map(i=>ja(i.key,t,i.width,e,r)).join(" ")}function Qa(t,e=80){let r=new Set(["size","price","fee"]),i=Ws(e).map(s=>r.has(s.key)?F(s.header,s.width):x(s.header,s.width)).join(" ");return t?`${z}${i}${K}`:i}function Xa(t,e,r){let n=t.netCash>=0?r?Ht:"":r?Kt:"",i=r?K:"",s=`Fills:${t.fillCount}`,_=`Open:${t.openOrders.size}`,o=`Fees:${X(t.totalFees)}`,a=`Net:${t.netCash>=0?"+":""}${X(t.netCash)}`,E=`${n}${a}${i}`,c=`${$t(t.heartbeat,r)} ${t.lastClock}`,l=`\xB7 ${t.lastClock}`,p=`${s} ${_} ${o} ${a}`,A=`${s} ${_} ${o} ${E}`,R=new Map;for(let[b,U]of t.positions){if(Math.abs(U)<1e-9)continue;let $=(b.match(/-/g)??[]).length===1?b.slice(0,b.indexOf("-")):b;R.set($,(R.get($)??0)+U)}let N=[],f=[];for(let[b,U]of R){if(Math.abs(U)<1e-9)continue;let V=`${b}:${jt(U)}`;N.push(V),f.push(V)}let M=e-p.length-l.length-6,k="";if(N.length>0&&M>8){let b="",U=0,V=0;for(let $=0;$<N.length;$++){let lt=V>0?" ":"";if(U+lt.length+f[$].length>M){let et=N.length-V;et>0&&(b+=` +${et}`);break}b+=lt+N[$],U+=lt.length+f[$].length,V++}k=b}let q=k?`${A} ${k}`:A;return zt(q,c,e)}function Bs(t,e,r,n,i){let s=i??e.events,_=t.cols,o=t.rows,a=o,E=o-1,g=o-2;n.inserts.forEach((c,l)=>{r.flashWithOffset(c.order_id,e.prependCount-1-l,1500),t.moveTo(Ke,1),t.insertLine(),t.write(de(c,!0,!0,t.cols)+"\x1B[K")});for(let c of n.updates){let l=s.indexOf(c);if(l>=0){let p=Ke+l;p<=g&&(r.flash(c.order_id,1500),t.moveTo(p,1),t.write(de(c,!0,!0,t.cols)+"\x1B[K"))}}for(let c of r.expired()){let l=s.findIndex(p=>p.order_id===c);if(l>=0){let p=Ke+l;p<=g&&(t.moveTo(p,1),t.write(de(s[l],!1,!0,t.cols)+"\x1B[K"))}}t.moveTo(E,1),t.write(At(_,!0)),t.moveTo(a,1),t.write(Xa(e,_-1,!0)+"\x1B[K")}function Br(t){t.enterAltScreen(),t.hideCursor();let e=t.rows;t.setScrollRegion(Ke,e-2),t.moveTo(1,1),t.write(Qa(!0,t.cols)+"\x1B[K"),t.moveTo(2,1),t.write(At(t.cols,!0))}function ws(t){return t?.toLowerCase()}function Ye(t,e,r){return{_ch:"user",_seq:e,_ts:r,order_id:t.order_id,status:ws(t.status),product_id:t.product_id,side:ws(t.order_side),filled_size:t.filled_size??null,price:t.average_filled_price??null,fees:t.total_fees??null}}function Hs(t,e,r){return JSON.stringify(Ye(t,e,r))}var Ke,qa,Ks=S(()=>{"use strict";u();d();ue();Yt();He();Ke=3,qa=[{header:"TIME",width:13,key:"time"},{header:"STATUS",width:10,key:"status"},{header:"PRODUCT",width:10,key:"product"},{header:"SIDE",width:5,key:"side"},{header:"SIZE",width:12,key:"size"},{header:"PRICE",width:12,key:"price"},{header:"FEE",width:8,key:"fee"},{header:"ORDER ID",width:12,key:"id"}]});function Ys(t,e,r,n=8){let i=r-e;if(i<=0)return"\u2500".repeat(n);let s=Math.max(0,Math.min(1,(t-e)/i)),_=Math.round(s*(n-1)),o="";for(let a=0;a<n;a++)o+=a===_?"\u25CF":"\u2500";return o}function qs(t,e,r){if(e<=0||t<=0)return"";let n=Math.max(0,Math.round(t/e*r));return"\u2588".repeat(n)}var Hr=S(()=>{"use strict";u();d()});function js(t){let e=[],r=0;for(let n of tc){if(r+n.width+1>t)break;e.push(n),r+=n.width+1}return e}function Qs(){return{products:new Map,prevPrices:new Map,productOrder:[],heartbeat:!1,updateCount:0,lastClock:Z()}}function Xs(t,e){let r=t.events;if(!r)return[];let n=[];for(let i of r){let s=i.tickers;if(s)for(let _ of s){let o={product_id:String(_.product_id??""),price:String(_.price??"0"),volume_24_h:String(_.volume_24_h??"0"),price_percent_chg_24_h:String(_.price_percent_chg_24_h??"0"),best_bid:String(_.best_bid??"0"),best_bid_quantity:String(_.best_bid_quantity??"0"),best_ask:String(_.best_ask??"0"),best_ask_quantity:String(_.best_ask_quantity??"0"),high_24_h:String(_.high_24_h??"0"),low_24_h:String(_.low_24_h??"0")},a=e.prevPrices.get(o.product_id),E=parseFloat(o.price),g=0;a!==void 0&&(E>a?g=1:E<a&&(g=-1)),e.prevPrices.set(o.product_id,E),e.products.set(o.product_id,o),e.productOrder.includes(o.product_id)||e.productOrder.push(o.product_id),e.updateCount++,e.lastClock=Z(),n.push({ticker:o,direction:g})}}return n}function ec(t,e,r,n,i,s){let _=parseFloat(e.price),o=s?K:"";switch(t){case"symbol":return x(e.product_id,r);case"price":return`${Wr(n,i,s)}${F(X(_),r)}${o}`;case"pct":{let a=parseFloat(e.price_percent_chg_24_h),E=a>0?1:a<0?-1:0;return`${Wr(E,!1,s)}${F(Fs(a),r)}${o}`}case"bid":return F(X(parseFloat(e.best_bid)),r);case"ask":return F(X(parseFloat(e.best_ask)),r);case"bidSz":return`${s?z:""}${F(jt(parseFloat(e.best_bid_quantity)),r)}${o}`;case"askSz":return`${s?z:""}${F(jt(parseFloat(e.best_ask_quantity)),r)}${o}`;case"low":return`${s?z:""}${F(X(parseFloat(e.low_24_h)),r)}${o}`;case"high":return`${s?z:""}${F(X(parseFloat(e.high_24_h)),r)}${o}`;case"range":return x(Ys(_,parseFloat(e.low_24_h),parseFloat(e.high_24_h),r),r);case"vol":return`${s?z:""}${F(ks(parseFloat(e.volume_24_h)),r)}${o}`;default:return x("",r)}}function $s(t,e,r,n,i=80){return js(i).map(_=>ec(_.key,t,_.width,e,r,n)).join(" ")}function rc(t,e=80){let n=js(e).map(i=>i.key==="symbol"||i.key==="range"?x(i.header,i.width):F(i.header,i.width)).join(" ");return t?`${z}${n}${K}`:n}function nc(t,e,r){let n=`${t.products.size} product${t.products.size!==1?"s":""}`,s=`${$t(t.heartbeat,r)} ${t.lastClock}`;return zt(n,s,e)}function Kr(t){t.enterAltScreen(),t.hideCursor(),t.moveTo(Za,1),t.write(rc(!0,t.cols)+"\x1B[K"),t.moveTo(Ja,1),t.write(At(t.cols,!0))}function Zs(t,e,r,n,i){let s=t.cols,_=t.rows,o=_,a=_-1;for(let{ticker:E,direction:g}of n){let c=e.productOrder.indexOf(E.product_id);if(c<0)continue;let l=zs+c;if(l>=a)continue;let p=i?.has(E.product_id)??!1,A=!p&&r.isFlashing(E.product_id);t.moveTo(l,1);let R=$s(E,p?0:g,A,!0,s);t.write((p?z+R+K:R)+"\x1B[K")}for(let E of r.expired()){let g=e.productOrder.indexOf(E);if(g<0)continue;let c=zs+g;if(c>=a)continue;let l=e.products.get(E);l&&(t.moveTo(c,1),t.write($s(l,0,!1,!0,s)+"\x1B[K"))}t.moveTo(a,1),t.write(At(s,!0)),t.moveTo(o,1),t.write(nc(e,s-1,!0)+"\x1B[K")}function Yr(t,e,r){return{_ch:"ticker",_seq:e,_ts:r,product_id:t.product_id,price:t.price,pct_24h:t.price_percent_chg_24_h,bid:t.best_bid,bid_size:t.best_bid_quantity,ask:t.best_ask,ask_size:t.best_ask_quantity,volume:t.volume_24_h,high:t.high_24_h,low:t.low_24_h}}function Js(t,e,r){return JSON.stringify(Yr(t,e,r))}var Za,Ja,zs,tc,t_=S(()=>{"use strict";u();d();ue();Yt();He();Hr();Za=1,Ja=2,zs=3,tc=[{header:"SYMBOL",width:10,key:"symbol"},{header:"PRICE",width:12,key:"price"},{header:"%24h",width:8,key:"pct"},{header:"BID",width:11,key:"bid"},{header:"ASK",width:11,key:"ask"},{header:"LOW",width:11,key:"low"},{header:"RANGE",width:10,key:"range"},{header:"HIGH",width:11,key:"high"},{header:"BIDSZ",width:7,key:"bidSz"},{header:"ASKSZ",width:7,key:"askSz"},{header:"VOL",width:6,key:"vol"}]});function e_(t,e){if(!t)return 0n;if(!ic.test(t))throw new Error(`invalid decimal: ${t}`);let r=t.startsWith("-"),[n,i=""]=(r?t.slice(1):t).split(".");if(i.length>e)throw new Error(`too many decimal places (max ${e}): ${t}`);let s=BigInt(n||"0")*10n**BigInt(e)+BigInt(i.padEnd(e,"0")||"0");return r?-s:s}function qe(t,e){let r=t<0n,n=(r?-t:t).toString().padStart(e+1,"0"),i=n.slice(0,n.length-e),s=n.slice(n.length-e).replace(/0+$/,"");return`${r?"-":""}${i}${s?`.${s}`:""}`}var ic,r_=S(()=>{"use strict";u();d();ic=/^-?(?:\d+(?:\.\d*)?|\.\d+)$/});function i_(t,e=0){return{productId:t,bids:new Map,asks:new Map,heartbeat:!1,updateCount:0,msgCount:0,lastMsgTime:Date.now(),msgRate:0,depth:e,lastClock:Z()}}function s_(t,e){let r=t.events;if(!r)return;e.msgCount++;let n=Date.now(),i=(n-e.lastMsgTime)/1e3;i>=1&&(e.msgRate=Math.round(e.msgCount/i),e.msgCount=0,e.lastMsgTime=n);for(let s of r){let _=s.type,o=s.updates;if(_==="snapshot"&&(e.bids.clear(),e.asks.clear()),!!o){for(let a of o){let E=String(a.side??"").toLowerCase(),g;try{g=e_(String(a.price_level??"0"),ze)}catch{continue}let c=parseFloat(String(a.new_quantity??"0"));if(g<=0n)continue;let l=E==="bid"?e.bids:e.asks;c<=0?l.delete(g):l.set(g,c)}e.updateCount++,e.lastClock=Z()}}}function je(t){let e=[];for(let[r,n]of t.bids)e.push({price:r,size:n});return e.sort((r,n)=>r.price<n.price?1:r.price>n.price?-1:0),e}function Qe(t){let e=[];for(let[r,n]of t.asks)e.push({price:r,size:n});return e.sort((r,n)=>r.price<n.price?-1:r.price>n.price?1:0),e}function $e(t){return Number(qe(t,ze))}function __(t,e){if(t.length===0||e.length===0)return null;let r=t[0].price,n=e[0].price;return{spread:qe(n-r,ze),mid:qe(5n*(n+r),ze+1)}}function n_(t,e,r,n,i,s,_){let o=_?i==="bid"?Ht:Kt:"",a=_?K:"",E=qs(r,n,s),g=`${o}${E}${a}`;return[`${o}${F(X(t),Nt[0])}${a}`,F(e.toFixed(4),Nt[1]),F(r.toFixed(4),Nt[2]),g].join(" ")}function oc(t,e,r){let n=__(je(t),Qe(t)),i=r?z:"",s=r?K:"";if(!n)return`${i}${x(" Waiting for data...",e)}${s}`;let _=Number(n.spread),o=Number(n.mid),a=_/o*100,E=` Spread: ${X(_).padStart(10)} (${a.toFixed(3).padStart(6)}%) Mid: ${X(o).padStart(12)}`;return`${i}${x(E,e)}${s}`}function ac(t,e,r){let n=_c.map((a,E)=>E===3?x(a,Nt[E]):F(a,Nt[E])).join(" "),i=r?z:"",s=r?Bt:"",_=r?K:"",o=`${s}${t.productId}${_}`;return`${x(o,e)}
53
+ ${i}${n}${_}`}function cc(t,e,r){let n=je(t).reduce((g,c)=>g+c.size,0),i=Qe(t).reduce((g,c)=>g+c.size,0),s=i>0?(n/i).toFixed(2):"-",o=`${t.depth?`Depth:${t.depth} `:""}B/A:${s} Rate:${t.msgRate}/s`,E=`${$t(t.heartbeat,r)} ${t.lastClock}`;return zt(o,E,e)}function qr(t,e){t.enterAltScreen(),t.hideCursor(),zr(t,e)}function zr(t,e){let r=t.cols,n=t.rows;if(n<4)return;let i=Nt[0]+Nt[1]+Nt[2]+3,s=Math.max(4,r-i),_=Qe(e),o=je(e),a=n-1,E=n,g=Math.max(0,n-4),c=Math.floor(g/2),l=g>c*2||c>0,p=e.depth?Math.min(c,e.depth):c,A=_.slice(0,p),R=o.slice(0,p),N=0,f=[];for(let U of A)N+=U.size,f.push(N);let M=0,k=[];for(let U of R)M+=U.size,k.push(M);let q=Math.max(N,M),b=1;t.moveTo(b,1),t.write(ac(e,r,!0)+"\x1B[K"),b=sc;for(let U=0;U<p&&b<a;U++,b++)if(t.moveTo(b,1),U<A.length){let V=A.length-1-U;t.write(n_($e(A[V].price),A[V].size,f[V],q,"ask",s,!0)+"\x1B[K")}else t.clearLine();l&&b<a&&(t.moveTo(b,1),t.write(oc(e,r,!0)+"\x1B[K"),b++);for(let U=0;U<p&&b<a;U++,b++)t.moveTo(b,1),U<R.length?t.write(n_($e(R[U].price),R[U].size,k[U],q,"bid",s,!0)+"\x1B[K"):t.clearLine();for(;b<a;)t.moveTo(b,1),t.clearLine(),b++;t.moveTo(a,1),t.write(At(r,!0)),t.moveTo(E,1),t.write(cc(e,r-1,!0)+"\x1B[K")}function $r(t,e,r){let n=je(t),i=Qe(t),s=__(n,i);return{_ch:"level2",_seq:e,_ts:r,product_id:t.productId,spread:s?s.spread:null,mid:s?s.mid:null,bids:n.map(_=>({price:$e(_.price),size:_.size})),asks:i.map(_=>({price:$e(_.price),size:_.size}))}}function o_(t,e,r){return JSON.stringify($r(t,e,r))}var sc,Nt,_c,ze,a_=S(()=>{"use strict";u();d();ue();Yt();He();Hr();r_();sc=3,Nt=[14,12,12,16],_c=["PRICE","SIZE","TOTAL","DEPTH"],ze=12});function c_(t,e,r,n,i){return new jr(t,e,r,n,i)}function E_(t,e,r){return new Qr(t,e,r)}function u_(t,e,r,n){return new Xr(t,e,r,n)}var jr,Qr,Xr,d_=S(()=>{"use strict";u();d();we();wr();Ms();vs();ue();Ks();t_();a_();be();jr=class{productIds=[];screen;refreshJWT;state=xs();flash=new Ee;queryFilter;context;jwt;until;liveness=!1;connected=!1;constructor(e,r,n,i,s){this.context=r,this.jwt=n,this.until=s,this.queryFilter=e.flags.query,e.isTTY&&!e.untilActive&&(this.screen=new qt(e.out),Br(this.screen),this.screen.onResize(()=>{Br(this.screen),this.repaintFrame()})),i.requiresAuth&&(this.refreshJWT=()=>this.freshJWT())}freshJWT(){let e=this.context.env;return e?.auth?.key_id&&e?.auth?.key_secret?xe(e.auth.key_id,e.auth.key_secret):this.jwt}matchesFilter(e){let r=this.queryFilter;return r?!(r.status&&e.status.toUpperCase()!==String(r.status).toUpperCase()||r.product_ids&&!String(r.product_ids).split(",").includes(e.product_id)||r.side&&e.order_side.toUpperCase()!==String(r.side).toUpperCase()):!0}visibleEvents(){return this.queryFilter?this.state.events.filter(e=>this.matchesFilter(e)):void 0}syncHeartbeat(){this.state.heartbeat=this.connected&&this.liveness}render(e){this.screen&&(this.syncHeartbeat(),Bs(this.screen,this.state,this.flash,e,this.visibleEvents()))}repaintFrame(){if(!this.screen)return;let e=this.queryFilter?this.state.events.filter(i=>this.matchesFilter(i)):this.state.events,r=this.screen.rows-4,n=Math.min(e.length,r);for(let i=n-1;i>=0;i--)this.screen.moveTo(3+i,1),this.screen.write(de(e[i],!1,!0,this.screen.cols)+"\x1B[K");for(let i=n;i<r;i++)this.screen.moveTo(3+i,1),this.screen.write("\x1B[K");this.render({inserts:[],updates:[]})}onData(e,r,n){let i=this.queryFilter?this.visibleEvents().map(a=>a.order_id):void 0,s=xr(e,this.state);this.liveness=!this.liveness;let _={inserts:s.inserts.filter(a=>this.matchesFilter(a)),updates:s.updates.filter(a=>this.matchesFilter(a))};if(i){let a=this.visibleEvents().map(g=>g.order_id);a.length!==i.length||a.some((g,c)=>g!==i[c])?this.repaintFrame():this.render(_)}else this.render(_);return[..._.inserts,..._.updates].map(a=>({obj:Ye(a,r,n),line:Hs(a,r,n)}))}onHeartbeat(){this.liveness=!this.liveness,this.state.lastClock=Z(),this.render({inserts:[],updates:[]})}onConnState(e){this.connected=e===H.SUBSCRIBED,this.repaintFrame()}onGap(){this.backfill().catch(()=>{})}onReconnected(){this.backfill().catch(()=>{})}setup(){return this.backfill()}cleanup(){this.screen?.cleanup()}async backfill(){try{let e=await Wt("orders_list",{query:{limit:100,...this.queryFilter}},this.context);if(e.status<400&&e.data?.orders){let r=e.data.orders;for(let n of r.reverse()){let s=xr({events:[{orders:[n]}]},this.state,"backfill");if(this.until.active)for(let _ of[...s.inserts,...s.updates]){let o=String(n.created_time??new Date().toISOString());if(this.until.check(Ye(_,0,o)))return}}}}catch{}this.repaintFrame()}};Qr=class{productIds;screen;state=Qs();flash=new Ee;until;liveness=!1;connected=!1;constructor(e,r,n){this.until=n,this.productIds=r,e.isTTY&&!e.untilActive&&(this.screen=new qt(e.out),Kr(this.screen),this.screen.onResize(()=>{Kr(this.screen),this.repaintFrame()}))}syncHeartbeat(){this.state.heartbeat=this.connected&&this.liveness}render(e){this.screen&&(this.syncHeartbeat(),Zs(this.screen,this.state,this.flash,e,this.until.active?this.until.stale:void 0))}repaintFrame(){if(!this.screen)return;let e=this.state.productOrder.map(r=>this.state.products.get(r)).filter(r=>!!r).map(r=>({ticker:r,direction:0}));this.render(e)}onData(e,r,n){let i=Xs(e,this.state);this.liveness=!this.liveness;for(let{ticker:s}of i)this.flash.flash(s.product_id,600);return this.render(i),i.map(({ticker:s})=>({obj:Yr(s,r,n),line:Js(s,r,n)}))}onHeartbeat(){this.liveness=!this.liveness,this.state.lastClock=Z(),this.render([])}onConnState(e){this.connected=e===H.SUBSCRIBED,this.render([])}onGap(){}onReconnected(){}async setup(){}cleanup(){this.screen?.cleanup()}};Xr=class{productIds;screen;state;productId;liveness=!1;connected=!1;constructor(e,r,n,i){this.productId=r,this.productIds=[r],this.state=i_(r,e.flags.depth??0),e.isTTY&&!e.untilActive&&(this.screen=new qt(e.out),qr(this.screen,this.state),this.screen.onResize(()=>{qr(this.screen,this.state),this.render()}))}syncHeartbeat(){this.state.heartbeat=this.connected&&this.liveness}render(){this.screen&&(this.syncHeartbeat(),zr(this.screen,this.state))}onData(e,r,n){return s_(e,this.state),this.liveness=!this.liveness,this.render(),[{obj:$r(this.state,r,n),line:o_(this.state,r,n)}]}onHeartbeat(){this.liveness=!this.liveness,this.state.lastClock=Z(),this.render()}onConnState(e){this.connected=e===H.SUBSCRIBED,this.render()}onGap(){return this.state.bids.clear(),this.state.asks.clear(),this.render(),{resubscribe:[this.productId]}}onReconnected(){}async setup(){}cleanup(){this.screen?.cleanup()}}});var g_={};Zt(g_,{applyJQ:()=>Zr});import{execFileSync as Ec}from"node:child_process";function Zr(t,e){try{return Ec("jq",["-r",e],{input:t,encoding:"utf8",maxBuffer:10*1024*1024,env:dr()}).trimEnd()}catch(r){if(r.code==="ENOENT")throw new Error("jq is not installed. Install it: https://jqlang.github.io/jq/download/");let n=(r.stderr??r.message??"").toString().trim();throw new Error(`jq: ${n}`)}}var Jr=S(()=>{"use strict";u();d();it()});var tn={};Zt(tn,{UntilController:()=>Qt,__test:()=>pc,startWatch:()=>Ic,surfaceForChannel:()=>St});function dc(t){return uc.find(e=>e.id===t)}function St(t){switch(t.name){case"user":return"blotter";case"ticker":return"watchlist";case"level2":return"ladder";default:return null}}async function lc(t,e){if(!e.requiresAuth)return;let n=t.env?.auth;if(!n)throw new Error("WebSocket channel requires authentication. Run: coinbase env <name> --key-file key.json");if(n.type==="oauth")throw new Error(`The --watch blotter requires CDP API key auth (WebSocket does not support OAuth).
54
+ Set up a CDP key: coinbase env <name> --key-file key.json`);if(n.type==="cdp_key"&&n.key_id&&n.key_secret)return xe(n.key_id,n.key_secret);throw new Error("Unsupported auth type for WebSocket")}async function Ic(t,e,r,n){let i=ot(t);if(!i)throw new Error(`--watch is not supported for "${t.replace(/_/g," ")}"`);let s=St(i);if(!s)throw new Error(`--watch is not yet implemented for channel "${i.name}"`);if(n.until){let a;try{a=Vr(n.until)}catch(c){throw new Error(`Invalid --until predicate: ${c.message}`)}let E=dc(t);if(E?.watchFields){let c=Ns(a,E.watchFields);if(c.length>0){let l=Object.keys(E.watchFields).join(", ");throw new Error(c.map(p=>p.message).join(`
55
55
  `)+`
56
56
  Available fields: ${l}`)}}let g=ae(a);if(g.length>0&&e.length>0){let c=g.filter(l=>!e.includes(l));if(c.length>0)throw new Error(`Predicate references product${c.length>1?"s":""} not in watch: ${c.join(", ")}
57
- Watching: ${e.join(", ")}`)}}let _=await uc(r,i),o=!!process.stdout.isTTY;await Ic(n),s==="blotter"?await l_(i,_,r,n,o):s==="watchlist"?await I_(i,e,_,n,o):s==="ladder"&&await p_(i,e,_,n,o)}async function tr(t,e,r,n,i,s){let _=n.start();await i.setup();let o=0,a;a=new Be({channel:t,WebSocketClass:s,onEvent:g=>{let c=g;o=c.sequence_num??o;let l=String(c.timestamp??new Date().toISOString()),p=i.onData(c,o,l);if(p.length!==0){if(!i.screen&&!n.active)for(let A of p)R_(A.line,r);if(n.active){for(let A of p)if(n.check(A.obj))return}}},onHeartbeat:()=>i.onHeartbeat(),onSequenceGap:()=>{let g=i.onGap();g&&(a.unsubscribe(g.resubscribe),a.subscribe(g.resubscribe,i.refreshJWT?i.refreshJWT():e))},onError:i.screen?void 0:g=>process.stderr.write(`ws error: ${g}
58
- `),onStateChange:g=>{g===K.FAILED&&n.onFailed(),i.onConnState(g)},onDisconnect:()=>n.onDisconnect(),onReconnect:()=>n.onReconnect(),onReconnected:()=>i.onReconnected(),refreshJWT:i.refreshJWT}),a.connect(),a.subscribe(i.productIds,e);let E=await lc(_,i.screen);a.close(),T_(E,i,r,n),E===null&&process.exit(process.exitCode??0)}async function l_(t,e,r,n,i,s,_){let o=new Qt(n),a=a_({isTTY:i,untilActive:o.active,flags:n,out:s?.out},r,e,t,o);await tr(t,e,n,o,a,_)}async function I_(t,e,r,n,i,s,_){if(e.length===0)throw new Error("--watch requires at least one product_id (e.g. BTC-USD)");let o=new Qt(n),a=c_({isTTY:i,untilActive:o.active,flags:n,out:s?.out},e,o);await tr(t,r,n,o,a,_)}async function p_(t,e,r,n,i,s,_){if(e.length===0)throw new Error("--watch requires a product_id (e.g. BTC-USD)");if(e.length>1)throw new Error("--watch book supports a single product_id; got: "+e.join(", "));let o=e[0],a=new Qt(n),E=E_({isTTY:i,untilActive:a.active,flags:n,out:s?.out},o,r,a);await tr(t,r,n,a,E,_)}function lc(t,e){return new Promise(r=>{let n=()=>{},i=s=>{n(),r(s)};if(e)e.installSignalHandlers(()=>i(null));else{let s=()=>i(null),_=()=>i(null);n=()=>{process.off("SIGINT",s),process.off("SIGTERM",_)},process.on("SIGINT",s),process.on("SIGTERM",_)}t.then(i)})}function T_(t,e,r,n){if(e.cleanup(),n?.cleanup(),!!t)switch(t.type){case"matched":R_(JSON.stringify(t.event),r??{}),process.exitCode=0;break;case"timeout":process.stderr.write(`error: --until timed out
57
+ Watching: ${e.join(", ")}`)}}let _=await lc(r,i),o=!!process.stdout.isTTY;await Rc(n),s==="blotter"?await I_(i,_,r,n,o):s==="watchlist"?await p_(i,e,_,n,o):s==="ladder"&&await T_(i,e,_,n,o)}async function Ze(t,e,r,n,i,s){let _=n.start();await i.setup();let o=0,a;a=new We({channel:t,WebSocketClass:s,onEvent:g=>{let c=g;o=c.sequence_num??o;let l=String(c.timestamp??new Date().toISOString()),p=i.onData(c,o,l);if(p.length!==0){if(!i.screen&&!n.active)for(let A of p)O_(A.line,r);if(n.active){for(let A of p)if(n.check(A.obj))return}}},onHeartbeat:()=>i.onHeartbeat(),onSequenceGap:()=>{let g=i.onGap();g&&(a.unsubscribe(g.resubscribe),a.subscribe(g.resubscribe,i.refreshJWT?i.refreshJWT():e))},onError:i.screen?void 0:g=>process.stderr.write(`ws error: ${g}
58
+ `),onStateChange:g=>{g===H.FAILED&&n.onFailed(),i.onConnState(g)},onDisconnect:()=>n.onDisconnect(),onReconnect:()=>n.onReconnect(),onReconnected:()=>i.onReconnected(),refreshJWT:i.refreshJWT}),a.connect(),a.subscribe(i.productIds,e);let E=await Tc(_,i.screen);a.close(),R_(E,i,r,n),E===null&&process.exit(process.exitCode??0)}async function I_(t,e,r,n,i,s,_){let o=new Qt(n),a=c_({isTTY:i,untilActive:o.active,flags:n,out:s?.out},r,e,t,o);await Ze(t,e,n,o,a,_)}async function p_(t,e,r,n,i,s,_){if(e.length===0)throw new Error("--watch requires at least one product_id (e.g. BTC-USD)");let o=new Qt(n),a=E_({isTTY:i,untilActive:o.active,flags:n,out:s?.out},e,o);await Ze(t,r,n,o,a,_)}async function T_(t,e,r,n,i,s,_){if(e.length===0)throw new Error("--watch requires a product_id (e.g. BTC-USD)");if(e.length>1)throw new Error("--watch book supports a single product_id; got: "+e.join(", "));let o=e[0],a=new Qt(n),E=u_({isTTY:i,untilActive:a.active,flags:n,out:s?.out},o,r,a);await Ze(t,r,n,a,E,_)}function Tc(t,e){return new Promise(r=>{let n=()=>{},i=s=>{n(),r(s)};if(e)e.installSignalHandlers(()=>i(null));else{let s=()=>i(null),_=()=>i(null);n=()=>{process.off("SIGINT",s),process.off("SIGTERM",_)},process.on("SIGINT",s),process.on("SIGTERM",_)}t.then(i)})}function R_(t,e,r,n){if(e.cleanup(),n?.cleanup(),!!t)switch(t.type){case"matched":O_(JSON.stringify(t.event),r??{}),process.exitCode=0;break;case"timeout":process.stderr.write(`error: --until timed out
59
59
  `),process.exitCode=124;break;case"failed":process.stderr.write(`error: WebSocket connection failed permanently
60
60
  `),process.exitCode=2;break;case"disconnect_budget_exceeded":process.stderr.write(`error: cumulative disconnection exceeded ${Math.round(t.totalMs/1e3)}s
61
- `),process.exitCode=2;break}}function R_(t,e){if(e.jq)try{let{applyJQ:r}=Je,n=r(new TextEncoder().encode(t),e.jq);process.stdout.write(n+`
61
+ `),process.exitCode=2;break}}function O_(t,e){if(e.jq)try{let{applyJQ:r}=Xe,n=r(new TextEncoder().encode(t),e.jq);process.stdout.write(n+`
62
62
  `)}catch(r){process.stderr.write(`jq error: ${r.message??r}
63
63
  `)}else process.stdout.write(t+`
64
- `)}async function Ic(t){if(t.jq&&!Je){Je=await Promise.resolve().then(()=>(Jr(),d_));try{let{applyJQ:e}=Je;e(new TextEncoder().encode("{}"),t.jq)}catch(e){throw new Error(`Invalid --jq expression: ${e.message??e}`)}}}var ac,Ec,g_,Qt,gc,Je,ge=S(()=>{"use strict";u();d();ce();Cs();xe();wr();Ps();Gr();ft();u_();ac=[...X.flatMap(t=>t.actions),...Object.values(Z)];Ec=300*1e3,g_=3e4,Qt=class{predicate;timeoutMs;timeoutTimer=null;disconnectStart=null;cumulativeDisconnectMs=0;resolve=null;settled=!1;signals;requiredProducts;reportedStale=new Set;constructor(e,r){this.predicate=e.until?Vr(e.until):null,this.timeoutMs=e.untilTimeout?e.untilTimeout*1e3:null,this.requiredProducts=this.predicate?[...new Set(ae(this.predicate))]:[],this.signals=r??new Ke}get active(){return this.predicate!==null}get stale(){return this.signals.staleProducts(this.requiredProducts,g_)}start(){return new Promise(e=>{this.resolve=e,this.active&&this.timeoutMs!==null&&(this.timeoutTimer=setTimeout(()=>{this.settle({type:"timeout"})},this.timeoutMs))})}check(e){if(!this.predicate||this.settled)return!1;let r=e.product_id;r&&(this.signals.update(r,e),this.reportedStale.delete(r)&&process.stderr.write(`notice: ${r} recovered
65
- `));for(let n of this.requiredProducts)if(this.signals.hasSeen(n)&&this.signals.isStale(n,g_))return this.reportedStale.has(n)||(this.reportedStale.add(n),process.stderr.write(`warning: ${n} stale (no update for ${Math.round(this.signals.age(n)/1e3)}s)
66
- `)),!1;return xt(this.predicate,e,this.signals.all())?(this.settle({type:"matched",event:e}),!0):!1}onDisconnect(){!this.active||this.settled||(this.disconnectStart=Date.now())}onReconnect(){!this.active||this.settled||(this.disconnectStart!==null&&(this.cumulativeDisconnectMs+=Date.now()-this.disconnectStart,this.disconnectStart=null),this.cumulativeDisconnectMs>Ec&&this.settle({type:"disconnect_budget_exceeded",totalMs:this.cumulativeDisconnectMs}))}onFailed(){this.settled||this.settle({type:"failed"})}cleanup(){this.timeoutTimer&&(clearTimeout(this.timeoutTimer),this.timeoutTimer=null)}settle(e){this.settled||(this.settled=!0,this.cleanup(),this.resolve?.(e))}};gc={runSurface:tr,runBlotter:l_,runWatchlist:I_,runLadder:p_,handleResult:T_};Je=null});var er={};Zt(er,{bodyBytes:()=>Cc,hasBody:()=>Sc,isFieldArg:()=>fc,parseFields:()=>Ac,setNested:()=>nn});import{readFileSync as pc,openSync as Tc,readSync as Rc,closeSync as Oc}from"node:fs";function Ac(t,e=mc){let r={body:{},query:new URLSearchParams,headers:{},rawBody:null};for(let n of t)if(n==="-")r.rawBody=e.readStdin();else if(n.startsWith("@"))r.rawBody=e.readFile(n.slice(1));else if(Nc(n)){let i=n.indexOf(":");r.headers[n.slice(0,i)]=n.slice(i+1).trim()}else{let i=n.indexOf("=");if(i<=0)throw new Error(`unrecognized argument: ${n} (use key=value, key:=json, key==query, or Header:value)`);if(n[i-1]===":"){let s=n.slice(0,i-1);try{nn(r.body,s,JSON.parse(n.slice(i+1)))}catch(_){throw new Error(`invalid JSON in ${s}: ${_.message}`)}}else n[i+1]==="="?r.query.append(n.slice(0,i),n.slice(i+2)):nn(r.body,n.slice(0,i),n.slice(i+1))}return r}function Nc(t){let e=t.indexOf(":");return e<=0||t.slice(0,e).includes("=")?!1:t[0]>="A"&&t[0]<="Z"}function Sc(t){return Object.keys(t.body).length>0||t.rawBody!==null}function Cc(t){return t.rawBody?t.rawBody:Object.keys(t.body).length===0?null:new TextEncoder().encode(JSON.stringify(t.body))}function fc(t){return!!(t.includes("=")||t.startsWith("@")||t.startsWith("-")||t.indexOf(":")>0&&t[0]>="A"&&t[0]<="Z")}function nn(t,e,r){let n=e.split("."),i=t;for(let s=0;s<n.length;s++){let _=n[s];if(Pc.has(_))throw new Error(`invalid field name: ${_}`);if(s===n.length-1){Object.defineProperty(i,_,{value:r,writable:!0,enumerable:!0,configurable:!0});return}(!Object.hasOwn(i,_)||typeof i[_]!="object"||i[_]===null)&&Object.defineProperty(i,_,{value:{},writable:!0,enumerable:!0,configurable:!0}),i=i[_]}}var mc,Pc,rr=S(()=>{"use strict";u();d();mc={readFile(t){try{return pc(t)}catch(e){throw new Error(`reading file ${t}: ${e.message}`)}},readStdin(){let t=[],e=Buffer.alloc(65536),r;try{r=Tc("/dev/stdin","r")}catch{throw new Error("reading stdin: cannot open")}try{let n;for(;(n=Rc(r,e))>0;)t.push(Buffer.from(e.subarray(0,n)))}catch{}return Oc(r),Buffer.concat(t)}};Pc=new Set(["__proto__","constructor","prototype"])});var S_={};Zt(S_,{outputResult:()=>Dc});function Dc(t,e){let r=JSON.stringify(t.data),n=t.status>=400;if(e)try{process.stdout.write(Zr(new TextEncoder().encode(r),e)+`
64
+ `)}async function Rc(t){if(t.jq&&!Xe){Xe=await Promise.resolve().then(()=>(Jr(),g_));try{let{applyJQ:e}=Xe;e(new TextEncoder().encode("{}"),t.jq)}catch(e){throw new Error(`Invalid --jq expression: ${e.message??e}`)}}}var uc,gc,l_,Qt,pc,Xe,ge=S(()=>{"use strict";u();d();ce();Ps();we();wr();fs();Gr();Rt();d_();uc=[...j.flatMap(t=>t.actions),...Object.values(Q)];gc=300*1e3,l_=3e4,Qt=class{predicate;timeoutMs;timeoutTimer=null;disconnectStart=null;cumulativeDisconnectMs=0;resolve=null;settled=!1;signals;requiredProducts;reportedStale=new Set;constructor(e,r){this.predicate=e.until?Vr(e.until):null,this.timeoutMs=e.untilTimeout?e.untilTimeout*1e3:null,this.requiredProducts=this.predicate?[...new Set(ae(this.predicate))]:[],this.signals=r??new Be}get active(){return this.predicate!==null}get stale(){return this.signals.staleProducts(this.requiredProducts,l_)}start(){return new Promise(e=>{this.resolve=e,this.active&&this.timeoutMs!==null&&(this.timeoutTimer=setTimeout(()=>{this.settle({type:"timeout"})},this.timeoutMs))})}check(e){if(!this.predicate||this.settled)return!1;let r=e.product_id;r&&(this.signals.update(r,e),this.reportedStale.delete(r)&&process.stderr.write(`notice: ${r} recovered
65
+ `));for(let n of this.requiredProducts)if(this.signals.hasSeen(n)&&this.signals.isStale(n,l_))return this.reportedStale.has(n)||(this.reportedStale.add(n),process.stderr.write(`warning: ${n} stale (no update for ${Math.round(this.signals.age(n)/1e3)}s)
66
+ `)),!1;return xt(this.predicate,e,this.signals.all())?(this.settle({type:"matched",event:e}),!0):!1}onDisconnect(){!this.active||this.settled||(this.disconnectStart=Date.now())}onReconnect(){!this.active||this.settled||(this.disconnectStart!==null&&(this.cumulativeDisconnectMs+=Date.now()-this.disconnectStart,this.disconnectStart=null),this.cumulativeDisconnectMs>gc&&this.settle({type:"disconnect_budget_exceeded",totalMs:this.cumulativeDisconnectMs}))}onFailed(){this.settled||this.settle({type:"failed"})}cleanup(){this.timeoutTimer&&(clearTimeout(this.timeoutTimer),this.timeoutTimer=null)}settle(e){this.settled||(this.settled=!0,this.cleanup(),this.resolve?.(e))}};pc={runSurface:Ze,runBlotter:I_,runWatchlist:p_,runLadder:T_,handleResult:R_};Xe=null});var Je={};Zt(Je,{bodyBytes:()=>Dc,hasBody:()=>fc,isFieldArg:()=>bc,parseFields:()=>Cc,setNested:()=>nn});import{readFileSync as Oc,openSync as mc,readSync as Ac,closeSync as Nc}from"node:fs";function Cc(t,e=Sc){let r={body:{},query:new URLSearchParams,headers:{},rawBody:null};for(let n of t)if(n==="-")r.rawBody=e.readStdin();else if(n.startsWith("@"))r.rawBody=e.readFile(n.slice(1));else if(Pc(n)){let i=n.indexOf(":");r.headers[n.slice(0,i)]=n.slice(i+1).trim()}else{let i=n.indexOf("=");if(i<=0)throw new Error(`unrecognized argument: ${n} (use key=value, key:=json, key==query, or Header:value)`);if(n[i-1]===":"){let s=n.slice(0,i-1);try{nn(r.body,s,JSON.parse(n.slice(i+1)))}catch(_){throw new Error(`invalid JSON in ${s}: ${_.message}`)}}else n[i+1]==="="?r.query.append(n.slice(0,i),n.slice(i+2)):nn(r.body,n.slice(0,i),n.slice(i+1))}return r}function Pc(t){let e=t.indexOf(":");return e<=0||t.slice(0,e).includes("=")?!1:t[0]>="A"&&t[0]<="Z"}function fc(t){return Object.keys(t.body).length>0||t.rawBody!==null}function Dc(t){return t.rawBody?t.rawBody:Object.keys(t.body).length===0?null:new TextEncoder().encode(JSON.stringify(t.body))}function bc(t){return!!(t.includes("=")||t.startsWith("@")||t.startsWith("-")||t.indexOf(":")>0&&t[0]>="A"&&t[0]<="Z")}function nn(t,e,r){let n=e.split("."),i=t;for(let s=0;s<n.length;s++){let _=n[s];if(yc.has(_))throw new Error(`invalid field name: ${_}`);if(s===n.length-1){Object.defineProperty(i,_,{value:r,writable:!0,enumerable:!0,configurable:!0});return}(!Object.hasOwn(i,_)||typeof i[_]!="object"||i[_]===null)&&Object.defineProperty(i,_,{value:{},writable:!0,enumerable:!0,configurable:!0}),i=i[_]}}var Sc,yc,tr=S(()=>{"use strict";u();d();Sc={readFile(t){try{return Oc(t)}catch(e){throw new Error(`reading file ${t}: ${e.message}`)}},readStdin(){let t=[],e=Buffer.alloc(65536),r;try{r=mc("/dev/stdin","r")}catch{throw new Error("reading stdin: cannot open")}try{let n;for(;(n=Ac(r,e))>0;)t.push(Buffer.from(e.subarray(0,n)))}catch{}return Nc(r),Buffer.concat(t)}};yc=new Set(["__proto__","constructor","prototype"])});var C_={};Zt(C_,{outputResult:()=>Lc});function Lc(t,e){let r=JSON.stringify(t.data),n=t.status>=400;if(e)try{process.stdout.write(Zr(new TextEncoder().encode(r),e)+`
67
67
  `)}catch(i){process.stdout.write(r+`
68
68
  `),process.stderr.write(`jq error: ${i.message}
69
69
  `)}else n&&process.stdout.isTTY||(process.stdout.isTTY?process.stdout.write(JSON.stringify(t.data,null,2)+`
70
70
  `):process.stdout.write(r+`
71
71
  `));if(n){let i=t.data?.message||t.data?.errorMessage||r.slice(0,200),s=t.data?.hint,_=t.data?.correlationId,o=t.headers?.get("trace-id"),a=[o?`trace ${o}`:"",_?`correlation ${_}`:""].filter(Boolean).join(", ");throw new Error(`${i} (HTTP ${t.status})${a?` [${a}]`:""}${s?`
72
- Hint: ${s}`:""}`)}}var C_=S(()=>{"use strict";u();d();Jr()});u();d();u();d();it();_r();import{createInterface as Rr}from"node:readline/promises";import{readFileSync as Q_}from"node:fs";function Vt(t,e={}){dr(()=>{let r=tt();t(r),ut(r,{allowPlaintext:e.allowPlaintext})})}function X_(t){let e=[];if(t.keyFile&&e.push("key-file"),(t.keyId||t.keySecret)&&e.push("key-id/--key-secret"),t.status&&e.push("status"),t.remove&&e.push("remove"),e.length>1)throw new Error(`--${e.join(", --")} are mutually exclusive on \`coinbase env\`. Pick one.`)}function Tr(t,e){if(!e&&!An())throw new Error(`OS keychain unavailable; refusing to persist secrets for "${t}".
73
- Re-run with --allow-plaintext-secrets to write secrets to ${st()} (file is mode 0600), or install/unlock your OS keychain (macOS Keychain, libsecret on Linux, Windows Credential Manager).`)}async function hn(t,e){X_(e);let r=tt();if(t.length===0){let c=[...new Set([...Object.keys(r.environments),...Object.keys(rt)])].sort();if(c.length===0){process.stderr.write(`No environments configured. Run: coinbase env <name>
74
- `);return}let l=Math.max(14,...c.map(T=>T.length)),p=45,A=T=>(T.length>p?T.slice(0,p-3)+"...":T).padEnd(p);process.stdout.write(`${"Environment".padEnd(l)} ${"Brokerage API".padEnd(p)} ${"Agent API".padEnd(p)} Key
75
- `);for(let T of c){let N=r.environments[T]??{},f=nt(N,T),M=Rt(N,T),v=te(N),Q=v?.type==="cdp_key"?v.key_id:"(no key)",y=Q.length>60?Q.slice(0,57)+"...":Q;process.stdout.write(`${T===r.env?"* ":" "}${T.padEnd(l)} ${A(f||"\u2014")} ${A(M||"\u2014")} ${y}
76
- `)}return}let n=t[0];if(e.remove){Vt(c=>{delete c.environments[n],c.env===n&&(c.env="")}),ur(n),process.stderr.write(`Removed ${n}.
77
- `);return}let i=r.environments[n]??{};if(e.status){to(n,i);return}let s=(c,l)=>{i.auth={type:"cdp_key",key_id:c,key_secret:l}},_=()=>{e.url&&(i.url=e.url,fe(e.url)||process.stderr.write(`warning: custom brokerage URL does not match a known endpoint
78
- `)),e.brokerageApiUrl&&(i.endpoints={...i.endpoints,brokerageApi:e.brokerageApiUrl}),e.agentApiUrl&&(i.endpoints={...i.endpoints,agentApi:e.agentApiUrl})};if(e.keyFile){Tr(n,!!e.allowPlaintextSecrets);let c=eo(e.keyFile);s(c.keyId,c.keySecret),_(),Vt(l=>{l.environments[n]=i,l.env=n},{allowPlaintext:e.allowPlaintextSecrets}),process.stderr.write(`Loaded key from ${e.keyFile}. Switched to ${n}.
79
- `);return}if(e.keyId||e.keySecret||e.url||e.brokerageApiUrl||e.agentApiUrl){let c=te(i),l=c?.type==="cdp_key"?c.key_id:"",p=c?.type==="cdp_key"?c.key_secret:"";(e.keyId||e.keySecret)&&(Tr(n,!!e.allowPlaintextSecrets),s(e.keyId??l,e.keySecret??p)),_(),Vt(A=>{A.environments[n]=i,A.env=n},{allowPlaintext:e.allowPlaintextSecrets}),process.stderr.write(`Saved and switched to ${n}.
72
+ Hint: ${s}`:""}`)}}var P_=S(()=>{"use strict";u();d();Jr()});u();d();u();d();it();ir();import{createInterface as pr}from"node:readline/promises";import{readFileSync as X_}from"node:fs";function Vt(t,e={}){Er(()=>{let r=J();t(r),Et(r,{allowPlaintext:e.allowPlaintext})})}function Z_(t){let e=[];if(t.keyFile&&e.push("key-file"),(t.keyId||t.keySecret)&&e.push("key-id/--key-secret"),t.status&&e.push("status"),t.remove&&e.push("remove"),e.length>1)throw new Error(`--${e.join(", --")} are mutually exclusive on \`coinbase env\`. Pick one.`)}function Ir(t,e){if(!e&&!Nn())throw new Error(`OS keychain unavailable; refusing to persist secrets for "${t}".
73
+ Re-run with --allow-plaintext-secrets to write secrets to ${st()} (file is mode 0600), or install/unlock your OS keychain (macOS Keychain, libsecret on Linux, Windows Credential Manager).`)}async function Un(t,e){Z_(e);let r=J();if(t.length===0){let c=[...new Set([...Object.keys(r.environments),...Object.keys(rt)])].sort();if(c.length===0){process.stderr.write(`No environments configured. Run: coinbase env <name>
74
+ `);return}let l=Math.max(14,...c.map(R=>R.length)),p=45,A=R=>(R.length>p?R.slice(0,p-3)+"...":R).padEnd(p);process.stdout.write(`${"Environment".padEnd(l)} ${"Brokerage API".padEnd(p)} ${"Agent API".padEnd(p)} Key
75
+ `);for(let R of c){let N=r.environments[R]??{},f=nt(N,R),M=Tt(N,R),k=te(N),q=k?.type==="cdp_key"?k.key_id:"(no key)",b=q.length>60?q.slice(0,57)+"...":q;process.stdout.write(`${R===r.env?"* ":" "}${R.padEnd(l)} ${A(f||"\u2014")} ${A(M||"\u2014")} ${b}
76
+ `)}return}let n=t[0];if(e.remove){Vt(c=>{delete c.environments[n],c.env===n&&(c.env="")}),cr(n),process.stderr.write(`Removed ${n}.
77
+ `);return}let i=r.environments[n]??{};if(e.status){eo(n,i);return}let s=(c,l)=>{i.auth={type:"cdp_key",key_id:c,key_secret:l}},_=()=>{e.url&&(i.url=e.url,fe(e.url)||process.stderr.write(`warning: custom brokerage URL does not match a known endpoint
78
+ `)),e.brokerageApiUrl&&(i.endpoints={...i.endpoints,brokerageApi:e.brokerageApiUrl}),e.agentApiUrl&&(i.endpoints={...i.endpoints,agentApi:e.agentApiUrl})};if(e.keyFile){Ir(n,!!e.allowPlaintextSecrets);let c=ro(e.keyFile);s(c.keyId,c.keySecret),_(),Vt(l=>{l.environments[n]=i,l.env=n},{allowPlaintext:e.allowPlaintextSecrets}),process.stderr.write(`Loaded key from ${e.keyFile}. Switched to ${n}.
79
+ `);return}if(e.keyId||e.keySecret||e.url||e.brokerageApiUrl||e.agentApiUrl){let c=te(i),l=c?.type==="cdp_key"?c.key_id:"",p=c?.type==="cdp_key"?c.key_secret:"";(e.keyId||e.keySecret)&&(Ir(n,!!e.allowPlaintextSecrets),s(e.keyId??l,e.keySecret??p)),_(),Vt(A=>{A.environments[n]=i,A.env=n},{allowPlaintext:e.allowPlaintextSecrets}),process.stderr.write(`Saved and switched to ${n}.
80
80
  `);return}if(te(i)){Vt(c=>{c.env=n}),process.stderr.write(`Switched to ${n}.
81
81
  `);return}if(r.environments[n]){Vt(c=>{c.env=n}),process.stderr.write(`Switched to ${n} (no credentials yet).
82
82
  `),process.stderr.write(` CDP key: coinbase env ${n} --key-file path/to/key.json
83
- `);return}if(!process.stdout.isTTY)throw new Error(`environment "${n}" needs API keys. Run: coinbase env ${n} --key-id=... --key-secret=...`);Tr(n,!!e.allowPlaintextSecrets);let a="",E="",g=Rr({input:process.stdin,output:process.stderr});try{if(!a){let c=await g.question("API Key ID: ");if(!c.trim())throw new Error("API Key ID is required");a=c.trim()}if(!E){g.close();let c=await Z_("API Key Secret: ");if(!c.trim())throw new Error("API Key Secret is required");E=c.trim(),g=Rr({input:process.stdin,output:process.stderr})}if(s(a,E),!nt(i,n)){let c=await g.question("Brokerage API URL (optional): ");c.trim()&&(i.endpoints={...i.endpoints,brokerageApi:c.trim()})}if(!Rt(i,n)){let c=await g.question("Agent API URL (optional): ");c.trim()&&(i.endpoints={...i.endpoints,agentApi:c.trim()})}}finally{g.close()}Vt(c=>{c.environments[n]=i,c.env=n},{allowPlaintext:e.allowPlaintextSecrets}),process.stderr.write(`Saved. Switched to ${n}.
84
- `)}function Z_(t){return process.stderr.write(t),process.stdin.isTTY?new Promise(e=>{let r=process.stdin;r.setRawMode(!0),r.resume(),r.setEncoding("utf8");let n="",i=s=>{s===`
83
+ `);return}if(!process.stdout.isTTY)throw new Error(`environment "${n}" needs API keys. Run: coinbase env ${n} --key-id=... --key-secret=...`);Ir(n,!!e.allowPlaintextSecrets);let a="",E="",g=pr({input:process.stdin,output:process.stderr});try{if(!a){let c=await g.question("API Key ID: ");if(!c.trim())throw new Error("API Key ID is required");a=c.trim()}if(!E){g.close();let c=await J_("API Key Secret: ");if(!c.trim())throw new Error("API Key Secret is required");E=c.trim(),g=pr({input:process.stdin,output:process.stderr})}if(s(a,E),!nt(i,n)){let c=await g.question("Brokerage API URL (optional): ");c.trim()&&(i.endpoints={...i.endpoints,brokerageApi:c.trim()})}if(!Tt(i,n)){let c=await g.question("Agent API URL (optional): ");c.trim()&&(i.endpoints={...i.endpoints,agentApi:c.trim()})}}finally{g.close()}Vt(c=>{c.environments[n]=i,c.env=n},{allowPlaintext:e.allowPlaintextSecrets}),process.stderr.write(`Saved. Switched to ${n}.
84
+ `)}function J_(t){return process.stderr.write(t),process.stdin.isTTY?new Promise(e=>{let r=process.stdin;r.setRawMode(!0),r.resume(),r.setEncoding("utf8");let n="",i=s=>{s===`
85
85
  `||s==="\r"||s===""?(r.setRawMode(!1),r.pause(),r.removeListener("data",i),process.stderr.write(`
86
- `),e(n)):s==="\x7F"||s==="\b"?n=n.slice(0,-1):s===""?process.exit(1):n+=s};r.on("data",i)}):new Promise(e=>{let r=Rr({input:process.stdin});r.once("line",n=>{r.close(),e(n)})})}function J_(t){return t?t.length<=12?"***":t.slice(0,8)+"\u2026"+t.slice(-4):"(none)"}function to(t,e){(!e.auth||e.auth.type!=="cdp_key")&&(process.stderr.write(`Environment "${t}" has no stored credentials.
86
+ `),e(n)):s==="\x7F"||s==="\b"?n=n.slice(0,-1):s===""?process.exit(1):n+=s};r.on("data",i)}):new Promise(e=>{let r=pr({input:process.stdin});r.once("line",n=>{r.close(),e(n)})})}function to(t){return t?t.length<=12?"***":t.slice(0,8)+"\u2026"+t.slice(-4):"(none)"}function eo(t,e){(!e.auth||e.auth.type!=="cdp_key")&&(process.stderr.write(`Environment "${t}" has no stored credentials.
87
87
  `),process.exit(1)),process.stdout.write(`env: ${t}
88
88
  `),process.stdout.write(`brokerage_api: ${nt(e,t)||"(unset)"}
89
- `),process.stdout.write(`agent_api: ${Rt(e,t)||"(unset)"}
89
+ `),process.stdout.write(`agent_api: ${Tt(e,t)||"(unset)"}
90
90
  `),process.stdout.write(`auth: cdp_key
91
- `),process.stdout.write(`key_id: ${J_(e.auth.key_id)}
92
- `)}function eo(t){let e;try{e=Q_(t,"utf-8")}catch{throw new Error(`cannot read key file: ${t}`)}let r;try{r=JSON.parse(e)}catch{throw new Error(`key file is not valid JSON: ${t}`)}let n=r.name??r.id,i=r.privateKey??r.secret;if(!n||!i)throw new Error(`key file must contain name/privateKey (or id/secret): ${t}`);return{keyId:n,keySecret:i}}u();d();ft();he();Sr();it();Fe();import{createInterface as Ea}from"node:readline";u();d();function Ve(){let t=process.env.COINBASE_TRANSPORT;if(!t||t==="auto")return"auto";if(t==="brokerage")return"brokerage";if(t==="agent")return"agent";throw new Error(`invalid COINBASE_TRANSPORT value "${t}"; expected "auto", "agent", or "brokerage"`)}Me();u();d();it();Ot();function w(t,e=!1){return{content:[{type:"text",text:t}],isError:e}}function se(t,e){return t===e?`coinbase_${t.replace(/-/g,"_")}`:`coinbase_${t.replace(/-/g,"_")}_${e.replace(/[-\s]/g,"_")}`}function Xi(t){let e=[{name:"coinbase_env",description:"Show the active environment and configured environments.",inputSchema:{type:"object",properties:{}}},{name:"coinbase_set_env",description:"Switch the active environment.",inputSchema:{type:"object",properties:{name:{type:"string",description:"Environment name"}},required:["name"]}},{name:"coinbase_template",description:"Get a full request body example for a command, ready to copy and modify.",inputSchema:{type:"object",properties:{resource:{type:"string",description:'Resource name (e.g. "orders"). Omit for top-level actions like balance, transfer, fees.'},action:{type:"string",description:'Action name (e.g. "create", "balance")'}},required:["action"]}},{name:"coinbase_help",description:"Get detailed help for a command: field descriptions, query parameters, and usage.",inputSchema:{type:"object",properties:{resource:{type:"string",description:'Resource name (e.g. "orders"). Omit for top-level actions like balance, transfer, fees.'},action:{type:"string",description:'Action name (e.g. "create", "balance")'}},required:["action"]}}];for(let r of t)for(let n of r.actions){let i={},s=[];for(let p of n.params){let A={type:p.type,description:p.description};p.enum&&(A.enum=p.enum),p.pattern&&(A.pattern=p.pattern),p.format&&(A.format=p.format),p.example!==void 0&&(A.example=p.example),p.default!==void 0&&(A.default=p.default),i[p.name]=A,p.required&&s.push(p.name)}let _=n.params.filter(p=>p.in==="body").length,o=n.params.filter(p=>p.in==="body"&&p.required).length,a=_>0?o>0?` (${_} fields, ${o} required)`:` (${_} fields)`:"",g=[...new Set(n.params.map(p=>p.oneOf).filter(p=>!!p))].map(p=>` (one of: ${p.split("|").join(", ")})`).join(""),c=(n.anyOf??[]).length>0?` (one of: ${n.anyOf.map(p=>p.join(" and ")).join(", ")})`:"",l=n.description||n.summary;e.push({name:se(r.name,n.name),description:`${n.method} ${n.path}${l?" \u2014 "+l:""}${a}${g}${c}`,inputSchema:{type:"object",properties:i,required:s.length>0?s:void 0,additionalProperties:n.closedInput||n.noInput?!1:void 0},...n.annotations?{annotations:n.annotations}:{}})}return e}function Zi(t){if(t.status>=400){let e=t.data?.message??JSON.stringify(t.data).slice(0,200),r=t.data?.correlationId,n=t.headers?.get("trace-id"),i=[n?`trace ${n}`:"",r?`correlation ${r}`:""].filter(Boolean).join(", ");return w(`HTTP ${t.status}: ${e}${i?` [${i}]`:""}`,!0)}if(t.data&&typeof t.data=="object"&&"error"in t.data&&typeof t.data.error=="string"){let e=t.data.message?P.stripGrpcPrefix(t.data.message):t.data.error;return w(`Error: ${e}`,!0)}return w(JSON.stringify(t.data,null,2))}function br(t){let e=Ft(t,""),r=Object.keys(t.environments??{}),n=[`Active: ${e||"(none)"}`,`Configured: ${r.length>0?r.join(", "):"(none)"}`];return e||n.push(`
93
- Run: coinbase env <name> --key-id=... --key-secret=... to configure.`),w(n.join(`
94
- `))}function Ji(t,e){if(!e)return w("Environment name is required.",!0);let r=Object.keys(t.environments??{});return r.length===0?w("No environments configured. Run: coinbase env <name> --key-id=... --key-secret=... to configure.",!0):t.environments[e]?{cfg:{...t,env:e}}:w(`Unknown environment: "${e}". Available environments: ${r.join(", ")}`,!0)}function ts(t){return br(t)}function aa(t,e){let r=t.params??[],n=[];n.push(`${t.summary||t.name}`),n.push(`${t.method} ${t.path}`);let i=t.pathParams.map(o=>`${o}="..."`).join(", ");n.push("",`Usage: ${e}(${i})`);let s=r.filter(o=>o.in==="body");if(s.length>0){n.push("","Fields:");for(let o of s){let a=o.required?" (required)":"",E=o.description?` \u2014 ${o.description}`:"";n.push(` ${o.name} (${o.type})${a}${E}`)}}let _=r.filter(o=>o.in==="query");if(_.length>0){n.push("","Query parameters:");for(let o of _){let a=o.description?` \u2014 ${o.description}`:"";n.push(` ${o.name} (${o.type})${a}`)}}return w(n.join(`
95
- `))}function es(t,e,r,n){if(n&&Object.hasOwn(n,e)&&(!t||t===e))return{act:n[e],toolName:`coinbase_${e}`};if(t){let _=r.find(o=>o.name===t);if(_){let o=_.actions.find(a=>a.name===e);return o?{act:o,toolName:se(_.name,o.name)}:w(`Unknown action: ${e}. Available for ${t}: ${_.actions.map(a=>a.name).join(", ")}`,!0)}}let i=r.map(_=>_.name),s=n?Object.keys(n):[];return w(`Not found. Resources: ${i.join(", ")}. Top-level actions: ${s.join(", ")}`,!0)}function rs(t,e,r,n){if(!e)return w("action is required",!0);let i=es(t,e,r,n);return"isError"in i?i:aa(i.act,i.toolName)}function ca(t){let e=(t.params??[]).filter(i=>i.in==="body");if(e.length===0)return w("This action has no request body.");let r=t.template??{},n=[];for(let i of e){let s=i.required?" (required)":"",_=i.description?` \u2014 ${i.description}`:"";n.push(`${i.name} (${i.type})${s}${_}`)}return w(`Template:
91
+ `),process.stdout.write(`key_id: ${to(e.auth.key_id)}
92
+ `)}function ro(t){let e;try{e=X_(t,"utf-8")}catch{throw new Error(`cannot read key file: ${t}`)}let r;try{r=JSON.parse(e)}catch{throw new Error(`key file is not valid JSON: ${t}`)}let n=r.name??r.id,i=r.privateKey??r.secret;if(!n||!i)throw new Error(`key file must contain name/privateKey (or id/secret): ${t}`);return{keyId:n,keySecret:i}}u();d();Rt();be();Sr();it();ve();import{createInterface as ga}from"node:readline";u();d();function ke(){let t=process.env.COINBASE_TRANSPORT;if(!t||t==="auto")return"auto";if(t==="brokerage")return"brokerage";if(t==="agent")return"agent";throw new Error(`invalid COINBASE_TRANSPORT value "${t}"; expected "auto", "agent", or "brokerage"`)}he();u();d();it();Ot();function W(t,e=!1){return{content:[{type:"text",text:t}],isError:e}}function se(t,e){return t===e?`coinbase_${t.replace(/-/g,"_")}`:`coinbase_${t.replace(/-/g,"_")}_${e.replace(/[-\s]/g,"_")}`}function Zi(t){let e=[{name:"coinbase_env",description:"Show the active environment and configured environments.",inputSchema:{type:"object",properties:{}}},{name:"coinbase_set_env",description:"Switch the active environment.",inputSchema:{type:"object",properties:{name:{type:"string",description:"Environment name"}},required:["name"]}},{name:"coinbase_template",description:"Get a full request body example for a command, ready to copy and modify.",inputSchema:{type:"object",properties:{resource:{type:"string",description:'Resource name (e.g. "orders"). Omit for top-level actions like balance, transfer, fees.'},action:{type:"string",description:'Action name (e.g. "create", "balance")'}},required:["action"]}},{name:"coinbase_help",description:"Get detailed help for a command: field descriptions, query parameters, and usage.",inputSchema:{type:"object",properties:{resource:{type:"string",description:'Resource name (e.g. "orders"). Omit for top-level actions like balance, transfer, fees.'},action:{type:"string",description:'Action name (e.g. "create", "balance")'}},required:["action"]}}];for(let r of t)for(let n of r.actions){let i={},s=[];for(let p of n.params){let A={type:p.type,description:p.description};p.enum&&(A.enum=p.enum),p.pattern&&(A.pattern=p.pattern),p.format&&(A.format=p.format),p.example!==void 0&&(A.example=p.example),p.default!==void 0&&(A.default=p.default),i[p.name]=A,p.required&&s.push(p.name)}let _=n.params.filter(p=>p.in==="body").length,o=n.params.filter(p=>p.in==="body"&&p.required).length,a=_>0?o>0?` (${_} fields, ${o} required)`:` (${_} fields)`:"",g=[...new Set(n.params.map(p=>p.oneOf).filter(p=>!!p))].map(p=>` (one of: ${p.split("|").join(", ")})`).join(""),c=(n.anyOf??[]).length>0?` (one of: ${n.anyOf.map(p=>p.join(" and ")).join(", ")})`:"",l=n.description||n.summary;e.push({name:se(r.name,n.name),description:`${n.method} ${n.path}${l?" \u2014 "+l:""}${a}${g}${c}`,inputSchema:{type:"object",properties:i,required:s.length>0?s:void 0,additionalProperties:n.closedInput||n.noInput?!1:void 0},...n.annotations?{annotations:n.annotations}:{}})}return e}function Ji(t){if(t.status>=400){let e=t.data?.message??JSON.stringify(t.data).slice(0,200),r=t.data?.correlationId,n=t.headers?.get("trace-id"),i=[n?`trace ${n}`:"",r?`correlation ${r}`:""].filter(Boolean).join(", ");return W(`HTTP ${t.status}: ${e}${i?` [${i}]`:""}`,!0)}if(t.data&&typeof t.data=="object"&&"error"in t.data&&typeof t.data.error=="string"){let e=t.data.message?P.stripGrpcPrefix(t.data.message):t.data.error;return W(`Error: ${e}`,!0)}return W(JSON.stringify(t.data,null,2))}function br(t){let e=Ft(t,""),r=Object.keys(t.environments??{}),n=[`Active: ${e||"(none)"}`,`Configured: ${r.length>0?r.join(", "):"(none)"}`];return e||n.push(`
93
+ Run: coinbase env <name> --key-id=... --key-secret=... to configure.`),W(n.join(`
94
+ `))}function ts(t,e){if(!e)return W("Environment name is required.",!0);let r=Object.keys(t.environments??{});return r.length===0?W("No environments configured. Run: coinbase env <name> --key-id=... --key-secret=... to configure.",!0):t.environments[e]?{cfg:{...t,env:e}}:W(`Unknown environment: "${e}". Available environments: ${r.join(", ")}`,!0)}function es(t){return br(t)}function ua(t,e){let r=t.params??[],n=[];n.push(`${t.summary||t.name}`),n.push(`${t.method} ${t.path}`);let i=t.pathParams.map(o=>`${o}="..."`).join(", ");n.push("",`Usage: ${e}(${i})`);let s=r.filter(o=>o.in==="body");if(s.length>0){n.push("","Fields:");for(let o of s){let a=o.required?" (required)":"",E=o.description?` \u2014 ${o.description}`:"";n.push(` ${o.name} (${o.type})${a}${E}`)}}let _=r.filter(o=>o.in==="query");if(_.length>0){n.push("","Query parameters:");for(let o of _){let a=o.description?` \u2014 ${o.description}`:"";n.push(` ${o.name} (${o.type})${a}`)}}return W(n.join(`
95
+ `))}function rs(t,e,r,n){if(n&&Object.hasOwn(n,e)&&(!t||t===e))return{act:n[e],toolName:`coinbase_${e}`};if(t){let _=r.find(o=>o.name===t);if(_){let o=_.actions.find(a=>a.name===e);return o?{act:o,toolName:se(_.name,o.name)}:W(`Unknown action: ${e}. Available for ${t}: ${_.actions.map(a=>a.name).join(", ")}`,!0)}}let i=r.map(_=>_.name),s=n?Object.keys(n):[];return W(`Not found. Resources: ${i.join(", ")}. Top-level actions: ${s.join(", ")}`,!0)}function ns(t,e,r,n){if(!e)return W("action is required",!0);let i=rs(t,e,r,n);return"isError"in i?i:ua(i.act,i.toolName)}function da(t){let e=(t.params??[]).filter(i=>i.in==="body");if(e.length===0)return W("This action has no request body.");let r=t.template??{},n=[];for(let i of e){let s=i.required?" (required)":"",_=i.description?` \u2014 ${i.description}`:"";n.push(`${i.name} (${i.type})${s}${_}`)}return W(`Template:
96
96
  ${JSON.stringify(r,null,2)}
97
97
 
98
98
  Fields:
99
99
  ${n.join(`
100
- `)}`)}function ns(t,e,r,n){if(!e)return w("action is required",!0);let i=es(t,e,r,n);return"isError"in i?i:ca(i.act)}var ua=(()=>{let t={},e=(r,n)=>{let i=t[r];if(i!==void 0&&i!==n)throw new Error(`operationIdForTool collision: tool "${r}" maps to both "${i}" and "${n}"`);t[r]=n};for(let r of Object.values(Z))e(se(r.name,r.name),r.id);for(let r of X)for(let n of r.actions)e(se(r.name,n.name),n.id);return t})();function ss(t){process.stdout.write(JSON.stringify({jsonrpc:"2.0",...t})+`
101
- `)}function _e(t,e){ss({id:t,result:e})}function oe(t,e,r){ss({id:t,error:{code:e,message:r}})}function da(){return X}async function ga(t,e){let r=da();if(t==="coinbase_env")return br(tt());if(t==="coinbase_set_env"){let n=tt(),i=Ji(n,e.name);return"isError"in i?i:(ut(i.cfg),gr(),ts(i.cfg))}return t==="coinbase_help"?rs(String(e.resource??""),String(e.action??""),r,Z):t==="coinbase_template"?ns(String(e.resource??""),String(e.action??""),r,Z):la(t,e)}async function la(t,e){let r=ua[t];if(!r||!Le(r))return w(`Unknown tool: ${t}`,!0);let n=tt(),i;try{i=re(n,"")}catch(o){return w(`Environment error: ${o.message}
100
+ `)}`)}function is(t,e,r,n){if(!e)return W("action is required",!0);let i=rs(t,e,r,n);return"isError"in i?i:da(i.act)}var la=(()=>{let t={},e=(r,n)=>{let i=t[r];if(i!==void 0&&i!==n)throw new Error(`operationIdForTool collision: tool "${r}" maps to both "${i}" and "${n}"`);t[r]=n};for(let r of Object.values(Q))e(se(r.name,r.name),r.id);for(let r of j)for(let n of r.actions)e(se(r.name,n.name),n.id);return t})();function _s(t){process.stdout.write(JSON.stringify({jsonrpc:"2.0",...t})+`
101
+ `)}function _e(t,e){_s({id:t,result:e})}function oe(t,e,r){_s({id:t,error:{code:e,message:r}})}function Ia(){return j}async function pa(t,e){let r=Ia();if(t==="coinbase_env")return br(J());if(t==="coinbase_set_env"){let n=J(),i=ts(n,e.name);return"isError"in i?i:(Et(i.cfg),ur(),es(i.cfg))}return t==="coinbase_help"?ns(String(e.resource??""),String(e.action??""),r,Q):t==="coinbase_template"?is(String(e.resource??""),String(e.action??""),r,Q):Ta(t,e)}async function Ta(t,e){let r=la[t];if(!r||!Fi(r))return W(`Unknown tool: ${t}`,!0);let n=J(),i;try{i=re(n,"")}catch(o){return W(`Environment error: ${o.message}
102
102
 
103
- Run: coinbase env <name> --key-id=... --key-secret=...`,!0)}let{name:s,env:_}=i;try{let o=await ee(s,_),a={envName:s,env:_,baseURL:nt(_,s),doRequest:g=>ke({...g,...o}),transport:Ve()},E=await Wt(r,e,a);return Zi(E)}catch(o){return w(`Request failed: ${o.message}`,!0)}}var Ia={name:"coinbase",version:gt},pa={tools:{}},Lr=null;function is(){if(!Lr){let t=[...X];for(let[e,r]of Object.entries(Z))t.push({name:e,actions:[r]});Lr=Xi(t)}return Lr}async function Ta(t){let{id:e,method:r,params:n}=t;switch(r){case"initialize":_e(e,{protocolVersion:"2024-11-05",serverInfo:Ia,capabilities:pa});break;case"notifications/initialized":break;case"tools/list":_e(e,{tools:is()});break;case"tools/call":{let{name:i,arguments:s}=n??{};if(!i){oe(e,-32602,"Missing tool name");return}if(!is().find(o=>o.name===i)){oe(e,-32602,`Unknown tool: ${i}`);return}try{let o=await ga(i,s??{});_e(e,o)}catch(o){_e(e,w(`Internal error: ${o.message}`,!0))}break}case"ping":_e(e,{});break;default:e!=null&&oe(e,-32601,`Method not found: ${r}`);break}}function _s(){let t=Ea({input:process.stdin,terminal:!1}),e=new Set;t.on("line",r=>{if(r.trim())try{let n=JSON.parse(r),i=Ta(n).catch(s=>{process.stderr.write(`MCP error: ${s.message}
104
- `),n.id!=null&&oe(n.id,-32603,s.message)}).finally(()=>e.delete(i));e.add(i)}catch{oe(null,-32700,"Parse error")}}),t.on("close",async()=>{await Promise.all(e),process.exit(0)}),process.stderr.write(`coinbase MCP server v${gt} ready
105
- `)}u();d();it();function os(t){let e=tt();if(t.length===0)return Ra(e);if(t[0]==="clear"){let r=t[1],n;if(r&&r.includes(".")){let i=r.indexOf(".");n=ne(e,r.slice(0,i),r.slice(i+1))}else r?n=ne(e,r):n=ne(e);ut(e),process.stderr.write(`Cleared ${n} history ${n===1?"entry":"entries"}.
106
- `);return}throw new Error("usage: coinbase history [clear [env.action]]")}function Ra(t){let e=[];for(let[i,s]of Object.entries(t.history))for(let[_,o]of Object.entries(s))e.push({env:i,action:_,lastUsed:o.last_used,fields:Object.keys(o.values)});if(e.length===0){process.stderr.write(`No saved history.
103
+ Run: coinbase env <name> --key-id=... --key-secret=...`,!0)}let{name:s,env:_}=i;try{let o=await ee(s,_),a={envName:s,env:_,baseURL:nt(_,s),doRequest:g=>Me({...g,...o}),transport:ke()},E=await Wt(r,e,a);return Ji(E)}catch(o){return W(`Request failed: ${o.message}`,!0)}}var Ra={name:"coinbase",version:dt},Oa={tools:{}},Lr=null;function ss(){if(!Lr){let t=[...j];for(let[e,r]of Object.entries(Q))t.push({name:e,actions:[r]});Lr=Zi(t)}return Lr}async function ma(t){let{id:e,method:r,params:n}=t;switch(r){case"initialize":_e(e,{protocolVersion:"2024-11-05",serverInfo:Ra,capabilities:Oa});break;case"notifications/initialized":break;case"tools/list":_e(e,{tools:ss()});break;case"tools/call":{let{name:i,arguments:s}=n??{};if(!i){oe(e,-32602,"Missing tool name");return}if(!ss().find(o=>o.name===i)){oe(e,-32602,`Unknown tool: ${i}`);return}try{let o=await pa(i,s??{});_e(e,o)}catch(o){_e(e,W(`Internal error: ${o.message}`,!0))}break}case"ping":_e(e,{});break;default:e!=null&&oe(e,-32601,`Method not found: ${r}`);break}}function os(){let t=ga({input:process.stdin,terminal:!1}),e=new Set;t.on("line",r=>{if(r.trim())try{let n=JSON.parse(r),i=ma(n).catch(s=>{process.stderr.write(`MCP error: ${s.message}
104
+ `),n.id!=null&&oe(n.id,-32603,s.message)}).finally(()=>e.delete(i));e.add(i)}catch{oe(null,-32700,"Parse error")}}),t.on("close",async()=>{await Promise.all(e),process.exit(0)}),process.stderr.write(`coinbase MCP server v${dt} ready
105
+ `)}u();d();it();function as(t){let e=J();if(t.length===0)return Aa(e);if(t[0]==="clear"){let r=t[1],n;if(r&&r.includes(".")){let i=r.indexOf(".");n=ne(e,r.slice(0,i),r.slice(i+1))}else r?n=ne(e,r):n=ne(e);Et(e),process.stderr.write(`Cleared ${n} history ${n===1?"entry":"entries"}.
106
+ `);return}throw new Error("usage: coinbase history [clear [env.action]]")}function Aa(t){let e=[];for(let[i,s]of Object.entries(t.history))for(let[_,o]of Object.entries(s))e.push({env:i,action:_,lastUsed:o.last_used,fields:Object.keys(o.values)});if(e.length===0){process.stderr.write(`No saved history.
107
107
  `);return}e.sort((i,s)=>s.lastUsed.localeCompare(i.lastUsed));let r=Math.max(...e.map(i=>i.env.length))+2,n=Math.max(...e.map(i=>i.action.length))+2;for(let i of e){let s=i.lastUsed.slice(0,10);process.stdout.write(`${i.env.padEnd(r)}${i.action.padEnd(n)}${s} ${i.fields.join(", ")}
108
- `)}}u();d();it();import{readFileSync as ds,writeFileSync as Oa,mkdirSync as gs,readdirSync as ls,existsSync as bt,cpSync as ma,rmSync as Aa}from"node:fs";import as,{join as lt,resolve as cs}from"node:path";import{fileURLToPath as Na}from"node:url";import{homedir as Es}from"node:os";import{createInterface as us}from"node:readline";function Ur(){try{return JSON.parse(ds(st(),"utf8"))}catch{return{}}}function hr(t){let e=Tt();gs(e,{recursive:!0,mode:448}),Oa(st(),JSON.stringify(t,null,2)+`
109
- `,{mode:384})}function Is(){let t=as.dirname(Na(import.meta.url));return as.join(t,"..","skills")}function Sa(t){let e=t.match(/^---\n([\s\S]*?)\n---/);if(!e)return{name:"",description:""};let r=e[1],n=r.match(/^name:\s*(.+)$/m),i=r.match(/^description:\s*(.+)$/m);return{name:(n?.[1]??"").trim(),description:(i?.[1]??"").trim()}}function ps(t){let e=t??Is();if(!bt(e))return[];let r=[];for(let n of ls(e,{withFileTypes:!0})){if(!n.isDirectory())continue;let i=lt(e,n.name,"SKILL.md");if(!bt(i))continue;let s=ds(i,"utf8"),_=Sa(s);r.push({name:_.name||n.name,description:_.description,dir:lt(e,n.name)})}return r.sort((n,i)=>n.name.localeCompare(i.name))}function Ca(t,e){if(!bt(t))return 0;gs(e,{recursive:!0});let r=0;for(let n of ls(t,{withFileTypes:!0})){if(!n.isDirectory())continue;let i=lt(t,n.name,"SKILL.md");if(!bt(i))continue;let s=lt(e,n.name);ma(lt(t,n.name),s,{recursive:!0,force:!0}),r++}return r}async function Pa(){let t=process.platform==="win32"?lt(process.env.USERPROFILE??Es(),".claude","skills"):lt(Es(),".claude","skills");process.stderr.write(`Where should skills be installed?
108
+ `)}}u();d();it();import{readFileSync as gs,writeFileSync as Na,mkdirSync as ls,readdirSync as Is,existsSync as bt,cpSync as Sa,rmSync as Ca}from"node:fs";import cs,{join as gt,resolve as Es}from"node:path";import{fileURLToPath as Pa}from"node:url";import{homedir as us}from"node:os";import{createInterface as ds}from"node:readline";function Ur(){try{return JSON.parse(gs(st(),"utf8"))}catch{return{}}}function hr(t){let e=pt();ls(e,{recursive:!0,mode:448}),Na(st(),JSON.stringify(t,null,2)+`
109
+ `,{mode:384})}function ps(){let t=cs.dirname(Pa(import.meta.url));return cs.join(t,"..","skills")}function fa(t){let e=t.match(/^---\n([\s\S]*?)\n---/);if(!e)return{name:"",description:""};let r=e[1],n=r.match(/^name:\s*(.+)$/m),i=r.match(/^description:\s*(.+)$/m);return{name:(n?.[1]??"").trim(),description:(i?.[1]??"").trim()}}function Ts(t){let e=t??ps();if(!bt(e))return[];let r=[];for(let n of Is(e,{withFileTypes:!0})){if(!n.isDirectory())continue;let i=gt(e,n.name,"SKILL.md");if(!bt(i))continue;let s=gs(i,"utf8"),_=fa(s);r.push({name:_.name||n.name,description:_.description,dir:gt(e,n.name)})}return r.sort((n,i)=>n.name.localeCompare(i.name))}function Da(t,e){if(!bt(t))return 0;ls(e,{recursive:!0});let r=0;for(let n of Is(t,{withFileTypes:!0})){if(!n.isDirectory())continue;let i=gt(t,n.name,"SKILL.md");if(!bt(i))continue;let s=gt(e,n.name);Sa(gt(t,n.name),s,{recursive:!0,force:!0}),r++}return r}async function ya(){let t=process.platform==="win32"?gt(process.env.USERPROFILE??us(),".claude","skills"):gt(us(),".claude","skills");process.stderr.write(`Where should skills be installed?
110
110
  `),process.stderr.write(`Tip: Not sure where your agent looks for skills? Ask your agent.
111
111
 
112
112
  `),process.stderr.write(` 1) ${t} User \u2014 available across all projects (Recommended)
113
113
  `),process.stderr.write(` 2) Other Specify a custom path
114
114
 
115
- `);let e=us({input:process.stdin,output:process.stderr}),r=await new Promise(n=>{e.question("? Skills directory [1]: ",i=>{e.close(),n(i.trim())})});if(!r||r==="1")return t;if(r==="2"){let n=us({input:process.stdin,output:process.stderr}),i=await new Promise(s=>{n.question("? Path: ",_=>{n.close(),s(_.trim())})});return i?cs(i):(process.stderr.write(`No path provided, using default.
116
- `),t)}return cs(r)}async function fa(t){let e=Ur(),r=t||e.settings?.skillsDir,n=!1;r||(process.stdin.isTTY||(process.stderr.write(`error: no skills directory configured.
115
+ `);let e=ds({input:process.stdin,output:process.stderr}),r=await new Promise(n=>{e.question("? Skills directory [1]: ",i=>{e.close(),n(i.trim())})});if(!r||r==="1")return t;if(r==="2"){let n=ds({input:process.stdin,output:process.stderr}),i=await new Promise(s=>{n.question("? Path: ",_=>{n.close(),s(_.trim())})});return i?Es(i):(process.stderr.write(`No path provided, using default.
116
+ `),t)}return Es(r)}async function ba(t){let e=Ur(),r=t||e.settings?.skillsDir,n=!1;r||(process.stdin.isTTY||(process.stderr.write(`error: no skills directory configured.
117
117
  Run: coinbase skills add --dir <path>
118
- `),process.exit(1)),r=await Pa(),n=!0),(!e.settings?.skillsDir||t&&e.settings.skillsDir!==r)&&(e.settings||(e.settings={}),e.settings.skillsDir=r,hr(e));let i=Is(),s=Ca(i,r);process.stderr.write(`Installed ${s} skills to ${r}.
118
+ `),process.exit(1)),r=await ya(),n=!0),(!e.settings?.skillsDir||t&&e.settings.skillsDir!==r)&&(e.settings||(e.settings={}),e.settings.skillsDir=r,hr(e));let i=ps(),s=Da(i,r);process.stderr.write(`Installed ${s} skills to ${r}.
119
119
  `),n&&process.stderr.write(`Skills will auto-update on future installs.
120
- `)}function Da(){let e=Ur().settings?.skillsDir,r=ps();if(r.length===0){process.stderr.write(`No bundled skills found.
120
+ `)}function La(){let e=Ur().settings?.skillsDir,r=Ts();if(r.length===0){process.stderr.write(`No bundled skills found.
121
121
  `);return}let n=Math.max(...r.map(i=>i.name.length),4);process.stderr.write(`${"Name".padEnd(n+2)}${"Installed".padEnd(12)}Description
122
122
  `),process.stderr.write(`${"\u2500".repeat(n+2)}${"\u2500".repeat(12)}${"\u2500".repeat(40)}
123
- `);for(let i of r){let _=e&&bt(lt(e,i.name,"SKILL.md"))?"yes":"no";process.stderr.write(`${i.name.padEnd(n+2)}${_.padEnd(12)}${i.description}
123
+ `);for(let i of r){let _=e&&bt(gt(e,i.name,"SKILL.md"))?"yes":"no";process.stderr.write(`${i.name.padEnd(n+2)}${_.padEnd(12)}${i.description}
124
124
  `)}process.stderr.write(`
125
125
  ${r.length} skills available.`),e?process.stderr.write(` Installed to: ${e}`):process.stderr.write(" Run: coinbase skills add"),process.stderr.write(`
126
- `)}function ya(){let t=Ur(),e=t.settings?.skillsDir;if(!e){process.stderr.write(`No skills directory configured. Nothing to remove.
126
+ `)}function ha(){let t=Ur(),e=t.settings?.skillsDir;if(!e){process.stderr.write(`No skills directory configured. Nothing to remove.
127
127
  `);return}if(!bt(e)){process.stderr.write(`Skills directory not found: ${e}
128
128
  `),t.settings&&delete t.settings.skillsDir,hr(t),process.stderr.write(`Cleared skillsDir from config.
129
- `);return}let r=ps(),n=0;for(let i of r){let s=lt(e,i.name);bt(s)&&(Aa(s,{recursive:!0,force:!0}),n++)}t.settings&&delete t.settings.skillsDir,hr(t),process.stderr.write(`Removed ${n} skills from ${e}.
129
+ `);return}let r=Ts(),n=0;for(let i of r){let s=gt(e,i.name);bt(s)&&(Ca(s,{recursive:!0,force:!0}),n++)}t.settings&&delete t.settings.skillsDir,hr(t),process.stderr.write(`Removed ${n} skills from ${e}.
130
130
  `),process.stderr.write(`Cleared skillsDir from config.
131
- `)}async function Ts(t){let e=t[0];if(!e||e==="-h"||e==="--help"){process.stderr.write(`Manage CDP agent skills
131
+ `)}async function Rs(t){let e=t[0];if(!e||e==="-h"||e==="--help"){process.stderr.write(`Manage CDP agent skills
132
132
 
133
133
  Usage:
134
134
  coinbase skills add Install/update skills to your skills directory
@@ -136,29 +136,29 @@ Usage:
136
136
  coinbase skills list List available skills from this package
137
137
  coinbase skills remove Remove installed skills and clear config
138
138
 
139
- `);return}let r,n=t.slice(1);for(let i=0;i<n.length;i++)if(n[i]==="--dir"&&n[i+1]){r=n[++i];break}else if(n[i].startsWith("--dir=")){r=n[i].slice(6);break}switch(e){case"add":await fa(r);break;case"list":Da();break;case"remove":ya();break;default:process.stderr.write(`error: unknown skills subcommand: ${e}
139
+ `);return}let r,n=t.slice(1);for(let i=0;i<n.length;i++)if(n[i]==="--dir"&&n[i+1]){r=n[++i];break}else if(n[i].startsWith("--dir=")){r=n[i].slice(6);break}switch(e){case"add":await ba(r);break;case"list":La();break;case"remove":ha();break;default:process.stderr.write(`error: unknown skills subcommand: ${e}
140
140
  Run: coinbase skills --help
141
- `),process.exit(1)}}u();d();ft();u();d();Ge();function La(t,e,r){return r?`\x1B]8;;${e}\x07\x1B[4m${t}\x1B[24m\x1B]8;;\x07`:`${t} (${e})`}function Os(t,e=Rs){return t.replace(/\[([^\]]+)\]\(([^)]+)\)/g,(r,n,i)=>La(n,i,e))}function Mr(t){return t.replace(/\*\*(.+?)\*\*/g,"$1").replace(/__(.+?)__/g,"$1").replace(/\*(.+?)\*/g,"$1").replace(/_(.+?)_/g,"$1").replace(/\[([^\]]+)\]\([^)]+\)/g,"$1").replace(/^#{1,6}\s+/gm,"")}function ms(t,e){let r=e??process.stdout.columns??100;return t.replace(/\r\n/g,`
141
+ `),process.exit(1)}}u();d();Rt();u();d();Fe();function Ma(t,e,r){return r?`\x1B]8;;${e}\x07\x1B[4m${t}\x1B[24m\x1B]8;;\x07`:`${t} (${e})`}function ms(t,e=Os){return t.replace(/\[([^\]]+)\]\(([^)]+)\)/g,(r,n,i)=>Ma(n,i,e))}function Mr(t){return t.replace(/\*\*(.+?)\*\*/g,"$1").replace(/__(.+?)__/g,"$1").replace(/\*(.+?)\*/g,"$1").replace(/_(.+?)_/g,"$1").replace(/\[([^\]]+)\]\([^)]+\)/g,"$1").replace(/^#{1,6}\s+/gm,"")}function As(t,e){let r=e??process.stdout.columns??100;return t.replace(/\r\n/g,`
142
142
  `).trim().split(`
143
143
  `).flatMap(n=>{n=Mr(n).replace(/^\s*\*\s+/," - ").replace(/^\s*(\d+)\.\s+/," $1. ");let i=[];for(;n.length>r;){let s=n.lastIndexOf(" ",r);s<=0&&(s=r),i.push(n.slice(0,s)),n=n.slice(s+1)}return i.push(n),i}).join(`
144
144
  `)+`
145
- `}u();d();Ge();function we(t,e,r,n){let i=n??e.length,s=Math.max(20,(process.stdout.columns||80)-i),_=r.split(" "),o="",a=!0;for(let E of _){let g=mt(E),c=mt(o),l=E.includes("\x1B]8;;");(c+g+1>s||l&&c>0&&c+g+1>s*.6)&&o.length>0&&(t.write((a?e:" ".repeat(i))+o.trimEnd()+`
145
+ `}u();d();Fe();function Ve(t,e,r,n){let i=n??e.length,s=Math.max(20,(process.stdout.columns||80)-i),_=r.split(" "),o="",a=!0;for(let E of _){let g=mt(E),c=mt(o),l=E.includes("\x1B]8;;");(c+g+1>s||l&&c>0&&c+g+1>s*.6)&&o.length>0&&(t.write((a?e:" ".repeat(i))+o.trimEnd()+`
146
146
  `),o="",a=!1),o+=(o?" ":"")+E}o&&t.write((a?e:" ".repeat(i))+o.trimEnd()+`
147
- `)}Gr();ce();ge();function en(){return X}function O_(t){return Mn.has(t)}function m_(t,e,r){for(let n of e.fields){let i=e.nested?.[n];t.write(`${r}${n}
148
- `),i&&m_(t,i,r+" ")}}function rn(t,e){let r=process.stderr,n=ot(e.id),i=n?St(n):null;r.write(`${e.summary||e.name}
147
+ `)}Gr();ce();ge();function en(){return j}function m_(t){return vn.has(t)}function A_(t,e,r){for(let n of e.fields){let i=e.nested?.[n];t.write(`${r}${n}
148
+ `),i&&A_(t,i,r+" ")}}function rn(t,e){let r=process.stderr,n=ot(e.id),i=n?St(n):null;r.write(`${e.summary||e.name}
149
149
  `),e.description&&r.write(`
150
- `+ms(e.description));let s=t===e.name?`coinbase ${e.name}`:`coinbase ${t} ${e.name}`;for(let c of e.pathParams)s+=` <${c}>`;let _=e.params??[];r.write(`
150
+ `+As(e.description));let s=t===e.name?`coinbase ${e.name}`:`coinbase ${t} ${e.name}`;for(let c of e.pathParams)s+=` <${c}>`;let _=e.params??[];r.write(`
151
151
  Usage:
152
152
  ${s}${e.noInput?"":" [fields...]"}
153
153
  `);let o=_.filter(c=>c.in==="path");if(o.length>0){r.write(`
154
154
  Arguments:
155
- `);let c=Math.max(...o.map(l=>l.name.length));for(let l of o){let p=` <${l.name}>${" ".repeat(Math.max(1,c-l.name.length+2))}${l.type}${l.required?" required":""} `,A=/[.!?]$/.test(l.description)?l.description:`${l.description}.`,T=i==="watchlist"?`${A} With --watch, accepts multiple comma-separated pairs (e.g. BTC-USD,ETH-USD).`:l.description;we(r,p,T)}}let a=_.filter(c=>c.in==="body");if(a.length>0){r.write(`
155
+ `);let c=Math.max(...o.map(l=>l.name.length));for(let l of o){let p=` <${l.name}>${" ".repeat(Math.max(1,c-l.name.length+2))}${l.type}${l.required?" required":""} `,A=/[.!?]$/.test(l.description)?l.description:`${l.description}.`,R=i==="watchlist"?`${A} With --watch, accepts multiple comma-separated pairs (e.g. BTC-USD,ETH-USD).`:l.description;Ve(r,p,R)}}let a=_.filter(c=>c.in==="body");if(a.length>0){r.write(`
156
156
  Fields:
157
- `);let c=Math.max(...a.map(l=>l.name.length));for(let l of a){let p=l.required?"required":"",A=" ".repeat(Math.max(1,c-l.name.length+2)),T=" ".repeat(Math.max(1,8-l.type.length)),N=p?" ":" ",f=l.type==="array"||l.type==="object"?" (use :=json)":"",M=Os(Mr(l.description)),v=` ${l.name}${A}${l.type}${T}${p}${N}`;we(r,v,M+f)}}let E=_.filter(c=>c.in==="query");if(E.length>0){r.write(`
157
+ `);let c=Math.max(...a.map(l=>l.name.length));for(let l of a){let p=l.required?"required":"",A=" ".repeat(Math.max(1,c-l.name.length+2)),R=" ".repeat(Math.max(1,8-l.type.length)),N=p?" ":" ",f=l.type==="array"||l.type==="object"?" (use :=json)":"",M=ms(Mr(l.description)),k=` ${l.name}${A}${l.type}${R}${p}${N}`;Ve(r,k,M+f)}}let E=_.filter(c=>c.in==="query");if(E.length>0){r.write(`
158
158
  Query params (use == syntax):
159
- `);let c=Math.max(...E.map(l=>l.name.length));for(let l of E){let p=l.description;l.enum?.length&&(p+=(p?" ":"")+`[${l.enum.join(", ")}]`);let A=` ${l.name}${" ".repeat(Math.max(1,c-l.name.length+2))}${l.type} `;we(r,A,p)}}e.responseFields&&(r.write(`
159
+ `);let c=Math.max(...E.map(l=>l.name.length));for(let l of E){let p=l.description;l.enum?.length&&(p+=(p?" ":"")+`[${l.enum.join(", ")}]`);let A=` ${l.name}${" ".repeat(Math.max(1,c-l.name.length+2))}${l.type} `;Ve(r,A,p)}}e.responseFields&&(r.write(`
160
160
  Response:
161
- `),m_(r,e.responseFields," "));let g=a.length>0;if(r.write(`
161
+ `),A_(r,e.responseFields," "));let g=a.length>0;if(r.write(`
162
162
  Flags:
163
163
  `),g&&r.write(` --template Show request body template from spec
164
164
  `),r.write(` --dry-run Preview request without sending
@@ -167,12 +167,12 @@ Flags:
167
167
  `),e.streamable&&r.write(` --paginate Auto-paginate using nextPageToken
168
168
  `),i!==null&&(r.write(` --watch Live stream via WebSocket
169
169
  `),e.watchFields&&(r.write(`
170
- `+Ns(e.watchFields)+`
170
+ `+Ss(e.watchFields)+`
171
171
  `),r.write(` --until-timeout <s> Exit 124 if predicate not matched within N seconds
172
172
  `))),g||E.length>0){r.write(`
173
173
  Example:
174
174
  `+s);for(let c of a)c.example!==void 0&&r.write(` ${c.name}=${c.example}`);for(let c of E)c.example!==void 0&&r.write(` ${c.name}==${c.example}`);r.write(`
175
- `)}}function A_(t){let e=X.find(i=>i.name===t);e||(process.stderr.write(`error: unknown resource: ${t}
175
+ `)}}function N_(t){let e=j.find(i=>i.name===t);e||(process.stderr.write(`error: unknown resource: ${t}
176
176
  Run: coinbase --help
177
177
  `),process.exit(1)),process.stderr.write(`Manage ${e.name}
178
178
 
@@ -185,34 +185,34 @@ Flags:
185
185
  `),n||process.stderr.write(` --edit Open request body in $EDITOR
186
186
  `),process.stderr.write(` --jq <expr> jq filter expression for response
187
187
  `),r&&process.stderr.write(` --watch Live stream watchable actions via WebSocket (add --until <predicate> to exit on a condition)
188
- `)}ce();ge();u();d();he();u();d();var N_=t=>t?.has_next===!1?null:t?.cursor||null;it();Fe();ce();function yc(t,e,r,n){for(let i of e){let s=r[i];if(typeof s=="string"&&s.includes(",")){let _=t.replace(/_/g," ");return`'${s}' looks like multiple values, but \`coinbase ${_}\` takes a single ${i}.`+(n?`
188
+ `)}ce();ge();u();d();be();u();d();var S_=t=>t?.has_next===!1?null:t?.cursor||null;it();ve();ce();function hc(t,e,r,n){for(let i of e){let s=r[i];if(typeof s=="string"&&s.includes(",")){let _=t.replace(/_/g," ");return`'${s}' looks like multiple values, but \`coinbase ${_}\` takes a single ${i}.`+(n?`
189
189
  To stream several live, add --watch:
190
- coinbase ${_} ${s} --watch`:"")}}return null}var bc=new Set(["x402_pay","x402_fetch"]);function P_(t){return!bc.has(t)}async function sn(t,e,r,n){if(e.noInput&&(r.args.length>0||r.flags.template||r.flags.edit))throw new Error(`${t} does not accept input fields; it always inspects the current credential.`);if(r.flags.template){let C=e.template??{};process.stdout.write(JSON.stringify(C,null,2)+`
191
- `);return}let i=[],s=[],{isFieldArg:_}=await Promise.resolve().then(()=>(rr(),er));for(let C of r.args)i.length<e.pathParams.length&&!_(C)?i.push(C):s.push(C);if(i.length<e.pathParams.length){let C=e.pathParams.slice(i.length);throw new Error(`Missing argument(s): ${C.map(U=>`<${U}>`).join(" ")}
190
+ coinbase ${_} ${s} --watch`:"")}}return null}var Uc=new Set(["x402_pay","x402_fetch"]);function f_(t){return!Uc.has(t)}async function sn(t,e,r,n,i=t.replace(/_/g," ")){if(e.noInput&&(r.args.length>0||r.flags.template||r.flags.edit))throw new Error(`${i} does not accept input fields; it always inspects the current credential.`);if(r.flags.template){let C=e.template??{};process.stdout.write(JSON.stringify(C,null,2)+`
191
+ `);return}let s=[],_=[],{isFieldArg:o}=await Promise.resolve().then(()=>(tr(),Je));for(let C of r.args)s.length<e.pathParams.length&&!o(C)?s.push(C):_.push(C);if(s.length<e.pathParams.length){let C=e.pathParams.slice(s.length);throw new Error(`Missing argument(s): ${C.map(L=>`<${L}>`).join(" ")}
192
192
 
193
- Usage: coinbase ${t.replace(/_/g," ")} ${e.pathParams.map(U=>`<${U}>`).join(" ")} [fields...]`)}let{parseFields:o}=await Promise.resolve().then(()=>(rr(),er)),a=o(s),E=!1,g={},c=tt(),l=Ft(c,n);if(P_(t)&&l&&De(c)){let C=pr(c,l,t);if(C){let{setNested:U}=await Promise.resolve().then(()=>(rr(),er));for(let[D,V]of Object.entries(C.values))try{U(g,D,JSON.parse(V))}catch{U(g,D,V)}E=!0}}let p=e.params??[];for(let C of Object.keys(a.body)){let U=p.find(D=>D.name===C);if(U?.oneOf)for(let D of p)D.oneOf===U.oneOf&&D.name!==C&&delete g[D.name]}let T=Object.keys(a.body).length>0?{...g,...a.body}:E?(process.stderr.write(`Using saved values from last ${t.replace(/_/g," ")} call. Pass fields to override.
194
- `),{...g}):{...a.body},N={};for(let[C,U]of a.query.entries())N[C]=U;let f={};for(let C=0;C<i.length;C++)f[e.pathParams[C]]=i[C];if(!r.flags.watch&&!r.flags.until){let U=e.pathParams.some(D=>typeof f[D]=="string"&&f[D].includes(","))?ot(t):null;if(U){let{surfaceForChannel:D}=await Promise.resolve().then(()=>(ge(),tn)),V=yc(t,e.pathParams,f,D(U)==="watchlist");if(V)throw new Error(V)}}let M=p.filter(C=>C.in==="body"&&C.required&&C.type!=="object"&&C.type!=="array"),v=M.map(C=>C.name);if(v.length>0&&Object.keys(T).length===0&&!r.flags.edit&&!a.rawBody)if(process.stdin.isTTY)if(M.length<=3){let{createInterface:C}=await import("node:readline"),U=C({input:process.stdin,output:process.stderr});for(let D of M){let V=D.enum?` [${D.enum.join(", ")}]`:"",B=D.example?` (e.g. ${D.example})`:"",Ct=await new Promise(G=>{U.question(`${D.name}${V}${B}: `,G)});Ct&&(T[D.name]=Ct)}U.close()}else process.stderr.write(`This action requires ${v.length} fields. Opening editor.
195
- `),r.flags.edit=!0;else{let C=v.join(", ");throw new Error(`Missing required field(s): ${C}
193
+ Usage: coinbase ${i} ${e.pathParams.map(L=>`<${L}>`).join(" ")} [fields...]`)}let{parseFields:a}=await Promise.resolve().then(()=>(tr(),Je)),E=a(_),g=!1,c={},l=J(),p=Ft(l,n);if(f_(t)&&p&&De(l)){let C=lr(l,p,t);if(C){let{setNested:L}=await Promise.resolve().then(()=>(tr(),Je));for(let[D,v]of Object.entries(C.values))try{L(c,D,JSON.parse(v))}catch{L(c,D,v)}g=!0}}let A=e.params??[];for(let C of Object.keys(E.body)){let L=A.find(D=>D.name===C);if(L?.oneOf)for(let D of A)D.oneOf===L.oneOf&&D.name!==C&&delete c[D.name]}let N=Object.keys(E.body).length>0?{...c,...E.body}:g?(process.stderr.write(`Using saved values from last ${i} call. Pass fields to override.
194
+ `),{...c}):{...E.body},f={};for(let[C,L]of E.query.entries())f[C]=L;let M={};for(let C=0;C<s.length;C++)M[e.pathParams[C]]=s[C];if(!r.flags.watch&&!r.flags.until){let L=e.pathParams.some(D=>typeof M[D]=="string"&&M[D].includes(","))?ot(t):null;if(L){let{surfaceForChannel:D}=await Promise.resolve().then(()=>(ge(),tn)),v=hc(t,e.pathParams,M,D(L)==="watchlist");if(v)throw new Error(v)}}let k=A.filter(C=>C.in==="body"&&C.required&&C.type!=="object"&&C.type!=="array"),q=k.map(C=>C.name);if(q.length>0&&Object.keys(N).length===0&&!r.flags.edit&&!E.rawBody)if(process.stdin.isTTY)if(k.length<=3){let{createInterface:C}=await import("node:readline"),L=C({input:process.stdin,output:process.stderr});for(let D of k){let v=D.enum?` [${D.enum.join(", ")}]`:"",at=D.example?` (e.g. ${D.example})`:"",w=await new Promise(Ct=>{L.question(`${D.name}${v}${at}: `,Ct)});w&&(N[D.name]=w)}L.close()}else process.stderr.write(`This action requires ${q.length} fields. Opening editor.
195
+ `),r.flags.edit=!0;else{let C=q.join(", ");throw new Error(`Missing required field(s): ${C}
196
196
 
197
197
  Provide fields inline:
198
- coinbase ${t.replace(/_/g," ")} ${v.map(U=>`${U}=<value>`).join(" ")}
198
+ coinbase ${i} ${q.map(L=>`${L}=<value>`).join(" ")}
199
199
 
200
200
  Or use --template to see the full body:
201
- coinbase ${t.replace(/_/g," ")} --template
202
- `)}if(r.flags.edit){let U={...e.template??{},...T},D=await Uc(JSON.stringify(U,null,2));for(let V of Object.keys(T))delete T[V];Object.assign(T,D)}if(r.flags["dry-run"]){process.stderr.write(`would execute ${t}
203
- `);let C={...f,...T,...Object.keys(N).length>0?{_query:N}:{}};process.stdout.write(JSON.stringify(C,null,2)+`
204
- `);return}let Q=Ve(),{name:y,env:h}=re(c,n),x=await ee(y,h),$={envName:y,env:h,baseURL:nt(h,y),doRequest:C=>ke({...C,...x}),transport:r.flags.watch||r.flags.until?"brokerage":Q};if(r.flags.watch||r.flags.until){let{startWatch:C}=await Promise.resolve().then(()=>(ge(),tn)),U=i.length>0?i.flatMap(B=>B.split(",")).filter(Boolean):[],D=r.flags.depth?Number(r.flags.depth):void 0,V=r.flags["until-timeout"]?Number(r.flags["until-timeout"]):void 0;if(D!==void 0&&(!Number.isFinite(D)||D<1))throw new Error(`Invalid --depth value: ${r.flags.depth}`);if(V!==void 0&&(!Number.isFinite(V)||V<1))throw new Error(`Invalid --until-timeout value: ${r.flags["until-timeout"]}`);await C(t,U,$,{jq:r.flags.jq,depth:D,until:r.flags.until,untilTimeout:V,query:Object.keys(N).length>0?N:void 0});return}let at={body:T,query:{...N},path:f,headers:a.headers,rawBody:a.rawBody??void 0},{outputResult:ct}=await Promise.resolve().then(()=>(C_(),S_)),Lt=0;do{let C=await Wt(t,at,$);if(ct(C,r.flags.jq),P_(t)&&C.status<400&&Object.keys(T).length>0)try{if(l&&De(c)){let D={};(function V(B,Ct){for(let[G,It]of Object.entries(Ct)){let I=B?`${B}.${G}`:G;typeof It=="object"&&It&&!Array.isArray(It)?V(I,It):D[I]=JSON.stringify(It)}})("",T),Ir(c,l,t,D),ut(c)}}catch{}if(!r.flags.paginate)break;let U=N_(C.data);if(!U||U===at.query.cursor)break;if(at.query.cursor=U,++Lt>=100){process.stderr.write(`Pagination limit reached (100 pages)
205
- `);break}}while(!0)}function Lc(){if(process.platform!=="win32")return"vi";try{let{execSync:t}=h_("node:child_process");return t("where code",{stdio:"pipe"}),"code --wait"}catch{}return"notepad"}function hc(t){return t.split(`
201
+ coinbase ${i} --template
202
+ `)}if(r.flags.edit){let L={...e.template??{},...N},D=await kc(JSON.stringify(L,null,2));for(let v of Object.keys(N))delete N[v];Object.assign(N,D)}if(r.flags["dry-run"]){process.stderr.write(`would execute ${t}
203
+ `);let C={...M,...N,...Object.keys(f).length>0?{_query:f}:{}};process.stdout.write(JSON.stringify(C,null,2)+`
204
+ `);return}let b=ke(),{name:U,env:V}=re(l,n),$=await ee(U,V),lt={envName:U,env:V,baseURL:nt(V,U),doRequest:C=>Me({...C,...$}),transport:r.flags.watch||r.flags.until?"brokerage":b};if(r.flags.watch||r.flags.until){let{startWatch:C}=await Promise.resolve().then(()=>(ge(),tn)),L=s.length>0?s.flatMap(at=>at.split(",")).filter(Boolean):[],D=r.flags.depth?Number(r.flags.depth):void 0,v=r.flags["until-timeout"]?Number(r.flags["until-timeout"]):void 0;if(D!==void 0&&(!Number.isFinite(D)||D<1))throw new Error(`Invalid --depth value: ${r.flags.depth}`);if(v!==void 0&&(!Number.isFinite(v)||v<1))throw new Error(`Invalid --until-timeout value: ${r.flags["until-timeout"]}`);await C(t,L,lt,{jq:r.flags.jq,depth:D,until:r.flags.until,untilTimeout:v,query:Object.keys(f).length>0?f:void 0});return}let et={body:N,query:{...f},path:M,headers:E.headers,rawBody:E.rawBody??void 0},{outputResult:Lt}=await Promise.resolve().then(()=>(P_(),C_)),on=0;do{let C=await Wt(t,et,lt);if(Lt(C,r.flags.jq),f_(t)&&C.status<400&&Object.keys(N).length>0)try{if(p&&De(l)){let D={};(function v(at,w){for(let[Ct,I]of Object.entries(w)){let T=at?`${at}.${Ct}`:Ct;typeof I=="object"&&I&&!Array.isArray(I)?v(T,I):D[T]=JSON.stringify(I)}})("",N),gr(l,p,t,D),Et(l)}}catch{}if(!r.flags.paginate)break;let L=S_(C.data);if(!L||L===et.query.cursor)break;if(et.query.cursor=L,++on>=100){process.stderr.write(`Pagination limit reached (100 pages)
205
+ `);break}}while(!0)}function Mc(){if(process.platform!=="win32")return"vi";try{let{execSync:t}=U_("node:child_process");return t("where code",{stdio:"pipe"}),"code --wait"}catch{}return"notepad"}function vc(t){return t.split(`
206
206
  `).filter(e=>!e.trimStart().startsWith("//")).join(`
207
- `)}async function Uc(t){let{writeFileSync:e,readFileSync:r,unlinkSync:n,mkdtempSync:i}=await import("node:fs"),{tmpdir:s}=await import("node:os"),{join:_}=await import("node:path"),{execFileSync:o}=await import("node:child_process"),{scrubbedEnv:a}=await Promise.resolve().then(()=>(it(),Ln));if(!process.stdin.isTTY)throw new Error("--edit requires an interactive terminal. Use --template to get the request body, then pass fields as arguments.");let E=process.env.VISUAL??process.env.EDITOR??Lc();(E.trim()==="code"||E.trim().endsWith("/code"))&&(E+=" --wait");let g=_(i(_(s(),"coinbase-")),"request.json");e(g,t);try{let[c,...l]=E.split(/\s+/);o(c,[...l,g],{stdio:"inherit",env:a()});let p=hc(r(g,"utf8"));return JSON.parse(p)}catch(c){throw new Error(c.message?.includes("Unexpected")?`Edited file is not valid JSON: ${c.message}`:`Editor: ${c.message}`)}finally{try{n(g)}catch{}}}ft();u();d();var le=class extends Error{constructor(e){super(e),this.name="HelpExit"}};function f_(t){let e={children:new Map};for(let r of t){let n=e;for(let i of r.name.split(" "))n.children.has(i)||n.children.set(i,{children:new Map}),n=n.children.get(i);n.action=r}return e}function D_(t,e,r){let n=t,i,s=0,_=[],o=[];for(let c=0;c<e.length;c++){let l=e[c],p=n.children.get(l);if(p){o.push(l),_=[...n.children.keys()],n=p,n.action&&(i=n.action,s=o.length);continue}if(l.includes("=")){let A=l.split("=")[0],T=n.children.get(A);if(T?.action){let N=T.action.pathParams.map(M=>` <${M}>`).join(""),f=o.length>0?`coinbase ${r} ${o.join(" ")}`:`coinbase ${r}`;throw new Error(`Did you mean: ${f} ${T.action.name.split(" ").pop()}${N}`)}}break}if(i)return{action:i,remaining:e.slice(s),siblingNames:_};let a=e[o.length],E=o.length>0?`coinbase ${r} ${o.join(" ")}`:`coinbase ${r}`,g=Mc(n,r);throw a&&a!=="--help"&&a!=="-h"?new Error(`unknown subcommand "${a}" for ${E}
207
+ `)}async function kc(t){let{writeFileSync:e,readFileSync:r,unlinkSync:n,mkdtempSync:i}=await import("node:fs"),{tmpdir:s}=await import("node:os"),{join:_}=await import("node:path"),{execFileSync:o}=await import("node:child_process"),{scrubbedEnv:a}=await Promise.resolve().then(()=>(it(),hn));if(!process.stdin.isTTY)throw new Error("--edit requires an interactive terminal. Use --template to get the request body, then pass fields as arguments.");let E=process.env.VISUAL??process.env.EDITOR??Mc();(E.trim()==="code"||E.trim().endsWith("/code"))&&(E+=" --wait");let g=_(i(_(s(),"coinbase-")),"request.json");e(g,t);try{let[c,...l]=E.split(/\s+/);o(c,[...l,g],{stdio:"inherit",env:a()});let p=vc(r(g,"utf8"));return JSON.parse(p)}catch(c){throw new Error(c.message?.includes("Unexpected")?`Edited file is not valid JSON: ${c.message}`:`Editor: ${c.message}`)}finally{try{n(g)}catch{}}}Rt();u();d();var le=class extends Error{constructor(e){super(e),this.name="HelpExit"}};function D_(t){let e={children:new Map};for(let r of t){let n=e;for(let i of r.name.split(" "))n.children.has(i)||n.children.set(i,{children:new Map}),n=n.children.get(i);n.action=r}return e}function y_(t,e,r){let n=t,i,s=0,_=[],o=[];for(let c=0;c<e.length;c++){let l=e[c],p=n.children.get(l);if(p){o.push(l),_=[...n.children.keys()],n=p,n.action&&(i=n.action,s=o.length);continue}if(l.includes("=")){let A=l.split("=")[0],R=n.children.get(A);if(R?.action){let N=R.action.pathParams.map(M=>` <${M}>`).join(""),f=o.length>0?`coinbase ${r} ${o.join(" ")}`:`coinbase ${r}`;throw new Error(`Did you mean: ${f} ${R.action.name.split(" ").pop()}${N}`)}}break}if(i)return{action:i,remaining:e.slice(s),siblingNames:_};let a=e[o.length],E=o.length>0?`coinbase ${r} ${o.join(" ")}`:`coinbase ${r}`,g=Fc(n,r);throw a&&a!=="--help"&&a!=="-h"?new Error(`unknown subcommand "${a}" for ${E}
208
208
 
209
209
  Available actions:
210
210
  ${g}`):new le(`${E}
211
211
 
212
212
  Available actions:
213
- ${g}`)}function Mc(t,e){let r=[];function n(i){if(i.action){let s=i.action.pathParams.map(_=>` <${_}>`).join("");r.push(` coinbase ${e} ${i.action.name}${s}`)}for(let s of i.children.values())n(s)}return n(t),r.join(`
214
- `)}Me();pe();u();d();function Xt(t,e){let r={},n=[],i=!1,s=new Map;for(let[_,o,a]of e)s.set("--"+_,[_,a]),o&&s.set("-"+o,[_,a]);for(let _=0;_<t.length;_++){let o=t[_];if(o==="-h"||o==="--help"){i=!0;continue}let a=o.indexOf("=");if(a>0&&o.startsWith("--")){let g=s.get(o.slice(0,a));if(g){r[g[0]]=o.slice(a+1);continue}}let E=s.get(o);if(E){r[E[0]]=E[1]?t[++_]??"":!0;continue}if(o.length>2&&o[0]==="-"&&o[1]!=="-"){let g=s.get(o.slice(0,2));if(g?.[1]){r[g[0]]=o.slice(2);continue}}n.push(o)}return{flags:r,args:n,help:i}}process.stdout.on("error",t=>{throw t.code==="EPIPE"&&process.exit(0),t});process.stderr.on("error",t=>{throw t.code==="EPIPE"&&process.exit(0),t});var[vc]=process.versions.node.split(".").map(Number);vc<22&&(process.stderr.write(`coinbase requires Node.js ${22}+. You have: ${process.versions.node}
215
- `),process.exit(1));function kc(){return`Coinbase CLI
213
+ ${g}`)}function Fc(t,e){let r=[];function n(i){if(i.action){let s=i.action.pathParams.map(_=>` <${_}>`).join("");r.push(` coinbase ${e} ${i.action.name}${s}`)}for(let s of i.children.values())n(s)}return n(t),r.join(`
214
+ `)}he();pe();u();d();function Xt(t,e){let r={},n=[],i=!1,s=new Map;for(let[_,o,a]of e)s.set("--"+_,[_,a]),o&&s.set("-"+o,[_,a]);for(let _=0;_<t.length;_++){let o=t[_];if(o==="-h"||o==="--help"){i=!0;continue}let a=o.indexOf("=");if(a>0&&o.startsWith("--")){let g=s.get(o.slice(0,a));if(g){r[g[0]]=o.slice(a+1);continue}}let E=s.get(o);if(E){r[E[0]]=E[1]?t[++_]??"":!0;continue}if(o.length>2&&o[0]==="-"&&o[1]!=="-"){let g=s.get(o.slice(0,2));if(g?.[1]){r[g[0]]=o.slice(2);continue}}n.push(o)}return{flags:r,args:n,help:i}}process.stdout.on("error",t=>{throw t.code==="EPIPE"&&process.exit(0),t});process.stderr.on("error",t=>{throw t.code==="EPIPE"&&process.exit(0),t});var[Vc]=process.versions.node.split(".").map(Number);Vc<22&&(process.stderr.write(`coinbase requires Node.js ${22}+. You have: ${process.versions.node}
215
+ `),process.exit(1));function Gc(){return`Coinbase CLI
216
216
 
217
217
  Usage:
218
218
  coinbase <resource> <action> [fields...]
@@ -239,8 +239,8 @@ Flags:
239
239
  -e, --env <name> Environment override
240
240
  -V, --version Show version
241
241
  -h, --help Show help
242
- `}async function Fc(){let t=process.argv.slice(2),e="",r=[];for(let s=0;s<t.length;s++){let _=t[s];_==="-e"||_==="--env"?e=t[++s]??"":_.startsWith("--env=")?e=_.slice(6):_.startsWith("-e")&&_.length>2?e=_.slice(2):r.push(_)}if(r[0]==="--version"||r[0]==="-V"){process.stdout.write(`coinbase ${gt}
243
- `);return}if(_n=zi(),r.length===0||r[0]==="-h"||r[0]==="--help"||r[0]==="help"){process.stderr.write(kc());return}let[n,...i]=r;if(n==="env"){let s=Xt(i,[["key-id",null,!0],["key-secret",null,!0],["key-file","k",!0],["status",null,!1],["url",null,!0],["brokerage-api-url",null,!0],["agent-api-url",null,!0],["remove",null,!1],["allow-plaintext-secrets",null,!1]]);if(s.help){process.stderr.write(`Manage environments and credentials
242
+ `}async function wc(){let t=process.argv.slice(2),e="",r=[];for(let s=0;s<t.length;s++){let _=t[s];_==="-e"||_==="--env"?e=t[++s]??"":_.startsWith("--env=")?e=_.slice(6):_.startsWith("-e")&&_.length>2?e=_.slice(2):r.push(_)}if(r[0]==="--version"||r[0]==="-V"){process.stdout.write(`coinbase ${dt}
243
+ `);return}if(_n=$i(),r.length===0||r[0]==="-h"||r[0]==="--help"||r[0]==="help"){process.stderr.write(Gc());return}let[n,...i]=r;if(n==="env"){let s=Xt(i,[["key-id",null,!0],["key-secret",null,!0],["key-file","k",!0],["status",null,!1],["url",null,!0],["brokerage-api-url",null,!0],["agent-api-url",null,!0],["remove",null,!1],["allow-plaintext-secrets",null,!1]]);if(s.help){process.stderr.write(`Manage environments and credentials
244
244
 
245
245
  Usage:
246
246
  coinbase env List all environments
@@ -261,14 +261,14 @@ Flags:
261
261
  --agent-api-url <url> First-party Agent API URL (includes /api)
262
262
  --remove Remove an environment
263
263
  --allow-plaintext-secrets Persist secrets to ~/.config/coinbase/config.json (mode 0600) when no OS keychain is available. Default: refuse and error.
264
- `);return}await hn(s.args,{keyId:s.flags["key-id"],keySecret:s.flags["key-secret"],keyFile:s.flags["key-file"],status:!!s.flags.status,url:s.flags.url,brokerageApiUrl:s.flags["brokerage-api-url"],agentApiUrl:s.flags["agent-api-url"],remove:!!s.flags.remove,allowPlaintextSecrets:!!s.flags["allow-plaintext-secrets"],envFlag:e})}else if(n==="history"){let s=Xt(i,[]);if(s.help){process.stderr.write(`View or clear saved request history
264
+ `);return}await Un(s.args,{keyId:s.flags["key-id"],keySecret:s.flags["key-secret"],keyFile:s.flags["key-file"],status:!!s.flags.status,url:s.flags.url,brokerageApiUrl:s.flags["brokerage-api-url"],agentApiUrl:s.flags["agent-api-url"],remove:!!s.flags.remove,allowPlaintextSecrets:!!s.flags["allow-plaintext-secrets"],envFlag:e})}else if(n==="history"){let s=Xt(i,[]);if(s.help){process.stderr.write(`View or clear saved request history
265
265
 
266
266
  Usage:
267
267
  coinbase history Show all saved history
268
268
  coinbase history clear Clear all history
269
269
  coinbase history clear <env> Clear history for an environment
270
270
  coinbase history clear <env>.<action> Clear a specific entry
271
- `);return}os(s.args)}else if(n==="skills")await Ts(i);else if(n==="mcp"){if(Xt(i,[]).help){process.stderr.write(`MCP server for AI agent integration
271
+ `);return}as(s.args)}else if(n==="skills")await Rs(i);else if(n==="mcp"){if(Xt(i,[]).help){process.stderr.write(`MCP server for AI agent integration
272
272
 
273
273
  Usage:
274
274
  coinbase mcp Start MCP server over stdio
@@ -276,9 +276,9 @@ Usage:
276
276
  The MCP server implements the Model Context Protocol (JSON-RPC over
277
277
  stdin/stdout) and exposes brokerage and x402 API resources as tools. It is
278
278
  typically invoked automatically by AI agents, not run directly.
279
- `);return}_s()}else if(O_(n)){let s=Z[n];s||(process.stderr.write(`error: "${n}" is not available
280
- `),process.exit(1));let _=Xt(i,[["template",null,!1],["dry-run",null,!1],["edit",null,!1],["jq",null,!0],["paginate",null,!1],["watch",null,!1],["depth",null,!0],["until",null,!0],["until-timeout",null,!0]]);if(_.help){rn(n,s);return}await sn(n,s,_,e)}else{let s=en().find(g=>g.name===n);if(s||(process.stderr.write(`error: unknown command "${n}"
279
+ `);return}os()}else if(m_(n)){let s=Q[n];s||(process.stderr.write(`error: "${n}" is not available
280
+ `),process.exit(1));let _=Xt(i,[["template",null,!1],["dry-run",null,!1],["edit",null,!1],["jq",null,!0],["paginate",null,!1],["watch",null,!1],["depth",null,!0],["until",null,!0],["until-timeout",null,!0]]);if(_.help){rn(n,s);return}await sn(s.id,s,_,e,n)}else{let s=en().find(g=>g.name===n);if(s||(process.stderr.write(`error: unknown command "${n}"
281
281
  Run: coinbase --help
282
- `),process.exit(1)),i.length===0||i[0]==="-h"||i[0]==="--help"){A_(n);return}let _=f_(s.actions),o=D_(_,i,n),a=Xt(o.remaining,[["template",null,!1],["dry-run",null,!1],["edit",null,!1],["jq",null,!0],["paginate",null,!1],["watch",null,!1],["depth",null,!0],["until",null,!0],["until-timeout",null,!0]]);if(a.help){rn(n,o.action);return}let E=o.action.id??`${n}_${o.action.name.replace(/[-\s]/g,"_")}`;await sn(E,o.action,a,e)}}var _n;Fc().catch(t=>{t instanceof le&&(process.stderr.write(t.message+`
282
+ `),process.exit(1)),i.length===0||i[0]==="-h"||i[0]==="--help"){N_(n);return}let _=D_(s.actions),o=y_(_,i,n),a=Xt(o.remaining,[["template",null,!1],["dry-run",null,!1],["edit",null,!1],["jq",null,!0],["paginate",null,!1],["watch",null,!1],["depth",null,!0],["until",null,!0],["until-timeout",null,!0]]);if(a.help){rn(n,o.action);return}let E=o.action.id??`${n}_${o.action.name.replace(/[-\s]/g,"_")}`;await sn(E,o.action,a,e)}}var _n;wc().catch(t=>{t instanceof le&&(process.stderr.write(t.message+`
283
283
  `),process.exit(0)),process.stderr.write(`error: ${t.message}
284
284
  `),process.exit(1)}).finally(async()=>{if(!_n||!process.stderr.isTTY)return;let t=await _n.catch(()=>"");t&&process.stderr.write(t)});