@coinbase/coinbase-cli 0.0.1 → 0.0.2

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,6 +1,5 @@
1
1
  #!/usr/bin/env node
2
- var hn=Object.defineProperty;var Pn=(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 C=(t,e)=>()=>(t&&(e=t(t=0)),e);var Ht=(t,e)=>{for(var r in e)hn(t,r,{get:e[r],enumerable:!0})};var m,u=C(()=>{m={live:"https://api.coinbase.com"}});var y,g=C(()=>{y={production:"live"}});var Pe,Rt,ke,Re,vt=C(()=>{"use strict";u();g();Pe="@coinbase/coinbase-cli",Rt="https://registry.npmjs.org",ke=typeof m<"u"?m:{live:"https://api.coinbase.com"},Re=typeof y<"u"?y:{production:"live"}});function et(t){return jt+Buffer.from(t,"utf8").toString("base64")}function rt(t){return t.startsWith(jt)?Buffer.from(t.slice(jt.length),"base64").toString("utf8"):t}var jt,Tt=C(()=>{"use strict";u();g();jt="b64:"});import{execFileSync as At}from"node:child_process";var xt,St,ve=C(()=>{"use strict";u();g();Tt();xt="/usr/bin/security",St=class{constructor(){try{At(xt,["list-keychains"],{stdio:["pipe","pipe","pipe"]})}catch{throw new Error("Keychain not accessible")}}get(e,r){try{let n=At(xt,["find-generic-password","-s",e,"-a",r,"-w"],{encoding:"utf8",stdio:["pipe","pipe","pipe"]}).trimEnd();return rt(n)}catch{return null}}set(e,r,n){if(/[\x00-\x1f\x7f]/.test(e)||/[\x00-\x1f\x7f]/.test(r))throw new Error("keychain: control characters in service or account name");let i=o=>`"${o.replace(/(["\\])/g,"\\$1")}"`,s=`add-generic-password -U -s ${i(e)} -a ${i(r)} -w ${et(n)}
3
- `;if(At(xt,["-i"],{input:s,stdio:["pipe","pipe","pipe"]}),this.get(e,r)!==n)throw new Error("Keychain write failed: verify-after-write mismatch")}delete(e,r){try{At(xt,["delete-generic-password","-s",e,"-a",r],{stdio:["pipe","pipe","pipe"]})}catch{}}}});import{execFileSync as Ct}from"node:child_process";var wt,Te=C(()=>{"use strict";u();g();Tt();wt=class{constructor(){try{Ct("which",["secret-tool"],{stdio:["pipe","pipe","pipe"]})}catch{throw new Error("secret-tool not found")}}get(e,r){try{let n=Ct("secret-tool",["lookup","service",e,"account",r],{encoding:"utf8",stdio:["pipe","pipe","pipe"]});return rt(n.trimEnd())}catch{return null}}set(e,r,n){Ct("secret-tool",["store","--label",`${e}:${r}`,"service",e,"account",r],{input:et(n),stdio:["pipe","pipe","pipe"]})}delete(e,r){try{Ct("secret-tool",["clear","service",e,"account",r],{stdio:["pipe","pipe","pipe"]})}catch{}}}});import{execFileSync as vn}from"node:child_process";function Kt(t,e){return`${t}:${e}`}function Nt(t){return t.replace(/'/g,"''")}function Yt(t,e){let r=Tn+t,n=Buffer.from(r,"utf16le").toString("base64"),i=e===void 0?process.env:{...process.env,[Ae]:e};return vn("powershell.exe",["-NoProfile","-NonInteractive","-EncodedCommand",n],{encoding:"utf8",stdio:["pipe","pipe","pipe"],env:i}).trimEnd()}var Tn,Ae,Gt,xe=C(()=>{"use strict";u();g();Tt();Tn=`
2
+ var Vs=Object.defineProperty;var $s=(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 h=(t,e)=>()=>(t&&(e=t(t=0)),e);var qt=(t,e)=>{for(var r in e)Vs(t,r,{get:e[r],enumerable:!0})};var f,g=h(()=>{f={live:"https://api.coinbase.com"}});var b,l=h(()=>{b={production:"live"}});var Wr,ne,Vr,$r,ie=h(()=>{"use strict";g();l();Wr="@coinbase/coinbase-cli",ne="https://registry.npmjs.org",Vr=typeof f<"u"?f:{live:"https://api.coinbase.com"},$r=typeof b<"u"?b:{production:"live"}});function yt(t){return qe+Buffer.from(t,"utf8").toString("base64")}function ht(t){return t.startsWith(qe)?Buffer.from(t.slice(qe.length),"base64").toString("utf8"):t}var qe,se=h(()=>{"use strict";g();l();qe="b64:"});import{execFileSync as oe}from"node:child_process";var ae,ce,Hr=h(()=>{"use strict";g();l();se();ae="/usr/bin/security",ce=class{constructor(){try{oe(ae,["list-keychains"],{stdio:["pipe","pipe","pipe"]})}catch{throw new Error("Keychain not accessible")}}get(e,r){try{let n=oe(ae,["find-generic-password","-s",e,"-a",r,"-w"],{encoding:"utf8",stdio:["pipe","pipe","pipe"]}).trimEnd();return ht(n)}catch{return null}}set(e,r,n){oe(ae,["add-generic-password","-U","-s",e,"-a",r,"-w",yt(n)],{stdio:["pipe","pipe","pipe"]})}delete(e,r){try{oe(ae,["delete-generic-password","-s",e,"-a",r],{stdio:["pipe","pipe","pipe"]})}catch{}}}});import{execFileSync as _e}from"node:child_process";var ue,jr=h(()=>{"use strict";g();l();se();ue=class{constructor(){try{_e("which",["secret-tool"],{stdio:["pipe","pipe","pipe"]})}catch{throw new Error("secret-tool not found")}}get(e,r){try{let n=_e("secret-tool",["lookup","service",e,"account",r],{encoding:"utf8",stdio:["pipe","pipe","pipe"]});return ht(n.trimEnd())}catch{return null}}set(e,r,n){_e("secret-tool",["store","--label",`${e}:${r}`,"service",e,"account",r],{input:yt(n),stdio:["pipe","pipe","pipe"]})}delete(e,r){try{_e("secret-tool",["clear","service",e,"account",r],{stdio:["pipe","pipe","pipe"]})}catch{}}}});import{execFileSync as Ks}from"node:child_process";function ze(t,e){return`${t}:${e}`}function de(t){return t.replace(/'/g,"''")}function We(t,e){let r=Ys+t,n=Buffer.from(r,"utf16le").toString("base64"),i=e===void 0?process.env:{...process.env,[Kr]:e};return Ks("powershell.exe",["-NoProfile","-NonInteractive","-EncodedCommand",n],{encoding:"utf8",stdio:["pipe","pipe","pipe"],env:i}).trimEnd()}var Ys,Kr,ge,Yr=h(()=>{"use strict";g();l();se();Ys=`
4
3
  if (-not ([System.Management.Automation.PSTypeName]'Win32.Cred').Type) {
5
4
  Add-Type -Namespace Win32 -Name Cred -MemberDefinition '
6
5
  [DllImport("advapi32.dll", SetLastError=true, CharSet=CharSet.Unicode)]
@@ -18,7 +17,7 @@ if (-not ([System.Management.Automation.PSTypeName]'Win32.Cred').Type) {
18
17
  public string TargetAlias; public string UserName;
19
18
  }'
20
19
  }
21
- `,Ae="COINBASE_KEYRING_SECRET";Gt=class{get(e,r){try{let n=Nt(Kt(e,r)),i=Yt(`
20
+ `,Kr="COINBASE_KEYRING_SECRET";ge=class{get(e,r){try{let n=de(ze(e,r)),i=We(`
22
21
  $ptr = [IntPtr]::Zero
23
22
  if ([Win32.Cred]::CredRead('${n}', 1, 0, [ref]$ptr)) {
24
23
  $cred = [Runtime.InteropServices.Marshal]::PtrToStructure($ptr, [Type][Win32.Cred+CREDENTIAL])
@@ -26,8 +25,8 @@ if ([Win32.Cred]::CredRead('${n}', 1, 0, [ref]$ptr)) {
26
25
  [Runtime.InteropServices.Marshal]::Copy($cred.CredentialBlob, $bytes, 0, $cred.CredentialBlobSize)
27
26
  [Win32.Cred]::CredFree($ptr)
28
27
  [Text.Encoding]::UTF8.GetString($bytes)
29
- }`);return i?rt(i):null}catch{return null}}set(e,r,n){let i=Nt(Kt(e,r)),s=Nt(r);Yt(`
30
- $sec = $env:${Ae}
28
+ }`);return i?ht(i):null}catch{return null}}set(e,r,n){let i=de(ze(e,r)),s=de(r);We(`
29
+ $sec = $env:${Kr}
31
30
  $bytes = [Text.Encoding]::UTF8.GetBytes($sec)
32
31
  $blob = [Runtime.InteropServices.Marshal]::AllocHGlobal($bytes.Length)
33
32
  [Runtime.InteropServices.Marshal]::Copy($bytes, 0, $blob, $bytes.Length)
@@ -41,77 +40,92 @@ $cred.Persist = 2
41
40
  if (-not [Win32.Cred]::CredWrite([ref]$cred, 0)) {
42
41
  throw "CredWrite failed: $([Runtime.InteropServices.Marshal]::GetLastWin32Error())"
43
42
  }
44
- [Runtime.InteropServices.Marshal]::FreeHGlobal($blob)`,et(n))}delete(e,r){try{Yt(`[void][Win32.Cred]::CredDelete('${Nt(Kt(e,r))}', 1, 0)`)}catch{}}}});function dt(){if($!==void 0)return $;try{process.platform==="darwin"?$=new St:process.platform==="linux"?$=new wt:process.platform==="win32"?$=new Gt:$=null}catch{Se||(process.stderr.write(`warning: OS keychain not accessible \u2014 secrets stored in keychain will not be available
45
- `),Se=!0),$=null}return $}function Ce(t){let e=dt();if(!e)return null;try{return e.get(Q,t)}catch{return null}}function we(t,e){let r=dt();if(!r)return!1;try{return r.set(Q,t,e),!0}catch{return!1}}function Ne(t){let e=dt();if(e)try{e.delete(Q,t)}catch{}}function Ge(){return dt()!==null}function De(){let t=dt();if(!t)return!1;let e="__coinbase_cli_preflight__";try{t.set(Q,e,"ok");let r=t.get(Q,e);return t.delete(Q,e),r==="ok"}catch{try{t.delete(Q,e)}catch{}return!1}}var Q,$,Se,Qt=C(()=>{"use strict";u();g();ve();Te();xe();Q="coinbase-cli",Se=!1});var Ve={};Ht(Ve,{activeEnvName:()=>at,activeEnvironment:()=>mt,authIsViable:()=>Jt,builtinEnvironments:()=>D,clearEnvironmentSecretsFromKeychain:()=>Zt,clearHistory:()=>yt,configDir:()=>H,configPath:()=>L,credentialsFor:()=>lt,envCredential:()=>pt,getHistory:()=>ne,historyEnabled:()=>Lt,hydrateEnvironmentSecrets:()=>Fe,isBuiltinURL:()=>st,loadConfig:()=>w,resolveURL:()=>U,saveConfig:()=>q,scrubbedEnv:()=>ee,setHistory:()=>re,setLockOptions:()=>Gn,withConfigLock:()=>te,writeEnvironmentSecretsToKeychain:()=>ze});import{readFileSync as Ue,writeFileSync as qe,mkdirSync as Be,renameSync as An,unlinkSync as Xt,openSync as xn,closeSync as Sn,statSync as Cn}from"node:fs";import{homedir as Le}from"node:os";import{join as Dt}from"node:path";function H(){if(process.env.COINBASE_CONFIG_DIR)return process.env.COINBASE_CONFIG_DIR;if(process.platform==="win32"){let t=process.env.APPDATA??Dt(Le(),"AppData","Roaming");return Dt(t,"coinbase")}return Dt(Le(),".config","coinbase")}function L(){return Dt(H(),"config.json")}function U(t,e){if(t.url)return t.url;if(D[e])return D[e];let r=Me[e];if(r&&D[r])return D[r];let n={...D};for(let[s,o]of Object.entries(Me))D[o]&&(n[s]=D[o]);let i=Object.keys(n).find(s=>e.startsWith(s+"-"));return i?n[i]:""}function st(t){return Object.values(D).some(e=>t.startsWith(e))}function wn(t,e){return Object.values(ot[e].secrets).map(r=>r(t))}function Jt(t){if(!t)return!1;let e=ot[t.type];return e?Object.keys(e.secrets).every(r=>!!t[r]):!1}function Fe(t,e){if(!e.auth)return e;let r=ot[e.auth.type];if(!r)return e;let n=e.auth,i={...n},s=!1,o=!1;for(let[a,d]of Object.entries(r.secrets)){if(n[a]){o=!0;continue}let c=Ce(d(t));c&&(i[a]=c,s=!0)}return Jt(i)?{...e,auth:i,...o&&!s?{_plaintextBacked:!0}:{}}:{...e,auth:void 0}}function ze(t,e){if(!e.auth)return!0;if(!Ge())return!1;let r=e.auth.type,n=ot[r];if(!n)return!0;if(!Jt(e.auth)){let s=Object.keys(n.secrets).filter(o=>!e.auth[o]);throw new Error(`writeEnvironmentSecretsToKeychain: ${r} for "${t}" missing ${s.join(", ")}`)}let i=!0;for(let[s,o]of Object.entries(n.secrets))we(o(t),e.auth[s])||(i=!1);return i}function Zt(t){for(let e of Object.keys(ot))for(let r of wn(t,e))Ne(r)}function pt(t){return t.auth}function lt(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 w(){let t={env:"",environments:{},history:{}};try{let e=Ue(L(),"utf8"),r=JSON.parse(e);t.env=r.env??"";let n=r.environments??{};for(let[i,s]of Object.entries(n))t.environments[i]=Fe(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 q(t,e={}){let r=H();Be(r,{recursive:!0,mode:448});let n={},i=[];for(let[d,c]of Object.entries(t.environments)){let _={};if(c.url!==void 0&&(_.url=c.url),!c.auth){n[d]=_;continue}let l=ze(d,c),I=e.allowPlaintext===!0||c._plaintextBacked===!0;if(!l){if(!I){i.push(d);continue}_.auth=c.auth,n[d]=_;continue}let O=ot[c.auth.type];O&&(_.auth=O.metadataOnly(c.auth)),n[d]=_}if(i.length)throw new Error(`OS keychain unavailable; refusing to persist secrets for environment(s): ${i.join(", ")}.
46
- Re-run the env-setup command with --allow-plaintext-secrets to write secrets to ${L()} (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 o=L(),a=`${o}.${process.pid}.${Date.now()}.tmp`;try{qe(a,JSON.stringify(s,null,2)+`
47
- `,{mode:384}),An(a,o)}catch(d){try{Xt(a)}catch{}throw d}}function Gn(t){nt={...nt,...t}}function it(){return L()+Nn}function Dn(t){let e=Date.now()+t;for(;Date.now()<e;);}function Ln(){try{let t=xn(it(),"wx",384);return qe(t,String(process.pid)),t}catch(t){if(t.code!=="EEXIST")throw t;return null}}function Mn(){try{let t=Cn(it());if(Date.now()-t.mtimeMs<nt.staleAfterMs)return!1;let e=Ue(it(),"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 te(t){Be(H(),{recursive:!0,mode:448});let e=null;for(let r=0;r<nt.retries&&(e=Ln(),e===null);r++){if(Mn()){try{Xt(it())}catch{}continue}Dn(nt.baseDelayMs*(1+Math.random()))}if(e===null)throw new Error(`could not acquire config lock after ${nt.retries} attempts: ${it()}`);try{return t()}finally{try{Sn(e)}catch{}try{Xt(it())}catch{}}}function at(t,e){return e||process.env.COINBASE_ENV||t.env}function mt(t,e){let r=at(t,e);if(!r)throw new Error("no environment configured. Run: coinbase env <name>");let n={...t.environments[r]},i=process.env.COINBASE_KEY_ID,s=process.env.COINBASE_KEY_SECRET;if(s&&delete process.env.COINBASE_KEY_SECRET,i&&delete process.env.COINBASE_KEY_ID,i||s){let a=n.auth?.type==="cdp_key"?n.auth:void 0,d=i??a?.key_id??"",c=s??a?.key_secret??"";d&&c&&(n.auth={type:"cdp_key",key_id:d,key_secret:c})}if(process.env.COINBASE_URL&&(n.url=process.env.COINBASE_URL,st(n.url)||process.stderr.write(`warning: COINBASE_URL overrides to non-standard endpoint: ${n.url}
48
- `)),!U(n,r))throw new Error(`no URL for environment "${r}". Set url in config or use a built-in env 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 ee(){let t={...process.env};for(let e of Un)delete t[e];return t}function Lt(t){return process.env.COINBASE_NO_HISTORY?!1:t.settings?.history?.enabled!==!1}function re(t,e,r,n){t.history[e]||(t.history[e]={}),t.history[e][r]={last_used:new Date().toISOString(),values:n}}function ne(t,e,r){return t.history[e]?.[r]}function yt(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 D,Me,ot,Nn,nt,Un,M=C(()=>{"use strict";u();g();vt();Qt();D=ke,Me=Re;ot={cdp_key:{secrets:{key_secret:t=>`${t}:cdp:key_secret`},metadataOnly:t=>({type:"cdp_key",key_id:t.key_id})}};Nn=".lock",nt={retries:50,baseDelayMs:20,staleAfterMs:5e3};Un=["COINBASE_KEY_SECRET","COINBASE_KEY_ID"]});var Wt={};Ht(Wt,{bodyBytes:()=>gs,hasBody:()=>us,isFieldArg:()=>ps,parseFields:()=>_s,setNested:()=>Ie});import{readFileSync as ns,openSync as is,readSync as ss,closeSync as os}from"node:fs";function _s(t,e=as){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(cs(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{Ie(r.body,s,JSON.parse(n.slice(i+1)))}catch(o){throw new Error(`invalid JSON in ${s}: ${o.message}`)}}else n[i+1]==="="?r.query.append(n.slice(0,i),n.slice(i+2)):Ie(r.body,n.slice(0,i),n.slice(i+1))}return r}function cs(t){let e=t.indexOf(":");return e<=0||t.slice(0,e).includes("=")?!1:t[0]>="A"&&t[0]<="Z"}function us(t){return Object.keys(t.body).length>0||t.rawBody!==null}function gs(t){return t.rawBody?t.rawBody:Object.keys(t.body).length===0?null:new TextEncoder().encode(JSON.stringify(t.body))}function ps(t){return!!(t.includes("=")||t.startsWith("@")||t.startsWith("-")||t.indexOf(":")>0&&t[0]>="A"&&t[0]<="Z")}function Ie(t,e,r){let n=e.split("."),i=t;for(let s=0;s<n.length;s++){let o=n[s];if(ds.has(o))throw new Error(`invalid field name: ${o}`);if(s===n.length-1){Object.defineProperty(i,o,{value:r,writable:!0,enumerable:!0,configurable:!0});return}(!Object.hasOwn(i,o)||typeof i[o]!="object"||i[o]===null)&&Object.defineProperty(i,o,{value:{},writable:!0,enumerable:!0,configurable:!0}),i=i[o]}}var as,ds,$t=C(()=>{"use strict";u();g();as={readFile(t){try{return ns(t)}catch(e){throw new Error(`reading file ${t}: ${e.message}`)}},readStdin(){let t=[],e=Buffer.alloc(65536),r;try{r=is("/dev/stdin","r")}catch{throw new Error("reading stdin: cannot open")}try{let n;for(;(n=ss(r,e))>0;)t.push(Buffer.from(e.subarray(0,n)))}catch{}return os(r),Buffer.concat(t)}};ds=new Set(["__proto__","constructor","prototype"])});import{execFileSync as ls}from"node:child_process";function mn(t,e){try{return ls("jq",["-r",e],{input:t,encoding:"utf8",maxBuffer:10*1024*1024,env:ee()}).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 yn=C(()=>{"use strict";u();g();M()});var bn={};Ht(bn,{outputResult:()=>ms});function ms(t,e){let r=JSON.stringify(t.data),n=t.status>=400;if(e)try{process.stdout.write(mn(new TextEncoder().encode(r),e)+`
43
+ [Runtime.InteropServices.Marshal]::FreeHGlobal($blob)`,yt(n))}delete(e,r){try{We(`[void][Win32.Cred]::CredDelete('${de(ze(e,r))}', 1, 0)`)}catch{}}}});function zt(){if(st!==void 0)return st;try{process.platform==="darwin"?st=new ce:process.platform==="linux"?st=new ue:process.platform==="win32"?st=new ge:st=null}catch{Qr||(process.stderr.write(`warning: OS keychain not accessible \u2014 secrets stored in keychain will not be available
44
+ `),Qr=!0),st=null}return st}function Jr(t){let e=zt();if(!e)return null;try{return e.get(gt,t)}catch{return null}}function Xr(t,e){let r=zt();if(!r)return!1;try{return r.set(gt,t,e),!0}catch{return!1}}function Zr(t){let e=zt();if(e)try{e.delete(gt,t)}catch{}}function tn(){return zt()!==null}function en(){let t=zt();if(!t)return!1;let e="__coinbase_cli_preflight__";try{t.set(gt,e,"ok");let r=t.get(gt,e);return t.delete(gt,e),r==="ok"}catch{try{t.delete(gt,e)}catch{}return!1}}var gt,st,Qr,Ve=h(()=>{"use strict";g();l();Hr();jr();Yr();gt="coinbase-cli",Qr=!1});var un={};qt(un,{activeEnvName:()=>vt,activeEnvironment:()=>$t,authIsViable:()=>Ke,builtinEnvironments:()=>K,clearEnvCredentialCache:()=>Je,clearEnvironmentSecretsFromKeychain:()=>Ye,clearHistory:()=>Ht,configDir:()=>ot,configPath:()=>Y,credentialsFor:()=>Vt,envCredential:()=>Wt,getHistory:()=>tr,historyEnabled:()=>pe,hydrateEnvironmentSecrets:()=>cn,isBuiltinURL:()=>Ot,loadConfig:()=>j,resolveURL:()=>Z,saveConfig:()=>tt,scrubbedEnv:()=>Xe,setHistory:()=>Ze,setLockOptions:()=>ro,withConfigLock:()=>Qe,writeEnvironmentSecretsToKeychain:()=>_n});import{readFileSync as sn,writeFileSync as on,mkdirSync as an,renameSync as Qs,unlinkSync as $e,openSync as Js,closeSync as Xs,statSync as Zs}from"node:fs";import{homedir as rn}from"node:os";import{join as le}from"node:path";function ot(){if(process.env.COINBASE_CONFIG_DIR)return process.env.COINBASE_CONFIG_DIR;if(process.platform==="win32"){let t=process.env.APPDATA??le(rn(),"AppData","Roaming");return le(t,"coinbase")}return le(rn(),".config","coinbase")}function Y(){return le(ot(),"config.json")}function Z(t,e){if(t.url)return t.url;if(K[e])return K[e];let r=nn[e];if(r&&K[r])return K[r];let n={...K};for(let[s,a]of Object.entries(nn))K[a]&&(n[s]=K[a]);let i=Object.keys(n).find(s=>e.startsWith(s+"-"));return i?n[i]:""}function Ot(t){return Object.values(K).some(e=>t.startsWith(e))}function to(t,e){return Object.values(kt[e].secrets).map(r=>r(t))}function Ke(t){if(!t)return!1;let e=kt[t.type];return e?Object.keys(e.secrets).every(r=>!!t[r]):!1}function cn(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,a=!1;for(let[o,c]of Object.entries(r.secrets)){if(n[o]){a=!0;continue}let _=Jr(c(t));_&&(i[o]=_,s=!0)}return Ke(i)?{...e,auth:i,...a&&!s?{_plaintextBacked:!0}:{}}:{...e,auth:void 0}}function _n(t,e){if(!e.auth)return!0;if(!tn())return!1;let r=e.auth.type,n=kt[r];if(!n)return!0;if(!Ke(e.auth)){let s=Object.keys(n.secrets).filter(a=>!e.auth[a]);throw new Error(`writeEnvironmentSecretsToKeychain: ${r} for "${t}" missing ${s.join(", ")}`)}let i=!0;for(let[s,a]of Object.entries(n.secrets))Xr(a(t),e.auth[s])||(i=!1);return i}function Ye(t){for(let e of Object.keys(kt))for(let r of to(t,e))Zr(r)}function Wt(t){return t.auth}function Vt(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=sn(Y(),"utf8"),r=JSON.parse(e);t.env=r.env??"";let n=r.environments??{};for(let[i,s]of Object.entries(n))t.environments[i]=cn(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 tt(t,e={}){let r=ot();an(r,{recursive:!0,mode:448});let n={},i=[];for(let[c,_]of Object.entries(t.environments)){let u={};if(_.url!==void 0&&(u.url=_.url),!_.auth){n[c]=u;continue}let d=_n(c,_),p=e.allowPlaintext===!0||_._plaintextBacked===!0;if(!d){if(!p){i.push(c);continue}u.auth=_.auth,n[c]=u;continue}let y=kt[_.auth.type];y&&(u.auth=y.metadataOnly(_.auth)),n[c]=u}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 ${Y()} (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 a=Y(),o=`${a}.${process.pid}.${Date.now()}.tmp`;try{on(o,JSON.stringify(s,null,2)+`
46
+ `,{mode:384}),Qs(o,a)}catch(c){try{$e(o)}catch{}throw c}}function ro(t){Et={...Et,...t}}function It(){return Y()+eo}function no(t){let e=Date.now()+t;for(;Date.now()<e;);}function io(){try{let t=Js(It(),"wx",384);return on(t,String(process.pid)),t}catch(t){if(t.code!=="EEXIST")throw t;return null}}function so(){try{let t=Zs(It());if(Date.now()-t.mtimeMs<Et.staleAfterMs)return!1;let e=sn(It(),"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 Qe(t){an(ot(),{recursive:!0,mode:448});let e=null;for(let r=0;r<Et.retries&&(e=io(),e===null);r++){if(so()){try{$e(It())}catch{}continue}no(Et.baseDelayMs*(1+Math.random()))}if(e===null)throw new Error(`could not acquire config lock after ${Et.retries} attempts: ${It()}`);try{return t()}finally{try{Xs(e)}catch{}try{$e(It())}catch{}}}function Je(){He=void 0,je=void 0}function oo(){return process.env.COINBASE_KEY_ID&&(He=process.env.COINBASE_KEY_ID,delete process.env.COINBASE_KEY_ID),process.env.COINBASE_KEY_SECRET&&(je=process.env.COINBASE_KEY_SECRET,delete process.env.COINBASE_KEY_SECRET),{keyId:He,keySecret:je}}function vt(t,e){return e||process.env.COINBASE_ENV||t.env}function $t(t,e){let r=vt(t,e);if(!r)throw new Error("no environment configured. Run: coinbase env <name>");let n={...t.environments[r]},{keyId:i,keySecret:s}=oo();if(i||s){let o=n.auth?.type==="cdp_key"?n.auth:void 0,c=i??o?.key_id??"",_=s??o?.key_secret??"";c&&_&&(n.auth={type:"cdp_key",key_id:c,key_secret:_})}if(process.env.COINBASE_URL&&(n.url=process.env.COINBASE_URL,Ot(n.url)||process.stderr.write(`warning: COINBASE_URL overrides to non-standard endpoint: ${n.url}
47
+ `)),!Z(n,r))throw new Error(`no URL for environment "${r}". Set url in config or use a built-in env 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 Xe(){let t={...process.env};for(let e of ao)delete t[e];return t}function pe(t){return process.env.COINBASE_NO_HISTORY?!1:t.settings?.history?.enabled!==!1}function Ze(t,e,r,n){t.history[e]||(t.history[e]={}),t.history[e][r]={last_used:new Date().toISOString(),values:n}}function tr(t,e,r){return t.history[e]?.[r]}function Ht(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 K,nn,kt,eo,Et,He,je,ao,Q=h(()=>{"use strict";g();l();ie();Ve();K=Vr,nn=$r;kt={cdp_key:{secrets:{key_secret:t=>`${t}:cdp:key_secret`},metadataOnly:t=>({type:"cdp_key",key_id:t.key_id})}};eo=".lock",Et={retries:50,baseDelayMs:20,staleAfterMs:5e3};ao=["COINBASE_KEY_SECRET","COINBASE_KEY_ID"]});function mo(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,X,gn,ln,pn,Pt=h(()=>{"use strict";g();l();J=[{name:"convert",actions:[{id:"convert_quote",name:"quote",method:"POST",path:"/convert/quote",summary:"Get Convert Quote",description:"",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,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"]}}}},{id:"convert_execute",name:"execute",method:"POST",path:"/convert/execute/{quote_id}",summary:"Execute Convert Trade",description:"",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,template:{from:"USDC",to:"USD"},responseFields:{fields:["trade"],nested:{trade:{fields:["id","status"]}}}},{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,template:{},responseFields:{fields:["id","status","source_currency","target_currency","exchange_rate"]}}]},{name:"orders",actions:[{id:"orders_list",name:"list",method:"GET",path:"/orders",summary:"List Orders",description:"",pathParams:[],params:[{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"]},{name:"product_type",in:"query",type:"string",required:!1,description:"Filter by product type",enum:["SPOT","FUTURE"]},{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:"number",description:"Average filled price"},filled_size:{type:"number",description:"Filled quantity"},fees:{type:"number",description:"Total fees"},product_id:{type:"string",description:"Trading pair"},order_id:{type:"string",description:"Order ID"}},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"]}}}},{id:"orders_create",name:"create",method:"POST",path:"/orders",summary:"Create Order",description:"",pathParams:[],params:[{name:"product_id",in:"body",type:"string",required:!0,description:"Trading pair",example:"BTC-USD"},{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). Market buy only. 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. buy 0.001 BTC). Any side/type.",oneOf:"base_size|quote_size",example:"0.001"},{name:"limit_price",in:"body",type:"string",required:!1,description:"Limit price (limit/stop_limit orders)"},{name:"stop_price",in:"body",type:"string",required:!1,description:"Stop price (stop_limit orders)"},{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"]},{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"]},{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"},{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:"Scopes the order to a specific portfolio (defaults to auth-scoped portfolio)"},{name:"client_order_id",in:"body",type:"string",required:!1,description:"Idempotency key (auto-generated if omitted)"}],streamable:!1,watchFields:null,template:{product_id:"BTC-USD",side:"BUY",type:"market",quote_size:"100.00",base_size:"0.001",limit_price:"<string>",stop_price:"<string>",stop_direction:"up",post_only:!1,time_in_force:"GTC",end_time:"<string>",reduce_only:!1,portfolio_id:"<string>",client_order_id:"<string>"},responseFields:{fields:["order_id","product_id","side","client_order_id"]}},{id:"orders_preview",name:"preview",method:"POST",path:"/orders/preview",summary:"Preview Order",description:"Estimate fees, fill price, and slippage without executing.",pathParams:[],params:[{name:"product_id",in:"body",type:"string",required:!0,description:"Trading pair (e.g. BTC-USD)",example:"BTC-USD"},{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"},{name:"limit_price",in:"body",type:"string",required:!1,description:"Limit price (for limit/stop_limit previews)"},{name:"stop_price",in:"body",type:"string",required:!1,description:"Stop price (for stop_limit previews)"},{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"]}],streamable:!1,watchFields:null,template:{product_id:"BTC-USD",side:"BUY",type:"market",quote_size:"100.00",base_size:"<string>",limit_price:"<string>",stop_price:"<string>",stop_direction:"up"},responseFields:{fields:["order_total","commission_total","slippage","est_average_filled_price","base_size","quote_size","best_bid","best_ask"]}},{id:"orders_edit",name:"edit",method:"POST",path:"/orders/edit",summary:"Edit Order",description:"Atomically update an open order's price or size without cancelling. Avoids the cancel+replace exposure window.",pathParams:[],params:[{name:"order_id",in:"body",type:"string",required:!0,description:"Order to edit"},{name:"base_size",in:"body",type:"string",required:!1,description:"New base size"},{name:"limit_price",in:"body",type:"string",required:!1,description:"New limit price"}],streamable:!1,watchFields:null,template:{order_id:"<string>",base_size:"<string>",limit_price:"<string>"},responseFields:{fields:["order_id","status"]}},{id:"orders_get",name:"get",method:"GET",path:"/orders/{order_id}",summary:"Get Order",description:"",pathParams:["order_id"],params:[{name:"order_id",in:"path",type:"string",required:!0,description:"Order ID"}],streamable:!1,watchFields: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"]}},{id:"orders_cancel",name:"cancel",method:"POST",path:"/orders/cancel",summary:"Cancel Orders",description:"",pathParams:[],params:[{name:"order_ids",in:"body",type:"array",required:!0,description:"Order IDs to cancel"}],streamable:!1,watchFields:null,template:{order_ids:[]},responseFields:{fields:["results"],nested:{results:{fields:["success","order_id"]}}}},{id:"orders_close_position",name:"close-position",method:"POST",path:"/orders/close-position",summary:"Close Position",description:"",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"},{name:"size",in:"body",type:"string",required:!1,description:"Partial close size (omit for full close)"}],streamable:!1,watchFields:null,template:{client_order_id:"<string>",product_id:"<string>",size:"<string>"},responseFields:null},{id:"orders_fills",name:"fills",method:"GET",path:"/orders/fills",summary:"List Fills",description:"",pathParams:[],params:[{name:"product_ids",in:"query",type:"string",required:!1,description:"Filter by product (e.g. BTC-USD)"},{name:"order_ids",in:"query",type:"string",required:!1,description:"Filter by order ID"},{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:"side",in:"query",type:"string",required:!1,description:"Filter by side",enum:["BUY","SELL"]},{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,template:{},responseFields:{fields:["fills","cursor"],nested:{fills:{fields:["trade_id","order_id","trade_time","price","size","commission","product_id","side","liquidity_indicator"]}}}}]},{name:"portfolios",actions:[{id:"portfolios_list",name:"list",method:"GET",path:"/portfolios",summary:"List Portfolios",description:"",pathParams:[],params:[{name:"portfolio_type",in:"query",type:"string",required:!1,description:"Filter by type (DEFAULT, CONSUMER, INTX)"}],streamable:!1,watchFields:null,template:{},responseFields:{fields:["portfolios"],nested:{portfolios:{fields:["uuid","name","type","deleted"]}}}},{id:"portfolios_create",name:"create",method:"POST",path:"/portfolios",summary:"Create Portfolio",description:"",pathParams:[],params:[{name:"name",in:"body",type:"string",required:!0,description:"Portfolio name",example:"agent-1"}],streamable:!1,watchFields:null,template:{name:"agent-1"},responseFields:{fields:["uuid","name","type","deleted"]}},{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,template:{},responseFields:{fields:["portfolio","portfolio_balances","spot_positions"],nested:{portfolio:{fields:["uuid","name","type","deleted"]},portfolio_balances:{fields:["total_balance","total_crypto_balance","total_cash_equivalent_balance"],nested:{total_balance:{fields:["value","currency"]},total_crypto_balance:{fields:["value","currency"]},total_cash_equivalent_balance:{fields:["value","currency"]}}},spot_positions:{fields:["asset","account_uuid","total_balance_fiat","total_balance_crypto","available_to_trade_fiat","allocation","is_cash"]}}}},{id:"portfolios_edit",name:"edit",method:"PUT",path:"/portfolios/{portfolio_id}",summary:"Edit Portfolio",description:"",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,template:{name:"<string>"},responseFields:{fields:["uuid","name","type","deleted"]}},{id:"portfolios_delete",name:"delete",method:"DELETE",path:"/portfolios/{portfolio_id}",summary:"Delete Portfolio",description:"",pathParams:["portfolio_id"],params:[{name:"portfolio_id",in:"path",type:"string",required:!0,description:"Portfolio UUID"}],streamable:!1,watchFields:null,template:{},responseFields:null}]},{name:"products",actions:[{id:"products_list",name:"list",method:"GET",path:"/products",summary:"List Products",description:"",pathParams:[],params:[{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 `get` (e.g. BTC-USD). Pagination ignored when set.",pattern:"^[A-Za-z0-9]+$"},{name:"product_type",in:"query",type:"string",required:!1,description:"Product type filter",enum:["SPOT","FUTURE"]},{name:"product_ids",in:"query",type:"string",required:!1,description:"Comma-separated product IDs"},{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,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"]}}}},{id:"products_get",name:"get",method:"GET",path:"/products/{product_id}",summary:"Get Product",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,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"]}},{id:"products_ticker",name:"ticker",method:"GET",path:"/products/{product_id}/ticker",summary:"Get Ticker",description:"",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:"number",description:"Last trade price"},bid:{type:"number",description:"Best bid"},ask:{type:"number",description:"Best ask"},bid_size:{type:"number",description:"Size at best bid"},ask_size:{type:"number",description:"Size at best ask"},volume:{type:"number",description:"24h volume"},high:{type:"number",description:"24h high"},low:{type:"number",description:"24h low"},pct_24h:{type:"number",description:"24h price change %"},product_id:{type:"string",description:"Trading pair"}},template:{},responseFields:{fields:["trades","best_bid","best_ask"],nested:{trades:{fields:["trade_id","product_id","price","size","time","side"]}}}},{id:"products_book",name:"book",method:"GET",path:"/products/{product_id}/book",summary:"Get Order Book",description:"",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:"number",description:"Bid-ask spread"},mid:{type:"number",description:"Midpoint price"},product_id:{type:"string",description:"Trading pair"}},template:{},responseFields:{fields:["pricebook"],nested:{pricebook:{fields:["product_id","bids","asks","time"],nested:{bids:{fields:["price","size"]},asks:{fields:["price","size"]}}}}}},{id:"products_candles",name:"candles",method:"GET",path:"/products/{product_id}/candles",summary:"Get Candles",description:"",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"]},{name:"limit",in:"query",type:"integer",required:!1,description:"Max candles"}],streamable:!1,watchFields:null,template:{},responseFields:{fields:["candles"],nested:{candles:{fields:["start","low","high","open","close","volume"]}}}},{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.",pathParams:[],params:[{name:"product_ids",in:"query",type:"string",required:!1,description:"Comma-separated product IDs (e.g. BTC-USD,ETH-USD)"}],streamable:!1,watchFields:null,template:{},responseFields:{fields:["pricebooks"],nested:{pricebooks:{fields:["product_id","bids","asks","time"],nested:{bids:{fields:["price","size"]},asks:{fields:["price","size"]}}}}}}]}],X={balance:{id:"balance",name:"balance",method:"GET",path:"/balance",summary:"View Balances",description:"",pathParams:[],params:[{name:"portfolio_id",in:"query",type:"string",required:!1,description:"Filter by 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,template:{},responseFields:{fields:["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"]}}}}}},transfer:{id:"transfer",name:"transfer",method:"POST",path:"/transfer",summary:"Move Funds Between Portfolios",description:"",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-..."},{name:"to",in:"body",type:"string",required:!0,description:"Target portfolio UUID",example:"a44ef7a8-..."}],streamable:!1,watchFields:null,template:{amount:"100.00",currency:"USD",from:"d17b3486-...",to:"a44ef7a8-..."},responseFields:{fields:["source_portfolio_uuid","target_portfolio_uuid"]}},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"]}],streamable:!1,watchFields: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"]}}}}},gn=new Set(["balance","transfer","fees"]),ln={"date-time":/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?(Z|[+-]\d{2}:\d{2})$/};pn={"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,a,o]=e;return mo(+r,+n,+i)&&+s<24&&+a<60&&+o<61}}});function mn(t){return typeof t=="object"&&"endpoint"in t}function C(t,e){return{endpoint:t,...e}}var lt=h(()=>{"use strict";g();l()});var fn,bn,yn,hn,En,In,On,kn,vn,Rn,Pn,Tn,Sn,wn,Cn,xn,Tt=h(()=>{"use strict";g();l();fn={origin:"RetailBrokerageApi_CancelOrders",method:"POST",path:"/api/v3/brokerage/orders/batch_cancel"},bn={origin:"RetailBrokerageApi_ClosePosition",method:"POST",path:"/api/v3/brokerage/orders/close_position"},yn={origin:"RetailBrokerageApi_CommitConvertTrade",method:"POST",path:"/api/v3/brokerage/convert/trade/{trade_id}"},hn={origin:"RetailBrokerageApi_CreatePortfolio",method:"POST",path:"/api/v3/brokerage/portfolios"},En={origin:"RetailBrokerageApi_DeletePortfolio",method:"DELETE",path:"/api/v3/brokerage/portfolios/{portfolio_uuid}"},In={origin:"RetailBrokerageApi_EditPortfolio",method:"PUT",path:"/api/v3/brokerage/portfolios/{portfolio_uuid}"},On={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}"},vn={origin:"RetailBrokerageApi_GetFills",method:"GET",path:"/api/v3/brokerage/orders/historical/fills"},Rn={origin:"RetailBrokerageApi_GetHistoricalOrder",method:"GET",path:"/api/v3/brokerage/orders/historical/{order_id}"},Pn={origin:"RetailBrokerageApi_GetHistoricalOrders",method:"GET",path:"/api/v3/brokerage/orders/historical/batch"},Tn={origin:"RetailBrokerageApi_GetPortfolioBreakdown",method:"GET",path:"/api/v3/brokerage/portfolios/{portfolio_uuid}"},Sn={origin:"RetailBrokerageApi_GetPortfolios",method:"GET",path:"/api/v3/brokerage/portfolios"},wn={origin:"RetailBrokerageApi_GetProduct",method:"GET",path:"/api/v3/brokerage/products/{product_id}"},Cn={origin:"RetailBrokerageApi_GetPublicProductBook",method:"GET",path:"/api/v3/brokerage/market/product_book"},xn={origin:"RetailBrokerageApi_GetTransactionSummary",method:"GET",path:"/api/v3/brokerage/transaction_summary"}});var An,Nn=h(()=>{"use strict";g();l();lt();Tt();An={portfolios_list:C(Sn),portfolios_get:C(Tn,{requestMap:{portfolio_id:"portfolio_uuid"},responseUnwrap:"breakdown"}),portfolios_create:C(hn,{responseUnwrap:"portfolio"}),portfolios_edit:C(In,{requestMap:{portfolio_id:"portfolio_uuid"},responseUnwrap:"portfolio"}),portfolios_delete:C(En,{requestMap:{portfolio_id:"portfolio_uuid"}})}});var L,pt=h(()=>{"use strict";g();l();L=class t extends Error{status;correlationId;traceId;constructor(e,r,n){super(e),this.status=r,this.correlationId=n?.correlationId,this.traceId=n?.traceId}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,a;try{let c=JSON.parse(i);c.errorType&&c.errorMessage?s=`${c.errorType} \u2014 ${c.errorMessage}`:c.message?s=t.stripGrpcPrefix(c.message):s=i.length>200?i.slice(0,200)+"...":i,a=c.correlationId||c.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:a,traceId:o})}}});function nr(t){if(t?.success===!1){let e=t.error_response,r=t.errors?.[0]?.edit_failure_reason,n=e?.new_order_failure_reason?String(e.new_order_failure_reason).replace(/^NEW_ORDER_FAILURE_REASON_/,"").replace(/_/g," ").toLowerCase():void 0;throw new L(e?.message||e?.error_details||n||r?.toString()||"Operation failed",400)}}var Gn=h(()=>{"use strict";g();l();pt()});var me,ir,mt,Dn=h(()=>{"use strict";g();l();me={MARKET:"market",LIMIT:"limit",STOP_LIMIT:"stop_limit"},ir={UP:"up",DOWN:"down"},mt={GTC:"GTC",IOC:"IOC",FOK:"FOK",GTD:"GTD"}});function fo(t,e){let r={...e},n=t;for(let[i,s]of Object.entries(r)){let a="{"+i+"}";s!=null&&n.includes(a)&&(n=n.replaceAll(a,encodeURIComponent(String(s))),delete r[i])}return{url:n,remaining:r}}async function et(t,e,r,n){let{url:i,remaining:s}=fo(r,n),a=e==="POST"||e==="PUT"||e==="DELETE"||e==="PATCH",o,c=null;if(a)o=t.baseURL+i,Object.keys(s).length>0&&(c=new TextEncoder().encode(JSON.stringify(s)));else{let p=Object.entries(s).filter(([,y])=>y!=null).map(([y,v])=>encodeURIComponent(y)+"="+encodeURIComponent(String(v))).join("&");o=t.baseURL+i+(p?"?"+p:"")}let _=await t.doRequest({method:e,url:o,body:c}),u=new TextDecoder().decode(_.body),d;try{d=JSON.parse(u)}catch{d=u}if(_.status>=400){let p=d,y=p?.error_response?.message??p?.error_response?.error_details??p?.message??p?.error_details??u.slice(0,200);throw new jt(y,_.status,d)}return{status:_.status,data:d}}function Ln(t,e){return et(t,"POST","/api/v3/brokerage/convert/quote",e)}function Mn(t,e){return et(t,"POST","/api/v3/brokerage/orders/edit",e)}function Fn(t,e){return et(t,"GET","/api/v3/brokerage/accounts",e)}function Un(t,e){return et(t,"GET","/api/v3/brokerage/products/{product_id}/candles",e)}function Bn(t,e){return et(t,"GET","/api/v3/brokerage/products/{product_id}/ticker",e)}function sr(t,e){return et(t,"GET","/api/v3/brokerage/products",e)}function qn(t,e){return et(t,"POST","/api/v3/brokerage/portfolios/move_funds",e)}function zn(t,e){return et(t,"POST","/api/v3/brokerage/orders",e)}function Wn(t,e){return et(t,"POST","/api/v3/brokerage/orders/preview",e)}var jt,ft=h(()=>{"use strict";g();l();jt=class extends Error{status;data;constructor(e,r,n){super(e),this.status=r,this.data=n}}});import{randomUUID as bo}from"node:crypto";function Vn(t){let e=t.type;if(e===me.MARKET)return{market_market_ioc:{...t.quote_size&&{quote_size:t.quote_size},...t.base_size&&{base_size:t.base_size}}};if(e===me.LIMIT){let r=t.time_in_force??mt.GTC,n={base_size:t.base_size,limit_price:t.limit_price,...t.post_only&&{post_only:!0}};return r===mt.IOC?{sor_limit_ioc:n}:r===mt.FOK?{limit_limit_fok:n}:r===mt.GTD?{limit_limit_gtd:{...n,...t.end_time&&{end_time:t.end_time}}}:{limit_limit_gtc:n}}else if(e===me.STOP_LIMIT){let r=t.stop_direction===ir.UP?"STOP_DIRECTION_STOP_UP":t.stop_direction===ir.DOWN?"STOP_DIRECTION_STOP_DOWN":(()=>{throw new L("stop_direction is required for stop_limit orders (up or down)",400)})(),n=t.time_in_force??mt.GTC,i={base_size:t.base_size,limit_price:t.limit_price,stop_price:t.stop_price,stop_direction:r};return n===mt.GTD?{stop_limit_stop_limit_gtd:{...i,...t.end_time&&{end_time:t.end_time}}}:{stop_limit_stop_limit_gtc:i}}throw new L(`Unknown order type: ${e}. Use market, limit, or stop_limit.`,400)}function yo(t){let e={client_order_id:t.client_order_id??bo(),product_id:t.product_id,side:t.side,order_configuration:Vn(t)};return t.portfolio_id&&(e.retail_portfolio_id=t.portfolio_id),t.reduce_only&&(e.reduce_only=!0),e}var ho,Eo,Io,$n,Hn=h(()=>{"use strict";g();l();lt();pt();Gn();Dn();Tt();ft();ho=async(t,e)=>{let r=yo(t),n=await zn(e,r);return nr(n.data),n.data.success_response??n.data},Eo=async(t,e)=>{let r=await Wn(e,{product_id:t.product_id,side:t.side,order_configuration:Vn(t)}),n=r.data;if(n.errs?.length>0)throw new L(n.errs[0].replace(/^PREVIEW_/,"").replace(/_/g," ").toLowerCase(),400);return r.data},Io=async(t,e)=>{if(!t.base_size&&!t.limit_price)throw new L("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 Mn(e,r);return nr(n.data),{order_id:t.order_id,status:"EDITED"}},$n={orders_list:C(Pn,{requestMap:{status:"order_status",side:"order_side",start:"start_date",end:"end_date"}}),orders_get:C(Rn,{responseUnwrap:"order"}),orders_create:ho,orders_preview:Eo,orders_edit:Io,orders_cancel:C(fn),orders_close_position:C(bn),orders_fills:C(vn,{requestMap:{side:"order_side",start:"start_sequence_timestamp",end:"end_sequence_timestamp"}})}});function jn(t){return String(Math.floor(new Date(t).getTime()/1e3))}var Oo,ko,vo,Ro,Po,To,Kn,Yn=h(()=>{"use strict";g();l();lt();Tt();ft();Oo={"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"},ko={"1m":60,"5m":300,"15m":900,"30m":1800,"1h":3600,"2h":7200,"4h":14400,"6h":21600,"1d":86400},vo=60,Ro=async(t,e)=>{let{symbol:r,limit:n,cursor:i,...s}=t;if(r){let o=r.toUpperCase(),u=((await sr(e,s)).data.products??[]).filter(p=>p.base_currency_id===o||p.quote_currency_id===o),d=n!==void 0&&n>0?u.slice(0,n):u;return{products:d,num_products:d.length}}return(await sr(e,{...s,limit:n,cursor:i})).data};Po=async(t,e)=>{let r=t.granularity??"1h",n=Oo[r],i=ko[r],s=Math.floor(Date.now()/1e3),a=t.end?jn(t.end):String(s),o=t.start?jn(t.start):String(Number(a)-vo*i);return(await Un(e,{...t,granularity:n,start:o,end:a})).data},To=async(t,e)=>{let r=t.limit??100;return(await Bn(e,{...t,limit:r})).data},Kn={products_list:Ro,products_get:C(wn),products_ticker:To,products_book:C(Cn),products_candles:Po,products_best_bid_ask:C(On)}});var So,Qn,Jn=h(()=>{"use strict";g();l();lt();Tt();ft();pt();So=async(t,e)=>{let{from:r,to:n,...i}=t,s=await Ln(e,{...i,from_account:r,to_account:n});if(!s.data?.trade?.id)throw new L(`Convert quote returned no trade for ${t.from} \u2192 ${t.to}. Verify balance, supported pair, and account eligibility.`,422);return s.data},Qn={convert_quote:So,convert_execute:C(yn,{requestMap:{quote_id:"trade_id",from:"from_account",to:"to_account"}}),convert_get:C(kn,{requestMap:{quote_id:"trade_id",from:"from_account",to:"to_account"},responseUnwrap:"trade"})}});var wo,Xn,Zn=h(()=>{"use strict";g();l();ft();wo=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 Fn(e,r)).data,s=i.accounts??[],a=t.show_zero?s:s.filter(o=>parseFloat(o.available_balance?.value??"0")!==0||parseFloat(o.hold?.value??"0")!==0);return{accounts:a,has_next:i.has_next,cursor:i.cursor,size:a.length}},Xn={balance:wo}});var Co,ti,ei=h(()=>{"use strict";g();l();pt();ft();Co=async(t,e)=>{let r={funds:{value:t.amount,currency:t.currency},source_portfolio_uuid:t.from,target_portfolio_uuid:t.to},i=(await qn(e,r)).data;if(!i?.source_portfolio_uuid)throw new L("Transfer failed \u2014 check amount, currency, and portfolio UUIDs",400);return i},ti={transfer:Co}});var ri,ni=h(()=>{"use strict";g();l();lt();Tt();ri={fees:C(xn)}});function fe(t){return xo[t]}var xo,or=h(()=>{"use strict";g();l();Nn();Hn();Yn();Jn();Zn();ei();ni();xo={...An,...$n,...Kn,...Qn,...Xn,...ti,...ri}});function ar(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 ii(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 si=h(()=>{"use strict";g();l()});function Ao(t,e){let r={...e},n=t;for(let[i,s]of Object.entries(e)){if(s==null||s==="")continue;let a=`{${i}}`;n.includes(a)&&(n=n.replaceAll(a,encodeURIComponent(String(s))),delete r[i])}return{resolvedPath:n,remainingParams:r}}function No(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 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 Do(t){return t&&typeof t=="object"&&("body"in t||"query"in t||"path"in t||"rawBody"in t)}function Kt(t,e){if(t==null||typeof t!="object")return t;if(Array.isArray(t))return t.map(n=>Kt(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=>Kt(s,i)):i&&typeof t[n]=="object"&&t[n]!==null?r[n]=Kt(t[n],i):r[n]=t[n]}return r}function Lo(t,e){let r=cr[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 St(t,e,r){let n=Do(e),i=n?e.body??{}:e,s=n?e.query??{}:{},a=n?e.path??{}:{},o=n?e.headers??{}:{},c=n?e.rawBody??null:null,_=fe(t);if(!_)return{status:404,data:{error:"UNKNOWN_OPERATION",code:404,message:`No route for ${t}`}};let u=oi.find(O=>O.id===t);if(u?.params){if(c)try{let O=JSON.parse(new TextDecoder().decode(c));O&&typeof O=="object"&&!Array.isArray(O)&&Object.assign(i,O)}catch{}{let m=u.params.filter(I=>I.in==="body"&&I.required).filter(I=>i[I.name]===void 0||i[I.name]==="");if(m.length>0)return{status:400,data:{error:"MISSING_FIELDS",code:400,message:`Missing required field(s): ${m.map(E=>E.name).join(", ")}`}}}{let O={...a,...i,...s},m={},I={};for(let E of u.params)if(E.oneOf&&(I[E.oneOf]||(I[E.oneOf]=[]),I[E.oneOf].push(E.name),O[E.name]!==void 0&&O[E.name]!=="")){if(m[E.oneOf])return{status:400,data:{error:"CONFLICTING_FIELDS",code:400,message:`${m[E.oneOf]} and ${E.name} are mutually exclusive. Provide one, not both.`}};m[E.oneOf]=E.name}for(let[E,D]of Object.entries(I))if(!m[E])return{status:400,data:{error:"MISSING_FIELDS",code:400,message:`One of ${D.join(", ")} is required.`}}}for(let O of u.params)for(let m of[i,s,a]){if(m[O.name]===void 0)continue;if(O.type==="boolean"&&typeof m[O.name]=="string")m[O.name]=m[O.name]==="true";else if((O.type==="integer"||O.type==="number")&&typeof m[O.name]=="string"){let V=Number(m[O.name]);if(!Number.isFinite(V))return{status:400,data:{error:"INVALID_VALUE",code:400,message:`Invalid value for ${O.name}: "${m[O.name]}". Expected a number.`}};m[O.name]=V}if(O.enum&&!O.enum.includes(String(m[O.name])))return{status:400,data:{error:"INVALID_VALUE",code:400,message:`Invalid value for ${O.name}: "${m[O.name]}". Expected one of: ${O.enum.join(", ")}`}};let I=O.pattern?ai.get(O.pattern):void 0,E=O.format?ln[O.format]:void 0,D=I??E;if(D&&typeof m[O.name]=="string"){let V=m[O.name],dt=O.format?pn[O.format]:void 0;if(!(D.test(V)&&(!I||!E||E.test(V))&&(!dt||dt(V)))){let it=(O.description??"").split(/\.\s/)[0].replace(/\.?\s*$/,""),re=it?`. ${it}.`:".";return{status:400,data:{error:"INVALID_VALUE",code:400,message:`Invalid value for ${O.name}: "${String(V).slice(0,80)}"${re}`}}}}}}if(!mn(_)){let O={...a,...i,...s};try{let m=await _(O,r),I=cr[t];return I&&(m=Kt(m,I)),{status:200,data:m}}catch(m){if(m instanceof jt)return{status:m.status,data:m.data};let I=m instanceof L?m.status:500,E=L.stripGrpcPrefix(m instanceof Error?m.message:String(m));return{status:I,data:{error:"HANDLER_ERROR",code:I,message:E}}}}let{endpoint:d}=_,p={...a,...i},y=ar(p,_.requestMap),{resolvedPath:v,remainingParams:k}=Ao(d.path,y);if(v.includes("{"))return{status:400,data:{error:"MISSING_PATH_PARAMS",code:400,message:`Missing required param(s): ${(v.match(/\{([^}]+)\}/g)?.map(m=>m.slice(1,-1))??[]).join(", ")}`}};let S=d.method==="POST"||d.method==="PUT"||d.method==="DELETE"||d.method==="PATCH",T,w=c??null,z={...ar(s,_.requestMap)};S?(T=`${r.baseURL}${v}`,!w&&Object.keys(k).length>0&&(w=new TextEncoder().encode(JSON.stringify(k)))):(Object.assign(z,k),T=`${r.baseURL}${v}`);let P=No(z);P&&(T+=P);let R=await r.doRequest({method:d.method,url:T,body:w,headers:Object.keys(o).length>0?o:void 0}),N=new TextDecoder().decode(R.body),G;try{G=JSON.parse(N)}catch{G=N}if(R.status>=400)return{status:R.status,data:G,headers:R.headers};_.responseUnwrap&&(G=Go(G,_.responseUnwrap)),_.responseMap&&(G=ii(G,_.responseMap));let ut=Lo(t,_.responseUnwrap);return ut&&(G=Kt(G,ut)),{status:R.status,data:G,headers:R.headers}}var oi,cr,ai,be=h(()=>{"use strict";g();l();lt();or();si();pt();ft();Pt();oi=[...J.flatMap(t=>t.actions),...Object.values(X)],cr={},ai=new Map;for(let t of oi){cr[t.id]=t.responseFields;for(let e of t.params)e.pattern&&ai.set(e.pattern,new RegExp(e.pattern))}});import{readFileSync as Mo,writeFileSync as Fo,mkdirSync as Uo}from"node:fs";import{join as _i}from"node:path";function ci(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 qo(t,e){let r=ci(t),n=ci(e);return n.major!==r.major?n.major>r.major:n.minor!==r.minor?n.minor>r.minor:n.patch>r.patch}function Wo(t,e){let r=ne===zo?"":` --registry ${ne}`;return`
48
+ Update available: ${t} \u2192 ${e}
49
+ Run: npm i -g ${ye}${r}
50
+ `}function gi(){return ot()}function $o(){try{return JSON.parse(Mo(_i(gi(),di),"utf8"))}catch{return null}}function Ho(t){try{let e=gi();Uo(e,{recursive:!0}),Fo(_i(e,di),JSON.stringify(t))}catch{}}async function jo(){try{let t=new AbortController,e=setTimeout(()=>t.abort(),3e3),r=await fetch(Bo,{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 li(){if(process.env.CI||process.env.COINBASE_NO_UPDATE_CHECK)return"";let t=$o();if(t&&Date.now()-t.checkedAt<Vo)return"";let e=await jo();return e?(Ho({checkedAt:Date.now(),latestVersion:e}),qo(rt,e)?Wo(rt,e):""):""}var ui,rt,ye,Bo,di,zo,Vo,he=h(()=>{"use strict";g();l();ie();Q();ui="0.0.2";rt=ui,ye=Wr,Bo=`${ne}/${encodeURIComponent(ye)}`,di="version-check.json";zo="https://registry.npmjs.org";Vo=1440*60*1e3});import{createSign as Ko,createPrivateKey as Yo,sign as Qo,randomBytes as Jo}from"node:crypto";function _r(t){return Buffer.from(t).toString("base64url")}function Ee(t){return _r(Buffer.from(JSON.stringify(t)))}function Xo(){return Jo(16).toString("hex")}function mi(t){return t.includes("-----BEGIN EC PRIVATE KEY-----")}function fi(t){let e=Buffer.from(t,"base64");return e.length===32||e.length===64}function ur(t,e,r,n,i){let s=Math.floor(Date.now()/1e3),a=Xo(),o={sub:t,iss:"cdp",nbf:s,iat:s,exp:s+120},c=`${r} ${n}${i}`;if(r&&n&&i&&(o.uris=[c]),mi(e))return ta(t,e,o,a);if(fi(e))return ea(t,e,o,a);throw new Error("invalid key format - must be either PEM EC key or base64 Ed25519 key")}function Zo(t,e,r){let n=`${Ee(t)}.${Ee(e)}`,i=Ko("SHA256");i.update(n);let s=i.sign(r);return`${n}.${_r(ra(s))}`}function ta(t,e,r,n){return Zo({alg:"ES256",typ:"JWT",kid:t,nonce:n},r,e)}function ea(t,e,r,n){let s=`${Ee({alg:"EdDSA",typ:"JWT",kid:t,nonce:n})}.${Ee(r)}`,a=Buffer.from(e,"base64"),o=Yo({key:Buffer.concat([Buffer.from("302e020100300506032b657004220420","hex"),a.subarray(0,32)]),format:"der",type:"pkcs8"}),c=Qo(null,Buffer.from(s),o);return`${s}.${_r(c)}`}function ra(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=pi(n,32),s=pi(s,32),Buffer.concat([n,s])}function pi(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 na(t){return mi(t)?"ecdsa":fi(t)?"ed25519":"unknown"}async function Ie(t){let e;if(t.keyId&&t.keySecret){let a=new URL(t.url);e=`Bearer ${ur(t.keyId,t.keySecret,t.method,a.host,a.pathname)}`}else throw new Error("doAuthenticatedRequest: must supply keyId+keySecret");let r={Authorization:e,"Content-Type":"application/json","Correlation-Context":`sdk_version=${encodeURIComponent(rt)},sdk_language=typescript,source=${encodeURIComponent(ye)}`,...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&&na(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 Oe=h(()=>{"use strict";g();l();he()});function va(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 at(t){return t.replace(/\x1b\]8;;[^\x07]*\x07/g,"").replace(/\x1b\[[0-9;]*m/g,"").length}var Ui,ke=h(()=>{"use strict";g();l();Ui=va(process.env,!!process.stdout.isTTY)});function Pa(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]:"",a=s.toLowerCase()in fr&&(r+1>=t.length||t[r+1]===" "||t[r+1]===" "||t[r+1]===")"||t[r+1]==="&"||t[r+1]==="|");if(s&&!a&&(s>="a"&&s<="z"||s>="A"&&s<="Z"||s==="-"))r=n;else{let o=parseFloat(i);r<t.length&&t[r].toLowerCase()in fr&&(o*=fr[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 Ta(t){return t>=3&&t<=8}function yr(t){let e=t.trim();if(e.length===0)throw new Error("Empty predicate");return new br(Pa(e)).parse()}function Jt(t){switch(t.type){case"comparison":return t.product?[t.product]:[];case"and":case"or":return[...Jt(t.left),...Jt(t.right)]}}function zi(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}s.type==="string"&&typeof i.value=="number"&&r.push({field:i.field,message:`'${i.field}' is a string field \u2014 use "${i.value}" not ${i.value}`}),s.type==="number"&&typeof i.value=="string"&&r.push({field:i.field,message:`'${i.field}' is a numeric field \u2014 use ${i.value} not "${i.value}"`}),s.type==="string"&&(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 Sa(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 Ca(t,e){if(typeof e=="number"){if(typeof t=="number")return[t,e];if(typeof t=="string"&&wa.test(t))return[parseFloat(t),e]}return null}function xa(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=Sa(n,t.field);if(i==null)return!1;let s=Ca(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 wt(t,e,r){switch(t.type){case"comparison":return xa(t,e,r);case"and":return wt(t.left,e,r)&&wt(t.right,e,r);case"or":return wt(t.left,e,r)||wt(t.right,e,r)}}function Wi(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,a]of Object.entries(t)){let o=a.enum?a.enum.join("|"):a.type;e.push(` ${s.padEnd(r)} ${o.padEnd(12)} ${a.description}`)}let n=Object.entries(t).filter(([,s])=>s.type==="number").map(([s])=>s),i=Object.entries(t).filter(([,s])=>s.enum).map(([s,a])=>({k:s,vals:a.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(`
51
+ `)}var fr,br,wa,hr=h(()=>{"use strict";g();l();fr={k:1e3,m:1e6,b:1e9};br=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&&Ta(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()}};wa=/^-?(\d+\.?\d*|\.\d+)([eE][+-]?\d+)?$/});function Re(t){return Na[t]??null}var Er,Aa,Na,Ir=h(()=>{"use strict";g();l();Er="wss://advanced-trade-ws.coinbase.com",Aa="wss://advanced-trade-ws-user.coinbase.com",Na={products_ticker:{name:"ticker",endpoint:Er,requiresAuth:!1,coalesce:!0},products_book:{name:"level2",wireName:"l2_data",endpoint:Er,requiresAuth:!1,coalesce:!0},orders_list:{name:"user",endpoint:Aa,requiresAuth:!0,coalesce:!1},products_trades:{name:"market_trades",endpoint:Er,requiresAuth:!1,coalesce:!0}}});var M,Ga,Da,Pe,Te=h(()=>{"use strict";g();l();M={CONNECTING:"CONNECTING",CONNECTED:"CONNECTED",SUBSCRIBED:"SUBSCRIBED",RECONNECTING:"RECONNECTING",FAILED:"FAILED"},Ga=3e4,Da=1e3,Pe=class{url;opts;ws=null;_state=M.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(M.CONNECTING);try{this.ws=new this.WSClass(this.url)}catch{this.scheduleReconnect();return}this.resetHeartbeat(),this.ws.onopen=()=>{this.lastActivityTime=this.now(),this.setState(M.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(M.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===M.RECONNECTING&&!this.wasReconnecting&&(this.wasReconnecting=!0,this.opts.onDisconnect?.()),e===M.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(M.FAILED);return}this.setState(M.RECONNECTING);let e=Math.min(Da*Math.pow(2,this.retryCount),Ga),r=500+Math.random()*(e-500);this.retryCount++,this.reconnectTimer=setTimeout(()=>{this.connect()},r)}}});var Se,Vi=h(()=>{"use strict";g();l();Te();Se=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===M.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 Pe(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===M.CONNECTED||this.conn.state===M.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 we(t,e){return ur(t,e,"","","")}var Or=h(()=>{"use strict";g();l();Oe()});var Ce,$i=h(()=>{"use strict";g();l();Ce=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 kr(t,e,r){if(!r||t===0)return"";let n=t>0?xt:At;return e?`${Ct}${n}`:n}function Ji(t,e,r){if(!r)return"";let n=t==="bid"||t==="BUY"?xt:At;return e?`${Ct}${n}`:n}var q,Ct,xt,At,Hi,F,ji,Ki,Yi,Qi,Nt=h(()=>{"use strict";g();l();q="\x1B[2m",Ct="\x1B[1m",xt="\x1B[32m",At="\x1B[31m",Hi="\x1B[33m",F="\x1B[0m",ji="\x1B[?25l",Ki="\x1B[?25h",Yi="\x1B[?1049h",Qi="\x1B[?1049l"});var Gt,Xi=h(()=>{"use strict";g();l();Nt();Gt=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(Yi),this.inAltScreen=!0}exitAltScreen(){this.out.write(Qi),this.inAltScreen=!1}hideCursor(){this.out.write(ji),this.cursorHidden=!0}showCursor(){this.out.write(Ki),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(F),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 Xt,Zi=h(()=>{"use strict";g();l();Xt=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 B(t,e){let r=at(t);return r>=e?t.slice(0,t.length-(r-e)):t+" ".repeat(e-r)}function x(t,e){let r=at(t);return r>=e?t.slice(0,t.length-(r-e)):" ".repeat(e-r)+t}function ct(t,e){let r="\u2500".repeat(t);return e?`${q}${r}${F}`:r}function Dt(t,e,r){let n=at(t),i=at(e);if(n+1+i>r){let o=r-i-1;return o>0?`${t.slice(0,o)} ${e}`:e.slice(0,r)}let a=r-n-i;return a<0?B(`${t} ${e}`,r):`${t}${" ".repeat(a)}${e}`}function Lt(t,e){return e?t?`${Ct}\xB7${F}`:`${q}\xB7${F}`:""}function $(){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 Zt=h(()=>{"use strict";g();l();ke();Nt()});function W(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 Mt(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 ts(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 es(t){return`${t>=0?"+":""}${t.toFixed(2)}%`}function rs(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 xe=h(()=>{"use strict";g();l()});function is(t){let e=[],r=0;for(let n of La){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 ss(){return{events:[],positions:new Map,openOrders:new Set,totalFees:0,lastClock:$(),netCash:0,fillCount:0,accounted:new Map,prependCount:0,heartbeat:!1,updateCount:0}}function Ma(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 Fa(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 vr(t,e,r="live"){let n=t.events;if(!n)return{inserts:[],updates:[]};let i=[],s=[];for(let a of n){let o=a.orders;if(o)for(let c of o){let _={order_id:String(c.order_id??""),status:String(c.status??""),product_id:String(c.product_id??""),order_side:String(c.order_side??c.side??""),order_type:c.order_type?String(c.order_type):void 0,average_filled_price:String(c.average_filled_price??c.avg_price??"0"),total_fees:String(c.total_fees??"0"),filled_size:String(c.filled_size??c.cumulative_quantity??"0"),base_size:Ma(c),creation_time:c.creation_time?String(c.creation_time):c.created_time?String(c.created_time):void 0},u=e.events.findIndex(d=>d.order_id===_.order_id);if(u>=0){let d=e.events[u],p=d.status!==_.status||d.filled_size!==_.filled_size||d.total_fees!==_.total_fees||d.average_filled_price!==_.average_filled_price;d.status=_.status,d.average_filled_price=_.average_filled_price,d.filled_size=_.filled_size,d.total_fees=_.total_fees,p&&(ns(e,_),s.push(d));continue}r==="backfill"?e.events.splice(Fa(e.events,_),0,_):e.events.unshift(_),e.prependCount++,ns(e,_),i.push(_),e.events.length>1e4&&e.events.pop()}}return{inserts:i,updates:s}}function ns(t,e){t.updateCount++,t.lastClock=$();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,a=i*s,o=t.accounted.get(e.order_id)??{fees:0,size:0,value:0},c=n-o.fees,_=i-o.size,u=a-o.value;(_!==0||c!==0)&&(o.size===0&&i>0&&t.fillCount++,t.totalFees+=c,e.order_side==="BUY"?(t.netCash-=u,t.positions.set(e.product_id,(t.positions.get(e.product_id)??0)+_)):(t.netCash+=u,t.positions.set(e.product_id,(t.positions.get(e.product_id)??0)-_)),t.accounted.set(e.order_id,{fees:n,size:i,value:a}))}function Ua(t,e,r,n,i){let s=e.order_side==="BUY"?"BUY":"SELL",a=Ji(s,n,i),o=e.status.toUpperCase(),c=i?F:"",_=parseFloat(e.average_filled_price??"0"),u=parseFloat(e.filled_size??"0");switch(t){case"time":return B(rs(e.creation_time??new Date().toISOString()),r);case"status":return`${(o==="OPEN"||o==="PENDING")&&i?Hi:""}${B(o,r)}${c}`;case"product":return B(e.product_id,r);case"side":return`${a}${B(s,r)}${c}`;case"size":{let d=u>0?Mt(u):e.base_size??"-";return`${a}${x(d,r)}${c}`}case"price":return`${a}${x(_>0?W(_):"-",r)}${c}`;case"fee":{let d=parseFloat(e.total_fees??"0");return x(d>0?W(d):"-",r)}case"id":return`${i?q:""}${B(e.order_id.slice(0,r),r)}${c}`;default:return B("",r)}}function te(t,e,r,n=80){return is(n).map(i=>Ua(i.key,t,i.width,e,r)).join(" ")}function Ba(t,e=80){let r=new Set(["size","price","fee"]),i=is(e).map(s=>r.has(s.key)?x(s.header,s.width):B(s.header,s.width)).join(" ");return t?`${q}${i}${F}`:i}function qa(t,e,r){let n=t.netCash>=0?r?xt:"":r?At:"",i=r?F:"",s=`Fills:${t.fillCount}`,a=`Open:${t.openOrders.size}`,o=`Fees:${W(t.totalFees)}`,c=`Net:${t.netCash>=0?"+":""}${W(t.netCash)}`,_=`${n}${c}${i}`,d=`${Lt(t.heartbeat,r)} ${t.lastClock}`,p=`\xB7 ${t.lastClock}`,y=`${s} ${a} ${o} ${c}`,v=`${s} ${a} ${o} ${_}`,k=[],S=[];for(let[z,P]of t.positions){if(Math.abs(P)<1e-6)continue;let N=`${z.replace(/-USD[C]?$/,"")}:${Mt(P)}`;k.push(N),S.push(N)}let T=e-y.length-p.length-6,w="";if(k.length>0&&T>8){let z="",P=0,R=0;for(let N=0;N<k.length;N++){let G=R>0?" ":"";if(P+G.length+S[N].length>T){let ut=k.length-R;ut>0&&(z+=` +${ut}`);break}z+=G+k[N],P+=G.length+S[N].length,R++}w=z}let H=w?`${v} ${w}`:v;return Dt(H,d,e)}function os(t,e,r,n,i){let s=i??e.events,a=t.cols,o=t.rows,c=o,_=o-1,u=o-2;n.inserts.forEach((d,p)=>{r.flashWithOffset(d.order_id,e.prependCount-1-p,1500),t.moveTo(Ae,1),t.insertLine(),t.write(te(d,!0,!0,t.cols)+"\x1B[K")});for(let d of n.updates){let p=s.indexOf(d);if(p>=0){let y=Ae+p;y<=u&&(r.flash(d.order_id,1500),t.moveTo(y,1),t.write(te(d,!0,!0,t.cols)+"\x1B[K"))}}for(let d of r.expired()){let p=s.findIndex(y=>y.order_id===d);if(p>=0){let y=Ae+p;y<=u&&(t.moveTo(y,1),t.write(te(s[p],!1,!0,t.cols)+"\x1B[K"))}}t.moveTo(_,1),t.write(ct(a,!0)),t.moveTo(c,1),t.write(qa(e,a-1,!0)+"\x1B[K")}function Rr(t){t.enterAltScreen(),t.hideCursor();let e=t.rows;t.setScrollRegion(Ae,e-2),t.moveTo(1,1),t.write(Ba(!0,t.cols)+"\x1B[K"),t.moveTo(2,1),t.write(ct(t.cols,!0))}function Ne(t,e,r){return{_ch:"user",_seq:e,_ts:r,order_id:t.order_id,status:t.status,product_id:t.product_id,side:t.order_side,filled_size:t.filled_size??null,price:t.average_filled_price??null,fees:t.total_fees??null}}function as(t,e,r){return JSON.stringify(Ne(t,e,r))}var Ae,La,cs=h(()=>{"use strict";g();l();Zt();Nt();xe();Ae=3,La=[{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 _s(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)),a=Math.round(s*(n-1)),o="";for(let c=0;c<n;c++)o+=c===a?"\u25CF":"\u2500";return o}function us(t,e,r){if(e<=0||t<=0)return"";let n=Math.max(0,Math.round(t/e*r));return"\u2588".repeat(n)}var Pr=h(()=>{"use strict";g();l()});function ls(t){let e=[],r=0;for(let n of Va){if(r+n.width+1>t)break;e.push(n),r+=n.width+1}return e}function ps(){return{products:new Map,prevPrices:new Map,productOrder:[],heartbeat:!1,updateCount:0,lastClock:$()}}function ms(t,e){let r=t.events;if(!r)return[];let n=[];for(let i of r){let s=i.tickers;if(s)for(let a of s){let o={product_id:String(a.product_id??""),price:String(a.price??"0"),volume_24_h:String(a.volume_24_h??"0"),price_percent_chg_24_h:String(a.price_percent_chg_24_h??"0"),best_bid:String(a.best_bid??"0"),best_bid_quantity:String(a.best_bid_quantity??"0"),best_ask:String(a.best_ask??"0"),best_ask_quantity:String(a.best_ask_quantity??"0"),high_24_h:String(a.high_24_h??"0"),low_24_h:String(a.low_24_h??"0")},c=e.prevPrices.get(o.product_id),_=parseFloat(o.price),u=0;c!==void 0&&(_>c?u=1:_<c&&(u=-1)),e.prevPrices.set(o.product_id,_),e.products.set(o.product_id,o),e.productOrder.includes(o.product_id)||e.productOrder.push(o.product_id),e.updateCount++,e.lastClock=$(),n.push({ticker:o,direction:u})}}return n}function $a(t,e,r,n,i,s){let a=parseFloat(e.price),o=s?F:"";switch(t){case"symbol":return B(e.product_id,r);case"price":return`${kr(n,i,s)}${x(W(a),r)}${o}`;case"pct":{let c=parseFloat(e.price_percent_chg_24_h),_=c>0?1:c<0?-1:0;return`${kr(_,!1,s)}${x(es(c),r)}${o}`}case"bid":return x(W(parseFloat(e.best_bid)),r);case"ask":return x(W(parseFloat(e.best_ask)),r);case"bidSz":return`${s?q:""}${x(Mt(parseFloat(e.best_bid_quantity)),r)}${o}`;case"askSz":return`${s?q:""}${x(Mt(parseFloat(e.best_ask_quantity)),r)}${o}`;case"low":return`${s?q:""}${x(W(parseFloat(e.low_24_h)),r)}${o}`;case"high":return`${s?q:""}${x(W(parseFloat(e.high_24_h)),r)}${o}`;case"range":return B(_s(a,parseFloat(e.low_24_h),parseFloat(e.high_24_h),r),r);case"vol":return`${s?q:""}${x(ts(parseFloat(e.volume_24_h)),r)}${o}`;default:return B("",r)}}function gs(t,e,r,n,i=80){return ls(i).map(a=>$a(a.key,t,a.width,e,r,n)).join(" ")}function Ha(t,e=80){let n=ls(e).map(i=>i.key==="symbol"||i.key==="range"?B(i.header,i.width):x(i.header,i.width)).join(" ");return t?`${q}${n}${F}`:n}function ja(t,e,r){let n=`${t.products.size} product${t.products.size!==1?"s":""}`,s=`${Lt(t.heartbeat,r)} ${t.lastClock}`;return Dt(n,s,e)}function Tr(t){t.enterAltScreen(),t.hideCursor(),t.moveTo(za,1),t.write(Ha(!0,t.cols)+"\x1B[K"),t.moveTo(Wa,1),t.write(ct(t.cols,!0))}function fs(t,e,r,n,i){let s=t.cols,a=t.rows,o=a,c=a-1;for(let{ticker:_,direction:u}of n){let d=e.productOrder.indexOf(_.product_id);if(d<0)continue;let p=ds+d;if(p>=c)continue;let y=i?.has(_.product_id)??!1,v=!y&&r.isFlashing(_.product_id);t.moveTo(p,1);let k=gs(_,y?0:u,v,!0,s);t.write((y?q+k+F:k)+"\x1B[K")}for(let _ of r.expired()){let u=e.productOrder.indexOf(_);if(u<0)continue;let d=ds+u;if(d>=c)continue;let p=e.products.get(_);p&&(t.moveTo(d,1),t.write(gs(p,0,!1,!0,s)+"\x1B[K"))}t.moveTo(c,1),t.write(ct(s,!0)),t.moveTo(o,1),t.write(ja(e,s-1,!0)+"\x1B[K")}function Sr(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 bs(t,e,r){return JSON.stringify(Sr(t,e,r))}var za,Wa,ds,Va,ys=h(()=>{"use strict";g();l();Zt();Nt();xe();Pr();za=1,Wa=2,ds=3,Va=[{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 Es(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:$()}}function Is(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 a=s.type,o=s.updates;if(a==="snapshot"&&(e.bids.clear(),e.asks.clear()),!!o){for(let c of o){let _=String(c.side??"").toLowerCase(),u=parseFloat(String(c.price_level??"0")),d=parseFloat(String(c.new_quantity??"0"));if(u<=0)continue;let p=_==="bid"?e.bids:e.asks;d<=0?p.delete(u):p.set(u,d)}e.updateCount++,e.lastClock=$()}}}function Ge(t){let e=[];for(let[r,n]of t.bids)e.push({price:r,size:n});return e.sort((r,n)=>n.price-r.price),e}function De(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),e}function hs(t,e,r,n,i,s,a){let o=a?i==="bid"?xt:At:"",c=a?F:"",_=us(r,n,s),u=`${o}${_}${c}`;return[`${o}${x(W(t),_t[0])}${c}`,x(e.toFixed(4),_t[1]),x(r.toFixed(4),_t[2]),u].join(" ")}function Qa(t,e,r){let n=De(t),i=Ge(t),s=n.length>0?n[0].price:0,a=i.length>0?i[0].price:0,o=s-a,c=(s+a)/2,_=c>0?o/c*100:0,u=c>0?` Spread: ${W(o).padStart(10)} (${_.toFixed(3).padStart(6)}%) Mid: ${W(c).padStart(12)}`:" Waiting for data...",d=r?q:"",p=r?F:"";return`${d}${B(u,e)}${p}`}function Ja(t,e,r){let n=Ya.map((c,_)=>_===3?B(c,_t[_]):x(c,_t[_])).join(" "),i=r?q:"",s=r?Ct:"",a=r?F:"",o=`${s}${t.productId}${a}`;return`${B(o,e)}
52
+ ${i}${n}${a}`}function Xa(t,e,r){let n=Ge(t).reduce((u,d)=>u+d.size,0),i=De(t).reduce((u,d)=>u+d.size,0),s=i>0?(n/i).toFixed(2):"-",o=`${t.depth?`Depth:${t.depth} `:""}B/A:${s} Rate:${t.msgRate}/s`,_=`${Lt(t.heartbeat,r)} ${t.lastClock}`;return Dt(o,_,e)}function wr(t,e){t.enterAltScreen(),t.hideCursor(),Cr(t,e)}function Cr(t,e){let r=t.cols,n=t.rows;if(n<4)return;let i=_t[0]+_t[1]+_t[2]+3,s=Math.max(4,r-i),a=De(e),o=Ge(e),c=n-1,_=n,u=Math.max(0,n-4),d=Math.floor(u/2),p=u>d*2||d>0,y=e.depth?Math.min(d,e.depth):d,v=a.slice(0,y),k=o.slice(0,y),S=0,T=[];for(let R of v)S+=R.size,T.push(S);let w=0,H=[];for(let R of k)w+=R.size,H.push(w);let z=Math.max(S,w),P=1;t.moveTo(P,1),t.write(Ja(e,r,!0)+"\x1B[K"),P=Ka;for(let R=0;R<y&&P<c;R++,P++)if(t.moveTo(P,1),R<v.length){let N=v.length-1-R;t.write(hs(v[N].price,v[N].size,T[N],z,"ask",s,!0)+"\x1B[K")}else t.clearLine();p&&P<c&&(t.moveTo(P,1),t.write(Qa(e,r,!0)+"\x1B[K"),P++);for(let R=0;R<y&&P<c;R++,P++)t.moveTo(P,1),R<k.length?t.write(hs(k[R].price,k[R].size,H[R],z,"bid",s,!0)+"\x1B[K"):t.clearLine();for(;P<c;)t.moveTo(P,1),t.clearLine(),P++;t.moveTo(c,1),t.write(ct(r,!0)),t.moveTo(_,1),t.write(Xa(e,r-1,!0)+"\x1B[K")}function xr(t,e,r){let n=Ge(t).map(o=>({price:o.price,size:o.size})),i=De(t).map(o=>({price:o.price,size:o.size})),s=i.length>0?i[0].price:0,a=n.length>0?n[0].price:0;return{_ch:"level2",_seq:e,_ts:r,product_id:t.productId,spread:s-a,mid:(s+a)/2,bids:n,asks:i}}function Os(t,e,r){return JSON.stringify(xr(t,e,r))}var Ka,_t,Ya,ks=h(()=>{"use strict";g();l();Zt();Nt();xe();Pr();Ka=3,_t=[14,12,12,16],Ya=["PRICE","SIZE","TOTAL","DEPTH"]});function vs(t,e,r,n,i){return new Ar(t,e,r,n,i)}function Rs(t,e,r){return new Nr(t,e,r)}function Ps(t,e,r,n){return new Gr(t,e,r,n)}var Ar,Nr,Gr,Ts=h(()=>{"use strict";g();l();Te();Or();Xi();Zi();Zt();cs();ys();ks();be();Ar=class{productIds=[];screen;refreshJWT;state=ss();flash=new Xt;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 Gt(e.out),Rr(this.screen),this.screen.onResize(()=>{Rr(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?we(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(),os(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(te(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(c=>c.order_id):void 0,s=vr(e,this.state);this.liveness=!this.liveness;let a={inserts:s.inserts.filter(c=>this.matchesFilter(c)),updates:s.updates.filter(c=>this.matchesFilter(c))};if(i){let c=this.visibleEvents().map(u=>u.order_id);c.length!==i.length||c.some((u,d)=>u!==i[d])?this.repaintFrame():this.render(a)}else this.render(a);return[...a.inserts,...a.updates].map(c=>({obj:Ne(c,r,n),line:as(c,r,n)}))}onHeartbeat(){this.liveness=!this.liveness,this.state.lastClock=$(),this.render({inserts:[],updates:[]})}onConnState(e){this.connected=e===M.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 St("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=vr({events:[{orders:[n]}]},this.state,"backfill");if(this.until.active)for(let a of[...s.inserts,...s.updates]){let o=String(n.created_time??new Date().toISOString());if(this.until.check(Ne(a,0,o)))return}}}}catch{}this.repaintFrame()}};Nr=class{productIds;screen;state=ps();flash=new Xt;until;liveness=!1;connected=!1;constructor(e,r,n){this.until=n,this.productIds=r,e.isTTY&&!e.untilActive&&(this.screen=new Gt(e.out),Tr(this.screen),this.screen.onResize(()=>{Tr(this.screen),this.repaintFrame()}))}syncHeartbeat(){this.state.heartbeat=this.connected&&this.liveness}render(e){this.screen&&(this.syncHeartbeat(),fs(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=ms(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:Sr(s,r,n),line:bs(s,r,n)}))}onHeartbeat(){this.liveness=!this.liveness,this.state.lastClock=$(),this.render([])}onConnState(e){this.connected=e===M.SUBSCRIBED,this.render([])}onGap(){}onReconnected(){}async setup(){}cleanup(){this.screen?.cleanup()}};Gr=class{productIds;screen;state;productId;liveness=!1;connected=!1;constructor(e,r,n,i){this.productId=r,this.productIds=[r],this.state=Es(r,e.flags.depth??0),e.isTTY&&!e.untilActive&&(this.screen=new Gt(e.out),wr(this.screen,this.state),this.screen.onResize(()=>{wr(this.screen,this.state),this.render()}))}syncHeartbeat(){this.state.heartbeat=this.connected&&this.liveness}render(){this.screen&&(this.syncHeartbeat(),Cr(this.screen,this.state))}onData(e,r,n){return Is(e,this.state),this.liveness=!this.liveness,this.render(),[{obj:xr(this.state,r,n),line:Os(this.state,r,n)}]}onHeartbeat(){this.liveness=!this.liveness,this.state.lastClock=$(),this.render()}onConnState(e){this.connected=e===M.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 Ss={};qt(Ss,{applyJQ:()=>Dr});import{execFileSync as Za}from"node:child_process";function Dr(t,e){try{return Za("jq",["-r",e],{input:t,encoding:"utf8",maxBuffer:10*1024*1024,env:Xe()}).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 Lr=h(()=>{"use strict";g();l();Q()});var Ds={};qt(Ds,{UntilController:()=>Ft,__test:()=>sc,startWatch:()=>ic,surfaceForChannel:()=>Me});function ec(t){return tc.find(e=>e.id===t)}function Me(t){switch(t.name){case"user":return"blotter";case"ticker":return"watchlist";case"level2":return"ladder";default:return null}}async function nc(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).
53
+ Set up a CDP key: coinbase env <name> --key-file key.json`);if(n.type==="cdp_key"&&n.key_id&&n.key_secret)return we(n.key_id,n.key_secret);throw new Error("Unsupported auth type for WebSocket")}async function ic(t,e,r,n){let i=Re(t);if(!i)throw new Error(`--watch is not supported for "${t.replace(/_/g," ")}"`);let s=Me(i);if(!s)throw new Error(`--watch is not yet implemented for channel "${i.name}"`);if(n.until){let c;try{c=yr(n.until)}catch(d){throw new Error(`Invalid --until predicate: ${d.message}`)}let _=ec(t);if(_?.watchFields){let d=zi(c,_.watchFields);if(d.length>0){let p=Object.keys(_.watchFields).join(", ");throw new Error(d.map(y=>y.message).join(`
54
+ `)+`
55
+ Available fields: ${p}`)}}let u=Jt(c);if(u.length>0&&e.length>0){let d=u.filter(p=>!e.includes(p));if(d.length>0)throw new Error(`Predicate references product${d.length>1?"s":""} not in watch: ${d.join(", ")}
56
+ Watching: ${e.join(", ")}`)}}let a=await nc(r,i),o=!!process.stdout.isTTY;await ac(n),s==="blotter"?await Cs(i,a,r,n,o):s==="watchlist"?await xs(i,e,a,n,o):s==="ladder"&&await As(i,e,a,n,o)}async function Fe(t,e,r,n,i,s){let a=n.start();await i.setup();let o=0,c;c=new Se({channel:t,WebSocketClass:s,onEvent:u=>{let d=u;o=d.sequence_num??o;let p=String(d.timestamp??new Date().toISOString()),y=i.onData(d,o,p);if(y.length!==0){if(!i.screen&&!n.active)for(let v of y)Gs(v.line,r);if(n.active){for(let v of y)if(n.check(v.obj))return}}},onHeartbeat:()=>i.onHeartbeat(),onSequenceGap:()=>{let u=i.onGap();u&&(c.unsubscribe(u.resubscribe),c.subscribe(u.resubscribe,i.refreshJWT?i.refreshJWT():e))},onError:i.screen?void 0:u=>process.stderr.write(`ws error: ${u}
57
+ `),onStateChange:u=>{u===M.FAILED&&n.onFailed(),i.onConnState(u)},onDisconnect:()=>n.onDisconnect(),onReconnect:()=>n.onReconnect(),onReconnected:()=>i.onReconnected(),refreshJWT:i.refreshJWT}),c.connect(),c.subscribe(i.productIds,e);let _=await oc(a,i.screen);c.close(),Ns(_,i,r,n)}async function Cs(t,e,r,n,i,s,a){let o=new Ft(n),c=vs({isTTY:i,untilActive:o.active,flags:n,out:s?.out},r,e,t,o);await Fe(t,e,n,o,c,a)}async function xs(t,e,r,n,i,s,a){if(e.length===0)throw new Error("--watch requires at least one product_id (e.g. BTC-USD)");let o=new Ft(n),c=Rs({isTTY:i,untilActive:o.active,flags:n,out:s?.out},e,o);await Fe(t,r,n,o,c,a)}async function As(t,e,r,n,i,s,a){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],c=new Ft(n),_=Ps({isTTY:i,untilActive:c.active,flags:n,out:s?.out},o,r,c);await Fe(t,r,n,c,_,a)}function oc(t,e){return new Promise(r=>{let n=()=>{},i=s=>{n(),r(s)};if(e)e.installSignalHandlers(()=>i(null));else{let s=()=>i(null),a=()=>i(null);n=()=>{process.off("SIGINT",s),process.off("SIGTERM",a)},process.on("SIGINT",s),process.on("SIGTERM",a)}t.then(i)})}function Ns(t,e,r,n){if(e.cleanup(),n?.cleanup(),!!t)switch(t.type){case"matched":Gs(JSON.stringify(t.event),r??{}),process.exitCode=0;break;case"timeout":process.stderr.write(`error: --until timed out
58
+ `),process.exitCode=124;break;case"failed":process.stderr.write(`error: WebSocket connection failed permanently
59
+ `),process.exitCode=2;break;case"disconnect_budget_exceeded":process.stderr.write(`error: cumulative disconnection exceeded ${Math.round(t.totalMs/1e3)}s
60
+ `),process.exitCode=2;break}}function Gs(t,e){if(e.jq)try{let{applyJQ:r}=Le,n=r(new TextEncoder().encode(t),e.jq);process.stdout.write(n+`
61
+ `)}catch(r){process.stderr.write(`jq error: ${r.message??r}
62
+ `)}else process.stdout.write(t+`
63
+ `)}async function ac(t){if(t.jq&&!Le){Le=await Promise.resolve().then(()=>(Lr(),Ss));try{let{applyJQ:e}=Le;e(new TextEncoder().encode("{}"),t.jq)}catch(e){throw new Error(`Invalid --jq expression: ${e.message??e}`)}}}var tc,rc,ws,Ft,sc,Le,Mr=h(()=>{"use strict";g();l();Ir();Vi();Te();Or();$i();hr();Pt();Ts();tc=[...J.flatMap(t=>t.actions),...Object.values(X)];rc=300*1e3,ws=3e4,Ft=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?yr(e.until):null,this.timeoutMs=e.untilTimeout?e.untilTimeout*1e3:null,this.requiredProducts=this.predicate?[...new Set(Jt(this.predicate))]:[],this.signals=r??new Ce}get active(){return this.predicate!==null}get stale(){return this.signals.staleProducts(this.requiredProducts,ws)}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
64
+ `));for(let n of this.requiredProducts)if(this.signals.hasSeen(n)&&this.signals.isStale(n,ws))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)
65
+ `)),!1;return wt(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>rc&&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))}};sc={runSurface:Fe,runBlotter:Cs,runWatchlist:xs,runLadder:As,handleResult:Ns};Le=null});var Ue={};qt(Ue,{bodyBytes:()=>fc,hasBody:()=>mc,isFieldArg:()=>yc,parseFields:()=>lc,setNested:()=>Br});import{readFileSync as cc,openSync as _c,readSync as uc,closeSync as dc}from"node:fs";function lc(t,e=gc){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{Br(r.body,s,JSON.parse(n.slice(i+1)))}catch(a){throw new Error(`invalid JSON in ${s}: ${a.message}`)}}else n[i+1]==="="?r.query.append(n.slice(0,i),n.slice(i+2)):Br(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 mc(t){return Object.keys(t.body).length>0||t.rawBody!==null}function fc(t){return t.rawBody?t.rawBody:Object.keys(t.body).length===0?null:new TextEncoder().encode(JSON.stringify(t.body))}function yc(t){return!!(t.includes("=")||t.startsWith("@")||t.startsWith("-")||t.indexOf(":")>0&&t[0]>="A"&&t[0]<="Z")}function Br(t,e,r){let n=e.split("."),i=t;for(let s=0;s<n.length;s++){let a=n[s];if(bc.has(a))throw new Error(`invalid field name: ${a}`);if(s===n.length-1){Object.defineProperty(i,a,{value:r,writable:!0,enumerable:!0,configurable:!0});return}(!Object.hasOwn(i,a)||typeof i[a]!="object"||i[a]===null)&&Object.defineProperty(i,a,{value:{},writable:!0,enumerable:!0,configurable:!0}),i=i[a]}}var gc,bc,Be=h(()=>{"use strict";g();l();gc={readFile(t){try{return cc(t)}catch(e){throw new Error(`reading file ${t}: ${e.message}`)}},readStdin(){let t=[],e=Buffer.alloc(65536),r;try{r=_c("/dev/stdin","r")}catch{throw new Error("reading stdin: cannot open")}try{let n;for(;(n=uc(r,e))>0;)t.push(Buffer.from(e.subarray(0,n)))}catch{}return dc(r),Buffer.concat(t)}};bc=new Set(["__proto__","constructor","prototype"])});var Us={};qt(Us,{outputResult:()=>hc});function hc(t,e){let r=JSON.stringify(t.data),n=t.status>=400;if(e)try{process.stdout.write(Dr(new TextEncoder().encode(r),e)+`
49
66
  `)}catch(i){process.stdout.write(r+`
50
67
  `),process.stderr.write(`jq error: ${i.message}
51
68
  `)}else n&&process.stdout.isTTY||(process.stdout.isTTY?process.stdout.write(JSON.stringify(t.data,null,2)+`
52
69
  `):process.stdout.write(r+`
53
- `));if(n){let i=t.data?.message||t.data?.errorMessage||r.slice(0,200),s=t.data?.correlationId,o=t.headers?.get("trace-id"),a=[o?`trace ${o}`:"",s?`correlation ${s}`:""].filter(Boolean).join(", ");throw new Error(`${i} (HTTP ${t.status})${a?` [${a}]`:""}`)}}var fn=C(()=>{"use strict";u();g();yn()});u();g();u();g();M();Qt();import{createInterface as se}from"node:readline/promises";import{readFileSync as qn}from"node:fs";function _t(t,e={}){te(()=>{let r=w();t(r),q(r,{allowPlaintext:e.allowPlaintext})})}function Bn(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 ie(t,e){if(!e&&!De())throw new Error(`OS keychain unavailable; refusing to persist secrets for "${t}".
54
- Re-run with --allow-plaintext-secrets to write secrets to ${L()} (file is mode 0600), or install/unlock your OS keychain (macOS Keychain, libsecret on Linux, Windows Credential Manager).`)}async function We(t,e){Bn(e);let r=w();if(t.length===0){let _=[...new Set([...Object.keys(r.environments),...Object.keys(D)])].sort();if(_.length===0){process.stderr.write(`No environments configured. Run: coinbase env <name>
55
- `);return}let l=Math.max(14,..._.map(I=>I.length));for(let I of _){let O=r.environments[I]??{},T=U(O,I),h=pt(O),N=!!r.environments[I],v=h?.type==="cdp_key"?h.key_id:"(no key)",G=v.length>60?v.slice(0,57)+"...":v;process.stdout.write(`${I===r.env?"* ":" "}${I.padEnd(l)} ${(T.length>45?T.slice(0,42)+"...":T).padEnd(45)} ${G}
56
- `)}return}let n=t[0];if(e.remove){_t(_=>{delete _.environments[n],_.env===n&&(_.env="")}),Zt(n),process.stderr.write(`Removed ${n}.
57
- `);return}let i=r.environments[n]??{};if(e.status){Vn(n,i);return}let s=(_,l)=>{i.auth={type:"cdp_key",key_id:_,key_secret:l}};if(e.keyFile){ie(n,!!e.allowPlaintextSecrets);let _=Wn(e.keyFile);s(_.keyId,_.keySecret),e.url&&(i.url=e.url,st(e.url)||process.stderr.write(`warning: custom URL does not match a known endpoint
58
- `)),_t(l=>{l.environments[n]=i,l.env=n},{allowPlaintext:e.allowPlaintextSecrets}),process.stderr.write(`Loaded key from ${e.keyFile}. Switched to ${n}.
59
- `);return}if(e.keyId||e.keySecret||e.url){let _=pt(i),l=_?.type==="cdp_key"?_.key_id:"",I=_?.type==="cdp_key"?_.key_secret:"";(e.keyId||e.keySecret)&&(ie(n,!!e.allowPlaintextSecrets),s(e.keyId??l,e.keySecret??I)),e.url&&(i.url=e.url,st(e.url)||process.stderr.write(`warning: custom URL does not match a known endpoint
60
- `)),_t(O=>{O.environments[n]=i,O.env=n},{allowPlaintext:e.allowPlaintextSecrets}),process.stderr.write(`Saved and switched to ${n}.
61
- `);return}if(pt(i)){_t(_=>{_.env=n}),process.stderr.write(`Switched to ${n}.
62
- `);return}if(r.environments[n]){_t(_=>{_.env=n}),process.stderr.write(`Switched to ${n} (no credentials yet).
70
+ `));if(n){let i=t.data?.message||t.data?.errorMessage||r.slice(0,200),s=t.data?.correlationId,a=t.headers?.get("trace-id"),o=[a?`trace ${a}`:"",s?`correlation ${s}`:""].filter(Boolean).join(", ");throw new Error(`${i} (HTTP ${t.status})${o?` [${o}]`:""}`)}}var Bs=h(()=>{"use strict";g();l();Lr()});g();l();g();l();Q();Ve();import{createInterface as rr}from"node:readline/promises";import{readFileSync as co}from"node:fs";function Rt(t,e={}){Qe(()=>{let r=j();t(r),tt(r,{allowPlaintext:e.allowPlaintext})})}function _o(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 er(t,e){if(!e&&!en())throw new Error(`OS keychain unavailable; refusing to persist secrets for "${t}".
71
+ Re-run with --allow-plaintext-secrets to write secrets to ${Y()} (file is mode 0600), or install/unlock your OS keychain (macOS Keychain, libsecret on Linux, Windows Credential Manager).`)}async function dn(t,e){_o(e);let r=j();if(t.length===0){let u=[...new Set([...Object.keys(r.environments),...Object.keys(K)])].sort();if(u.length===0){process.stderr.write(`No environments configured. Run: coinbase env <name>
72
+ `);return}let d=Math.max(14,...u.map(p=>p.length));for(let p of u){let y=r.environments[p]??{},v=Z(y,p),k=Wt(y),S=!!r.environments[p],T=k?.type==="cdp_key"?k.key_id:"(no key)",w=T.length>60?T.slice(0,57)+"...":T;process.stdout.write(`${p===r.env?"* ":" "}${p.padEnd(d)} ${(v.length>45?v.slice(0,42)+"...":v).padEnd(45)} ${w}
73
+ `)}return}let n=t[0];if(e.remove){Rt(u=>{delete u.environments[n],u.env===n&&(u.env="")}),Ye(n),process.stderr.write(`Removed ${n}.
74
+ `);return}let i=r.environments[n]??{};if(e.status){lo(n,i);return}let s=(u,d)=>{i.auth={type:"cdp_key",key_id:u,key_secret:d}};if(e.keyFile){er(n,!!e.allowPlaintextSecrets);let u=po(e.keyFile);s(u.keyId,u.keySecret),e.url&&(i.url=e.url,Ot(e.url)||process.stderr.write(`warning: custom URL does not match a known endpoint
75
+ `)),Rt(d=>{d.environments[n]=i,d.env=n},{allowPlaintext:e.allowPlaintextSecrets}),process.stderr.write(`Loaded key from ${e.keyFile}. Switched to ${n}.
76
+ `);return}if(e.keyId||e.keySecret||e.url){let u=Wt(i),d=u?.type==="cdp_key"?u.key_id:"",p=u?.type==="cdp_key"?u.key_secret:"";(e.keyId||e.keySecret)&&(er(n,!!e.allowPlaintextSecrets),s(e.keyId??d,e.keySecret??p)),e.url&&(i.url=e.url,Ot(e.url)||process.stderr.write(`warning: custom URL does not match a known endpoint
77
+ `)),Rt(y=>{y.environments[n]=i,y.env=n},{allowPlaintext:e.allowPlaintextSecrets}),process.stderr.write(`Saved and switched to ${n}.
78
+ `);return}if(Wt(i)){Rt(u=>{u.env=n}),process.stderr.write(`Switched to ${n}.
79
+ `);return}if(r.environments[n]){Rt(u=>{u.env=n}),process.stderr.write(`Switched to ${n} (no credentials yet).
63
80
  `),process.stderr.write(` CDP key: coinbase env ${n} --key-file path/to/key.json
64
- `);return}if(!process.stdout.isTTY)throw new Error(`environment "${n}" needs API keys. Run: coinbase env ${n} --key-id=... --key-secret=...`);ie(n,!!e.allowPlaintextSecrets);let a="",d="",c=se({input:process.stdin,output:process.stderr});try{if(!a){let _=await c.question("API Key ID: ");if(!_.trim())throw new Error("API Key ID is required");a=_.trim()}if(!d){c.close();let _=await Fn("API Key Secret: ");if(!_.trim())throw new Error("API Key Secret is required");d=_.trim(),c=se({input:process.stdin,output:process.stderr})}if(s(a,d),!i.url&&!U(i,n)){let _=await c.question("URL (optional): ");_.trim()&&(i.url=_.trim(),st(i.url)||process.stderr.write(`warning: custom URL does not match a known endpoint
65
- `))}}finally{c.close()}_t(_=>{_.environments[n]=i,_.env=n},{allowPlaintext:e.allowPlaintextSecrets}),process.stderr.write(`Saved. Switched to ${n}.
66
- `)}function Fn(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===`
81
+ `);return}if(!process.stdout.isTTY)throw new Error(`environment "${n}" needs API keys. Run: coinbase env ${n} --key-id=... --key-secret=...`);er(n,!!e.allowPlaintextSecrets);let o="",c="",_=rr({input:process.stdin,output:process.stderr});try{if(!o){let u=await _.question("API Key ID: ");if(!u.trim())throw new Error("API Key ID is required");o=u.trim()}if(!c){_.close();let u=await uo("API Key Secret: ");if(!u.trim())throw new Error("API Key Secret is required");c=u.trim(),_=rr({input:process.stdin,output:process.stderr})}if(s(o,c),!i.url&&!Z(i,n)){let u=await _.question("URL (optional): ");u.trim()&&(i.url=u.trim(),Ot(i.url)||process.stderr.write(`warning: custom URL does not match a known endpoint
82
+ `))}}finally{_.close()}Rt(u=>{u.environments[n]=i,u.env=n},{allowPlaintext:e.allowPlaintextSecrets}),process.stderr.write(`Saved. Switched to ${n}.
83
+ `)}function uo(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===`
67
84
  `||s==="\r"||s===""?(r.setRawMode(!1),r.pause(),r.removeListener("data",i),process.stderr.write(`
68
- `),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=se({input:process.stdin});r.once("line",n=>{r.close(),e(n)})})}function zn(t){return t?t.length<=12?"***":t.slice(0,8)+"\u2026"+t.slice(-4):"(none)"}function Vn(t,e){(!e.auth||e.auth.type!=="cdp_key")&&(process.stderr.write(`Environment "${t}" has no stored credentials.
85
+ `),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 go(t){return t?t.length<=12?"***":t.slice(0,8)+"\u2026"+t.slice(-4):"(none)"}function lo(t,e){(!e.auth||e.auth.type!=="cdp_key")&&(process.stderr.write(`Environment "${t}" has no stored credentials.
69
86
  `),process.exit(1)),process.stdout.write(`env: ${t}
70
87
  `),process.stdout.write(`auth: cdp_key
71
- `),process.stdout.write(`key_id: ${zn(e.auth.key_id)}
72
- `)}function Wn(t){let e;try{e=qn(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();g();import{createInterface as Mi}from"node:readline";u();g();var j=[{name:"convert",actions:[{id:"convert_quote",name:"quote",method:"POST",path:"/convert/quote",summary:"Get Convert Quote",description:"",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,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"]}}}},{id:"convert_execute",name:"execute",method:"POST",path:"/convert/execute/{quote_id}",summary:"Execute Convert Trade",description:"",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,template:{from:"USDC",to:"USD"},responseFields:{fields:["trade"],nested:{trade:{fields:["id","status"]}}}},{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,template:{},responseFields:{fields:["id","status","source_currency","target_currency","exchange_rate"]}}]},{name:"orders",actions:[{id:"orders_list",name:"list",method:"GET",path:"/orders",summary:"List Orders",description:"",pathParams:[],params:[{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"]},{name:"product_type",in:"query",type:"string",required:!1,description:"Filter by product type",enum:["SPOT","FUTURE"]},{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:!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"]}}}},{id:"orders_create",name:"create",method:"POST",path:"/orders",summary:"Create Order",description:"",pathParams:[],params:[{name:"product_id",in:"body",type:"string",required:!0,description:"Trading pair",example:"BTC-USD"},{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). Market buy only. 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. buy 0.001 BTC). Any side/type.",oneOf:"base_size|quote_size",example:"0.001"},{name:"limit_price",in:"body",type:"string",required:!1,description:"Limit price (limit/stop_limit orders)"},{name:"stop_price",in:"body",type:"string",required:!1,description:"Stop price (stop_limit orders)"},{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"]},{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"]},{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"},{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:"Scopes the order to a specific portfolio (defaults to auth-scoped portfolio)"},{name:"client_order_id",in:"body",type:"string",required:!1,description:"Idempotency key (auto-generated if omitted)"}],streamable:!1,template:{product_id:"BTC-USD",side:"BUY",type:"market",quote_size:"100.00",base_size:"0.001",limit_price:"<string>",stop_price:"<string>",stop_direction:"up",post_only:!1,time_in_force:"GTC",end_time:"<string>",reduce_only:!1,portfolio_id:"<string>",client_order_id:"<string>"},responseFields:{fields:["order_id","product_id","side","client_order_id"]}},{id:"orders_preview",name:"preview",method:"POST",path:"/orders/preview",summary:"Preview Order",description:"Estimate fees, fill price, and slippage without executing.",pathParams:[],params:[{name:"product_id",in:"body",type:"string",required:!0,description:"Trading pair (e.g. BTC-USD)",example:"BTC-USD"},{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"},{name:"limit_price",in:"body",type:"string",required:!1,description:"Limit price (for limit/stop_limit previews)"},{name:"stop_price",in:"body",type:"string",required:!1,description:"Stop price (for stop_limit previews)"},{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"]}],streamable:!1,template:{product_id:"BTC-USD",side:"BUY",type:"market",quote_size:"100.00",base_size:"<string>",limit_price:"<string>",stop_price:"<string>",stop_direction:"up"},responseFields:{fields:["order_total","commission_total","slippage","est_average_filled_price","base_size","quote_size","best_bid","best_ask"]}},{id:"orders_edit",name:"edit",method:"POST",path:"/orders/edit",summary:"Edit Order",description:"Atomically update an open order's price or size without cancelling. Avoids the cancel+replace exposure window.",pathParams:[],params:[{name:"order_id",in:"body",type:"string",required:!0,description:"Order to edit"},{name:"base_size",in:"body",type:"string",required:!1,description:"New base size"},{name:"limit_price",in:"body",type:"string",required:!1,description:"New limit price"}],streamable:!1,template:{order_id:"<string>",base_size:"<string>",limit_price:"<string>"},responseFields:{fields:["order_id","status"]}},{id:"orders_get",name:"get",method:"GET",path:"/orders/{order_id}",summary:"Get Order",description:"",pathParams:["order_id"],params:[{name:"order_id",in:"path",type:"string",required:!0,description:"Order ID"}],streamable:!1,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"]}},{id:"orders_cancel",name:"cancel",method:"POST",path:"/orders/cancel",summary:"Cancel Orders",description:"",pathParams:[],params:[{name:"order_ids",in:"body",type:"array",required:!0,description:"Order IDs to cancel"}],streamable:!1,template:{order_ids:[]},responseFields:{fields:["results"],nested:{results:{fields:["success","order_id"]}}}},{id:"orders_close_position",name:"close-position",method:"POST",path:"/orders/close-position",summary:"Close Position",description:"",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"},{name:"size",in:"body",type:"string",required:!1,description:"Partial close size (omit for full close)"}],streamable:!1,template:{client_order_id:"<string>",product_id:"<string>",size:"<string>"},responseFields:null},{id:"orders_fills",name:"fills",method:"GET",path:"/orders/fills",summary:"List Fills",description:"",pathParams:[],params:[{name:"product_ids",in:"query",type:"string",required:!1,description:"Filter by product (e.g. BTC-USD)"},{name:"order_ids",in:"query",type:"string",required:!1,description:"Filter by order ID"},{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:"side",in:"query",type:"string",required:!1,description:"Filter by side",enum:["BUY","SELL"]},{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,template:{},responseFields:{fields:["fills","cursor"],nested:{fills:{fields:["trade_id","order_id","trade_time","price","size","commission","product_id","side","liquidity_indicator"]}}}}]},{name:"portfolios",actions:[{id:"portfolios_list",name:"list",method:"GET",path:"/portfolios",summary:"List Portfolios",description:"",pathParams:[],params:[{name:"portfolio_type",in:"query",type:"string",required:!1,description:"Filter by type (DEFAULT, CONSUMER, INTX)"}],streamable:!1,template:{},responseFields:{fields:["portfolios"],nested:{portfolios:{fields:["uuid","name","type","deleted"]}}}},{id:"portfolios_create",name:"create",method:"POST",path:"/portfolios",summary:"Create Portfolio",description:"",pathParams:[],params:[{name:"name",in:"body",type:"string",required:!0,description:"Portfolio name",example:"agent-1"}],streamable:!1,template:{name:"agent-1"},responseFields:{fields:["uuid","name","type","deleted"]}},{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,template:{},responseFields:{fields:["portfolio","portfolio_balances","spot_positions"],nested:{portfolio:{fields:["uuid","name","type","deleted"]},portfolio_balances:{fields:["total_balance","total_crypto_balance","total_cash_equivalent_balance"],nested:{total_balance:{fields:["value","currency"]},total_crypto_balance:{fields:["value","currency"]},total_cash_equivalent_balance:{fields:["value","currency"]}}},spot_positions:{fields:["asset","account_uuid","total_balance_fiat","total_balance_crypto","available_to_trade_fiat","allocation","is_cash"]}}}},{id:"portfolios_edit",name:"edit",method:"PUT",path:"/portfolios/{portfolio_id}",summary:"Edit Portfolio",description:"",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,template:{name:"<string>"},responseFields:{fields:["uuid","name","type","deleted"]}},{id:"portfolios_delete",name:"delete",method:"DELETE",path:"/portfolios/{portfolio_id}",summary:"Delete Portfolio",description:"",pathParams:["portfolio_id"],params:[{name:"portfolio_id",in:"path",type:"string",required:!0,description:"Portfolio UUID"}],streamable:!1,template:{},responseFields:null}]},{name:"products",actions:[{id:"products_list",name:"list",method:"GET",path:"/products",summary:"List Products",description:"",pathParams:[],params:[{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 `get` (e.g. BTC-USD). Pagination ignored when set.",pattern:"^[A-Za-z0-9]+$"},{name:"product_type",in:"query",type:"string",required:!1,description:"Product type filter",enum:["SPOT","FUTURE"]},{name:"product_ids",in:"query",type:"string",required:!1,description:"Comma-separated product IDs"},{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,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"]}}}},{id:"products_get",name:"get",method:"GET",path:"/products/{product_id}",summary:"Get Product",description:"",pathParams:["product_id"],params:[{name:"product_id",in:"path",type:"string",required:!0,description:"Product ID (e.g. BTC-USD)"}],streamable:!1,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"]}},{id:"products_ticker",name:"ticker",method:"GET",path:"/products/{product_id}/ticker",summary:"Get Ticker",description:"",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,template:{},responseFields:{fields:["trades","best_bid","best_ask"],nested:{trades:{fields:["trade_id","product_id","price","size","time","side"]}}}},{id:"products_book",name:"book",method:"GET",path:"/products/{product_id}/book",summary:"Get Order Book",description:"",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,template:{},responseFields:{fields:["pricebook"],nested:{pricebook:{fields:["product_id","bids","asks","time"],nested:{bids:{fields:["price","size"]},asks:{fields:["price","size"]}}}}}},{id:"products_candles",name:"candles",method:"GET",path:"/products/{product_id}/candles",summary:"Get Candles",description:"",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"]},{name:"limit",in:"query",type:"integer",required:!1,description:"Max candles"}],streamable:!0,template:{},responseFields:{fields:["candles"],nested:{candles:{fields:["start","low","high","open","close","volume"]}}}},{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.",pathParams:[],params:[{name:"product_ids",in:"query",type:"string",required:!1,description:"Comma-separated product IDs (e.g. BTC-USD,ETH-USD)"}],streamable:!1,template:{},responseFields:{fields:["pricebooks"],nested:{pricebooks:{fields:["product_id","bids","asks","time"],nested:{bids:{fields:["price","size"]},asks:{fields:["price","size"]}}}}}}]}],K={balance:{id:"balance",name:"balance",method:"GET",path:"/balance",summary:"View Balances",description:"",pathParams:[],params:[{name:"portfolio_id",in:"query",type:"string",required:!1,description:"Filter by 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,template:{},responseFields:{fields:["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"]}}}}}},transfer:{id:"transfer",name:"transfer",method:"POST",path:"/transfer",summary:"Move Funds Between Portfolios",description:"",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-..."},{name:"to",in:"body",type:"string",required:!0,description:"Target portfolio UUID",example:"a44ef7a8-..."}],streamable:!1,template:{amount:"100.00",currency:"USD",from:"d17b3486-...",to:"a44ef7a8-..."},responseFields:{fields:["source_portfolio_uuid","target_portfolio_uuid"]}},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"]}],streamable:!1,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"]}}}}},$e=new Set(["balance","transfer","fees"]),He={"date-time":/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?(Z|[+-]\d{2}:\d{2})$/};function $n(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 je={"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,a]=e;return $n(+r,+n,+i)&&+s<24&&+o<60&&+a<61}};u();g();u();g();function Ke(t){return typeof t=="object"&&"endpoint"in t}function P(t,e){return{endpoint:t,...e}}u();g();u();g();u();g();var Ye={origin:"RetailBrokerageApi_CancelOrders",method:"POST",path:"/api/v3/brokerage/orders/batch_cancel"},Qe={origin:"RetailBrokerageApi_ClosePosition",method:"POST",path:"/api/v3/brokerage/orders/close_position"},Xe={origin:"RetailBrokerageApi_CommitConvertTrade",method:"POST",path:"/api/v3/brokerage/convert/trade/{trade_id}"};var Je={origin:"RetailBrokerageApi_CreatePortfolio",method:"POST",path:"/api/v3/brokerage/portfolios"},Ze={origin:"RetailBrokerageApi_DeletePortfolio",method:"DELETE",path:"/api/v3/brokerage/portfolios/{portfolio_uuid}"};var tr={origin:"RetailBrokerageApi_EditPortfolio",method:"PUT",path:"/api/v3/brokerage/portfolios/{portfolio_uuid}"};var er={origin:"RetailBrokerageApi_GetBestBidAsk",method:"GET",path:"/api/v3/brokerage/best_bid_ask"};var rr={origin:"RetailBrokerageApi_GetConvertTrade",method:"GET",path:"/api/v3/brokerage/convert/trade/{trade_id}"};var nr={origin:"RetailBrokerageApi_GetFills",method:"GET",path:"/api/v3/brokerage/orders/historical/fills"},ir={origin:"RetailBrokerageApi_GetHistoricalOrder",method:"GET",path:"/api/v3/brokerage/orders/historical/{order_id}"},sr={origin:"RetailBrokerageApi_GetHistoricalOrders",method:"GET",path:"/api/v3/brokerage/orders/historical/batch"};var or={origin:"RetailBrokerageApi_GetPortfolioBreakdown",method:"GET",path:"/api/v3/brokerage/portfolios/{portfolio_uuid}"},ar={origin:"RetailBrokerageApi_GetPortfolios",method:"GET",path:"/api/v3/brokerage/portfolios"},_r={origin:"RetailBrokerageApi_GetProduct",method:"GET",path:"/api/v3/brokerage/products/{product_id}"};var cr={origin:"RetailBrokerageApi_GetPublicProductBook",method:"GET",path:"/api/v3/brokerage/market/product_book"};var ur={origin:"RetailBrokerageApi_GetTransactionSummary",method:"GET",path:"/api/v3/brokerage/transaction_summary"};var gr={portfolios_list:P(ar),portfolios_get:P(or,{requestMap:{portfolio_id:"portfolio_uuid"},responseUnwrap:"breakdown"}),portfolios_create:P(Je,{responseUnwrap:"portfolio"}),portfolios_edit:P(tr,{requestMap:{portfolio_id:"portfolio_uuid"},responseUnwrap:"portfolio"}),portfolios_delete:P(Ze,{requestMap:{portfolio_id:"portfolio_uuid"}})};u();g();import{randomUUID as jn}from"node:crypto";u();g();var R=class t extends Error{status;correlationId;traceId;constructor(e,r,n){super(e),this.status=r,this.correlationId=n?.correlationId,this.traceId=n?.traceId}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,o;try{let d=JSON.parse(i);d.errorType&&d.errorMessage?s=`${d.errorType} \u2014 ${d.errorMessage}`:d.message?s=t.stripGrpcPrefix(d.message):s=i.length>200?i.slice(0,200)+"...":i,o=d.correlationId||d.correlation_id||void 0}catch{s=i.length>200?i.slice(0,200)+"...":i}let a=n?.get("trace-id")??void 0;return new t(s,r,{correlationId:o,traceId:a})}};u();g();function oe(t){if(t?.success===!1){let e=t.error_response,r=t.errors?.[0]?.edit_failure_reason,n=e?.new_order_failure_reason?String(e.new_order_failure_reason).replace(/^NEW_ORDER_FAILURE_REASON_/,"").replace(/_/g," ").toLowerCase():void 0;throw new R(e?.message||e?.error_details||n||r?.toString()||"Operation failed",400)}}u();g();var Mt={MARKET:"market",LIMIT:"limit",STOP_LIMIT:"stop_limit"};var ae={UP:"up",DOWN:"down"},X={GTC:"GTC",IOC:"IOC",FOK:"FOK",GTD:"GTD"};u();g();function Hn(t,e){let r={...e},n=t;for(let[i,s]of Object.entries(r)){let o="{"+i+"}";s!=null&&n.includes(o)&&(n=n.replaceAll(o,encodeURIComponent(String(s))),delete r[i])}return{url:n,remaining:r}}var bt=class extends Error{status;data;constructor(e,r,n){super(e),this.status=r,this.data=n}};async function B(t,e,r,n){let{url:i,remaining:s}=Hn(r,n),o=e==="POST"||e==="PUT"||e==="DELETE"||e==="PATCH",a,d=null;if(o)a=t.baseURL+i,Object.keys(s).length>0&&(d=new TextEncoder().encode(JSON.stringify(s)));else{let I=Object.entries(s).filter(([,O])=>O!=null).map(([O,T])=>encodeURIComponent(O)+"="+encodeURIComponent(String(T))).join("&");a=t.baseURL+i+(I?"?"+I:"")}let c=await t.doRequest({method:e,url:a,body:d}),_=new TextDecoder().decode(c.body),l;try{l=JSON.parse(_)}catch{l=_}if(c.status>=400){let I=l,O=I?.error_response?.message??I?.error_response?.error_details??I?.message??I?.error_details??_.slice(0,200);throw new bt(O,c.status,l)}return{status:c.status,data:l}}function dr(t,e){return B(t,"POST","/api/v3/brokerage/convert/quote",e)}function pr(t,e){return B(t,"POST","/api/v3/brokerage/orders/edit",e)}function lr(t,e){return B(t,"GET","/api/v3/brokerage/accounts",e)}function mr(t,e){return B(t,"GET","/api/v3/brokerage/products/{product_id}/candles",e)}function yr(t,e){return B(t,"GET","/api/v3/brokerage/products/{product_id}/ticker",e)}function _e(t,e){return B(t,"GET","/api/v3/brokerage/products",e)}function br(t,e){return B(t,"POST","/api/v3/brokerage/portfolios/move_funds",e)}function fr(t,e){return B(t,"POST","/api/v3/brokerage/orders",e)}function Er(t,e){return B(t,"POST","/api/v3/brokerage/orders/preview",e)}function Ir(t){let e=t.type;if(e===Mt.MARKET)return{market_market_ioc:{...t.quote_size&&{quote_size:t.quote_size},...t.base_size&&{base_size:t.base_size}}};if(e===Mt.LIMIT){let r=t.time_in_force??X.GTC,n={base_size:t.base_size,limit_price:t.limit_price,...t.post_only&&{post_only:!0}};return r===X.IOC?{sor_limit_ioc:n}:r===X.FOK?{limit_limit_fok:n}:r===X.GTD?{limit_limit_gtd:{...n,...t.end_time&&{end_time:t.end_time}}}:{limit_limit_gtc:n}}else if(e===Mt.STOP_LIMIT){let r=t.stop_direction===ae.UP?"STOP_DIRECTION_STOP_UP":t.stop_direction===ae.DOWN?"STOP_DIRECTION_STOP_DOWN":(()=>{throw new R("stop_direction is required for stop_limit orders (up or down)",400)})(),n=t.time_in_force??X.GTC,i={base_size:t.base_size,limit_price:t.limit_price,stop_price:t.stop_price,stop_direction:r};return n===X.GTD?{stop_limit_stop_limit_gtd:{...i,...t.end_time&&{end_time:t.end_time}}}:{stop_limit_stop_limit_gtc:i}}throw new R(`Unknown order type: ${e}. Use market, limit, or stop_limit.`,400)}function Kn(t){let e={client_order_id:t.client_order_id??jn(),product_id:t.product_id,side:t.side,order_configuration:Ir(t)};return t.portfolio_id&&(e.retail_portfolio_id=t.portfolio_id),t.reduce_only&&(e.reduce_only=!0),e}var Yn=async(t,e)=>{let r=Kn(t),n=await fr(e,r);return oe(n.data),n.data.success_response??n.data},Qn=async(t,e)=>{let r=await Er(e,{product_id:t.product_id,side:t.side,order_configuration:Ir(t)}),n=r.data;if(n.errs?.length>0)throw new R(n.errs[0].replace(/^PREVIEW_/,"").replace(/_/g," ").toLowerCase(),400);return r.data},Xn=async(t,e)=>{if(!t.base_size&&!t.limit_price)throw new R("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 pr(e,r);return oe(n.data),{order_id:t.order_id,status:"EDITED"}},Or={orders_list:P(sr,{requestMap:{status:"order_status",side:"order_side",start:"start_date",end:"end_date"}}),orders_get:P(ir,{responseUnwrap:"order"}),orders_create:Yn,orders_preview:Qn,orders_edit:Xn,orders_cancel:P(Ye),orders_close_position:P(Qe),orders_fills:P(nr,{requestMap:{side:"order_side",start:"start_sequence_timestamp",end:"end_sequence_timestamp"}})};u();g();var Jn={"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"},Zn={"1m":60,"5m":300,"15m":900,"30m":1800,"1h":3600,"2h":7200,"4h":14400,"6h":21600,"1d":86400},ti=60,ei=async(t,e)=>{let{symbol:r,limit:n,cursor:i,...s}=t;if(r){let a=r.toUpperCase(),_=((await _e(e,s)).data.products??[]).filter(I=>I.base_currency_id===a||I.quote_currency_id===a),l=n!==void 0&&n>0?_.slice(0,n):_;return{products:l,num_products:l.length}}return(await _e(e,{...s,limit:n,cursor:i})).data};function hr(t){return String(Math.floor(new Date(t).getTime()/1e3))}var ri=async(t,e)=>{let r=t.granularity??"1h",n=Jn[r],i=Zn[r],s=Math.floor(Date.now()/1e3),o=t.end?hr(t.end):String(s),a=t.start?hr(t.start):String(Number(o)-ti*i);return(await mr(e,{...t,granularity:n,start:a,end:o})).data},ni=async(t,e)=>{let r=t.limit??100;return(await yr(e,{...t,limit:r})).data},Pr={products_list:ei,products_get:P(_r),products_ticker:ni,products_book:P(cr),products_candles:ri,products_best_bid_ask:P(er)};u();g();var ii=async(t,e)=>{let{from:r,to:n,...i}=t,s=await dr(e,{...i,from_account:r,to_account:n});if(!s.data?.trade?.id)throw new R(`Convert quote returned no trade for ${t.from} \u2192 ${t.to}. Verify balance, supported pair, and account eligibility.`,422);return s.data},kr={convert_quote:ii,convert_execute:P(Xe,{requestMap:{quote_id:"trade_id",from:"from_account",to:"to_account"}}),convert_get:P(rr,{requestMap:{quote_id:"trade_id",from:"from_account",to:"to_account"},responseUnwrap:"trade"})};u();g();var si=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 lr(e,r)).data,s=i.accounts??[],o=t.show_zero?s:s.filter(a=>parseFloat(a.available_balance?.value??"0")!==0||parseFloat(a.hold?.value??"0")!==0);return{accounts:o,has_next:i.has_next,cursor:i.cursor,size:o.length}},Rr={balance:si};u();g();var oi=async(t,e)=>{let r={funds:{value:t.amount,currency:t.currency},source_portfolio_uuid:t.from,target_portfolio_uuid:t.to},i=(await br(e,r)).data;if(!i?.source_portfolio_uuid)throw new R("Transfer failed \u2014 check amount, currency, and portfolio UUIDs",400);return i},vr={transfer:oi};u();g();var Tr={fees:P(ur)};var ai={...gr,...Or,...Pr,...kr,...Rr,...vr,...Tr};function Ut(t){return ai[t]}u();g();function ce(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 Ar(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 xr=[...j.flatMap(t=>t.actions),...Object.values(K)],ue={},Sr=new Map;for(let t of xr){ue[t.id]=t.responseFields;for(let e of t.params)e.pattern&&Sr.set(e.pattern,new RegExp(e.pattern))}function _i(t,e){let r={...e},n=t;for(let[i,s]of Object.entries(e)){if(s==null||s==="")continue;let o=`{${i}}`;n.includes(o)&&(n=n.replaceAll(o,encodeURIComponent(String(s))),delete r[i])}return{resolvedPath:n,remainingParams:r}}function ci(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 ui(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 gi(t){return t&&typeof t=="object"&&("body"in t||"query"in t||"path"in t||"rawBody"in t)}function ft(t,e){if(t==null||typeof t!="object")return t;if(Array.isArray(t))return t.map(n=>ft(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=>ft(s,i)):i&&typeof t[n]=="object"&&t[n]!==null?r[n]=ft(t[n],i):r[n]=t[n]}return r}function di(t,e){let r=ue[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 qt(t,e,r){let n=gi(e),i=n?e.body??{}:e,s=n?e.query??{}:{},o=n?e.path??{}:{},a=n?e.headers??{}:{},d=n?e.rawBody??null:null,c=Ut(t);if(!c)return{status:404,data:{error:"UNKNOWN_OPERATION",code:404,message:`No route for ${t}`}};let _=xr.find(b=>b.id===t);if(_?.params){if(d)try{let b=JSON.parse(new TextDecoder().decode(d));b&&typeof b=="object"&&!Array.isArray(b)&&Object.assign(i,b)}catch{}{let p=_.params.filter(f=>f.in==="body"&&f.required).filter(f=>i[f.name]===void 0||i[f.name]==="");if(p.length>0)return{status:400,data:{error:"MISSING_FIELDS",code:400,message:`Missing required field(s): ${p.map(E=>E.name).join(", ")}`}}}{let b={...o,...i,...s},p={},f={};for(let E of _.params)if(E.oneOf&&(f[E.oneOf]||(f[E.oneOf]=[]),f[E.oneOf].push(E.name),b[E.name]!==void 0&&b[E.name]!=="")){if(p[E.oneOf])return{status:400,data:{error:"CONFLICTING_FIELDS",code:400,message:`${p[E.oneOf]} and ${E.name} are mutually exclusive. Provide one, not both.`}};p[E.oneOf]=E.name}for(let[E,x]of Object.entries(f))if(!p[E])return{status:400,data:{error:"MISSING_FIELDS",code:400,message:`One of ${x.join(", ")} is required.`}}}for(let b of _.params)for(let p of[i,s,o]){if(p[b.name]===void 0)continue;if(b.type==="boolean"&&typeof p[b.name]=="string")p[b.name]=p[b.name]==="true";else if((b.type==="integer"||b.type==="number")&&typeof p[b.name]=="string"){let S=Number(p[b.name]);if(!Number.isFinite(S))return{status:400,data:{error:"INVALID_VALUE",code:400,message:`Invalid value for ${b.name}: "${p[b.name]}". Expected a number.`}};p[b.name]=S}if(b.enum&&!b.enum.includes(String(p[b.name])))return{status:400,data:{error:"INVALID_VALUE",code:400,message:`Invalid value for ${b.name}: "${p[b.name]}". Expected one of: ${b.enum.join(", ")}`}};let f=b.pattern?Sr.get(b.pattern):void 0,E=b.format?He[b.format]:void 0,x=f??E;if(x&&typeof p[b.name]=="string"){let S=p[b.name],Y=b.format?je[b.format]:void 0;if(!(x.test(S)&&(!f||!E||E.test(S))&&(!Y||Y(S)))){let W=(b.description??"").split(/\.\s/)[0].replace(/\.?\s*$/,""),kt=W?`. ${W}.`:".";return{status:400,data:{error:"INVALID_VALUE",code:400,message:`Invalid value for ${b.name}: "${String(S).slice(0,80)}"${kt}`}}}}}}if(!Ke(c)){let b={...o,...i,...s};try{let p=await c(b,r),f=ue[t];return f&&(p=ft(p,f)),{status:200,data:p}}catch(p){if(p instanceof bt)return{status:p.status,data:p.data};let f=p instanceof R?p.status:500,E=R.stripGrpcPrefix(p instanceof Error?p.message:String(p));return{status:f,data:{error:"HANDLER_ERROR",code:f,message:E}}}}let{endpoint:l}=c,I={...o,...i},O=ce(I,c.requestMap),{resolvedPath:T,remainingParams:h}=_i(l.path,O);if(T.includes("{"))return{status:400,data:{error:"MISSING_PATH_PARAMS",code:400,message:`Missing required param(s): ${(T.match(/\{([^}]+)\}/g)?.map(p=>p.slice(1,-1))??[]).join(", ")}`}};let N=l.method==="POST"||l.method==="PUT"||l.method==="DELETE"||l.method==="PATCH",v,G=d??null,Z={...ce(s,c.requestMap)};N?(v=`${r.baseURL}${T}`,!G&&Object.keys(h).length>0&&(G=new TextEncoder().encode(JSON.stringify(h)))):(Object.assign(Z,h),v=`${r.baseURL}${T}`);let tt=ci(Z);tt&&(v+=tt);let V=await r.doRequest({method:l.method,url:v,body:G,headers:Object.keys(a).length>0?a:void 0}),ht=new TextDecoder().decode(V.body),A;try{A=JSON.parse(ht)}catch{A=ht}if(V.status>=400)return{status:V.status,data:A,headers:V.headers};c.responseUnwrap&&(A=ui(A,c.responseUnwrap)),c.responseMap&&(A=Ar(A,c.responseMap));let Pt=di(t,c.responseUnwrap);return Pt&&(A=ft(A,Pt)),{status:V.status,data:A,headers:V.headers}}M();u();g();import{createSign as ki,createPrivateKey as Ri,sign as vi,randomBytes as Ti}from"node:crypto";u();g();vt();M();import{readFileSync as pi,writeFileSync as li,mkdirSync as mi}from"node:fs";import{join as wr}from"node:path";var Nr;Nr="0.0.1";var F=Nr,Bt=Pe,yi=`${Rt}/${encodeURIComponent(Bt)}`,Gr="version-check.json";function Cr(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 bi(t,e){let r=Cr(t),n=Cr(e);return n.major!==r.major?n.major>r.major:n.minor!==r.minor?n.minor>r.minor:n.patch>r.patch}var fi="https://registry.npmjs.org";function Ei(t,e){let r=Rt===fi?"":` --registry ${Rt}`;return`
73
- Update available: ${t} \u2192 ${e}
74
- Run: npm i -g ${Bt}${r}
75
- `}var Ii=1440*60*1e3;function Dr(){return H()}function Oi(){try{return JSON.parse(pi(wr(Dr(),Gr),"utf8"))}catch{return null}}function hi(t){try{let e=Dr();mi(e,{recursive:!0}),li(wr(e,Gr),JSON.stringify(t))}catch{}}async function Pi(){try{let t=new AbortController,e=setTimeout(()=>t.abort(),3e3),r=await fetch(yi,{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 Lr(){if(process.env.CI||process.env.COINBASE_NO_UPDATE_CHECK)return"";let t=Oi();if(t&&Date.now()-t.checkedAt<Ii)return"";let e=await Pi();return e?(hi({checkedAt:Date.now(),latestVersion:e}),bi(F,e)?Ei(F,e):""):""}function ge(t){return Buffer.from(t).toString("base64url")}function Ft(t){return ge(Buffer.from(JSON.stringify(t)))}function Ai(){return Ti(16).toString("hex")}function Ur(t){return t.includes("-----BEGIN EC PRIVATE KEY-----")}function qr(t){let e=Buffer.from(t,"base64");return e.length===32||e.length===64}function xi(t,e,r,n,i){let s=Math.floor(Date.now()/1e3),o=Ai(),a={sub:t,iss:"cdp",nbf:s,iat:s,exp:s+120},d=`${r} ${n}${i}`;if(r&&n&&i&&(a.uris=[d]),Ur(e))return Ci(t,e,a,o);if(qr(e))return wi(t,e,a,o);throw new Error("invalid key format - must be either PEM EC key or base64 Ed25519 key")}function Si(t,e,r){let n=`${Ft(t)}.${Ft(e)}`,i=ki("SHA256");i.update(n);let s=i.sign(r);return`${n}.${ge(Ni(s))}`}function Ci(t,e,r,n){return Si({alg:"ES256",typ:"JWT",kid:t,nonce:n},r,e)}function wi(t,e,r,n){let s=`${Ft({alg:"EdDSA",typ:"JWT",kid:t,nonce:n})}.${Ft(r)}`,o=Buffer.from(e,"base64"),a=Ri({key:Buffer.concat([Buffer.from("302e020100300506032b657004220420","hex"),o.subarray(0,32)]),format:"der",type:"pkcs8"}),d=vi(null,Buffer.from(s),a);return`${s}.${ge(d)}`}function Ni(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=Mr(n,32),s=Mr(s,32),Buffer.concat([n,s])}function Mr(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 Gi(t){return Ur(t)?"ecdsa":qr(t)?"ed25519":"unknown"}async function zt(t){let e;if(t.keyId&&t.keySecret){let o=new URL(t.url);e=`Bearer ${xi(t.keyId,t.keySecret,t.method,o.host,o.pathname)}`}else throw new Error("doAuthenticatedRequest: must supply keyId+keySecret");let r={Authorization:e,"Content-Type":"application/json","Correlation-Context":`sdk_version=${encodeURIComponent(F)},sdk_language=typescript,source=${encodeURIComponent(Bt)}`,...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&&Gi(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}u();g();M();function k(t,e=!1){return{content:[{type:"text",text:t}],isError:e}}function Br(t,e){return t===e?`coinbase_${t.replace(/-/g,"_")}`:`coinbase_${t.replace(/-/g,"_")}_${e.replace(/[-\s]/g,"_")}`}function Fr(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 c of n.params){let _={type:c.type,description:c.description};c.enum&&(_.enum=c.enum),c.pattern&&(_.pattern=c.pattern),c.format&&(_.format=c.format),i[c.name]=_,c.required&&s.push(c.name)}let o=n.params.filter(c=>c.in==="body").length,a=n.params.filter(c=>c.in==="body"&&c.required).length,d=o>0?a>0?` (${o} fields, ${a} required)`:` (${o} fields)`:"";e.push({name:Br(r.name,n.name),description:`${n.method} ${n.path}${n.summary?" \u2014 "+n.summary:""}${d}`,inputSchema:{type:"object",properties:i,required:s.length>0?s:void 0}})}return e}function zr(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 k(`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?R.stripGrpcPrefix(t.data.message):t.data.error;return k(`Error: ${e}`,!0)}return k(JSON.stringify(t.data,null,2))}function de(t){let e=at(t,""),r=Object.keys(t.environments??{}),n=[`Active: ${e||"(none)"}`,`Configured: ${r.length>0?r.join(", "):"(none)"}`];return e||n.push(`
76
- Run: coinbase env <name> --key-id=... --key-secret=... to configure.`),k(n.join(`
77
- `))}function Vr(t,e){if(!e)return k("Environment name is required.",!0);let r=Object.keys(t.environments??{});return r.length===0?k("No environments configured. Run: coinbase env <name> --key-id=... --key-secret=... to configure.",!0):t.environments[e]?{cfg:{...t,env:e}}:k(`Unknown environment: "${e}". Available environments: ${r.join(", ")}`,!0)}function Wr(t){return de(t)}function Di(t,e){let r=t.params??[],n=[];n.push(`${t.summary||t.name}`),n.push(`${t.method} ${t.path}`);let i=t.pathParams.map(a=>`${a}="..."`).join(", ");n.push("",`Usage: ${e}(${i})`);let s=r.filter(a=>a.in==="body");if(s.length>0){n.push("","Fields:");for(let a of s){let d=a.required?" (required)":"",c=a.description?` \u2014 ${a.description}`:"";n.push(` ${a.name} (${a.type})${d}${c}`)}}let o=r.filter(a=>a.in==="query");if(o.length>0){n.push("","Query parameters:");for(let a of o){let d=a.description?` \u2014 ${a.description}`:"";n.push(` ${a.name} (${a.type})${d}`)}}return k(n.join(`
78
- `))}function $r(t,e,r,n){if(n&&Object.hasOwn(n,e)&&(!t||t===e))return{act:n[e],toolName:`coinbase_${e}`};if(t){let o=r.find(a=>a.name===t);if(o){let a=o.actions.find(d=>d.name===e);return a?{act:a,toolName:Br(o.name,a.name)}:k(`Unknown action: ${e}. Available for ${t}: ${o.actions.map(d=>d.name).join(", ")}`,!0)}}let i=r.map(o=>o.name),s=n?Object.keys(n):[];return k(`Not found. Resources: ${i.join(", ")}. Top-level actions: ${s.join(", ")}`,!0)}function Hr(t,e,r,n){if(!e)return k("action is required",!0);let i=$r(t,e,r,n);return"isError"in i?i:Di(i.act,i.toolName)}function Li(t){let e=(t.params??[]).filter(i=>i.in==="body");if(e.length===0)return k("This action has no request body.");let r=t.template??{},n=[];for(let i of e){let s=i.required?" (required)":"",o=i.description?` \u2014 ${i.description}`:"";n.push(`${i.name} (${i.type})${s}${o}`)}return k(`Template:
88
+ `),process.stdout.write(`key_id: ${go(e.auth.key_id)}
89
+ `)}function po(t){let e;try{e=co(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}}g();l();Pt();be();or();Q();Oe();he();import{createInterface as oa}from"node:readline";g();l();Q();pt();function A(t,e=!1){return{content:[{type:"text",text:t}],isError:e}}function bi(t,e){return t===e?`coinbase_${t.replace(/-/g,"_")}`:`coinbase_${t.replace(/-/g,"_")}_${e.replace(/[-\s]/g,"_")}`}function yi(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 _ of n.params){let u={type:_.type,description:_.description};_.enum&&(u.enum=_.enum),_.pattern&&(u.pattern=_.pattern),_.format&&(u.format=_.format),i[_.name]=u,_.required&&s.push(_.name)}let a=n.params.filter(_=>_.in==="body").length,o=n.params.filter(_=>_.in==="body"&&_.required).length,c=a>0?o>0?` (${a} fields, ${o} required)`:` (${a} fields)`:"";e.push({name:bi(r.name,n.name),description:`${n.method} ${n.path}${n.summary?" \u2014 "+n.summary:""}${c}`,inputSchema:{type:"object",properties:i,required:s.length>0?s:void 0}})}return e}function hi(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 A(`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?L.stripGrpcPrefix(t.data.message):t.data.error;return A(`Error: ${e}`,!0)}return A(JSON.stringify(t.data,null,2))}function dr(t){let e=vt(t,""),r=Object.keys(t.environments??{}),n=[`Active: ${e||"(none)"}`,`Configured: ${r.length>0?r.join(", "):"(none)"}`];return e||n.push(`
90
+ Run: coinbase env <name> --key-id=... --key-secret=... to configure.`),A(n.join(`
91
+ `))}function Ei(t,e){if(!e)return A("Environment name is required.",!0);let r=Object.keys(t.environments??{});return r.length===0?A("No environments configured. Run: coinbase env <name> --key-id=... --key-secret=... to configure.",!0):t.environments[e]?{cfg:{...t,env:e}}:A(`Unknown environment: "${e}". Available environments: ${r.join(", ")}`,!0)}function Ii(t){return dr(t)}function ia(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 c=o.required?" (required)":"",_=o.description?` \u2014 ${o.description}`:"";n.push(` ${o.name} (${o.type})${c}${_}`)}}let a=r.filter(o=>o.in==="query");if(a.length>0){n.push("","Query parameters:");for(let o of a){let c=o.description?` \u2014 ${o.description}`:"";n.push(` ${o.name} (${o.type})${c}`)}}return A(n.join(`
92
+ `))}function Oi(t,e,r,n){if(n&&Object.hasOwn(n,e)&&(!t||t===e))return{act:n[e],toolName:`coinbase_${e}`};if(t){let a=r.find(o=>o.name===t);if(a){let o=a.actions.find(c=>c.name===e);return o?{act:o,toolName:bi(a.name,o.name)}:A(`Unknown action: ${e}. Available for ${t}: ${a.actions.map(c=>c.name).join(", ")}`,!0)}}let i=r.map(a=>a.name),s=n?Object.keys(n):[];return A(`Not found. Resources: ${i.join(", ")}. Top-level actions: ${s.join(", ")}`,!0)}function ki(t,e,r,n){if(!e)return A("action is required",!0);let i=Oi(t,e,r,n);return"isError"in i?i:ia(i.act,i.toolName)}function sa(t){let e=(t.params??[]).filter(i=>i.in==="body");if(e.length===0)return A("This action has no request body.");let r=t.template??{},n=[];for(let i of e){let s=i.required?" (required)":"",a=i.description?` \u2014 ${i.description}`:"";n.push(`${i.name} (${i.type})${s}${a}`)}return A(`Template:
79
93
  ${JSON.stringify(r,null,2)}
80
94
 
81
95
  Fields:
82
96
  ${n.join(`
83
- `)}`)}function jr(t,e,r,n){if(!e)return k("action is required",!0);let i=$r(t,e,r,n);return"isError"in i?i:Li(i.act)}function Yr(t){process.stdout.write(JSON.stringify({jsonrpc:"2.0",...t})+`
84
- `)}function Et(t,e){Yr({id:t,result:e})}function It(t,e,r){Yr({id:t,error:{code:e,message:r}})}function Ui(){return j}async function qi(t,e){let r=Ui();if(t==="coinbase_env")return de(w());if(t==="coinbase_set_env"){let n=w(),i=Vr(n,e.name);return"isError"in i?i:(q(i.cfg),Wr(i.cfg))}return t==="coinbase_help"?Hr(String(e.resource??""),String(e.action??""),r,K):t==="coinbase_template"?jr(String(e.resource??""),String(e.action??""),r,K):Bi(t,e)}async function Bi(t,e){let r=t.replace(/^coinbase_/,"");if(!Ut(r))return k(`Unknown tool: ${t}`,!0);let n=w(),i;try{i=mt(n,"")}catch(a){return k(`Environment error: ${a.message}
97
+ `)}`)}function vi(t,e,r,n){if(!e)return A("action is required",!0);let i=Oi(t,e,r,n);return"isError"in i?i:sa(i.act)}function Pi(t){process.stdout.write(JSON.stringify({jsonrpc:"2.0",...t})+`
98
+ `)}function Yt(t,e){Pi({id:t,result:e})}function Qt(t,e,r){Pi({id:t,error:{code:e,message:r}})}function aa(){return J}async function ca(t,e){let r=aa();if(t==="coinbase_env")return dr(j());if(t==="coinbase_set_env"){let n=j(),i=Ei(n,e.name);return"isError"in i?i:(tt(i.cfg),Je(),Ii(i.cfg))}return t==="coinbase_help"?ki(String(e.resource??""),String(e.action??""),r,X):t==="coinbase_template"?vi(String(e.resource??""),String(e.action??""),r,X):_a(t,e)}async function _a(t,e){let r=t.replace(/^coinbase_/,"");if(!fe(r))return A(`Unknown tool: ${t}`,!0);let n=j(),i;try{i=$t(n,"")}catch(o){return A(`Environment error: ${o.message}
85
99
 
86
- Run: coinbase env <name> --key-id=... --key-secret=...`,!0)}let{name:s,env:o}=i;try{let a=await lt(s,o),d={envName:s,env:o,baseURL:U(o,s),doRequest:_=>zt({..._,...a})},c=await qt(r,e,d);return zr(c)}catch(a){return k(`Request failed: ${a.message}`,!0)}}var Fi={name:"coinbase",version:F},zi={tools:{}},pe=null;function Kr(){if(!pe){let t=[...j];for(let[e,r]of Object.entries(K))t.push({name:e,actions:[r]});pe=Fr(t)}return pe}async function Vi(t){let{id:e,method:r,params:n}=t;switch(r){case"initialize":Et(e,{protocolVersion:"2024-11-05",serverInfo:Fi,capabilities:zi});break;case"notifications/initialized":break;case"tools/list":Et(e,{tools:Kr()});break;case"tools/call":{let{name:i,arguments:s}=n??{};if(!i){It(e,-32602,"Missing tool name");return}if(!Kr().find(a=>a.name===i)){It(e,-32602,`Unknown tool: ${i}`);return}try{let a=await qi(i,s??{});Et(e,a)}catch(a){Et(e,k(`Internal error: ${a.message}`,!0))}break}case"ping":Et(e,{});break;default:e!=null&&It(e,-32601,`Method not found: ${r}`);break}}function Qr(){let t=Mi({input:process.stdin,terminal:!1}),e=new Set;t.on("line",r=>{if(r.trim())try{let n=JSON.parse(r),i=Vi(n).catch(s=>{process.stderr.write(`MCP error: ${s.message}
87
- `),n.id!=null&&It(n.id,-32603,s.message)}).finally(()=>e.delete(i));e.add(i)}catch{It(null,-32700,"Parse error")}}),t.on("close",async()=>{await Promise.all(e),process.exit(0)}),process.stderr.write(`coinbase MCP server v${F} ready
88
- `)}u();g();M();function Xr(t){let e=w();if(t.length===0)return Wi(e);if(t[0]==="clear"){let r=t[1],n;if(r&&r.includes(".")){let i=r.indexOf(".");n=yt(e,r.slice(0,i),r.slice(i+1))}else r?n=yt(e,r):n=yt(e);q(e),process.stderr.write(`Cleared ${n} history ${n===1?"entry":"entries"}.
89
- `);return}throw new Error("usage: coinbase history [clear [env.action]]")}function Wi(t){let e=[];for(let[i,s]of Object.entries(t.history))for(let[o,a]of Object.entries(s))e.push({env:i,action:o,lastUsed:a.last_used,fields:Object.keys(a.values)});if(e.length===0){process.stderr.write(`No saved history.
100
+ Run: coinbase env <name> --key-id=... --key-secret=...`,!0)}let{name:s,env:a}=i;try{let o=await Vt(s,a),c={envName:s,env:a,baseURL:Z(a,s),doRequest:u=>Ie({...u,...o})},_=await St(r,e,c);return hi(_)}catch(o){return A(`Request failed: ${o.message}`,!0)}}var ua={name:"coinbase",version:rt},da={tools:{}},gr=null;function Ri(){if(!gr){let t=[...J];for(let[e,r]of Object.entries(X))t.push({name:e,actions:[r]});gr=yi(t)}return gr}async function ga(t){let{id:e,method:r,params:n}=t;switch(r){case"initialize":Yt(e,{protocolVersion:"2024-11-05",serverInfo:ua,capabilities:da});break;case"notifications/initialized":break;case"tools/list":Yt(e,{tools:Ri()});break;case"tools/call":{let{name:i,arguments:s}=n??{};if(!i){Qt(e,-32602,"Missing tool name");return}if(!Ri().find(o=>o.name===i)){Qt(e,-32602,`Unknown tool: ${i}`);return}try{let o=await ca(i,s??{});Yt(e,o)}catch(o){Yt(e,A(`Internal error: ${o.message}`,!0))}break}case"ping":Yt(e,{});break;default:e!=null&&Qt(e,-32601,`Method not found: ${r}`);break}}function Ti(){let t=oa({input:process.stdin,terminal:!1}),e=new Set;t.on("line",r=>{if(r.trim())try{let n=JSON.parse(r),i=ga(n).catch(s=>{process.stderr.write(`MCP error: ${s.message}
101
+ `),n.id!=null&&Qt(n.id,-32603,s.message)}).finally(()=>e.delete(i));e.add(i)}catch{Qt(null,-32700,"Parse error")}}),t.on("close",async()=>{await Promise.all(e),process.exit(0)}),process.stderr.write(`coinbase MCP server v${rt} ready
102
+ `)}g();l();Q();function Si(t){let e=j();if(t.length===0)return la(e);if(t[0]==="clear"){let r=t[1],n;if(r&&r.includes(".")){let i=r.indexOf(".");n=Ht(e,r.slice(0,i),r.slice(i+1))}else r?n=Ht(e,r):n=Ht(e);tt(e),process.stderr.write(`Cleared ${n} history ${n===1?"entry":"entries"}.
103
+ `);return}throw new Error("usage: coinbase history [clear [env.action]]")}function la(t){let e=[];for(let[i,s]of Object.entries(t.history))for(let[a,o]of Object.entries(s))e.push({env:i,action:a,lastUsed:o.last_used,fields:Object.keys(o.values)});if(e.length===0){process.stderr.write(`No saved history.
90
104
  `);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(", ")}
91
- `)}}u();g();M();import{readFileSync as rn,writeFileSync as $i,mkdirSync as nn,readdirSync as sn,existsSync as J,cpSync as Hi,rmSync as ji}from"node:fs";import Jr,{join as z,resolve as Zr}from"node:path";import{fileURLToPath as Ki}from"node:url";import{homedir as tn}from"node:os";import{createInterface as en}from"node:readline";function me(){try{return JSON.parse(rn(L(),"utf8"))}catch{return{}}}function le(t){let e=H();nn(e,{recursive:!0,mode:448}),$i(L(),JSON.stringify(t,null,2)+`
92
- `,{mode:384})}function on(){let t=Jr.dirname(Ki(import.meta.url));return Jr.join(t,"..","skills")}function Yi(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 an(t){let e=t??on();if(!J(e))return[];let r=[];for(let n of sn(e,{withFileTypes:!0})){if(!n.isDirectory())continue;let i=z(e,n.name,"SKILL.md");if(!J(i))continue;let s=rn(i,"utf8"),o=Yi(s);r.push({name:o.name||n.name,description:o.description,dir:z(e,n.name)})}return r.sort((n,i)=>n.name.localeCompare(i.name))}function Qi(t,e){if(!J(t))return 0;nn(e,{recursive:!0});let r=0;for(let n of sn(t,{withFileTypes:!0})){if(!n.isDirectory())continue;let i=z(t,n.name,"SKILL.md");if(!J(i))continue;let s=z(e,n.name);Hi(z(t,n.name),s,{recursive:!0,force:!0}),r++}return r}async function Xi(){let t=process.platform==="win32"?z(process.env.USERPROFILE??tn(),".claude","skills"):z(tn(),".claude","skills");process.stderr.write(`Where should skills be installed?
105
+ `)}}g();l();Q();import{readFileSync as Ni,writeFileSync as pa,mkdirSync as Gi,readdirSync as Di,existsSync as bt,cpSync as ma,rmSync as fa}from"node:fs";import wi,{join as nt,resolve as Ci}from"node:path";import{fileURLToPath as ba}from"node:url";import{homedir as xi}from"node:os";import{createInterface as Ai}from"node:readline";function pr(){try{return JSON.parse(Ni(Y(),"utf8"))}catch{return{}}}function lr(t){let e=ot();Gi(e,{recursive:!0,mode:448}),pa(Y(),JSON.stringify(t,null,2)+`
106
+ `,{mode:384})}function Li(){let t=wi.dirname(ba(import.meta.url));return wi.join(t,"..","skills")}function ya(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 Mi(t){let e=t??Li();if(!bt(e))return[];let r=[];for(let n of Di(e,{withFileTypes:!0})){if(!n.isDirectory())continue;let i=nt(e,n.name,"SKILL.md");if(!bt(i))continue;let s=Ni(i,"utf8"),a=ya(s);r.push({name:a.name||n.name,description:a.description,dir:nt(e,n.name)})}return r.sort((n,i)=>n.name.localeCompare(i.name))}function ha(t,e){if(!bt(t))return 0;Gi(e,{recursive:!0});let r=0;for(let n of Di(t,{withFileTypes:!0})){if(!n.isDirectory())continue;let i=nt(t,n.name,"SKILL.md");if(!bt(i))continue;let s=nt(e,n.name);ma(nt(t,n.name),s,{recursive:!0,force:!0}),r++}return r}async function Ea(){let t=process.platform==="win32"?nt(process.env.USERPROFILE??xi(),".claude","skills"):nt(xi(),".claude","skills");process.stderr.write(`Where should skills be installed?
93
107
  `),process.stderr.write(`Tip: Not sure where your agent looks for skills? Ask your agent.
94
108
 
95
109
  `),process.stderr.write(` 1) ${t} User \u2014 available across all projects (Recommended)
96
110
  `),process.stderr.write(` 2) Other Specify a custom path
97
111
 
98
- `);let e=en({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=en({input:process.stdin,output:process.stderr}),i=await new Promise(s=>{n.question("? Path: ",o=>{n.close(),s(o.trim())})});return i?Zr(i):(process.stderr.write(`No path provided, using default.
99
- `),t)}return Zr(r)}async function Ji(t){let e=me(),r=t||e.settings?.skillsDir,n=!1;r||(process.stdin.isTTY||(process.stderr.write(`error: no skills directory configured.
112
+ `);let e=Ai({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=Ai({input:process.stdin,output:process.stderr}),i=await new Promise(s=>{n.question("? Path: ",a=>{n.close(),s(a.trim())})});return i?Ci(i):(process.stderr.write(`No path provided, using default.
113
+ `),t)}return Ci(r)}async function Ia(t){let e=pr(),r=t||e.settings?.skillsDir,n=!1;r||(process.stdin.isTTY||(process.stderr.write(`error: no skills directory configured.
100
114
  Run: coinbase skills add --dir <path>
101
- `),process.exit(1)),r=await Xi(),n=!0),(!e.settings?.skillsDir||t&&e.settings.skillsDir!==r)&&(e.settings||(e.settings={}),e.settings.skillsDir=r,le(e));let i=on(),s=Qi(i,r);process.stderr.write(`Installed ${s} skills to ${r}.
115
+ `),process.exit(1)),r=await Ea(),n=!0),(!e.settings?.skillsDir||t&&e.settings.skillsDir!==r)&&(e.settings||(e.settings={}),e.settings.skillsDir=r,lr(e));let i=Li(),s=ha(i,r);process.stderr.write(`Installed ${s} skills to ${r}.
102
116
  `),n&&process.stderr.write(`Skills will auto-update on future installs.
103
- `)}function Zi(){let e=me().settings?.skillsDir,r=an();if(r.length===0){process.stderr.write(`No bundled skills found.
117
+ `)}function Oa(){let e=pr().settings?.skillsDir,r=Mi();if(r.length===0){process.stderr.write(`No bundled skills found.
104
118
  `);return}let n=Math.max(...r.map(i=>i.name.length),4);process.stderr.write(`${"Name".padEnd(n+2)}${"Installed".padEnd(12)}Description
105
119
  `),process.stderr.write(`${"\u2500".repeat(n+2)}${"\u2500".repeat(12)}${"\u2500".repeat(40)}
106
- `);for(let i of r){let o=e&&J(z(e,i.name,"SKILL.md"))?"yes":"no";process.stderr.write(`${i.name.padEnd(n+2)}${o.padEnd(12)}${i.description}
120
+ `);for(let i of r){let a=e&&bt(nt(e,i.name,"SKILL.md"))?"yes":"no";process.stderr.write(`${i.name.padEnd(n+2)}${a.padEnd(12)}${i.description}
107
121
  `)}process.stderr.write(`
108
122
  ${r.length} skills available.`),e?process.stderr.write(` Installed to: ${e}`):process.stderr.write(" Run: coinbase skills add"),process.stderr.write(`
109
- `)}function ts(){let t=me(),e=t.settings?.skillsDir;if(!e){process.stderr.write(`No skills directory configured. Nothing to remove.
110
- `);return}if(!J(e)){process.stderr.write(`Skills directory not found: ${e}
111
- `),t.settings&&delete t.settings.skillsDir,le(t),process.stderr.write(`Cleared skillsDir from config.
112
- `);return}let r=an(),n=0;for(let i of r){let s=z(e,i.name);J(s)&&(ji(s,{recursive:!0,force:!0}),n++)}t.settings&&delete t.settings.skillsDir,le(t),process.stderr.write(`Removed ${n} skills from ${e}.
123
+ `)}function ka(){let t=pr(),e=t.settings?.skillsDir;if(!e){process.stderr.write(`No skills directory configured. Nothing to remove.
124
+ `);return}if(!bt(e)){process.stderr.write(`Skills directory not found: ${e}
125
+ `),t.settings&&delete t.settings.skillsDir,lr(t),process.stderr.write(`Cleared skillsDir from config.
126
+ `);return}let r=Mi(),n=0;for(let i of r){let s=nt(e,i.name);bt(s)&&(fa(s,{recursive:!0,force:!0}),n++)}t.settings&&delete t.settings.skillsDir,lr(t),process.stderr.write(`Removed ${n} skills from ${e}.
113
127
  `),process.stderr.write(`Cleared skillsDir from config.
114
- `)}async function _n(t){let e=t[0];if(!e||e==="-h"||e==="--help"){process.stderr.write(`Manage CDP agent skills
128
+ `)}async function Fi(t){let e=t[0];if(!e||e==="-h"||e==="--help"){process.stderr.write(`Manage CDP agent skills
115
129
 
116
130
  Usage:
117
131
  coinbase skills add Install/update skills to your skills directory
@@ -119,36 +133,40 @@ Usage:
119
133
  coinbase skills list List available skills from this package
120
134
  coinbase skills remove Remove installed skills and clear config
121
135
 
122
- `);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 Ji(r);break;case"list":Zi();break;case"remove":ts();break;default:process.stderr.write(`error: unknown skills subcommand: ${e}
136
+ `);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 Ia(r);break;case"list":Oa();break;case"remove":ka();break;default:process.stderr.write(`error: unknown skills subcommand: ${e}
123
137
  Run: coinbase skills --help
124
- `),process.exit(1)}}u();g();u();g();u();g();function es(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)}var cn=es(process.env,!!process.stdout.isTTY);function ye(t){return t.replace(/\x1b\]8;;[^\x07]*\x07/g,"").replace(/\x1b\[[0-9;]*m/g,"").length}function rs(t,e,r){return r?`\x1B]8;;${e}\x07\x1B[4m${t}\x1B[24m\x1B]8;;\x07`:`${t} (${e})`}function un(t,e=cn){return t.replace(/\[([^\]]+)\]\(([^)]+)\)/g,(r,n,i)=>rs(n,i,e))}function be(t){return t.replace(/\*\*(.+?)\*\*/g,"$1").replace(/__(.+?)__/g,"$1").replace(/\*(.+?)\*/g,"$1").replace(/_(.+?)_/g,"$1").replace(/\[([^\]]+)\]\([^)]+\)/g,"$1").replace(/^#{1,6}\s+/gm,"")}function gn(t,e){let r=e??process.stdout.columns??100;return t.replace(/\r\n/g,`
138
+ `),process.exit(1)}}g();l();Pt();g();l();ke();function Ra(t,e,r){return r?`\x1B]8;;${e}\x07\x1B[4m${t}\x1B[24m\x1B]8;;\x07`:`${t} (${e})`}function Bi(t,e=Ui){return t.replace(/\[([^\]]+)\]\(([^)]+)\)/g,(r,n,i)=>Ra(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 qi(t,e){let r=e??process.stdout.columns??100;return t.replace(/\r\n/g,`
125
139
  `).trim().split(`
126
- `).flatMap(n=>{n=be(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(`
140
+ `).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(`
127
141
  `)+`
128
- `}u();g();function Vt(t,e,r,n){let i=n??e.length,s=Math.max(20,(process.stdout.columns||80)-i),o=r.split(" "),a="",d=!0;for(let c of o){let _=ye(c),l=ye(a),I=c.includes("\x1B]8;;");(l+_+1>s||I&&l>0&&l+_+1>s*.6)&&a.length>0&&(t.write((d?e:" ".repeat(i))+a.trimEnd()+`
129
- `),a="",d=!1),a+=(a?" ":"")+c}a&&t.write((d?e:" ".repeat(i))+a.trimEnd()+`
130
- `)}function fe(){return j}function dn(t){return $e.has(t)}function Ee(t,e){let r=process.stderr;r.write(`${e.summary||e.name}
142
+ `}g();l();ke();function ve(t,e,r,n){let i=n??e.length,s=Math.max(20,(process.stdout.columns||80)-i),a=r.split(" "),o="",c=!0;for(let _ of a){let u=at(_),d=at(o),p=_.includes("\x1B]8;;");(d+u+1>s||p&&d>0&&d+u+1>s*.6)&&o.length>0&&(t.write((c?e:" ".repeat(i))+o.trimEnd()+`
143
+ `),o="",c=!1),o+=(o?" ":"")+_}o&&t.write((c?e:" ".repeat(i))+o.trimEnd()+`
144
+ `)}hr();Ir();Mr();function Fr(){return J}function Ls(t){return gn.has(t)}function Ur(t,e){let r=process.stderr;r.write(`${e.summary||e.name}
131
145
  `),e.description&&r.write(`
132
- `+gn(e.description));let n=t===e.name?`coinbase ${e.name}`:`coinbase ${t} ${e.name}`;for(let c of e.pathParams)n+=` <${c}>`;r.write(`
146
+ `+qi(e.description));let n=t===e.name?`coinbase ${e.name}`:`coinbase ${t} ${e.name}`;for(let d of e.pathParams)n+=` <${d}>`;r.write(`
133
147
  Usage:
134
148
  ${n} [fields...]
135
- `);let i=e.params??[],s=i.filter(c=>c.in==="path");if(s.length>0){r.write(`
149
+ `);let i=e.params??[],s=i.filter(d=>d.in==="path");if(s.length>0){r.write(`
136
150
  Arguments:
137
- `);let c=Math.max(...s.map(_=>_.name.length));for(let _ of s){let l=` <${_.name}>${" ".repeat(Math.max(1,c-_.name.length+2))}${_.type}${_.required?" required":""} `;Vt(r,l,_.description)}}let o=i.filter(c=>c.in==="body");if(o.length>0){r.write(`
151
+ `);let d=Math.max(...s.map(p=>p.name.length));for(let p of s){let y=` <${p.name}>${" ".repeat(Math.max(1,d-p.name.length+2))}${p.type}${p.required?" required":""} `;ve(r,y,p.description)}}let a=i.filter(d=>d.in==="body");if(a.length>0){r.write(`
138
152
  Fields:
139
- `);let c=Math.max(...o.map(_=>_.name.length));for(let _ of o){let l=_.required?"required":"",I=" ".repeat(Math.max(1,c-_.name.length+2)),O=" ".repeat(Math.max(1,8-_.type.length)),T=l?" ":" ",h=_.type==="array"||_.type==="object"?" (use :=json)":"",N=un(be(_.description)),v=` ${_.name}${I}${_.type}${O}${l}${T}`;Vt(r,v,N+h)}}let a=i.filter(c=>c.in==="query");if(a.length>0){r.write(`
153
+ `);let d=Math.max(...a.map(p=>p.name.length));for(let p of a){let y=p.required?"required":"",v=" ".repeat(Math.max(1,d-p.name.length+2)),k=" ".repeat(Math.max(1,8-p.type.length)),S=y?" ":" ",T=p.type==="array"||p.type==="object"?" (use :=json)":"",w=Bi(mr(p.description)),H=` ${p.name}${v}${p.type}${k}${y}${S}`;ve(r,H,w+T)}}let o=i.filter(d=>d.in==="query");if(o.length>0){r.write(`
140
154
  Query params (use == syntax):
141
- `);let c=Math.max(...a.map(_=>_.name.length));for(let _ of a){let l=_.description;_.enum?.length&&(l+=(l?" ":"")+`[${_.enum.join(", ")}]`);let I=` ${_.name}${" ".repeat(Math.max(1,c-_.name.length+2))}${_.type} `;Vt(r,I,l)}}let d=o.length>0;if(r.write(`
155
+ `);let d=Math.max(...o.map(p=>p.name.length));for(let p of o){let y=p.description;p.enum?.length&&(y+=(y?" ":"")+`[${p.enum.join(", ")}]`);let v=` ${p.name}${" ".repeat(Math.max(1,d-p.name.length+2))}${p.type} `;ve(r,v,y)}}let c=a.length>0;r.write(`
142
156
  Flags:
143
- `),d&&r.write(` --template Show request body template from spec
157
+ `),c&&r.write(` --template Show request body template from spec
144
158
  `),r.write(` --dry-run Preview request without sending
145
- `),d&&r.write(` --edit Open request body in $EDITOR
159
+ `),c&&r.write(` --edit Open request body in $EDITOR
146
160
  `),r.write(` --jq <expr> Filter response with jq
147
161
  `),e.streamable&&r.write(` --paginate Auto-paginate using nextPageToken
148
- `),d||a.length>0){r.write(`
162
+ `);let _=Re(e.id);if(_&&Me(_)!==null&&(r.write(` --watch Live stream via WebSocket
163
+ `),e.watchFields&&(r.write(`
164
+ `+Wi(e.watchFields)+`
165
+ `),r.write(` --until-timeout <s> Exit 124 if predicate not matched within N seconds
166
+ `))),c||o.length>0){r.write(`
149
167
  Example:
150
- `+n);for(let c of o)c.example!==void 0&&r.write(` ${c.name}=${c.example}`);for(let c of a)c.example!==void 0&&r.write(` ${c.name}==${c.example}`);r.write(`
151
- `)}}function pn(t){let e=j.find(r=>r.name===t);e||(process.stderr.write(`error: unknown resource: ${t}
168
+ `+n);for(let d of a)d.example!==void 0&&r.write(` ${d.name}=${d.example}`);for(let d of o)d.example!==void 0&&r.write(` ${d.name}==${d.example}`);r.write(`
169
+ `)}}function Ms(t){let e=J.find(r=>r.name===t);e||(process.stderr.write(`error: unknown resource: ${t}
152
170
  Run: coinbase --help
153
171
  `),process.exit(1)),process.stderr.write(`Manage ${e.name}
154
172
 
@@ -160,39 +178,39 @@ Flags:
160
178
  --dry-run Show assembled request without sending
161
179
  --edit Open request body in $EDITOR
162
180
  --jq <expr> jq filter expression for response
163
- `)}u();g();u();g();var ln=t=>t?.has_next===!1?null:t?.cursor||null;M();async function Oe(t,e,r,n){if(r.flags.template){let p=e.template??{};process.stdout.write(JSON.stringify(p,null,2)+`
164
- `);return}let i=[],s=[],{isFieldArg:o}=await Promise.resolve().then(()=>($t(),Wt));for(let p of r.args)i.length<e.pathParams.length&&!o(p)?i.push(p):s.push(p);if(i.length<e.pathParams.length){let p=e.pathParams.slice(i.length);throw new Error(`Missing argument(s): ${p.map(f=>`<${f}>`).join(" ")}
181
+ `)}g();l();be();g();l();var Fs=t=>t?.has_next===!1?null:t?.cursor||null;Q();Oe();async function qr(t,e,r,n){if(r.flags.template){let m=e.template??{};process.stdout.write(JSON.stringify(m,null,2)+`
182
+ `);return}let i=[],s=[],{isFieldArg:a}=await Promise.resolve().then(()=>(Be(),Ue));for(let m of r.args)i.length<e.pathParams.length&&!a(m)?i.push(m):s.push(m);if(i.length<e.pathParams.length){let m=e.pathParams.slice(i.length);throw new Error(`Missing argument(s): ${m.map(I=>`<${I}>`).join(" ")}
165
183
 
166
- Usage: coinbase ${t.replace(/_/g," ")} ${e.pathParams.map(f=>`<${f}>`).join(" ")} [fields...]`)}let{parseFields:a}=await Promise.resolve().then(()=>($t(),Wt)),d=a(s),c=!1,_={},l=w(),I=at(l,n);if(I&&Lt(l)){let p=ne(l,I,t);if(p){let{setNested:f}=await Promise.resolve().then(()=>($t(),Wt));for(let[E,x]of Object.entries(p.values))try{f(_,E,JSON.parse(x))}catch{f(_,E,x)}c=!0}}let O=e.params??[];for(let p of Object.keys(d.body)){let f=O.find(E=>E.name===p);if(f?.oneOf)for(let E of O)E.oneOf===f.oneOf&&E.name!==p&&delete _[E.name]}let h=Object.keys(d.body).length>0?{..._,...d.body}:c?(process.stderr.write(`Using saved values from last ${t.replace(/_/g," ")} call. Pass fields to override.
167
- `),{..._}):{...d.body},N={};for(let[p,f]of d.query.entries())N[p]=f;let v={};for(let p=0;p<i.length;p++)v[e.pathParams[p]]=i[p];let G=O.filter(p=>p.in==="body"&&p.required&&p.type!=="object"&&p.type!=="array"),ut=G.map(p=>p.name);if(ut.length>0&&Object.keys(h).length===0&&!r.flags.edit&&!d.rawBody)if(process.stdin.isTTY)if(G.length<=3){let{createInterface:p}=await import("node:readline"),f=p({input:process.stdin,output:process.stderr});for(let E of G){let x=E.enum?` [${E.enum.join(", ")}]`:"",S=E.example?` (e.g. ${E.example})`:"",Y=await new Promise(gt=>{f.question(`${E.name}${x}${S}: `,gt)});Y&&(h[E.name]=Y)}f.close()}else process.stderr.write(`This action requires ${ut.length} fields. Opening editor.
168
- `),r.flags.edit=!0;else{let p=ut.join(", ");throw new Error(`Missing required field(s): ${p}
184
+ Usage: coinbase ${t.replace(/_/g," ")} ${e.pathParams.map(I=>`<${I}>`).join(" ")} [fields...]`)}let{parseFields:o}=await Promise.resolve().then(()=>(Be(),Ue)),c=o(s),_=!1,u={},d=j(),p=vt(d,n);if(p&&pe(d)){let m=tr(d,p,t);if(m){let{setNested:I}=await Promise.resolve().then(()=>(Be(),Ue));for(let[E,D]of Object.entries(m.values))try{I(u,E,JSON.parse(D))}catch{I(u,E,D)}_=!0}}let y=e.params??[];for(let m of Object.keys(c.body)){let I=y.find(E=>E.name===m);if(I?.oneOf)for(let E of y)E.oneOf===I.oneOf&&E.name!==m&&delete u[E.name]}let k=Object.keys(c.body).length>0?{...u,...c.body}:_?(process.stderr.write(`Using saved values from last ${t.replace(/_/g," ")} call. Pass fields to override.
185
+ `),{...u}):{...c.body},S={};for(let[m,I]of c.query.entries())S[m]=I;let T={};for(let m=0;m<i.length;m++)T[e.pathParams[m]]=i[m];let w=y.filter(m=>m.in==="body"&&m.required&&m.type!=="object"&&m.type!=="array"),H=w.map(m=>m.name);if(H.length>0&&Object.keys(k).length===0&&!r.flags.edit&&!c.rawBody)if(process.stdin.isTTY)if(w.length<=3){let{createInterface:m}=await import("node:readline"),I=m({input:process.stdin,output:process.stderr});for(let E of w){let D=E.enum?` [${E.enum.join(", ")}]`:"",V=E.example?` (e.g. ${E.example})`:"",dt=await new Promise(Bt=>{I.question(`${E.name}${D}${V}: `,Bt)});dt&&(k[E.name]=dt)}I.close()}else process.stderr.write(`This action requires ${H.length} fields. Opening editor.
186
+ `),r.flags.edit=!0;else{let m=H.join(", ");throw new Error(`Missing required field(s): ${m}
169
187
 
170
188
  Provide fields inline:
171
- coinbase ${t.replace(/_/g," ")} ${ut.map(f=>`${f}=<value>`).join(" ")}
189
+ coinbase ${t.replace(/_/g," ")} ${H.map(I=>`${I}=<value>`).join(" ")}
172
190
 
173
191
  Or use --template to see the full body:
174
192
  coinbase ${t.replace(/_/g," ")} --template
175
- `)}if(r.flags.edit){let f={...e.template??{},...h},E=await fs(JSON.stringify(f,null,2));for(let x of Object.keys(h))delete h[x];Object.assign(h,E)}if(r.flags["dry-run"]){process.stderr.write(`would execute ${t}
176
- `);let p={...v,...h,...Object.keys(N).length>0?{_query:N}:{}};process.stdout.write(JSON.stringify(p,null,2)+`
177
- `);return}let{name:Z,env:tt}=mt(l,n),V=await lt(Z,tt),ht={envName:Z,env:tt,baseURL:U(tt,Z),doRequest:p=>zt({...p,...V})},A={body:h,query:{...N},path:v,headers:d.headers,rawBody:d.rawBody??void 0},{outputResult:Pt}=await Promise.resolve().then(()=>(fn(),bn)),b=0;do{let p=await qt(t,A,ht);if(Pt(p,r.flags.jq),p.status<400&&Object.keys(h).length>0)try{if(I&&Lt(l)){let E={};(function x(S,Y){for(let[gt,W]of Object.entries(Y)){let kt=S?`${S}.${gt}`:gt;typeof W=="object"&&W&&!Array.isArray(W)?x(kt,W):E[kt]=JSON.stringify(W)}})("",h),re(l,I,t,E),q(l)}}catch{}if(!r.flags.paginate)break;let f=ln(p.data);if(!f||f===A.query.cursor)break;if(A.query.cursor=f,++b>=100){process.stderr.write(`Pagination limit reached (100 pages)
178
- `);break}}while(!0)}function ys(){if(process.platform!=="win32")return"vi";try{let{execSync:t}=Pn("node:child_process");return t("where code",{stdio:"pipe"}),"code --wait"}catch{}return"notepad"}function bs(t){return t.split(`
193
+ `)}if(r.flags.edit){let I={...e.template??{},...k},E=await Oc(JSON.stringify(I,null,2));for(let D of Object.keys(k))delete k[D];Object.assign(k,E)}if(r.flags["dry-run"]){process.stderr.write(`would execute ${t}
194
+ `);let m={...T,...k,...Object.keys(S).length>0?{_query:S}:{}};process.stdout.write(JSON.stringify(m,null,2)+`
195
+ `);return}let{name:z,env:P}=$t(d,n),R=await Vt(z,P),N={envName:z,env:P,baseURL:Z(P,z),doRequest:m=>Ie({...m,...R})};if(r.flags.watch||r.flags.until){let{startWatch:m}=await Promise.resolve().then(()=>(Mr(),Ds)),I=i.length>0?i.flatMap(V=>V.split(",")).filter(Boolean):[],E=r.flags.depth?Number(r.flags.depth):void 0,D=r.flags["until-timeout"]?Number(r.flags["until-timeout"]):void 0;if(E!==void 0&&(!Number.isFinite(E)||E<1))throw new Error(`Invalid --depth value: ${r.flags.depth}`);if(D!==void 0&&(!Number.isFinite(D)||D<1))throw new Error(`Invalid --until-timeout value: ${r.flags["until-timeout"]}`);await m(t,I,N,{jq:r.flags.jq,depth:E,until:r.flags.until,untilTimeout:D,query:Object.keys(S).length>0?S:void 0});return}let G={body:k,query:{...S},path:T,headers:c.headers,rawBody:c.rawBody??void 0},{outputResult:ut}=await Promise.resolve().then(()=>(Bs(),Us)),O=0;do{let m=await St(t,G,N);if(ut(m,r.flags.jq),m.status<400&&Object.keys(k).length>0)try{if(p&&pe(d)){let E={};(function D(V,dt){for(let[Bt,it]of Object.entries(dt)){let re=V?`${V}.${Bt}`:Bt;typeof it=="object"&&it&&!Array.isArray(it)?D(re,it):E[re]=JSON.stringify(it)}})("",k),Ze(d,p,t,E),tt(d)}}catch{}if(!r.flags.paginate)break;let I=Fs(m.data);if(!I||I===G.query.cursor)break;if(G.query.cursor=I,++O>=100){process.stderr.write(`Pagination limit reached (100 pages)
196
+ `);break}}while(!0)}function Ec(){if(process.platform!=="win32")return"vi";try{let{execSync:t}=$s("node:child_process");return t("where code",{stdio:"pipe"}),"code --wait"}catch{}return"notepad"}function Ic(t){return t.split(`
179
197
  `).filter(e=>!e.trimStart().startsWith("//")).join(`
180
- `)}async function fs(t){let{writeFileSync:e,readFileSync:r,unlinkSync:n,mkdtempSync:i}=await import("node:fs"),{tmpdir:s}=await import("node:os"),{join:o}=await import("node:path"),{execFileSync:a}=await import("node:child_process"),{scrubbedEnv:d}=await Promise.resolve().then(()=>(M(),Ve));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 c=process.env.VISUAL??process.env.EDITOR??ys();(c.trim()==="code"||c.trim().endsWith("/code"))&&(c+=" --wait");let _=o(i(o(s(),"coinbase-")),"request.json");e(_,t);try{let[l,...I]=c.split(/\s+/);a(l,[...I,_],{stdio:"inherit",env:d()});let O=bs(r(_,"utf8"));return JSON.parse(O)}catch(l){throw new Error(l.message?.includes("Unexpected")?`Edited file is not valid JSON: ${l.message}`:`Editor: ${l.message}`)}finally{try{n(_)}catch{}}}u();g();var Ot=class extends Error{constructor(e){super(e),this.name="HelpExit"}};function En(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 In(t,e,r){let n=t,i,s=0,o=[],a=[];for(let l=0;l<e.length;l++){let I=e[l],O=n.children.get(I);if(O){a.push(I),o=[...n.children.keys()],n=O,n.action&&(i=n.action,s=a.length);continue}if(I.includes("=")){let T=I.split("=")[0],h=n.children.get(T);if(h?.action){let N=h.action.pathParams.map(G=>` <${G}>`).join(""),v=a.length>0?`coinbase ${r} ${a.join(" ")}`:`coinbase ${r}`;throw new Error(`Did you mean: ${v} ${h.action.name.split(" ").pop()}${N}`)}}break}if(i)return{action:i,remaining:e.slice(s),siblingNames:o};let d=e[a.length],c=a.length>0?`coinbase ${r} ${a.join(" ")}`:`coinbase ${r}`,_=Es(n,r);throw d&&d!=="--help"&&d!=="-h"?new Error(`unknown subcommand "${d}" for ${c}
198
+ `)}async function Oc(t){let{writeFileSync:e,readFileSync:r,unlinkSync:n,mkdtempSync:i}=await import("node:fs"),{tmpdir:s}=await import("node:os"),{join:a}=await import("node:path"),{execFileSync:o}=await import("node:child_process"),{scrubbedEnv:c}=await Promise.resolve().then(()=>(Q(),un));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 _=process.env.VISUAL??process.env.EDITOR??Ec();(_.trim()==="code"||_.trim().endsWith("/code"))&&(_+=" --wait");let u=a(i(a(s(),"coinbase-")),"request.json");e(u,t);try{let[d,...p]=_.split(/\s+/);o(d,[...p,u],{stdio:"inherit",env:c()});let y=Ic(r(u,"utf8"));return JSON.parse(y)}catch(d){throw new Error(d.message?.includes("Unexpected")?`Edited file is not valid JSON: ${d.message}`:`Editor: ${d.message}`)}finally{try{n(u)}catch{}}}Pt();g();l();var ee=class extends Error{constructor(e){super(e),this.name="HelpExit"}};function qs(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 zs(t,e,r){let n=t,i,s=0,a=[],o=[];for(let d=0;d<e.length;d++){let p=e[d],y=n.children.get(p);if(y){o.push(p),a=[...n.children.keys()],n=y,n.action&&(i=n.action,s=o.length);continue}if(p.includes("=")){let v=p.split("=")[0],k=n.children.get(v);if(k?.action){let S=k.action.pathParams.map(w=>` <${w}>`).join(""),T=o.length>0?`coinbase ${r} ${o.join(" ")}`:`coinbase ${r}`;throw new Error(`Did you mean: ${T} ${k.action.name.split(" ").pop()}${S}`)}}break}if(i)return{action:i,remaining:e.slice(s),siblingNames:a};let c=e[o.length],_=o.length>0?`coinbase ${r} ${o.join(" ")}`:`coinbase ${r}`,u=kc(n,r);throw c&&c!=="--help"&&c!=="-h"?new Error(`unknown subcommand "${c}" for ${_}
181
199
 
182
200
  Available actions:
183
- ${_}`):new Ot(`${c}
201
+ ${u}`):new ee(`${_}
184
202
 
185
203
  Available actions:
186
- ${_}`)}function Es(t,e){let r=[];function n(i){if(i.action){let s=i.action.pathParams.map(o=>` <${o}>`).join("");r.push(` coinbase ${e} ${i.action.name}${s}`)}for(let s of i.children.values())n(s)}return n(t),r.join(`
187
- `)}vt();u();g();function ct(t,e){let r={},n=[],i=!1,s=new Map;for(let[o,a,d]of e)s.set("--"+o,[o,d]),a&&s.set("-"+a,[o,d]);for(let o=0;o<t.length;o++){let a=t[o];if(a==="-h"||a==="--help"){i=!0;continue}let d=a.indexOf("=");if(d>0&&a.startsWith("--")){let _=s.get(a.slice(0,d));if(_){r[_[0]]=a.slice(d+1);continue}}let c=s.get(a);if(c){r[c[0]]=c[1]?t[++o]??"":!0;continue}if(a.length>2&&a[0]==="-"&&a[1]!=="-"){let _=s.get(a.slice(0,2));if(_?.[1]){r[_[0]]=a.slice(2);continue}}n.push(a)}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[Is]=process.versions.node.split(".").map(Number);Is<22&&(process.stderr.write(`coinbase requires Node.js ${22}+. You have: ${process.versions.node}
188
- `),process.exit(1));function Os(){return`Coinbase CLI
204
+ ${u}`)}function kc(t,e){let r=[];function n(i){if(i.action){let s=i.action.pathParams.map(a=>` <${a}>`).join("");r.push(` coinbase ${e} ${i.action.name}${s}`)}for(let s of i.children.values())n(s)}return n(t),r.join(`
205
+ `)}he();ie();g();l();function Ut(t,e){let r={},n=[],i=!1,s=new Map;for(let[a,o,c]of e)s.set("--"+a,[a,c]),o&&s.set("-"+o,[a,c]);for(let a=0;a<t.length;a++){let o=t[a];if(o==="-h"||o==="--help"){i=!0;continue}let c=o.indexOf("=");if(c>0&&o.startsWith("--")){let u=s.get(o.slice(0,c));if(u){r[u[0]]=o.slice(c+1);continue}}let _=s.get(o);if(_){r[_[0]]=_[1]?t[++a]??"":!0;continue}if(o.length>2&&o[0]==="-"&&o[1]!=="-"){let u=s.get(o.slice(0,2));if(u?.[1]){r[u[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}
206
+ `),process.exit(1));function Rc(){return`Coinbase CLI
189
207
 
190
208
  Usage:
191
209
  coinbase <resource> <action> [fields...]
192
210
  coinbase <action> [fields...]
193
211
 
194
212
  Resources:
195
- ${fe().map(r=>` ${r.name.padEnd(20)}${r.actions.map(n=>n.name).join(", ")}`).join(`
213
+ ${Fr().map(r=>` ${r.name.padEnd(20)}${r.actions.map(n=>n.name).join(", ")}`).join(`
196
214
  `)}
197
215
 
198
216
  Actions:
@@ -211,8 +229,8 @@ Flags:
211
229
  -e, --env <name> Environment override
212
230
  -V, --version Show version
213
231
  -h, --help Show help
214
- `}async function hs(){let t=process.argv.slice(2),e="",r=[];for(let s=0;s<t.length;s++){let o=t[s];o==="-e"||o==="--env"?e=t[++s]??"":o.startsWith("--env=")?e=o.slice(6):o.startsWith("-e")&&o.length>2?e=o.slice(2):r.push(o)}if(r[0]==="--version"||r[0]==="-V"){process.stdout.write(`coinbase ${F}
215
- `);return}if(he=Lr(),r.length===0||r[0]==="-h"||r[0]==="--help"||r[0]==="help"){process.stderr.write(Os());return}let[n,...i]=r;if(n==="env"){let s=ct(i,[["key-id",null,!0],["key-secret",null,!0],["key-file","k",!0],["status",null,!1],["url",null,!0],["remove",null,!1],["allow-plaintext-secrets",null,!1]]);if(s.help){process.stderr.write(`Manage environments and credentials
232
+ `}async function Pc(){let t=process.argv.slice(2),e="",r=[];for(let s=0;s<t.length;s++){let a=t[s];a==="-e"||a==="--env"?e=t[++s]??"":a.startsWith("--env=")?e=a.slice(6):a.startsWith("-e")&&a.length>2?e=a.slice(2):r.push(a)}if(r[0]==="--version"||r[0]==="-V"){process.stdout.write(`coinbase ${rt}
233
+ `);return}if(zr=li(),r.length===0||r[0]==="-h"||r[0]==="--help"||r[0]==="help"){process.stderr.write(Rc());return}let[n,...i]=r;if(n==="env"){let s=Ut(i,[["key-id",null,!0],["key-secret",null,!0],["key-file","k",!0],["status",null,!1],["url",null,!0],["remove",null,!1],["allow-plaintext-secrets",null,!1]]);if(s.help){process.stderr.write(`Manage environments and credentials
216
234
 
217
235
  Usage:
218
236
  coinbase env List all environments
@@ -230,14 +248,14 @@ Flags:
230
248
  --url <url> Custom base URL
231
249
  --remove Remove an environment
232
250
  --allow-plaintext-secrets Persist secrets to ~/.config/coinbase/config.json (mode 0600) when no OS keychain is available. Default: refuse and error.
233
- `);return}await We(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,remove:!!s.flags.remove,allowPlaintextSecrets:!!s.flags["allow-plaintext-secrets"],envFlag:e})}else if(n==="history"){let s=ct(i,[]);if(s.help){process.stderr.write(`View or clear saved request history
251
+ `);return}await dn(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,remove:!!s.flags.remove,allowPlaintextSecrets:!!s.flags["allow-plaintext-secrets"],envFlag:e})}else if(n==="history"){let s=Ut(i,[]);if(s.help){process.stderr.write(`View or clear saved request history
234
252
 
235
253
  Usage:
236
254
  coinbase history Show all saved history
237
255
  coinbase history clear Clear all history
238
256
  coinbase history clear <env> Clear history for an environment
239
257
  coinbase history clear <env>.<action> Clear a specific entry
240
- `);return}Xr(s.args)}else if(n==="skills")await _n(i);else if(n==="mcp"){if(ct(i,[]).help){process.stderr.write(`MCP server for AI agent integration
258
+ `);return}Si(s.args)}else if(n==="skills")await Fi(i);else if(n==="mcp"){if(Ut(i,[]).help){process.stderr.write(`MCP server for AI agent integration
241
259
 
242
260
  Usage:
243
261
  coinbase mcp Start MCP server over stdio
@@ -245,9 +263,9 @@ Usage:
245
263
  The MCP server implements the Model Context Protocol (JSON-RPC over
246
264
  stdin/stdout) and exposes all brokerage API resources as tools. It is
247
265
  typically invoked automatically by AI agents, not run directly.
248
- `);return}Qr()}else if(dn(n)){let s=K[n];s||(process.stderr.write(`error: "${n}" is not available
249
- `),process.exit(1));let o=ct(i,[["template",null,!1],["dry-run",null,!1],["edit",null,!1],["jq",null,!0],["paginate",null,!1]]);if(o.help){Ee(n,s);return}await Oe(n,s,o,e)}else{let s=fe().find(_=>_.name===n);if(s||(process.stderr.write(`error: unknown command "${n}"
266
+ `);return}Ti()}else if(Ls(n)){let s=X[n];s||(process.stderr.write(`error: "${n}" is not available
267
+ `),process.exit(1));let a=Ut(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(a.help){Ur(n,s);return}await qr(n,s,a,e)}else{let s=Fr().find(u=>u.name===n);if(s||(process.stderr.write(`error: unknown command "${n}"
250
268
  Run: coinbase --help
251
- `),process.exit(1)),i.length===0||i[0]==="-h"||i[0]==="--help"){pn(n);return}let o=En(s.actions),a=In(o,i,n),d=ct(a.remaining,[["template",null,!1],["dry-run",null,!1],["edit",null,!1],["jq",null,!0],["paginate",null,!1]]);if(d.help){Ee(n,a.action);return}let c=a.action.id??`${n}_${a.action.name.replace(/[-\s]/g,"_")}`;await Oe(c,a.action,d,e)}}var he;hs().catch(t=>{t instanceof Ot&&(process.stderr.write(t.message+`
269
+ `),process.exit(1)),i.length===0||i[0]==="-h"||i[0]==="--help"){Ms(n);return}let a=qs(s.actions),o=zs(a,i,n),c=Ut(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(c.help){Ur(n,o.action);return}let _=o.action.id??`${n}_${o.action.name.replace(/[-\s]/g,"_")}`;await qr(_,o.action,c,e)}}var zr;Pc().catch(t=>{t instanceof ee&&(process.stderr.write(t.message+`
252
270
  `),process.exit(0)),process.stderr.write(`error: ${t.message}
253
- `),process.exit(1)}).finally(async()=>{if(!he||!process.stderr.isTTY)return;let t=await he.catch(()=>"");t&&process.stderr.write(t)});
271
+ `),process.exit(1)}).finally(async()=>{if(!zr||!process.stderr.isTTY)return;let t=await zr.catch(()=>"");t&&process.stderr.write(t)});
package/dist/version.txt CHANGED
@@ -1 +1 @@
1
- 0.0.1
1
+ 0.0.2
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coinbase/coinbase-cli",
3
- "version": "0.0.1",
3
+ "version": "0.0.2",
4
4
  "description": "Coinbase for agents — CLI and MCP server for trading, wallets, payments, and onchain across the Coinbase platform",
5
5
  "type": "module",
6
6
  "bin": {
@@ -31,6 +31,11 @@
31
31
  "typescript": "^5.7.0",
32
32
  "yaml": "^2.6.0"
33
33
  },
34
+ "pnpm": {
35
+ "onlyBuiltDependencies": [
36
+ "esbuild"
37
+ ]
38
+ },
34
39
  "license": "MIT",
35
40
  "homepage": "https://docs.cdp.coinbase.com",
36
41
  "keywords": [
@@ -107,10 +107,10 @@ SELL market orders use `base_size` (amount of asset to sell). BUY market orders
107
107
  ### Manage orders
108
108
 
109
109
  ```sh
110
- coinbase orders list order_status==OPEN
110
+ coinbase orders list status==OPEN
111
111
  coinbase orders get <order_id>
112
112
  coinbase orders cancel order_ids:='["id-1","id-2"]'
113
- coinbase orders edit <order_id> price=50000
113
+ coinbase orders edit <order_id> limit_price=50000
114
114
  ```
115
115
 
116
116
  ### Portfolios
@@ -125,8 +125,8 @@ coinbase portfolios create name="Day Trading"
125
125
 
126
126
  ```sh
127
127
  coinbase convert quote from=USD to=USDC amount=100
128
- coinbase convert execute <trade_id> from=USD to=USDC
129
- coinbase convert get <trade_id>
128
+ coinbase convert execute <quote_id> from=USD to=USDC
129
+ coinbase convert get <quote_id>
130
130
  ```
131
131
 
132
132
  ### Transfer funds between portfolios