@coinbase/coinbase-cli 0.0.5 → 0.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- var ao=Object.defineProperty;var co=(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 I=(t,e)=>()=>(t&&(e=t(t=0)),e);var jt=(t,e)=>{for(var r in e)ao(t,r,{get:e[r],enumerable:!0})};var y,g=I(()=>{y={live:{brokerageApi:"https://api.coinbase.com",agentApi:"https://agents.coinbase.com/api"}}});var b,l=I(()=>{b={production:"live"}});var go,tn,de,en,rn,ge=I(()=>{"use strict";g();l();go="https://agents.coinbase.com/api",tn="@coinbase/coinbase-cli",de="https://registry.npmjs.org",en=typeof y<"u"?y:{live:{brokerageApi:"https://api.coinbase.com",agentApi:go}},rn=typeof b<"u"?b:{production:"live"}});function Rt(t){return Ye+Buffer.from(t,"utf8").toString("base64")}function Pt(t){return t.startsWith(Ye)?Buffer.from(t.slice(Ye.length),"base64").toString("utf8"):t}var Ye,le=I(()=>{"use strict";g();l();Ye="b64:"});import{execFileSync as pe}from"node:child_process";var me,fe,nn=I(()=>{"use strict";g();l();le();me="/usr/bin/security",fe=class{constructor(){try{pe(me,["list-keychains"],{stdio:["pipe","pipe","pipe"]})}catch{throw new Error("Keychain not accessible")}}get(e,r){try{let n=pe(me,["find-generic-password","-s",e,"-a",r,"-w"],{encoding:"utf8",stdio:["pipe","pipe","pipe"]}).trimEnd();return Pt(n)}catch{return null}}set(e,r,n){pe(me,["add-generic-password","-U","-s",e,"-a",r,"-w",Rt(n)],{stdio:["pipe","pipe","pipe"]})}delete(e,r){try{pe(me,["delete-generic-password","-s",e,"-a",r],{stdio:["pipe","pipe","pipe"]})}catch{}}}});import{execFileSync as ye}from"node:child_process";var be,sn=I(()=>{"use strict";g();l();le();be=class{constructor(){try{ye("which",["secret-tool"],{stdio:["pipe","pipe","pipe"]})}catch{throw new Error("secret-tool not found")}}get(e,r){try{let n=ye("secret-tool",["lookup","service",e,"account",r],{encoding:"utf8",stdio:["pipe","pipe","pipe"]});return Pt(n.trimEnd())}catch{return null}}set(e,r,n){ye("secret-tool",["store","--label",`${e}:${r}`,"service",e,"account",r],{input:Rt(n),stdio:["pipe","pipe","pipe"]})}delete(e,r){try{ye("secret-tool",["clear","service",e,"account",r],{stdio:["pipe","pipe","pipe"]})}catch{}}}});import{execFileSync as lo}from"node:child_process";function Qe(t,e){return`${t}:${e}`}function he(t){return t.replace(/'/g,"''")}function Je(t,e){let r=po+t,n=Buffer.from(r,"utf16le").toString("base64"),i=e===void 0?process.env:{...process.env,[on]:e};return lo("powershell.exe",["-NoProfile","-NonInteractive","-EncodedCommand",n],{encoding:"utf8",stdio:["pipe","pipe","pipe"],env:i}).trimEnd()}var po,on,Ee,an=I(()=>{"use strict";g();l();le();po=`
2
+ var go=Object.defineProperty;var lo=(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 I=(t,e)=>()=>(t&&(e=t(t=0)),e);var Yt=(t,e)=>{for(var r in e)go(t,r,{get:e[r],enumerable:!0})};var y,g=I(()=>{y={live:{brokerageApi:"https://api.coinbase.com",agentApi:"https://agents.coinbase.com/api"}}});var b,l=I(()=>{b={production:"live"}});var fo,rn,le,nn,sn,pe=I(()=>{"use strict";g();l();fo="https://agents.coinbase.com/api",rn="@coinbase/coinbase-cli",le="https://registry.npmjs.org",nn=typeof y<"u"?y:{live:{brokerageApi:"https://api.coinbase.com",agentApi:fo}},sn=typeof b<"u"?b:{production:"live"}});function Rt(t){return Je+Buffer.from(t,"utf8").toString("base64")}function Pt(t){return t.startsWith(Je)?Buffer.from(t.slice(Je.length),"base64").toString("utf8"):t}var Je,me=I(()=>{"use strict";g();l();Je="b64:"});import{execFileSync as fe}from"node:child_process";var ye,be,on=I(()=>{"use strict";g();l();me();ye="/usr/bin/security",be=class{constructor(){try{fe(ye,["list-keychains"],{stdio:["pipe","pipe","pipe"]})}catch{throw new Error("Keychain not accessible")}}get(e,r){try{let n=fe(ye,["find-generic-password","-s",e,"-a",r,"-w"],{encoding:"utf8",stdio:["pipe","pipe","pipe"]}).trimEnd();return Pt(n)}catch{return null}}set(e,r,n){fe(ye,["add-generic-password","-U","-s",e,"-a",r,"-w",Rt(n)],{stdio:["pipe","pipe","pipe"]})}delete(e,r){try{fe(ye,["delete-generic-password","-s",e,"-a",r],{stdio:["pipe","pipe","pipe"]})}catch{}}}});import{execFileSync as he}from"node:child_process";var Ee,an=I(()=>{"use strict";g();l();me();Ee=class{constructor(){try{he("which",["secret-tool"],{stdio:["pipe","pipe","pipe"]})}catch{throw new Error("secret-tool not found")}}get(e,r){try{let n=he("secret-tool",["lookup","service",e,"account",r],{encoding:"utf8",stdio:["pipe","pipe","pipe"]});return Pt(n.trimEnd())}catch{return null}}set(e,r,n){he("secret-tool",["store","--label",`${e}:${r}`,"service",e,"account",r],{input:Rt(n),stdio:["pipe","pipe","pipe"]})}delete(e,r){try{he("secret-tool",["clear","service",e,"account",r],{stdio:["pipe","pipe","pipe"]})}catch{}}}});import{execFileSync as yo}from"node:child_process";function Xe(t,e){return`${t}:${e}`}function Ie(t){return t.replace(/'/g,"''")}function Ze(t,e){let r=bo+t,n=Buffer.from(r,"utf16le").toString("base64"),i=e===void 0?process.env:{...process.env,[cn]:e};return yo("powershell.exe",["-NoProfile","-NonInteractive","-EncodedCommand",n],{encoding:"utf8",stdio:["pipe","pipe","pipe"],env:i}).trimEnd()}var bo,cn,Oe,_n=I(()=>{"use strict";g();l();me();bo=`
3
3
  if (-not ([System.Management.Automation.PSTypeName]'Win32.Cred').Type) {
4
4
  Add-Type -Namespace Win32 -Name Cred -MemberDefinition '
5
5
  [DllImport("advapi32.dll", SetLastError=true, CharSet=CharSet.Unicode)]
@@ -17,7 +17,7 @@ if (-not ([System.Management.Automation.PSTypeName]'Win32.Cred').Type) {
17
17
  public string TargetAlias; public string UserName;
18
18
  }'
19
19
  }
20
- `,on="COINBASE_KEYRING_SECRET";Ee=class{get(e,r){try{let n=he(Qe(e,r)),i=Je(`
20
+ `,cn="COINBASE_KEYRING_SECRET";Oe=class{get(e,r){try{let n=Ie(Xe(e,r)),i=Ze(`
21
21
  $ptr = [IntPtr]::Zero
22
22
  if ([Win32.Cred]::CredRead('${n}', 1, 0, [ref]$ptr)) {
23
23
  $cred = [Runtime.InteropServices.Marshal]::PtrToStructure($ptr, [Type][Win32.Cred+CREDENTIAL])
@@ -25,8 +25,8 @@ if ([Win32.Cred]::CredRead('${n}', 1, 0, [ref]$ptr)) {
25
25
  [Runtime.InteropServices.Marshal]::Copy($cred.CredentialBlob, $bytes, 0, $cred.CredentialBlobSize)
26
26
  [Win32.Cred]::CredFree($ptr)
27
27
  [Text.Encoding]::UTF8.GetString($bytes)
28
- }`);return i?Pt(i):null}catch{return null}}set(e,r,n){let i=he(Qe(e,r)),s=he(r);Je(`
29
- $sec = $env:${on}
28
+ }`);return i?Pt(i):null}catch{return null}}set(e,r,n){let i=Ie(Xe(e,r)),s=Ie(r);Ze(`
29
+ $sec = $env:${cn}
30
30
  $bytes = [Text.Encoding]::UTF8.GetBytes($sec)
31
31
  $blob = [Runtime.InteropServices.Marshal]::AllocHGlobal($bytes.Length)
32
32
  [Runtime.InteropServices.Marshal]::Copy($bytes, 0, $blob, $bytes.Length)
@@ -40,95 +40,95 @@ $cred.Persist = 2
40
40
  if (-not [Win32.Cred]::CredWrite([ref]$cred, 0)) {
41
41
  throw "CredWrite failed: $([Runtime.InteropServices.Marshal]::GetLastWin32Error())"
42
42
  }
43
- [Runtime.InteropServices.Marshal]::FreeHGlobal($blob)`,Rt(n))}delete(e,r){try{Je(`[void][Win32.Cred]::CredDelete('${he(Qe(e,r))}', 1, 0)`)}catch{}}}});function Kt(){if(dt!==void 0)return dt;try{process.platform==="darwin"?dt=new fe:process.platform==="linux"?dt=new be:process.platform==="win32"?dt=new Ee:dt=null}catch{cn||(process.stderr.write(`warning: OS keychain not accessible \u2014 secrets stored in keychain will not be available
44
- `),cn=!0),dt=null}return dt}function _n(t){let e=Kt();if(!e)return null;try{return e.get(Et,t)}catch{return null}}function un(t,e){let r=Kt();if(!r)return!1;try{return r.set(Et,t,e),!0}catch{return!1}}function dn(t){let e=Kt();if(e)try{e.delete(Et,t)}catch{}}function gn(){return Kt()!==null}function ln(){let t=Kt();if(!t)return!1;let e="__coinbase_cli_preflight__";try{t.set(Et,e,"ok");let r=t.get(Et,e);return t.delete(Et,e),r==="ok"}catch{try{t.delete(Et,e)}catch{}return!1}}var Et,dt,cn,Xe=I(()=>{"use strict";g();l();nn();sn();an();Et="coinbase-cli",cn=!1});var kn={};jt(kn,{activeEnvName:()=>wt,activeEnvironment:()=>Jt,authIsViable:()=>rr,builtinEnvironments:()=>X,clearEnvCredentialCache:()=>sr,clearEnvironmentSecretsFromKeychain:()=>nr,clearHistory:()=>Xt,configDir:()=>gt,configPath:()=>et,credentialsFor:()=>Qt,envCredential:()=>Yt,getHistory:()=>cr,historyEnabled:()=>ve,hydrateEnvironmentSecrets:()=>En,isBuiltinURL:()=>ke,loadConfig:()=>J,resolveAgentAPIURLForEnvironment:()=>lt,resolveBrokerageURL:()=>Z,resolveURL:()=>ho,saveConfig:()=>ot,scrubbedEnv:()=>or,setHistory:()=>ar,setLockOptions:()=>ko,withConfigLock:()=>ir,writeEnvironmentSecretsToKeychain:()=>In});import{readFileSync as fn,writeFileSync as yn,mkdirSync as bn,renameSync as mo,unlinkSync as Ze,openSync as fo,closeSync as yo,statSync as bo}from"node:fs";import{homedir as pn}from"node:os";import{join as Ie}from"node:path";function gt(){if(process.env.COINBASE_CONFIG_DIR)return process.env.COINBASE_CONFIG_DIR;if(process.platform==="win32"){let t=process.env.APPDATA??Ie(pn(),"AppData","Roaming");return Ie(t,"coinbase")}return Ie(pn(),".config","coinbase")}function et(){return Ie(gt(),"config.json")}function hn(t){if(X[t])return X[t];let e=mn[t];if(e&&X[e])return X[e];let r={...X};for(let[i,s]of Object.entries(mn))X[s]&&(r[i]=X[s]);let n=Object.keys(r).find(i=>t.startsWith(i+"-"));return n?r[n]:void 0}function Z(t,e){return t.endpoints?.brokerageApi??t.url??hn(e)?.brokerageApi??""}function ho(t,e){return Z(t,e)}function lt(t,e){return t.endpoints?.agentApi??hn(e)?.agentApi??""}function ke(t){return Object.values(X).some(e=>e.brokerageApi&&t.startsWith(e.brokerageApi))}function Eo(t,e){return Object.values(xt[e].secrets).map(r=>r(t))}function rr(t){if(!t)return!1;let e=xt[t.type];return e?Object.keys(e.secrets).every(r=>!!t[r]):!1}function En(t,e){if(!e.auth)return e;let r=xt[e.auth.type];if(!r)return e;let n=e.auth,i={...n},s=!1,o=!1;for(let[a,c]of Object.entries(r.secrets)){if(n[a]){o=!0;continue}let d=_n(c(t));d&&(i[a]=d,s=!0)}return rr(i)?{...e,auth:i,...o&&!s?{_plaintextBacked:!0}:{}}:{...e,auth:void 0}}function In(t,e){if(!e.auth)return!0;if(!gn())return!1;let r=e.auth.type,n=xt[r];if(!n)return!0;if(!rr(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))un(o(t),e.auth[s])||(i=!1);return i}function nr(t){for(let e of Object.keys(xt))for(let r of Eo(t,e))dn(r)}function Yt(t){return t.auth}function Qt(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=fn(et(),"utf8"),r=JSON.parse(e);t.env=r.env??"";let n=r.environments??{};for(let[i,s]of Object.entries(n))t.environments[i]=En(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 ot(t,e={}){let r=gt();bn(r,{recursive:!0,mode:448});let n={},i=[];for(let[c,d]of Object.entries(t.environments)){let p={};if(d.url!==void 0&&(p.url=d.url),d.endpoints!==void 0&&(p.endpoints={...d.endpoints}),!d.auth){n[c]=p;continue}let _=In(c,d),u=e.allowPlaintext===!0||d._plaintextBacked===!0;if(!_){if(!u){i.push(c);continue}p.auth=d.auth,n[c]=p;continue}let f=xt[d.auth.type];f&&(p.auth=f.metadataOnly(d.auth)),n[c]=p}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 ${et()} (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=et(),a=`${o}.${process.pid}.${Date.now()}.tmp`;try{yn(a,JSON.stringify(s,null,2)+`
46
- `,{mode:384}),mo(a,o)}catch(c){try{Ze(a)}catch{}throw c}}function ko(t){Tt={...Tt,...t}}function St(){return et()+Io}function vo(t){let e=Date.now()+t;for(;Date.now()<e;);}function Oo(){try{let t=fo(St(),"wx",384);return yn(t,String(process.pid)),t}catch(t){if(t.code!=="EEXIST")throw t;return null}}function Ro(){try{let t=bo(St());if(Date.now()-t.mtimeMs<Tt.staleAfterMs)return!1;let e=fn(St(),"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 ir(t){bn(gt(),{recursive:!0,mode:448});let e=null;for(let r=0;r<Tt.retries&&(e=Oo(),e===null);r++){if(Ro()){try{Ze(St())}catch{}continue}vo(Tt.baseDelayMs*(1+Math.random()))}if(e===null)throw new Error(`could not acquire config lock after ${Tt.retries} attempts: ${St()}`);try{return t()}finally{try{yo(e)}catch{}try{Ze(St())}catch{}}}function sr(){tr=void 0,er=void 0}function Po(){return process.env.COINBASE_KEY_ID&&(tr=process.env.COINBASE_KEY_ID,delete process.env.COINBASE_KEY_ID),process.env.COINBASE_KEY_SECRET&&(er=process.env.COINBASE_KEY_SECRET,delete process.env.COINBASE_KEY_SECRET),{keyId:tr,keySecret:er}}function wt(t,e){return e||process.env.COINBASE_ENV||t.env}function Jt(t,e){let r=wt(t,e);if(!r)throw new Error("no environment configured. Run: coinbase env <name>");let n={...t.environments[r]},{keyId:i,keySecret:s}=Po();if(i||s){let c=n.auth?.type==="cdp_key"?n.auth:void 0,d=i??c?.key_id??"",p=s??c?.key_secret??"";d&&p&&(n.auth={type:"cdp_key",key_id:d,key_secret:p})}if(process.env.COINBASE_URL){let c=process.env.COINBASE_URL;n.endpoints={...n.endpoints,brokerageApi:c},n.url=c,ke(c)||process.stderr.write(`warning: COINBASE_URL overrides to non-standard endpoint: ${c}
47
- `)}let o=Z(n,r),a=lt(n,r);if(!o&&!a)throw new Error(`no REST endpoint for environment "${r}". Set a brokerage URL, an Agent API URL, or use a built-in environment name`);if(!n.auth)throw new Error(`no credentials for "${r}". Run: coinbase env ${r} --key-file path/to/key.json`);return{name:r,env:n}}function or(){let t={...process.env};for(let e of To)delete t[e];return t}function ve(t){return process.env.COINBASE_NO_HISTORY?!1:t.settings?.history?.enabled!==!1}function ar(t,e,r,n){t.history[e]||(t.history[e]={}),t.history[e][r]={last_used:new Date().toISOString(),values:n}}function cr(t,e,r){return t.history[e]?.[r]}function Xt(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 X,mn,xt,Io,Tt,tr,er,To,tt=I(()=>{"use strict";g();l();ge();Xe();X=en,mn=rn;xt={cdp_key:{secrets:{key_secret:t=>`${t}:cdp:key_secret`},metadataOnly:t=>({type:"cdp_key",key_id:t.key_id})}};Io=".lock",Tt={retries:50,baseDelayMs:20,staleAfterMs:5e3};To=["COINBASE_KEY_SECRET","COINBASE_KEY_ID"]});function Go(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 rt,nt,On,Rn,Pn,Ct=I(()=>{"use strict";g();l();rt=[{name:"convert",actions:[{id:"convert_quote",name:"quote",method:"POST",path:"/convert/quote",summary:"Get Convert Quote",description:"Quotes a currency conversion (e.g. stablecoin pairs), returning rate, fees, and a quote id. Read-only preview \u2014 pass the id to convert_execute to commit; quotes expire, so execute promptly.",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:"Executes a previously quoted conversion using the quote id from convert_quote. This moves funds at the quoted rate \u2014 always get a fresh quote first, since quotes expire. The from/to currencies must match the original quote.",pathParams:["quote_id"],params:[{name:"quote_id",in:"path",type:"string",required:!0,description:"Quote ID from convert quote response"},{name:"from",in:"body",type:"string",required:!0,description:"Source currency",example:"USDC"},{name:"to",in:"body",type:"string",required:!0,description:"Target currency",example:"USD"}],streamable:!1,watchFields:null,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:"Lists orders with optional filters by status, product, side, and time range. Read-only. Use status=OPEN to find resting orders that can be edited or cancelled.",pathParams:[],params:[{name:"status",in:"query",type:"string",required:!1,description:"Filter by status"},{name:"product_ids",in:"query",type:"array",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"]}}},agentApi:"eligible",agentQueryTransforms:{product_ids:"join-comma"}},{id:"orders_create",name:"create",method:"POST",path:"/orders",summary:"Create Order",description:"Places a live order \u2014 executes immediately and moves funds (market buy spends quote currency; sell disposes of base). Preview with orders_preview first to estimate fees, fill price, and slippage.",pathParams:[],params:[{name:"product_id",in:"body",type:"string",required:!0,description:"Trading pair (BASE-QUOTE). Use the quote currency the user names (e.g. USDC); never default to USD. If unspecified, check balance; prefer USDC if both held. Tell the user if the pair is unavailable.",example:"BASE-QUOTE"},{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 now; limit = fill at price or better; stop_limit = limit triggered at 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)",example:"65000.00"},{name:"stop_price",in:"body",type:"string",required:!1,description:"Stop price (stop_limit orders)",example:"60000.00"},{name:"stop_direction",in:"body",type:"string",required:!1,description:"up = trigger when price rises above stop_price. down = trigger when falls below.",enum:["up","down"],example:"down"},{name:"post_only",in:"body",type:"boolean",required:!1,description:"Post-only mode (limit orders). Rejects if would take liquidity."},{name:"time_in_force",in:"body",type:"string",required:!1,description:"GTC=good til cancelled. IOC=immediate or cancel. FOK=fill or kill.",enum:["GTC","IOC","FOK","GTD"],example:"GTC"},{name:"end_time",in:"body",type:"string",required:!1,description:"Expiry time for GTD orders (RFC 3339). Required when time_in_force=GTD.",format:"date-time",example:"2024-12-31T23:59:59Z"},{name:"reduce_only",in:"body",type:"boolean",required:!1,description:"Only reduce existing position. Rejects if would increase exposure."},{name:"portfolio_id",in:"body",type:"string",required:!1,description:"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:"BASE-QUOTE",side:"BUY",type:"market",quote_size:"100.00",base_size:"0.001",limit_price:"65000.00",stop_price:"60000.00",stop_direction:"up",post_only:!1,time_in_force:"GTC",end_time:"2024-12-31T23:59:59Z",reduce_only:!1,portfolio_id:"<string>",client_order_id:"<string>"},responseFields:{fields:["order_id","product_id","side","client_order_id"]},agentApi:"eligible"},{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 (BASE-QUOTE). Use the quote currency the user names (e.g. USDC); never default to USD. If unspecified, check balance; prefer USDC if both held. Tell the user if the pair is unavailable.",example:"BASE-QUOTE"},{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 now; limit = fill at price or better; stop_limit = limit triggered at stop_price",enum:["market","limit","stop_limit"],example:"market"},{name:"quote_size",in:"body",type:"string",required:!1,description:"Quote currency amount (e.g. spend $100 USD). Mutually exclusive with base_size.",oneOf:"base_size|quote_size",example:"100.00"},{name:"base_size",in:"body",type:"string",required:!1,description:"Base currency amount (e.g. 0.001 BTC). Mutually exclusive with quote_size.",oneOf:"base_size|quote_size",example:"0.001"},{name:"limit_price",in:"body",type:"string",required:!1,description:"Limit price (for limit/stop_limit previews)",example:"65000.00"},{name:"stop_price",in:"body",type:"string",required:!1,description:"Stop price (for stop_limit previews)",example:"60000.00"},{name:"stop_direction",in:"body",type:"string",required:!1,description:"up = trigger when price rises above stop_price. down = trigger when falls below.",enum:["up","down"],example:"down"}],streamable:!1,watchFields:null,template:{product_id:"BASE-QUOTE",side:"BUY",type:"market",quote_size:"100.00",base_size:"0.001",limit_price:"65000.00",stop_price:"60000.00",stop_direction:"up"},responseFields:{fields:["order_total","commission_total","slippage","est_average_filled_price","base_size","quote_size","best_bid","best_ask"]},agentApi:"eligible"},{id:"orders_edit",name:"edit",method:"POST",path:"/orders/edit/{order_id}",summary:"Edit Order",description:"Atomically update an open order's price or size without cancelling. Avoids the cancel+replace exposure window.",pathParams:["order_id"],params:[{name:"order_id",in:"path",type:"string",required:!0,description:"Order to edit"},{name:"base_size",in:"body",type:"string",required:!1,description:"New base size",example:"0.002"},{name:"limit_price",in:"body",type:"string",required:!1,description:"New limit price",example:"64000.00"}],streamable:!1,watchFields:null,template:{base_size:"0.002",limit_price:"64000.00"},responseFields:{fields:["order_id","status"]},agentApi:"eligible",agentPath:"/orders/edit"},{id:"orders_get",name:"get",method:"GET",path:"/orders/{order_id}",summary:"Get Order",description:"Retrieves the full status and fill details of a single order by ID. Read-only. Use after creating an order to confirm execution.",pathParams:["order_id"],params:[{name:"order_id",in:"path",type:"string",required:!0,description:"Order ID"}],streamable:!1,watchFields:null,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"]},agentApi:"eligible"},{id:"orders_cancel",name:"cancel",method:"POST",path:"/orders/cancel",summary:"Cancel Orders",description:"Cancels one or more open orders by ID. Removes resting orders from the book so reserved funds are released; already-filled portions are unaffected. Returns per-order success so a partial batch can fail.",pathParams:[],params:[{name:"order_ids",in:"body",type:"array",required:!0,description:"Order IDs to cancel"}],streamable:!1,watchFields:null,template:{order_ids:[]},responseFields:{fields:["results"],nested:{results:{fields:["success","order_id"]}}},agentApi:"eligible"},{id:"orders_close_position",name:"close-position",method:"POST",path:"/orders/close-position",summary:"Close Position",description:"Places a market order to flatten an open position for a product, moving funds immediately. Omit size for a full close or set it for a partial close. Preview the equivalent order first if fee or slippage impact matters.",pathParams:[],params:[{name:"client_order_id",in:"body",type:"string",required:!0,description:"Idempotency key"},{name:"product_id",in:"body",type:"string",required:!0,description:"Product to close",example:"BTC-PERP"},{name:"size",in:"body",type:"string",required:!1,description:"Partial close size (omit for full close)",example:"0.001"}],streamable:!1,watchFields:null,template:{client_order_id:"<string>",product_id:"BTC-PERP",size:"0.001"},responseFields:null,agentApi:"eligible"},{id:"orders_fills",name:"fills",method:"GET",path:"/orders/fills",summary:"List Fills",description:"Lists individual trade executions (fills) with commissions and maker/taker indicator, filterable by product, order, side, and time range. Read-only. Use this to reconcile actual fill prices and fees paid.",pathParams:[],params:[{name:"product_ids",in:"query",type:"array",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"]}}},agentApi:"eligible",agentQueryTransforms:{product_ids:"join-comma",order_ids:"split-comma"}}]},{name:"portfolios",actions:[{id:"portfolios_list",name:"list",method:"GET",path:"/portfolios",summary:"List Portfolios",description:"Lists all portfolios on the account, including their UUIDs and types. Read-only. Use this to find the portfolio_id needed for orders, transfers, and balance queries.",pathParams:[],params:[{name:"portfolio_type",in:"query",type:"string",required:!1,description:"Filter by type (DEFAULT, CONSUMER, 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:"Creates a new named portfolio for segregating funds and positions. Does not move any funds; use transfer afterward to fund it.",pathParams:[],params:[{name:"name",in:"body",type:"string",required:!0,description:"Portfolio name",example:"agent-1"}],streamable:!1,watchFields:null,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"]}}},agentApi:"eligible"},{id:"portfolios_edit",name:"edit",method:"PUT",path:"/portfolios/{portfolio_id}",summary:"Edit Portfolio",description:"Renames an existing portfolio. Metadata-only change; does not affect balances or positions.",pathParams:["portfolio_id"],params:[{name:"portfolio_id",in:"path",type:"string",required:!0,description:"Portfolio UUID"},{name:"name",in:"body",type:"string",required:!1,description:"New portfolio name"}],streamable:!1,watchFields:null,template:{name:"<string>"},responseFields:{fields:["uuid","name","type","deleted"]}},{id:"portfolios_delete",name:"delete",method:"DELETE",path:"/portfolios/{portfolio_id}",summary:"Delete Portfolio",description:"Permanently deletes a portfolio. The portfolio must be empty first \u2014 transfer out any remaining funds and close all positions before deleting. The DEFAULT portfolio cannot be deleted.",pathParams:["portfolio_id"],params:[{name:"portfolio_id",in:"path",type:"string",required:!0,description:"Portfolio UUID"}],streamable:!1,watchFields:null,template:{},responseFields:null}]},{name:"products",actions:[{id:"products_list",name:"list",method:"GET",path:"/products",summary:"List Products",description:"Lists tradable products and their current price and 24h stats, optionally filtered by symbol or type. Read-only. Use to discover valid product_id values before placing orders.",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:"array",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:"Returns full details for a single product, including price and trading increments/min sizes. Read-only. Use base_increment and base_min_size to size orders that the exchange will accept.",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"]},agentApi:"eligible"},{id:"products_ticker",name:"ticker",method:"GET",path:"/products/{product_id}/ticker",summary:"Get Ticker",description:"Returns recent trades plus the current best bid and ask for a product. Read-only. Use for a quick spot price snapshot before previewing or placing an order.",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:"Returns the bid/ask order book (price levels and sizes) for a product. Read-only. Use to gauge available liquidity and likely slippage before sizing a market order.",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:"Returns historical OHLCV candles for a product at a chosen granularity and time range. Read-only. Use for price history and technical analysis.",pathParams:["product_id"],params:[{name:"product_id",in:"path",type:"string",required:!0,description:"Trading pair (e.g. BTC-USD)"},{name:"start",in:"query",type:"string",required:!1,description:"Start time (RFC 3339, e.g. 2024-01-01T00:00:00Z). Defaults to 60 candles before end.",format:"date-time"},{name:"end",in:"query",type:"string",required:!1,description:"End time (RFC 3339, e.g. 2024-01-01T00:00:00Z). Defaults to now.",format:"date-time"},{name:"granularity",in:"query",type:"string",required:!1,description:"Candle interval: 1m, 5m, 15m, 30m, 1h, 2h, 4h, 6h, 1d. Defaults to 1h.",enum:["1m","5m","15m","30m","1h","2h","4h","6h","1d"],default:"1h"},{name:"limit",in:"query",type:"integer",required:!1,description:"Max candles"}],streamable:!1,watchFields:null,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:"array",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"]}}}}}}]},{name:"x402",actions:[{id:"x402_resources",name:"resources",method:"GET",path:"/x402/resources",summary:"Discover x402 Resources",description:"Discover curated x402-enabled resources. Discovery does not spend funds; use the returned payment requirements as budget hints and the input schema to call a resource.",pathParams:[],params:[{name:"q",in:"query",type:"string",required:!1,description:"Optional keyword filter over resource descriptions, providers, and tags"}],streamable:!1,watchFields:null,template:{},responseFields:{fields:["resources"],nested:{resources:{fields:["resource","description","accepts","inputSchema","outputSchema"],nested:{accepts:{fields:["amount"]}}}}},agentApi:"only"},{id:"x402_pay",name:"pay",method:"POST",path:"/x402/pay",summary:"Pay an x402 Payment Requirement",description:"Creates a ready-to-send x402 payment header by placing a USDC hold. This moves funds; use the smallest amount that satisfies the requirement and reuse idempotency_key only when retrying the same payment.",pathParams:[],params:[{name:"scheme",in:"body",type:"string",required:!0,description:"x402 payment scheme (currently exact)"},{name:"network",in:"body",type:"string",required:!0,description:"CAIP-2 network (currently eip155:8453)"},{name:"asset",in:"body",type:"string",required:!0,description:"USDC asset contract address"},{name:"pay_to",in:"body",type:"string",required:!0,description:"Recipient address"},{name:"amount",in:"body",type:"string",required:!0,description:"Required atomic-unit amount from the x402 challenge"},{name:"max_amount",in:"body",type:"string",required:!0,description:"Caller spend cap in atomic units"},{name:"max_timeout_seconds",in:"body",type:"integer",required:!0,description:"Authorization validity window in seconds"},{name:"x402_version",in:"body",type:"integer",required:!1,description:"x402 protocol version; defaults to 2",default:2},{name:"extra",in:"body",type:"object",required:!1,description:"EIP-712 domain; required by protocol semantics for x402_version 2"},{name:"portfolio_id",in:"body",type:"string",required:!1,description:"Optional portfolio UUID to pay from"},{name:"account_id",in:"body",type:"string",required:!1,description:"Optional USDC account UUID to debit"},{name:"idempotency_key",in:"body",type:"string",required:!1,description:"Reuse only to retry the same logical payment"}],streamable:!1,watchFields:null,template:{scheme:"<string>",network:"<string>",asset:"<string>",pay_to:"<string>",amount:"<string>",max_amount:"<string>",max_timeout_seconds:0,x402_version:2,extra:{name:"<string>",version:"<string>"},portfolio_id:"<string>",account_id:"<string>",idempotency_key:"<string>"},responseFields:{fields:["payment_header","payment_id","idempotency_key","expires_at"]},history:"disabled",agentApi:"only"},{id:"x402_fetch",name:"fetch",method:"POST",path:"/x402/fetch",summary:"Pay For and Fetch x402 Resource",description:"Fetches a resource returned by x402 resources. On a 402 challenge, the Agent API pays from custodial USDC and retries automatically. Only catalog URLs and catalog-declared input fields are accepted; input is sent as query parameters for GET resources and as JSON for POST resources. Protocol v2 only. max_amount optionally tightens the catalog advisory ceiling, which is enforced when omitted.",pathParams:[],params:[{name:"resource",in:"body",type:"string",required:!0,description:"Exact URL returned by x402 resources"},{name:"input",in:"body",type:"object",required:!1,description:"Request parameters validated against the resource catalog schema"},{name:"max_amount",in:"body",type:"string",required:!1,description:"Optional caller cap; catalog advisory ceiling applies when omitted"},{name:"portfolio_id",in:"body",type:"string",required:!1,description:"Optional portfolio UUID to pay from"},{name:"account_id",in:"body",type:"string",required:!1,description:"Optional USDC account UUID to debit"},{name:"idempotency_key",in:"body",type:"string",required:!1,description:"Reuse only to retry the same logical fetch"}],streamable:!1,watchFields:null,template:{resource:"<string>",input:{},max_amount:"<string>",portfolio_id:"<string>",account_id:"<string>",idempotency_key:"<string>"},responseFields:{fields:["data","paid","payment_id","idempotency_key","expires_at"]},history:"disabled",agentApi:"only"}]}],nt={balance:{id:"balance",name:"balance",method:"GET",path:"/balance",summary:"View Balances",description:"Lists account balances across currencies, showing available funds and amounts on hold. Read-only. Use before trading or transferring to confirm available funds; available_balance excludes funds held by open orders.",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:"Moves funds of a single currency from one portfolio to another. This executes immediately and moves money \u2014 verify the source has sufficient available balance first. Both portfolio UUIDs come from portfolios_list.",pathParams:[],params:[{name:"amount",in:"body",type:"string",required:!0,description:"Amount to transfer",example:"100.00"},{name:"currency",in:"body",type:"string",required:!0,description:"Currency",example:"USD"},{name:"from",in:"body",type:"string",required:!0,description:"Source portfolio UUID",example:"d17b3486-..."},{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"]}}}}},On=new Set(["balance","transfer","fees"]),Rn={"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,o,a]=e;return Go(+r,+n,+i)&&+s<24&&+o<60&&+a<61}}});function dr(t){return typeof t=="object"&&"endpoint"in t}function C(t,e){return{endpoint:t,...e}}var It=I(()=>{"use strict";g();l()});var Tn,Sn,xn,wn,An,Cn,Nn,Gn,Dn,Ln,Mn,Fn,Un,qn,Bn,zn,Nt=I(()=>{"use strict";g();l();Tn={origin:"RetailBrokerageApi_CancelOrders",method:"POST",path:"/api/v3/brokerage/orders/batch_cancel"},Sn={origin:"RetailBrokerageApi_ClosePosition",method:"POST",path:"/api/v3/brokerage/orders/close_position"},xn={origin:"RetailBrokerageApi_CommitConvertTrade",method:"POST",path:"/api/v3/brokerage/convert/trade/{trade_id}"},wn={origin:"RetailBrokerageApi_CreatePortfolio",method:"POST",path:"/api/v3/brokerage/portfolios"},An={origin:"RetailBrokerageApi_DeletePortfolio",method:"DELETE",path:"/api/v3/brokerage/portfolios/{portfolio_uuid}"},Cn={origin:"RetailBrokerageApi_EditPortfolio",method:"PUT",path:"/api/v3/brokerage/portfolios/{portfolio_uuid}"},Nn={origin:"RetailBrokerageApi_GetBestBidAsk",method:"GET",path:"/api/v3/brokerage/best_bid_ask"},Gn={origin:"RetailBrokerageApi_GetConvertTrade",method:"GET",path:"/api/v3/brokerage/convert/trade/{trade_id}"},Dn={origin:"RetailBrokerageApi_GetFills",method:"GET",path:"/api/v3/brokerage/orders/historical/fills"},Ln={origin:"RetailBrokerageApi_GetHistoricalOrder",method:"GET",path:"/api/v3/brokerage/orders/historical/{order_id}"},Mn={origin:"RetailBrokerageApi_GetHistoricalOrders",method:"GET",path:"/api/v3/brokerage/orders/historical/batch"},Fn={origin:"RetailBrokerageApi_GetPortfolioBreakdown",method:"GET",path:"/api/v3/brokerage/portfolios/{portfolio_uuid}"},Un={origin:"RetailBrokerageApi_GetPortfolios",method:"GET",path:"/api/v3/brokerage/portfolios"},qn={origin:"RetailBrokerageApi_GetProduct",method:"GET",path:"/api/v3/brokerage/products/{product_id}"},Bn={origin:"RetailBrokerageApi_GetPublicProductBook",method:"GET",path:"/api/v3/brokerage/market/product_book"},zn={origin:"RetailBrokerageApi_GetTransactionSummary",method:"GET",path:"/api/v3/brokerage/transaction_summary"}});var Wn,$n=I(()=>{"use strict";g();l();It();Nt();Wn={portfolios_list:C(Un),portfolios_get:C(Fn,{requestMap:{portfolio_id:"portfolio_uuid"},responseUnwrap:"breakdown"}),portfolios_create:C(wn,{responseUnwrap:"portfolio"}),portfolios_edit:C(Cn,{requestMap:{portfolio_id:"portfolio_uuid"},responseUnwrap:"portfolio"}),portfolios_delete:C(An,{requestMap:{portfolio_id:"portfolio_uuid"}})}});var D,pt=I(()=>{"use strict";g();l();D=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 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,o=c.correlationId||c.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})}}});function gr(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 D(e?.message||e?.error_details||n||r?.toString()||"Operation failed",400)}}var Vn=I(()=>{"use strict";g();l();pt()});var Oe,lr,kt,Hn=I(()=>{"use strict";g();l();Oe={MARKET:"market",LIMIT:"limit",STOP_LIMIT:"stop_limit"},lr={UP:"up",DOWN:"down"},kt={GTC:"GTC",IOC:"IOC",FOK:"FOK",GTD:"GTD"}});function Do(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}}async function at(t,e,r,n){let{url:i,remaining:s}=Do(r,n),o=e==="POST"||e==="PUT"||e==="DELETE"||e==="PATCH",a,c=null;if(o)a=t.baseURL+i,Object.keys(s).length>0&&(c=new TextEncoder().encode(JSON.stringify(s)));else{let u=Object.entries(s).filter(([,f])=>f!=null).flatMap(([f,O])=>(Array.isArray(O)?O:[O]).map(E=>encodeURIComponent(f)+"="+encodeURIComponent(String(E)))).join("&");a=t.baseURL+i+(u?"?"+u:"")}let d=await t.doRequest({method:e,url:a,body:c}),p=new TextDecoder().decode(d.body),_;try{_=JSON.parse(p)}catch{_=p}if(d.status>=400){let u=_,f=u?.error_response?.message??u?.error_response?.error_details??u?.message??u?.error_details??p.slice(0,200);throw new Zt(f,d.status,_)}return{status:d.status,data:_}}function jn(t,e){return at(t,"POST","/api/v3/brokerage/convert/quote",e)}function Kn(t,e){return at(t,"POST","/api/v3/brokerage/orders/edit",e)}function Yn(t,e){return at(t,"GET","/api/v3/brokerage/accounts",e)}function Qn(t,e){return at(t,"GET","/api/v3/brokerage/products/{product_id}/candles",e)}function Jn(t,e){return at(t,"GET","/api/v3/brokerage/products/{product_id}/ticker",e)}function pr(t,e){return at(t,"GET","/api/v3/brokerage/products",e)}function Xn(t,e){return at(t,"POST","/api/v3/brokerage/portfolios/move_funds",e)}function Zn(t,e){return at(t,"POST","/api/v3/brokerage/orders",e)}function ti(t,e){return at(t,"POST","/api/v3/brokerage/orders/preview",e)}var Zt,vt=I(()=>{"use strict";g();l();Zt=class extends Error{status;data;constructor(e,r,n){super(e),this.status=r,this.data=n}}});import{randomUUID as Lo}from"node:crypto";function ei(t){let e=t.type;if(e===Oe.MARKET)return{market_market_ioc:{...t.quote_size&&{quote_size:t.quote_size},...t.base_size&&{base_size:t.base_size}}};if(e===Oe.LIMIT){let r=t.time_in_force??kt.GTC,n={base_size:t.base_size,limit_price:t.limit_price,...t.post_only&&{post_only:!0}};return r===kt.IOC?{sor_limit_ioc:n}:r===kt.FOK?{limit_limit_fok:n}:r===kt.GTD?{limit_limit_gtd:{...n,...t.end_time&&{end_time:t.end_time}}}:{limit_limit_gtc:n}}else if(e===Oe.STOP_LIMIT){let r=t.stop_direction===lr.UP?"STOP_DIRECTION_STOP_UP":t.stop_direction===lr.DOWN?"STOP_DIRECTION_STOP_DOWN":(()=>{throw new D("stop_direction is required for stop_limit orders (up or down)",400)})(),n=t.time_in_force??kt.GTC,i={base_size:t.base_size,limit_price:t.limit_price,stop_price:t.stop_price,stop_direction:r};return n===kt.GTD?{stop_limit_stop_limit_gtd:{...i,...t.end_time&&{end_time:t.end_time}}}:{stop_limit_stop_limit_gtc:i}}throw new D(`Unknown order type: ${e}. Use market, limit, or stop_limit.`,400)}function Mo(t){let e={client_order_id:t.client_order_id??Lo(),product_id:t.product_id,side:t.side,order_configuration:ei(t)};return t.portfolio_id&&(e.retail_portfolio_id=t.portfolio_id),t.reduce_only&&(e.reduce_only=!0),e}var Fo,Uo,qo,ri,ni=I(()=>{"use strict";g();l();It();pt();Vn();Hn();Nt();vt();Fo=async(t,e)=>{let r=Mo(t),n=await Zn(e,r);return gr(n.data),n.data.success_response??n.data},Uo=async(t,e)=>{let r=await ti(e,{product_id:t.product_id,side:t.side,order_configuration:ei(t)}),n=r.data;if(n.errs?.length>0)throw new D(n.errs[0].replace(/^PREVIEW_/,"").replace(/_/g," ").toLowerCase(),400);return r.data},qo=async(t,e)=>{if(!t.base_size&&!t.limit_price)throw new D("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 Kn(e,r);return gr(n.data),{order_id:t.order_id,status:"EDITED"}},ri={orders_list:C(Mn,{requestMap:{status:"order_status",side:"order_side",start:"start_date",end:"end_date"}}),orders_get:C(Ln,{responseUnwrap:"order"}),orders_create:Fo,orders_preview:Uo,orders_edit:qo,orders_cancel:C(Tn),orders_close_position:C(Sn),orders_fills:C(Dn,{requestMap:{side:"order_side",start:"start_sequence_timestamp",end:"end_sequence_timestamp"}})}});function ii(t){return String(Math.floor(new Date(t).getTime()/1e3))}var Bo,zo,Wo,$o,Vo,Ho,si,oi=I(()=>{"use strict";g();l();It();pt();Nt();vt();Bo={"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"},zo={"1m":60,"5m":300,"15m":900,"30m":1800,"1h":3600,"2h":7200,"4h":14400,"6h":21600,"1d":86400},Wo=60,$o=async(t,e)=>{let{symbol:r,limit:n,cursor:i,...s}=t;if(r){let a=r.toUpperCase(),p=((await pr(e,s)).data.products??[]).filter(u=>u.base_currency_id===a||u.quote_currency_id===a),_=n!==void 0&&n>0?p.slice(0,n):p;return{products:_,num_products:_.length}}return(await pr(e,{...s,limit:n,cursor:i})).data};Vo=async(t,e)=>{if(!t.granularity)throw new D("granularity is required (expected execute() to apply its default)",500);let r=t.granularity,n=Bo[r],i=zo[r],s=Math.floor(Date.now()/1e3),o=t.end?ii(t.end):String(s),a=t.start?ii(t.start):String(Number(o)-Wo*i);return(await Qn(e,{...t,granularity:n,start:a,end:o})).data},Ho=async(t,e)=>{let r=t.limit??100;return(await Jn(e,{...t,limit:r})).data},si={products_list:$o,products_get:C(qn),products_ticker:Ho,products_book:C(Bn),products_candles:Vo,products_best_bid_ask:C(Nn)}});var jo,ai,ci=I(()=>{"use strict";g();l();It();Nt();vt();pt();jo=async(t,e)=>{let{from:r,to:n,...i}=t,s=await jn(e,{...i,from_account:r,to_account:n});if(!s.data?.trade?.id)throw new D(`Convert quote returned no trade for ${t.from} \u2192 ${t.to}. Verify balance, supported pair, and account eligibility.`,422);return s.data},ai={convert_quote:jo,convert_execute:C(xn,{requestMap:{quote_id:"trade_id",from:"from_account",to:"to_account"}}),convert_get:C(Gn,{requestMap:{quote_id:"trade_id",from:"from_account",to:"to_account"},responseUnwrap:"trade"})}});var Ko,_i,ui=I(()=>{"use strict";g();l();vt();Ko=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 Yn(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}},_i={balance:Ko}});var Yo,di,gi=I(()=>{"use strict";g();l();pt();vt();Yo=async(t,e)=>{let r={funds:{value:t.amount,currency:t.currency},source_portfolio_uuid:t.from,target_portfolio_uuid:t.to},i=(await Xn(e,r)).data;if(!i?.source_portfolio_uuid)throw new D("Transfer failed \u2014 check amount, currency, and portfolio UUIDs",400);return i},di={transfer:Yo}});var li,pi=I(()=>{"use strict";g();l();It();Nt();li={fees:C(zn)}});var mi,fi=I(()=>{"use strict";g();l();mi={x402_resources:{endpoint:{origin:"AgentAPI_X402Resources",method:"GET",path:"/x402/resources"}},x402_pay:{endpoint:{origin:"AgentAPI_X402Pay",method:"POST",path:"/x402/pay"}},x402_fetch:{endpoint:{origin:"AgentAPI_X402Fetch",method:"POST",path:"/x402/fetch"}}}});function Re(t){return Qo[t]}var Qo,mr=I(()=>{"use strict";g();l();$n();ni();oi();ci();ui();gi();pi();fi();Qo={...Wn,...ri,...si,...ai,..._i,...di,...li,...mi}});function fr(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 yi(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 bi=I(()=>{"use strict";g();l()});function Jo(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 Xo(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 Zo(t,e){if(!e)return t;let r={...t};for(let[n,i]of Object.entries(e)){let s=r[n];if(s!=null){if(i==="join-comma"&&Array.isArray(s))r[n]=s.join(",");else if(i==="split-comma"){let o=Array.isArray(s)?s:[s];r[n]=o.flatMap(a=>String(a).split(",").map(c=>c.trim()).filter(Boolean))}}}return r}function hi(t,e){return`${t.replace(/\/+$/,"")}${e}`}function ta(t){return t===408||t===429||t>=500}function ea(t){return t instanceof TypeError||t instanceof Error&&(t.name==="AbortError"||t.name==="TimeoutError")}function ra(t,e){if(t&&typeof t=="object"&&!Array.isArray(t)){let r=typeof t.hint=="string"&&t.hint?`${t.hint} `:"";return{...t,hint:`${r}${yr}`}}return{error:"AGENT_API_REQUEST_FAILED",code:e,message:typeof t=="string"&&t?t:`Agent API request failed with HTTP ${e}.`,hint:yr}}function Ei(t,e){return{status:400,data:{error:"REST_ENDPOINT_UNAVAILABLE",code:400,message:`${e} endpoint is not configured for environment "${t.envName}". Configure the endpoint for this environment before retrying.`}}}function na(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 ia(t){return t&&typeof t=="object"&&("body"in t||"query"in t||"path"in t||"rawBody"in t)}function te(t,e){if(t==null||typeof t!="object")return t;if(Array.isArray(t))return t.map(n=>te(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=>te(s,i)):i&&typeof t[n]=="object"&&t[n]!==null?r[n]=te(t[n],i):r[n]=t[n]}return r}function sa(t,e){let r=br[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 Gt(t,e,r){let n=ia(e),i=n?e.body??{}:{},s=n?e.query??{}:{},o=n?e.path??{}:{},a=n?e.headers??{}:{},c=n?e.rawBody??null:null,d=!1,p=Re(t);if(!p)return{status:404,data:{error:"UNKNOWN_OPERATION",code:404,message:`No route for ${t}`}};let _=Ii.find(m=>m.id===t);if(!n)for(let[m,h]of Object.entries(e)){let A=_?.params.find(ut=>ut.name===m),S=A?.in==="query"?s:A?.in==="path"?o:i;S[m]=h}if(r.transport==="agent"&&!_?.agentApi)return{status:400,data:{error:"AGENT_API_ROUTE_UNAVAILABLE",code:400,message:`${t} is not available through the Agent API. Set COINBASE_TRANSPORT=brokerage to use direct brokerage.`}};let u=_?.agentApi?lt(r.env,r.envName):"",f=_?.agentApi==="only"||r.transport==="agent"||_?.agentApi==="eligible"&&r.transport!=="brokerage"&&!!u;if(_?.params){if(c)try{let m=JSON.parse(new TextDecoder().decode(c));m&&typeof m=="object"&&!Array.isArray(m)&&(d=!0,Object.assign(i,m))}catch{}for(let m of _.params){if(m.default===void 0||m.required||o[m.name]!==void 0||i[m.name]!==void 0||s[m.name]!==void 0)continue;let h=m.in==="query"?s:m.in==="path"?o:i;h[m.name]=m.default}{let m=_.params.filter(S=>(S.in==="body"||!dr(p)&&S.in==="path")&&S.required),h={...o,...i,...s},A=m.filter(S=>h[S.name]===void 0||h[S.name]==="");if(A.length>0)return{status:400,data:{error:"MISSING_FIELDS",code:400,message:`Missing required field(s): ${A.map(ut=>ut.name).join(", ")}`}}}{let m={...o,...i,...s},h={},A={};for(let S of _.params)if(S.oneOf&&(A[S.oneOf]||(A[S.oneOf]=[]),A[S.oneOf].push(S.name),m[S.name]!==void 0&&m[S.name]!=="")){if(h[S.oneOf])return{status:400,data:{error:"CONFLICTING_FIELDS",code:400,message:`${h[S.oneOf]} and ${S.name} are mutually exclusive. Provide one, not both.`}};h[S.oneOf]=S.name}for(let[S,ut]of Object.entries(A))if(!h[S])return{status:400,data:{error:"MISSING_FIELDS",code:400,message:`One of ${ut.join(", ")} is required.`}}}for(let m of _.params)for(let h of[i,s,o]){if(h[m.name]===void 0)continue;if(m.type==="array"&&typeof h[m.name]=="string"&&(h[m.name]=h[m.name].split(",").map(st=>st.trim()).filter(Boolean)),m.type==="boolean"){if(typeof h[m.name]!="boolean"&&(typeof h[m.name]!="string"||h[m.name]!=="true"&&h[m.name]!=="false"))return{status:400,data:{error:"INVALID_VALUE",code:400,message:`Invalid value for ${m.name}: "${h[m.name]}". Expected "true" or "false".`}};typeof h[m.name]=="string"&&(h[m.name]=h[m.name]==="true")}else if((m.type==="integer"||m.type==="number")&&typeof h[m.name]=="string"){let st=Number(h[m.name]);if(!Number.isFinite(st))return{status:400,data:{error:"INVALID_VALUE",code:400,message:`Invalid value for ${m.name}: "${h[m.name]}". Expected a number.`}};h[m.name]=st}if(m.enum&&!m.enum.includes(String(h[m.name])))return{status:400,data:{error:"INVALID_VALUE",code:400,message:`Invalid value for ${m.name}: "${h[m.name]}". Expected one of: ${m.enum.join(", ")}`}};let A=m.pattern?ki.get(m.pattern):void 0,S=m.format?Rn[m.format]:void 0,ut=A??S;if(ut&&typeof h[m.name]=="string"){let st=h[m.name],Xr=m.format?Pn[m.format]:void 0;if(!(ut.test(st)&&(!A||!S||S.test(st))&&(!Xr||Xr(st)))){let Zr=(m.description??"").split(/\.\s/)[0].replace(/\.?\s*$/,""),oo=Zr?`. ${Zr}.`:".";return{status:400,data:{error:"INVALID_VALUE",code:400,message:`Invalid value for ${m.name}: "${String(st).slice(0,80)}"${oo}`}}}}}}if(!f&&!r.baseURL)return Ei(r,"Brokerage API");if(!f&&!dr(p)){let m={...i,...s,...o};try{let h=await p(m,r),A=br[t];return A&&(h=te(h,A)),{status:200,data:h}}catch(h){if(h instanceof Zt)return{status:h.status,data:h.data};let A=h instanceof D?h.status:500,S=D.stripGrpcPrefix(h instanceof Error?h.message:String(h));return{status:A,data:{error:"HANDLER_ERROR",code:A,message:S}}}}let O=p,E=f?{origin:"AgentAPI",method:_.method,path:_.agentPath??_.path}:O.endpoint,x=f?void 0:O.requestMap,w=f?void 0:O.responseMap,G=f?void 0:O.responseUnwrap,F={...i,...o},Y=fr(F,x),{resolvedPath:R,remainingParams:P}=Jo(E.path,Y);if(R.includes("{"))return{status:400,data:{error:"MISSING_PATH_PARAMS",code:400,message:`Missing required param(s): ${(R.match(/\{([^}]+)\}/g)?.map(h=>h.slice(1,-1))??[]).join(", ")}`}};let H=E.method==="POST"||E.method==="PUT"||E.method==="DELETE"||E.method==="PATCH",V,Q=c??null,ue={...f?Zo(s,_.agentQueryTransforms):fr(s,x)},k=f?u:E.baseURL??r.baseURL;if(!k)return Ei(r,f?"Agent API":"Brokerage API");if(H){V=hi(k,R);let m=f&&Object.keys(o).some(h=>Object.hasOwn(P,h));c&&d&&m?Q=new TextEncoder().encode(JSON.stringify(P)):!Q&&Object.keys(P).length>0&&(Q=new TextEncoder().encode(JSON.stringify(P)))}else Object.assign(ue,P),V=hi(k,R);let T=Xo(ue);T&&(V+=T);let v;try{v=await r.doRequest({method:E.method,url:V,body:Q,headers:Object.keys(a).length>0?a:void 0})}catch(m){if(!f||_?.agentApi!=="eligible"||!ea(m))throw m;let h=m instanceof Error?m.message:String(m);throw new Error(`${h}
48
- Hint: ${yr}`)}let L=new TextDecoder().decode(v.body),U;try{U=JSON.parse(L)}catch{U=L}if(v.status>=400){let m=f&&_?.agentApi==="eligible"&&ta(v.status)?ra(U,v.status):U;return{status:v.status,data:m,headers:v.headers}}G&&(U=na(U,G)),w&&(U=yi(U,w));let ht=sa(t,G);return ht&&(U=te(U,ht)),{status:v.status,data:U,headers:v.headers}}var Ii,br,ki,yr,Pe=I(()=>{"use strict";g();l();It();mr();bi();pt();vt();Ct();tt();Ii=[...rt.flatMap(t=>t.actions),...Object.values(nt)],br={},ki=new Map;for(let t of Ii){br[t.id]=t.responseFields;for(let e of t.params)e.pattern&&ki.set(e.pattern,new RegExp(e.pattern))}yr="To bypass the Agent API temporarily, retry with COINBASE_TRANSPORT=brokerage."});import{readFileSync as oa,writeFileSync as aa,mkdirSync as ca}from"node:fs";import{join as Oi}from"node:path";function vi(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 ua(t,e){let r=vi(t),n=vi(e);return n.major!==r.major?n.major>r.major:n.minor!==r.minor?n.minor>r.minor:n.patch>r.patch}function ga(t,e){let r=de===da?"":` --registry ${de}`;return`
43
+ [Runtime.InteropServices.Marshal]::FreeHGlobal($blob)`,Rt(n))}delete(e,r){try{Ze(`[void][Win32.Cred]::CredDelete('${Ie(Xe(e,r))}', 1, 0)`)}catch{}}}});function Kt(){if(dt!==void 0)return dt;try{process.platform==="darwin"?dt=new be:process.platform==="linux"?dt=new Ee:process.platform==="win32"?dt=new Oe:dt=null}catch{un||(process.stderr.write(`warning: OS keychain not accessible \u2014 secrets stored in keychain will not be available
44
+ `),un=!0),dt=null}return dt}function dn(t){let e=Kt();if(!e)return null;try{return e.get(It,t)}catch{return null}}function gn(t,e){let r=Kt();if(!r)return!1;try{return r.set(It,t,e),!0}catch{return!1}}function ln(t){let e=Kt();if(e)try{e.delete(It,t)}catch{}}function pn(){return Kt()!==null}function mn(){let t=Kt();if(!t)return!1;let e="__coinbase_cli_preflight__";try{t.set(It,e,"ok");let r=t.get(It,e);return t.delete(It,e),r==="ok"}catch{try{t.delete(It,e)}catch{}return!1}}var It,dt,un,tr=I(()=>{"use strict";g();l();on();an();_n();It="coinbase-cli",un=!1});var kn={};Yt(kn,{activeEnvName:()=>xt,activeEnvironment:()=>Xt,authIsViable:()=>ir,builtinEnvironments:()=>X,clearEnvCredentialCache:()=>ar,clearEnvironmentSecretsFromKeychain:()=>sr,clearHistory:()=>Zt,configDir:()=>gt,configPath:()=>nt,credentialsFor:()=>Jt,envCredential:()=>Qt,getHistory:()=>ur,historyEnabled:()=>Re,hydrateEnvironmentSecrets:()=>On,isBuiltinURL:()=>ke,loadConfig:()=>J,resolveAgentAPIURLForEnvironment:()=>lt,resolveBrokerageURL:()=>Z,resolveURL:()=>vo,saveConfig:()=>at,scrubbedEnv:()=>cr,setHistory:()=>_r,setLockOptions:()=>Po,withConfigLock:()=>or,writeEnvironmentSecretsToKeychain:()=>vn});import{readFileSync as bn,writeFileSync as hn,mkdirSync as En,renameSync as ho,unlinkSync as er,openSync as Eo,closeSync as Io,statSync as Oo}from"node:fs";import{homedir as fn}from"node:os";import{join as ve}from"node:path";function gt(){if(process.env.COINBASE_CONFIG_DIR)return process.env.COINBASE_CONFIG_DIR;if(process.platform==="win32"){let t=process.env.APPDATA??ve(fn(),"AppData","Roaming");return ve(t,"coinbase")}return ve(fn(),".config","coinbase")}function nt(){return ve(gt(),"config.json")}function In(t){if(X[t])return X[t];let e=yn[t];if(e&&X[e])return X[e];let r={...X};for(let[i,s]of Object.entries(yn))X[s]&&(r[i]=X[s]);let n=Object.keys(r).find(i=>t.startsWith(i+"-"));return n?r[n]:void 0}function Z(t,e){return t.endpoints?.brokerageApi??t.url??In(e)?.brokerageApi??""}function vo(t,e){return Z(t,e)}function lt(t,e){return t.endpoints?.agentApi??In(e)?.agentApi??""}function ke(t){return Object.values(X).some(e=>e.brokerageApi&&t.startsWith(e.brokerageApi))}function ko(t,e){return Object.values(At[e].secrets).map(r=>r(t))}function ir(t){if(!t)return!1;let e=At[t.type];return e?Object.keys(e.secrets).every(r=>!!t[r]):!1}function On(t,e){if(!e.auth)return e;let r=At[e.auth.type];if(!r)return e;let n=e.auth,i={...n},s=!1,o=!1;for(let[a,c]of Object.entries(r.secrets)){if(n[a]){o=!0;continue}let d=dn(c(t));d&&(i[a]=d,s=!0)}return ir(i)?{...e,auth:i,...o&&!s?{_plaintextBacked:!0}:{}}:{...e,auth:void 0}}function vn(t,e){if(!e.auth)return!0;if(!pn())return!1;let r=e.auth.type,n=At[r];if(!n)return!0;if(!ir(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))gn(o(t),e.auth[s])||(i=!1);return i}function sr(t){for(let e of Object.keys(At))for(let r of ko(t,e))ln(r)}function Qt(t){return t.auth}function Jt(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=bn(nt(),"utf8"),r=JSON.parse(e);t.env=r.env??"";let n=r.environments??{};for(let[i,s]of Object.entries(n))t.environments[i]=On(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 at(t,e={}){let r=gt();En(r,{recursive:!0,mode:448});let n={},i=[];for(let[c,d]of Object.entries(t.environments)){let p={};if(d.url!==void 0&&(p.url=d.url),d.endpoints!==void 0&&(p.endpoints={...d.endpoints}),!d.auth){n[c]=p;continue}let _=vn(c,d),u=e.allowPlaintext===!0||d._plaintextBacked===!0;if(!_){if(!u){i.push(c);continue}p.auth=d.auth,n[c]=p;continue}let f=At[d.auth.type];f&&(p.auth=f.metadataOnly(d.auth)),n[c]=p}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 ${nt()} (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=nt(),a=`${o}.${process.pid}.${Date.now()}.tmp`;try{hn(a,JSON.stringify(s,null,2)+`
46
+ `,{mode:384}),ho(a,o)}catch(c){try{er(a)}catch{}throw c}}function Po(t){Tt={...Tt,...t}}function St(){return nt()+Ro}function To(t){let e=Date.now()+t;for(;Date.now()<e;);}function So(){try{let t=Eo(St(),"wx",384);return hn(t,String(process.pid)),t}catch(t){if(t.code!=="EEXIST")throw t;return null}}function Ao(){try{let t=Oo(St());if(Date.now()-t.mtimeMs<Tt.staleAfterMs)return!1;let e=bn(St(),"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 or(t){En(gt(),{recursive:!0,mode:448});let e=null;for(let r=0;r<Tt.retries&&(e=So(),e===null);r++){if(Ao()){try{er(St())}catch{}continue}To(Tt.baseDelayMs*(1+Math.random()))}if(e===null)throw new Error(`could not acquire config lock after ${Tt.retries} attempts: ${St()}`);try{return t()}finally{try{Io(e)}catch{}try{er(St())}catch{}}}function ar(){rr=void 0,nr=void 0}function xo(){return process.env.COINBASE_KEY_ID&&(rr=process.env.COINBASE_KEY_ID,delete process.env.COINBASE_KEY_ID),process.env.COINBASE_KEY_SECRET&&(nr=process.env.COINBASE_KEY_SECRET,delete process.env.COINBASE_KEY_SECRET),{keyId:rr,keySecret:nr}}function xt(t,e){return e||process.env.COINBASE_ENV||t.env}function Xt(t,e){let r=xt(t,e);if(!r)throw new Error("no environment configured. Run: coinbase env <name>");let n={...t.environments[r]},{keyId:i,keySecret:s}=xo();if(i||s){let c=n.auth?.type==="cdp_key"?n.auth:void 0,d=i??c?.key_id??"",p=s??c?.key_secret??"";d&&p&&(n.auth={type:"cdp_key",key_id:d,key_secret:p})}if(process.env.COINBASE_URL){let c=process.env.COINBASE_URL;n.endpoints={...n.endpoints,brokerageApi:c},n.url=c,ke(c)||process.stderr.write(`warning: COINBASE_URL overrides to non-standard endpoint: ${c}
47
+ `)}let o=Z(n,r),a=lt(n,r);if(!o&&!a)throw new Error(`no REST endpoint for environment "${r}". Set a brokerage URL, an Agent API URL, or use a built-in environment name`);if(!n.auth)throw new Error(`no credentials for "${r}". Run: coinbase env ${r} --key-file path/to/key.json`);return{name:r,env:n}}function cr(){let t={...process.env};for(let e of wo)delete t[e];return t}function Re(t){return process.env.COINBASE_NO_HISTORY?!1:t.settings?.history?.enabled!==!1}function _r(t,e,r,n){t.history[e]||(t.history[e]={}),t.history[e][r]={last_used:new Date().toISOString(),values:n}}function ur(t,e,r){return t.history[e]?.[r]}function Zt(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 X,yn,At,Ro,Tt,rr,nr,wo,tt=I(()=>{"use strict";g();l();pe();tr();X=nn,yn=sn;At={cdp_key:{secrets:{key_secret:t=>`${t}:cdp:key_secret`},metadataOnly:t=>({type:"cdp_key",key_id:t.key_id})}};Ro=".lock",Tt={retries:50,baseDelayMs:20,staleAfterMs:5e3};wo=["COINBASE_KEY_SECRET","COINBASE_KEY_ID"]});function Pn(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 et,rt,Tn,Sn,An,Ct=I(()=>{"use strict";g();l();et=[{name:"convert",actions:[{id:"convert_quote",name:"quote",method:"POST",path:"/convert/quote",summary:"Get Convert Quote",description:"Quotes a currency conversion (e.g. stablecoin pairs), returning rate, fees, and a quote id. Read-only preview \u2014 pass the id to convert_execute to commit; quotes expire, so execute promptly.",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"]}}},agentApi:"eligible"},{id:"convert_execute",name:"execute",method:"POST",path:"/convert/execute/{quote_id}",summary:"Execute Convert Trade",description:"Executes a previously quoted conversion using the quote id from convert_quote. This moves funds at the quoted rate \u2014 always get a fresh quote first, since quotes expire. The from/to currencies must match the original quote.",pathParams:["quote_id"],params:[{name:"quote_id",in:"path",type:"string",required:!0,description:"Quote ID from convert quote response"},{name:"from",in:"body",type:"string",required:!0,description:"Source currency",example:"USDC"},{name:"to",in:"body",type:"string",required:!0,description:"Target currency",example:"USD"}],streamable:!1,watchFields:null,template:{from:"USDC",to:"USD"},responseFields:{fields:["trade"],nested:{trade:{fields:["id","status"]}}},agentApi:"eligible"},{id:"convert_get",name:"get",method:"GET",path:"/convert/get/{quote_id}",summary:"Get Convert Status",description:"Check status of a conversion by quote ID.",pathParams:["quote_id"],params:[{name:"quote_id",in:"path",type:"string",required:!0,description:"Quote ID"},{name:"from",in:"query",type:"string",required:!0,description:"Source currency"},{name:"to",in:"query",type:"string",required:!0,description:"Target currency"}],streamable:!1,watchFields:null,template:{},responseFields:{fields:["id","status","source_currency","target_currency","exchange_rate"]},agentApi:"eligible"}]},{name:"orders",actions:[{id:"orders_list",name:"list",method:"GET",path:"/orders",summary:"List Orders",description:"Lists orders with optional filters by status, product, side, and time range. Read-only. Use status=OPEN to find resting orders that can be edited or cancelled.",pathParams:[],params:[{name:"status",in:"query",type:"string",required:!1,description:"Filter by status"},{name:"product_ids",in:"query",type:"array",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","EQUITY"]},{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"]}}},agentApi:"eligible",agentQueryTransforms:{product_ids:"join-comma"}},{id:"orders_create",name:"create",method:"POST",path:"/orders",summary:"Create Order",description:"Places a live order \u2014 executes immediately and moves funds (market buy spends quote currency; sell disposes of base). Preview with orders_preview first to estimate fees, fill price, and slippage. A FUTURE order rejected on eligibility grounds means the account isn't approved for futures. Send the user to https://help.coinbase.com/en/coinbase/trading-and-funding/derivatives/futures-intro to apply.",pathParams:[],params:[{name:"product_id",in:"body",type:"string",required:!0,description:"Trading pair (BASE-QUOTE) or equity TICKER-QUOTE (AAPL-USD), required exact. Use named quote; never default to USD. Check balance; prefer USDC if both held; flag if unavailable.",example:"BASE-QUOTE"},{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 now; limit = fill at price or better; stop_limit = limit triggered at 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)",example:"65000.00"},{name:"stop_price",in:"body",type:"string",required:!1,description:"Stop price (stop_limit orders)",example:"60000.00"},{name:"stop_direction",in:"body",type:"string",required:!1,description:"up = trigger when price rises above stop_price. down = trigger when falls below.",enum:["up","down"],example:"down"},{name:"post_only",in:"body",type:"boolean",required:!1,description:"Post-only mode (limit orders). Rejects if would take liquidity."},{name:"time_in_force",in:"body",type:"string",required:!1,description:"GTC=good til cancelled. IOC=immediate or cancel. FOK=fill or kill.",enum:["GTC","IOC","FOK","GTD"],example:"GTC"},{name:"end_time",in:"body",type:"string",required:!1,description:"Expiry time for GTD orders (RFC 3339). Required when time_in_force=GTD.",format:"date-time",example:"2024-12-31T23:59:59Z"},{name:"reduce_only",in:"body",type:"boolean",required:!1,description:"Only reduce existing position. Rejects if would increase exposure."},{name:"portfolio_id",in:"body",type:"string",required:!1,description:"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)"},{name:"equity_trading_session",in:"body",type:"string",required:!1,description:"Equity orders only. Trading session for the order. Ignored for crypto and futures.",enum:["NORMAL","PRE_MARKET","AFTER_HOURS","OVERNIGHT","MULTI_SESSION"]},{name:"equity_order_date",in:"body",type:"string",required:!1,description:"Equity orders only. Trade date for the order (YYYY-MM-DD). Ignored for crypto and futures.",format:"date"}],streamable:!1,watchFields:null,template:{product_id:"BASE-QUOTE",side:"BUY",type:"market",quote_size:"100.00",base_size:"0.001",limit_price:"65000.00",stop_price:"60000.00",stop_direction:"up",post_only:!1,time_in_force:"GTC",end_time:"2024-12-31T23:59:59Z",reduce_only:!1,portfolio_id:"<string>",client_order_id:"<string>",equity_trading_session:"NORMAL",equity_order_date:"<string>"},responseFields:{fields:["order_id","product_id","side","client_order_id"]},agentApi:"eligible"},{id:"orders_preview",name:"preview",method:"POST",path:"/orders/preview",summary:"Preview Order",description:"Estimate fees, fill price, and slippage without executing. A FUTURE preview rejected on eligibility grounds means the account isn't approved for futures. Send the user to https://help.coinbase.com/en/coinbase/trading-and-funding/derivatives/futures-intro to apply.",pathParams:[],params:[{name:"product_id",in:"body",type:"string",required:!0,description:"Trading pair (BASE-QUOTE) or equity TICKER-QUOTE (AAPL-USD), required exact. Use named quote; never default to USD. Check balance; prefer USDC if both held; flag if unavailable.",example:"BASE-QUOTE"},{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 now; limit = fill at price or better; stop_limit = limit triggered at stop_price",enum:["market","limit","stop_limit"],example:"market"},{name:"quote_size",in:"body",type:"string",required:!1,description:"Quote currency amount (e.g. spend $100 USD). Mutually exclusive with base_size.",oneOf:"base_size|quote_size",example:"100.00"},{name:"base_size",in:"body",type:"string",required:!1,description:"Base currency amount (e.g. 0.001 BTC). Mutually exclusive with quote_size.",oneOf:"base_size|quote_size",example:"0.001"},{name:"limit_price",in:"body",type:"string",required:!1,description:"Limit price (for limit/stop_limit previews)",example:"65000.00"},{name:"stop_price",in:"body",type:"string",required:!1,description:"Stop price (for stop_limit previews)",example:"60000.00"},{name:"stop_direction",in:"body",type:"string",required:!1,description:"up = trigger when price rises above stop_price. down = trigger when falls below.",enum:["up","down"],example:"down"},{name:"equity_trading_session",in:"body",type:"string",required:!1,description:"Equity orders only. Trading session for the order. Ignored for crypto and futures.",enum:["NORMAL","PRE_MARKET","AFTER_HOURS","OVERNIGHT","MULTI_SESSION"]},{name:"equity_order_date",in:"body",type:"string",required:!1,description:"Equity orders only. Trade date for the order (YYYY-MM-DD). Ignored for crypto and futures.",format:"date"}],streamable:!1,watchFields:null,template:{product_id:"BASE-QUOTE",side:"BUY",type:"market",quote_size:"100.00",base_size:"0.001",limit_price:"65000.00",stop_price:"60000.00",stop_direction:"up",equity_trading_session:"NORMAL",equity_order_date:"<string>"},responseFields:{fields:["order_total","commission_total","slippage","est_average_filled_price","base_size","quote_size","best_bid","best_ask","long_leverage","short_leverage","max_leverage","position_notional_limit","available_buying_power","predicted_liquidation_price"]},agentApi:"eligible"},{id:"orders_edit",name:"edit",method:"POST",path:"/orders/edit/{order_id}",summary:"Edit Order",description:"Atomically update an open order's price or size without cancelling. Avoids the cancel+replace exposure window.",pathParams:["order_id"],params:[{name:"order_id",in:"path",type:"string",required:!0,description:"Order to edit"},{name:"base_size",in:"body",type:"string",required:!1,description:"New base size",example:"0.002"},{name:"limit_price",in:"body",type:"string",required:!1,description:"New limit price",example:"64000.00"}],streamable:!1,watchFields:null,template:{base_size:"0.002",limit_price:"64000.00"},responseFields:{fields:["order_id","status"]},agentApi:"eligible",agentPath:"/orders/edit"},{id:"orders_get",name:"get",method:"GET",path:"/orders/{order_id}",summary:"Get Order",description:"Retrieves the full status and fill details of a single order by ID. Read-only. Use after creating an order to confirm execution.",pathParams:["order_id"],params:[{name:"order_id",in:"path",type:"string",required:!0,description:"Order ID"}],streamable:!1,watchFields:null,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"]},agentApi:"eligible"},{id:"orders_cancel",name:"cancel",method:"POST",path:"/orders/cancel",summary:"Cancel Orders",description:"Cancels one or more open orders by ID. Removes resting orders from the book so reserved funds are released; already-filled portions are unaffected. Returns per-order success so a partial batch can fail.",pathParams:[],params:[{name:"order_ids",in:"body",type:"array",required:!0,description:"Order IDs to cancel"}],streamable:!1,watchFields:null,template:{order_ids:[]},responseFields:{fields:["results"],nested:{results:{fields:["success","order_id"]}}},agentApi:"eligible"},{id:"orders_close_position",name:"close-position",method:"POST",path:"/orders/close-position",summary:"Close Position",description:"Places a market order to flatten an open position for a product, moving funds immediately. Omit size for a full close or set it for a partial close. Preview the equivalent order first if fee or slippage impact matters.",pathParams:[],params:[{name:"client_order_id",in:"body",type:"string",required:!0,description:"Idempotency key"},{name:"product_id",in:"body",type:"string",required:!0,description:"Product to close",example:"BTC-PERP"},{name:"size",in:"body",type:"string",required:!1,description:"Partial close size (omit for full close)",example:"0.001"}],streamable:!1,watchFields:null,template:{client_order_id:"<string>",product_id:"BTC-PERP",size:"0.001"},responseFields:null,agentApi:"eligible"},{id:"orders_fills",name:"fills",method:"GET",path:"/orders/fills",summary:"List Fills",description:"Lists individual trade executions (fills) with commissions and maker/taker indicator, filterable by product, order, side, and time range. Read-only. Use this to reconcile actual fill prices and fees paid.",pathParams:[],params:[{name:"product_ids",in:"query",type:"array",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"]}}},agentApi:"eligible",agentQueryTransforms:{product_ids:"join-comma",order_ids:"split-comma"}}]},{name:"portfolios",actions:[{id:"portfolios_list",name:"list",method:"GET",path:"/portfolios",summary:"List Portfolios",description:"Lists all portfolios on the account, including their UUIDs and types. Read-only. Use this to find the portfolio_id needed for orders, transfers, and balance queries.",pathParams:[],params:[{name:"portfolio_type",in:"query",type:"string",required:!1,description:"Filter by type (DEFAULT, CONSUMER)"}],streamable:!1,watchFields:null,template:{},responseFields:{fields:["portfolios"],nested:{portfolios:{fields:["uuid","name","type","deleted"]}}},agentApi:"eligible"},{id:"portfolios_create",name:"create",method:"POST",path:"/portfolios",summary:"Create Portfolio",description:"Creates a new named portfolio for segregating funds and positions. Does not move any funds; use transfer afterward to fund it.",pathParams:[],params:[{name:"name",in:"body",type:"string",required:!0,description:"Portfolio name",example:"agent-1"}],streamable:!1,watchFields:null,template:{name:"agent-1"},responseFields:{fields:["uuid","name","type","deleted"]},agentApi:"eligible"},{id:"portfolios_get",name:"get",method:"GET",path:"/portfolios/{portfolio_id}",summary:"Get Portfolio Breakdown",description:"Returns portfolio metadata, balances, and positions.",pathParams:["portfolio_id"],params:[{name:"portfolio_id",in:"path",type:"string",required:!0,description:"Portfolio UUID"},{name:"currency",in:"query",type:"string",required:!1,description:"Currency for balance denomination"}],streamable:!1,watchFields:null,template:{},responseFields:{fields:["portfolio","portfolio_balances","spot_positions","futures_positions","equity_positions"],nested:{portfolio:{fields:["uuid","name","type","deleted"]},portfolio_balances:{fields:["total_balance","total_crypto_balance","total_cash_equivalent_balance","total_equities_balance"],nested:{total_balance:{fields:["value","currency"]},total_crypto_balance:{fields:["value","currency"]},total_cash_equivalent_balance:{fields:["value","currency"]},total_equities_balance:{fields:["value","currency"]}}},spot_positions:{fields:["asset","account_uuid","total_balance_fiat","total_balance_crypto","available_to_trade_fiat","allocation","is_cash"]},futures_positions:{fields:["product_id","contract_size","side","amount","avg_entry_price","current_price","unrealized_pnl","expiry","underlying_asset","product_name","venue","notional_value"]},equity_positions:{fields:["asset","account_uuid","total_balance_fiat","total_balance_equity","available_to_trade_equity","available_to_trade_fiat","account_type","allocation","cost_basis","average_entry_price","unrealized_pnl"]}}},agentApi:"eligible"},{id:"portfolios_edit",name:"edit",method:"PUT",path:"/portfolios/{portfolio_id}",summary:"Edit Portfolio",description:"Renames an existing portfolio. Metadata-only change; does not affect balances or positions.",pathParams:["portfolio_id"],params:[{name:"portfolio_id",in:"path",type:"string",required:!0,description:"Portfolio UUID"},{name:"name",in:"body",type:"string",required:!1,description:"New portfolio name"}],streamable:!1,watchFields:null,template:{name:"<string>"},responseFields:{fields:["uuid","name","type","deleted"]},agentApi:"eligible"},{id:"portfolios_delete",name:"delete",method:"DELETE",path:"/portfolios/{portfolio_id}",summary:"Delete Portfolio",description:"Permanently deletes a portfolio. The portfolio must be empty first \u2014 transfer out any remaining funds and close all positions before deleting. The DEFAULT portfolio cannot be deleted.",pathParams:["portfolio_id"],params:[{name:"portfolio_id",in:"path",type:"string",required:!0,description:"Portfolio UUID"}],streamable:!1,watchFields:null,template:{},responseFields:null,agentApi:"eligible"}]},{name:"products",actions:[{id:"products_list",name:"list",method:"GET",path:"/products",summary:"List Products",description:"Lists tradable products and their current price and 24h stats, optionally filtered by symbol or type. Read-only. Use to discover valid product_id values before placing orders. Viewing products, including FUTURE ones, doesn't require any special account approval \u2014 trading them is a separate matter (see the product_type field 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","EQUITY"]},{name:"product_ids",in:"query",type:"array",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","future_product_details"],nested:{future_product_details:{fields:["contract_expiry_type"]}}}}},agentApi:"eligible",agentQueryTransforms:{product_ids:"join-comma"}},{id:"products_get",name:"get",method:"GET",path:"/products/{product_id}",summary:"Get Product",description:"Returns full details for a single product, including price and trading increments/min sizes. Read-only. Use base_increment and base_min_size to size orders that the exchange will accept. Viewing a product, including a FUTURE one, doesn't require any special account approval \u2014 trading it is a separate matter (see the product_type field description).",pathParams:["product_id"],params:[{name:"product_id",in:"path",type:"string",required:!0,description:"Product ID (e.g. BTC-USD)"}],streamable:!1,watchFields:null,template:{},responseFields:{fields:["product_id","price","price_percentage_change_24h","volume_24h","product_type","quote_currency_id","base_currency_id","base_increment","quote_increment","base_min_size","base_max_size","quote_min_size","quote_max_size","status","future_product_details"],nested:{future_product_details:{fields:["contract_expiry_type"]}}},agentApi:"eligible"},{id:"products_ticker",name:"ticker",method:"GET",path:"/products/{product_id}/ticker",summary:"Get Ticker",description:"Returns recent trades plus the current best bid and ask for a product. Read-only. Use for a quick spot price snapshot before previewing or placing an order.",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"]}}},agentApi:"eligible"},{id:"products_book",name:"book",method:"GET",path:"/products/{product_id}/book",summary:"Get Order Book",description:"Returns the bid/ask order book (price levels and sizes) for a product. Read-only. Use to gauge available liquidity and likely slippage before sizing a market order.",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"]}}}}},agentApi:"eligible"},{id:"products_candles",name:"candles",method:"GET",path:"/products/{product_id}/candles",summary:"Get Candles",description:"Returns historical OHLCV candles for a product at a chosen granularity and time range. Read-only. Use for price history and technical analysis.",pathParams:["product_id"],params:[{name:"product_id",in:"path",type:"string",required:!0,description:"Trading pair (e.g. BTC-USD)"},{name:"start",in:"query",type:"string",required:!1,description:"Start time (RFC 3339, e.g. 2024-01-01T00:00:00Z). Defaults to 60 candles before end.",format:"date-time"},{name:"end",in:"query",type:"string",required:!1,description:"End time (RFC 3339, e.g. 2024-01-01T00:00:00Z). Defaults to now.",format:"date-time"},{name:"granularity",in:"query",type:"string",required:!1,description:"Candle interval: 1m, 5m, 15m, 30m, 1h, 2h, 4h, 6h, 1d. Defaults to 1h.",enum:["1m","5m","15m","30m","1h","2h","4h","6h","1d"],default:"1h"},{name:"limit",in:"query",type:"integer",required:!1,description:"Max candles"}],streamable:!1,watchFields:null,template:{},responseFields:{fields:["candles"],nested:{candles:{fields:["start","low","high","open","close","volume"]}}},agentApi:"eligible"},{id:"products_best_bid_ask",name:"best-bid-ask",method:"GET",path:"/products/best-bid-ask",summary:"Best Bid/Ask for Multiple Products",description:"Returns best bid and ask for one or more products in a single call.",pathParams:[],params:[{name:"product_ids",in:"query",type:"array",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"]}}}}}}]},{name:"x402",actions:[{id:"x402_resources",name:"resources",method:"GET",path:"/x402/resources",summary:"Discover x402 Resources",description:"Discover curated x402-enabled resources. Discovery does not spend funds; use the returned payment requirements as budget hints and the input schema to call a resource.",pathParams:[],params:[{name:"q",in:"query",type:"string",required:!1,description:"Optional keyword filter over resource descriptions, providers, and tags"}],streamable:!1,watchFields:null,template:{},responseFields:{fields:["resources"],nested:{resources:{fields:["resource","description","accepts","inputSchema","outputSchema"],nested:{accepts:{fields:["amount"]}}}}},agentApi:"only"},{id:"x402_pay",name:"pay",method:"POST",path:"/x402/pay",summary:"Pay an x402 Payment Requirement",description:"Creates a payment header by placing a USDC hold. Copy the challenge's x402Version into x402_version. Send payment_header as X-PAYMENT for v1 or PAYMENT-SIGNATURE for v2. Headers are not interchangeable; never send X-PAYMENT to a v2 resource or PAYMENT-SIGNATURE to a v1 resource. If rejected, verify x402_version and the header name match before creating another payment. Use the smallest amount.",pathParams:[],params:[{name:"scheme",in:"body",type:"string",required:!0,description:"x402 payment scheme (currently exact)"},{name:"network",in:"body",type:"string",required:!0,description:"CAIP-2 network (currently eip155:8453)"},{name:"asset",in:"body",type:"string",required:!0,description:"USDC asset contract address"},{name:"pay_to",in:"body",type:"string",required:!0,description:"Recipient address"},{name:"amount",in:"body",type:"string",required:!0,description:"Required atomic-unit amount from the x402 challenge"},{name:"max_amount",in:"body",type:"string",required:!0,description:"Caller spend cap in atomic units"},{name:"max_timeout_seconds",in:"body",type:"integer",required:!0,description:"Authorization validity window in seconds"},{name:"x402_version",in:"body",type:"integer",required:!1,description:"x402 protocol version; defaults to 2",default:2},{name:"extra",in:"body",type:"object",required:!1,description:"EIP-712 domain; required by protocol semantics for x402_version 2"},{name:"portfolio_id",in:"body",type:"string",required:!1,description:"Optional portfolio UUID to pay from"},{name:"account_id",in:"body",type:"string",required:!1,description:"Optional USDC account UUID to debit"},{name:"idempotency_key",in:"body",type:"string",required:!1,description:"Reuse only to retry the same logical payment"}],streamable:!1,watchFields:null,template:{scheme:"<string>",network:"<string>",asset:"<string>",pay_to:"<string>",amount:"<string>",max_amount:"<string>",max_timeout_seconds:0,x402_version:2,extra:{name:"<string>",version:"<string>"},portfolio_id:"<string>",account_id:"<string>",idempotency_key:"<string>"},responseFields:{fields:["payment_header","payment_id","idempotency_key","expires_at"]},history:"disabled",agentApi:"only"},{id:"x402_fetch",name:"fetch",method:"POST",path:"/x402/fetch",summary:"Pay For and Fetch x402 Resource",description:"Fetches a resource returned by x402 resources. On a 402 challenge, the Agent API pays from custodial USDC and retries automatically. Only catalog URLs and catalog-declared input fields are accepted; input is sent as query parameters for GET resources and as JSON for POST resources. Protocol v2 only. max_amount optionally tightens the catalog advisory ceiling, which is enforced when omitted.",pathParams:[],params:[{name:"resource",in:"body",type:"string",required:!0,description:"Exact URL returned by x402 resources"},{name:"input",in:"body",type:"object",required:!1,description:"Request parameters validated against the resource catalog schema"},{name:"max_amount",in:"body",type:"string",required:!1,description:"Optional caller cap; catalog advisory ceiling applies when omitted"},{name:"portfolio_id",in:"body",type:"string",required:!1,description:"Optional portfolio UUID to pay from"},{name:"account_id",in:"body",type:"string",required:!1,description:"Optional USDC account UUID to debit"},{name:"idempotency_key",in:"body",type:"string",required:!1,description:"Reuse only to retry the same logical fetch"}],streamable:!1,watchFields:null,template:{resource:"<string>",input:{},max_amount:"<string>",portfolio_id:"<string>",account_id:"<string>",idempotency_key:"<string>"},responseFields:{fields:["data","paid","payment_id","idempotency_key","expires_at"]},history:"disabled",agentApi:"only"}]}],rt={balance:{id:"balance",name:"balance",method:"GET",path:"/balance",summary:"View Balances",description:"Lists account balances across currencies, showing available funds and amounts on hold. Read-only. Use before trading or transferring to confirm available funds; available_balance excludes funds held by open orders.",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"]}}}}},agentApi:"eligible"},transfer:{id:"transfer",name:"transfer",method:"POST",path:"/transfer",summary:"Move Funds Between Portfolios",description:"Moves funds of a single currency from one portfolio to another. This executes immediately and moves money \u2014 verify the source has sufficient available balance first. Both portfolio UUIDs come from portfolios_list.",pathParams:[],params:[{name:"amount",in:"body",type:"string",required:!0,description:"Amount to transfer",example:"100.00"},{name:"currency",in:"body",type:"string",required:!0,description:"Currency",example:"USD"},{name:"from",in:"body",type:"string",required:!0,description:"Source portfolio UUID",example:"d17b3486-..."},{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"]},agentApi:"eligible"},fees:{id:"fees",name:"fees",method:"GET",path:"/fees",summary:"Fee Tier and Volume",description:"Fee tier, maker/taker rates, and 30-day volume.",pathParams:[],params:[{name:"product_type",in:"query",type:"string",required:!1,description:"Filter by product type",enum:["SPOT","FUTURE","EQUITY"]}],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"]}}},agentApi:"eligible"}},Tn=new Set(["balance","transfer","fees"]),Sn={"date-time":/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?(Z|[+-]\d{2}:\d{2})$/,date:/^\d{4}-\d{2}-\d{2}$/};An={"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 Pn(+r,+n,+i)&&+s<24&&+o<60&&+a<61},date:t=>{let e=t.match(/^(\d{4})-(\d{2})-(\d{2})$/);if(!e)return!1;let[,r,n,i]=e;return Pn(+r,+n,+i)}}});function lr(t){return typeof t=="object"&&"endpoint"in t}function D(t,e){return{endpoint:t,...e}}var Ot=I(()=>{"use strict";g();l()});var xn,wn,Cn,Nn,Gn,Dn,Ln,Mn,Un,Fn,qn,Bn,zn,Wn,$n,Nt=I(()=>{"use strict";g();l();xn={origin:"RetailBrokerageApi_CancelOrders",method:"POST",path:"/api/v3/brokerage/orders/batch_cancel"},wn={origin:"RetailBrokerageApi_ClosePosition",method:"POST",path:"/api/v3/brokerage/orders/close_position"},Cn={origin:"RetailBrokerageApi_CommitConvertTrade",method:"POST",path:"/api/v3/brokerage/convert/trade/{trade_id}"},Nn={origin:"RetailBrokerageApi_CreatePortfolio",method:"POST",path:"/api/v3/brokerage/portfolios"},Gn={origin:"RetailBrokerageApi_DeletePortfolio",method:"DELETE",path:"/api/v3/brokerage/portfolios/{portfolio_uuid}"},Dn={origin:"RetailBrokerageApi_EditPortfolio",method:"PUT",path:"/api/v3/brokerage/portfolios/{portfolio_uuid}"},Ln={origin:"RetailBrokerageApi_GetBestBidAsk",method:"GET",path:"/api/v3/brokerage/best_bid_ask"},Mn={origin:"RetailBrokerageApi_GetConvertTrade",method:"GET",path:"/api/v3/brokerage/convert/trade/{trade_id}"},Un={origin:"RetailBrokerageApi_GetFills",method:"GET",path:"/api/v3/brokerage/orders/historical/fills"},Fn={origin:"RetailBrokerageApi_GetHistoricalOrder",method:"GET",path:"/api/v3/brokerage/orders/historical/{order_id}"},qn={origin:"RetailBrokerageApi_GetHistoricalOrders",method:"GET",path:"/api/v3/brokerage/orders/historical/batch"},Bn={origin:"RetailBrokerageApi_GetPortfolios",method:"GET",path:"/api/v3/brokerage/portfolios"},zn={origin:"RetailBrokerageApi_GetProduct",method:"GET",path:"/api/v3/brokerage/products/{product_id}"},Wn={origin:"RetailBrokerageApi_GetPublicProductBook",method:"GET",path:"/api/v3/brokerage/market/product_book"},$n={origin:"RetailBrokerageApi_GetTransactionSummary",method:"GET",path:"/api/v3/brokerage/transaction_summary"}});function Uo(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}}async function it(t,e,r,n){let{url:i,remaining:s}=Uo(r,n),o=e==="POST"||e==="PUT"||e==="DELETE"||e==="PATCH",a,c=null;if(o)a=t.baseURL+i,Object.keys(s).length>0&&(c=new TextEncoder().encode(JSON.stringify(s)));else{let u=Object.entries(s).filter(([,f])=>f!=null).flatMap(([f,k])=>(Array.isArray(k)?k:[k]).map(E=>encodeURIComponent(f)+"="+encodeURIComponent(String(E)))).join("&");a=t.baseURL+i+(u?"?"+u:"")}let d=await t.doRequest({method:e,url:a,body:c}),p=new TextDecoder().decode(d.body),_;try{_=JSON.parse(p)}catch{_=p}if(d.status>=400){let u=_,f=u?.error_response?.message??u?.error_response?.error_details??u?.message??u?.error_details??p.slice(0,200);throw new te(f,d.status,_)}return{status:d.status,data:_}}function Vn(t,e){return it(t,"POST","/api/v3/brokerage/convert/quote",e)}function Hn(t,e){return it(t,"POST","/api/v3/brokerage/orders/edit",e)}function jn(t,e){return it(t,"GET","/api/v3/brokerage/accounts",e)}function Yn(t,e){return it(t,"GET","/api/v3/brokerage/products/{product_id}/candles",e)}function Kn(t,e){return it(t,"GET","/api/v3/brokerage/products/{product_id}/ticker",e)}function Qn(t,e){return it(t,"GET","/api/v3/brokerage/portfolios/{portfolio_uuid}",e)}function pr(t,e){return it(t,"GET","/api/v3/brokerage/products",e)}function Jn(t,e){return it(t,"POST","/api/v3/brokerage/portfolios/move_funds",e)}function Xn(t,e){return it(t,"POST","/api/v3/brokerage/orders",e)}function Zn(t,e){return it(t,"POST","/api/v3/brokerage/orders/preview",e)}var te,pt=I(()=>{"use strict";g();l();te=class extends Error{status;data;constructor(e,r,n){super(e),this.status=r,this.data=n}}});function Bo(t,e,r){if(!(!t||t===r))return e[t]??t}function Wo(t){if(typeof t=="number")return t;if(t&&typeof t=="object"&&"value"in t){let e=Number(t.value);return Number.isFinite(e)?e:void 0}}var Fo,qo,zo,$o,ti,ei=I(()=>{"use strict";g();l();Ot();Nt();pt();Fo={FUTURES_POSITION_SIDE_LONG:"LONG",FUTURES_POSITION_SIDE_SHORT:"SHORT"},qo="FUTURES_POSITION_SIDE_UNSPECIFIED";zo=["total_balance_fiat","total_balance_equity","available_to_trade_equity","available_to_trade_fiat","cost_basis","average_entry_price","unrealized_pnl"];$o=async(t,e)=>{let n=(await Qn(e,{portfolio_uuid:t.portfolio_id,currency:t.currency})).data.breakdown??{},i=(n.futures_positions??[]).map(o=>({...o,side:Bo(o.side,Fo,qo)})),s=(n.equity_positions??[]).map(o=>{let a={...o};for(let c of zo)c in a&&(a[c]=Wo(a[c]));return a});return{...n,futures_positions:i,equity_positions:s}},ti={portfolios_list:D(Bn),portfolios_get:$o,portfolios_create:D(Nn,{responseUnwrap:"portfolio"}),portfolios_edit:D(Dn,{requestMap:{portfolio_id:"portfolio_uuid"},responseUnwrap:"portfolio"}),portfolios_delete:D(Gn,{requestMap:{portfolio_id:"portfolio_uuid"}})}});var C,mt=I(()=>{"use strict";g();l();C=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 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,o=c.correlationId||c.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})}}});function ri(t){return String(t).replace(/^(NEW_ORDER_FAILURE_REASON_|PREVIEW_|EDIT_ORDER_FAILURE_REASON_)/,"").replace(/_/g," ").toLowerCase()}function mr(t){if(t?.success===!1){let e=t.error_response,r=t.errors?.[0]?.edit_failure_reason,n=e?.new_order_failure_reason??e?.preview_failure_reason??e?.error,i=n?ri(n):void 0;throw new C(e?.message||e?.error_details||i||(r?ri(r):void 0)||"Operation failed",400)}}var ni=I(()=>{"use strict";g();l();mt()});var Pe,fr,vt,Gt,ii=I(()=>{"use strict";g();l();Pe={MARKET:"market",LIMIT:"limit",STOP_LIMIT:"stop_limit"},fr={UP:"up",DOWN:"down"},vt={GTC:"GTC",IOC:"IOC",FOK:"FOK",GTD:"GTD"},Gt={NORMAL:"NORMAL",PRE_MARKET:"PRE_MARKET",AFTER_HOURS:"AFTER_HOURS",OVERNIGHT:"OVERNIGHT",MULTI_SESSION:"MULTI_SESSION"}});import{randomUUID as Vo}from"node:crypto";function si(t){let e=t.type;if(e===Pe.MARKET)return{market_market_ioc:{...t.quote_size&&{quote_size:t.quote_size},...t.base_size&&{base_size:t.base_size}}};if(e===Pe.LIMIT){let r=t.time_in_force??vt.GTC,n={base_size:t.base_size,limit_price:t.limit_price,...t.post_only&&{post_only:!0}};return r===vt.IOC?{sor_limit_ioc:n}:r===vt.FOK?{limit_limit_fok:n}:r===vt.GTD?{limit_limit_gtd:{...n,...t.end_time&&{end_time:t.end_time}}}:{limit_limit_gtc:n}}else if(e===Pe.STOP_LIMIT){let r=t.stop_direction===fr.UP?"STOP_DIRECTION_STOP_UP":t.stop_direction===fr.DOWN?"STOP_DIRECTION_STOP_DOWN":(()=>{throw new C("stop_direction is required for stop_limit orders (up or down)",400)})(),n=t.time_in_force??vt.GTC,i={base_size:t.base_size,limit_price:t.limit_price,stop_price:t.stop_price,stop_direction:r};return n===vt.GTD?{stop_limit_stop_limit_gtd:{...i,...t.end_time&&{end_time:t.end_time}}}:{stop_limit_stop_limit_gtc:i}}throw new C(`Unknown order type: ${e}. Use market, limit, or stop_limit.`,400)}function oi(t){if(!t.equity_trading_session&&!t.equity_order_date)return;let e={};if(t.equity_trading_session){let r=Ho[t.equity_trading_session];if(!r)throw new C(`Unknown equity_trading_session: ${t.equity_trading_session}`,400);e.equity_trading_session=r}if(t.equity_order_date){let r=t.equity_order_date.match(jo);if(!r)throw new C("equity_order_date must be YYYY-MM-DD",400);e.equity_order_date={year:Number(r[1]),month:Number(r[2]),day:Number(r[3])}}return e}function Yo(t){let e={client_order_id:t.client_order_id??Vo(),product_id:t.product_id,side:t.side,order_configuration:si(t)};t.portfolio_id&&(e.retail_portfolio_id=t.portfolio_id),t.reduce_only&&(e.reduce_only=!0);let r=oi(t);return r&&(e.equity_order_metadata=r),e}var Ho,jo,Ko,Qo,Jo,Xo,ai,ci=I(()=>{"use strict";g();l();Ot();mt();ni();ii();Nt();pt();Ho={[Gt.NORMAL]:"EQUITY_TRADING_SESSION_NORMAL",[Gt.PRE_MARKET]:"EQUITY_TRADING_SESSION_PRE_MARKET",[Gt.AFTER_HOURS]:"EQUITY_TRADING_SESSION_AFTER_HOURS",[Gt.OVERNIGHT]:"EQUITY_TRADING_SESSION_OVERNIGHT",[Gt.MULTI_SESSION]:"EQUITY_TRADING_SESSION_MULTI_SESSION"},jo=new RegExp("^(\\d{4})-(\\d{2})-(\\d{2})$");Ko=async(t,e)=>{let r=Yo(t),n=await Xn(e,r);return mr(n.data),n.data.success_response??n.data},Qo=async(t,e)=>{let r=oi(t),n=await Zn(e,{product_id:t.product_id,side:t.side,order_configuration:si(t),...r&&{equity_order_metadata:r}}),i=n.data;if(i.errs?.length>0)throw new C(i.errs[0].replace(/^PREVIEW_/,"").replace(/_/g," ").toLowerCase(),400);return n.data},Jo=async(t,e)=>{if(!t.base_size&&!t.limit_price)throw new C("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 Hn(e,r);return mr(n.data),{order_id:t.order_id,status:"EDITED"}},Xo={status:"order_status",side:"order_side",start:"start_date",end:"end_date"},ai={orders_list:D(qn,{requestMap:Xo}),orders_get:D(Fn,{responseUnwrap:"order"}),orders_create:Ko,orders_preview:Qo,orders_edit:Jo,orders_cancel:D(xn),orders_close_position:D(wn),orders_fills:D(Un,{requestMap:{side:"order_side",start:"start_sequence_timestamp",end:"end_sequence_timestamp"}})}});function _i(t){return String(Math.floor(new Date(t).getTime()/1e3))}var Zo,ta,ea,ra,na,ia,ui,di=I(()=>{"use strict";g();l();Ot();mt();Nt();pt();Zo={"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"},ta={"1m":60,"5m":300,"15m":900,"30m":1800,"1h":3600,"2h":7200,"4h":14400,"6h":21600,"1d":86400},ea=60,ra=async(t,e)=>{let{symbol:r,limit:n,cursor:i,...s}=t;if(r){let a=r.toUpperCase(),p=((await pr(e,s)).data.products??[]).filter(u=>u.base_currency_id===a||u.quote_currency_id===a),_=n!==void 0&&n>0?p.slice(0,n):p;return{products:_,num_products:_.length}}return(await pr(e,{...s,limit:n,cursor:i})).data};na=async(t,e)=>{if(!t.granularity)throw new C("granularity is required (expected execute() to apply its default)",500);let r=t.granularity,n=Zo[r],i=ta[r],s=Math.floor(Date.now()/1e3),o=t.end?_i(t.end):String(s),a=t.start?_i(t.start):String(Number(o)-ea*i);return(await Yn(e,{...t,granularity:n,start:a,end:o})).data},ia=async(t,e)=>{let r=t.limit??100;return(await Kn(e,{...t,limit:r})).data},ui={products_list:ra,products_get:D(zn),products_ticker:ia,products_book:D(Wn),products_candles:na,products_best_bid_ask:D(Ln)}});var sa,gi,li=I(()=>{"use strict";g();l();Ot();Nt();pt();mt();sa=async(t,e)=>{let{from:r,to:n,...i}=t,s=await Vn(e,{...i,from_account:r,to_account:n});if(!s.data?.trade?.id)throw new C(`Convert quote returned no trade for ${t.from} \u2192 ${t.to}. Verify balance, supported pair, and account eligibility.`,422);return s.data},gi={convert_quote:sa,convert_execute:D(Cn,{requestMap:{quote_id:"trade_id",from:"from_account",to:"to_account"}}),convert_get:D(Mn,{requestMap:{quote_id:"trade_id",from:"from_account",to:"to_account"},responseUnwrap:"trade"})}});var oa,pi,mi=I(()=>{"use strict";g();l();pt();oa=async(t,e)=>{let r={};t.portfolio_id&&(r.retail_portfolio_id=t.portfolio_id),t.limit&&(r.limit=t.limit),t.cursor&&(r.cursor=t.cursor);let i=(await jn(e,r)).data,s=i.accounts??[],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}},pi={balance:oa}});var aa,fi,yi=I(()=>{"use strict";g();l();mt();pt();aa=async(t,e)=>{let r={funds:{value:t.amount,currency:t.currency},source_portfolio_uuid:t.from,target_portfolio_uuid:t.to},i=(await Jn(e,r)).data;if(!i?.source_portfolio_uuid)throw new C("Transfer failed \u2014 check amount, currency, and portfolio UUIDs",400);return i},fi={transfer:aa}});var bi,hi=I(()=>{"use strict";g();l();Ot();Nt();bi={fees:D($n)}});var Ei,Ii=I(()=>{"use strict";g();l();Ei={x402_resources:{endpoint:{origin:"AgentAPI_X402Resources",method:"GET",path:"/x402/resources"}},x402_pay:{endpoint:{origin:"AgentAPI_X402Pay",method:"POST",path:"/x402/pay"}},x402_fetch:{endpoint:{origin:"AgentAPI_X402Fetch",method:"POST",path:"/x402/fetch"}}}});function Te(t){return ca[t]}var ca,yr=I(()=>{"use strict";g();l();ei();ci();di();li();mi();yi();hi();Ii();ca={...ti,...ai,...ui,...gi,...pi,...fi,...bi,...Ei}});function br(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 Oi(t,e){if(!e||typeof t!="object"||t===null||Array.isArray(t))return t;let r={};for(let[n,i]of Object.entries(t)){let s=e[n]??n;r[s]=i}return r}var vi=I(()=>{"use strict";g();l()});function _a(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 ua(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 da(t,e){if(!e)return t;let r={...t};for(let[n,i]of Object.entries(e)){let s=r[n];if(s!=null){if(i==="join-comma"&&Array.isArray(s))r[n]=s.join(",");else if(i==="split-comma"){let o=Array.isArray(s)?s:[s];r[n]=o.flatMap(a=>String(a).split(",").map(c=>c.trim()).filter(Boolean))}}}return r}function ki(t,e){return`${t.replace(/\/+$/,"")}${e}`}function ga(t){return t===408||t===429||t>=500}function la(t){return t instanceof TypeError||t instanceof Error&&(t.name==="AbortError"||t.name==="TimeoutError")}function pa(t,e){if(t&&typeof t=="object"&&!Array.isArray(t)){let r=typeof t.hint=="string"&&t.hint?`${t.hint} `:"";return{...t,hint:`${r}${hr}`}}return{error:"AGENT_API_REQUEST_FAILED",code:e,message:typeof t=="string"&&t?t:`Agent API request failed with HTTP ${e}.`,hint:hr}}function Ri(t,e){return{status:400,data:{error:"REST_ENDPOINT_UNAVAILABLE",code:400,message:`${e} endpoint is not configured for environment "${t.envName}". Configure the endpoint for this environment before retrying.`}}}function ma(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 fa(t){return t&&typeof t=="object"&&("body"in t||"query"in t||"path"in t||"rawBody"in t)}function ee(t,e){if(t==null||typeof t!="object")return t;if(Array.isArray(t))return t.map(n=>ee(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=>ee(s,i)):i&&typeof t[n]=="object"&&t[n]!==null?r[n]=ee(t[n],i):r[n]=t[n]}return r}function ya(t,e){let r=Er[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 Dt(t,e,r){let n=fa(e),i=n?e.body??{}:{},s=n?e.query??{}:{},o=n?e.path??{}:{},a=n?e.headers??{}:{},c=n?e.rawBody??null:null,d=!1,p=Te(t);if(!p)return{status:404,data:{error:"UNKNOWN_OPERATION",code:404,message:`No route for ${t}`}};let _=Pi.find(m=>m.id===t);if(!n)for(let[m,h]of Object.entries(e)){let w=_?.params.find(ut=>ut.name===m),S=w?.in==="query"?s:w?.in==="path"?o:i;S[m]=h}if(r.transport==="agent"&&!_?.agentApi)return{status:400,data:{error:"AGENT_API_ROUTE_UNAVAILABLE",code:400,message:`${t} is not available through the Agent API. Set COINBASE_TRANSPORT=brokerage to use direct brokerage.`}};let u=_?.agentApi?lt(r.env,r.envName):"",f=_?.agentApi==="only"||r.transport==="agent"||_?.agentApi==="eligible"&&r.transport!=="brokerage"&&!!u;if(_?.params){if(c)try{let m=JSON.parse(new TextDecoder().decode(c));m&&typeof m=="object"&&!Array.isArray(m)&&(d=!0,Object.assign(i,m))}catch{}for(let m of _.params){if(m.default===void 0||m.required||o[m.name]!==void 0||i[m.name]!==void 0||s[m.name]!==void 0)continue;let h=m.in==="query"?s:m.in==="path"?o:i;h[m.name]=m.default}{let m=_.params.filter(S=>(S.in==="body"||!lr(p)&&S.in==="path")&&S.required),h={...o,...i,...s},w=m.filter(S=>h[S.name]===void 0||h[S.name]==="");if(w.length>0)return{status:400,data:{error:"MISSING_FIELDS",code:400,message:`Missing required field(s): ${w.map(ut=>ut.name).join(", ")}`}}}{let m={...o,...i,...s},h={},w={};for(let S of _.params)if(S.oneOf&&(w[S.oneOf]||(w[S.oneOf]=[]),w[S.oneOf].push(S.name),m[S.name]!==void 0&&m[S.name]!=="")){if(h[S.oneOf])return{status:400,data:{error:"CONFLICTING_FIELDS",code:400,message:`${h[S.oneOf]} and ${S.name} are mutually exclusive. Provide one, not both.`}};h[S.oneOf]=S.name}for(let[S,ut]of Object.entries(w))if(!h[S])return{status:400,data:{error:"MISSING_FIELDS",code:400,message:`One of ${ut.join(", ")} is required.`}}}for(let m of _.params)for(let h of[i,s,o]){if(h[m.name]===void 0)continue;if(m.type==="array"&&typeof h[m.name]=="string"&&(h[m.name]=h[m.name].split(",").map(ot=>ot.trim()).filter(Boolean)),m.type==="boolean"){if(typeof h[m.name]!="boolean"&&(typeof h[m.name]!="string"||h[m.name]!=="true"&&h[m.name]!=="false"))return{status:400,data:{error:"INVALID_VALUE",code:400,message:`Invalid value for ${m.name}: "${h[m.name]}". Expected "true" or "false".`}};typeof h[m.name]=="string"&&(h[m.name]=h[m.name]==="true")}else if((m.type==="integer"||m.type==="number")&&typeof h[m.name]=="string"){let ot=Number(h[m.name]);if(!Number.isFinite(ot))return{status:400,data:{error:"INVALID_VALUE",code:400,message:`Invalid value for ${m.name}: "${h[m.name]}". Expected a number.`}};h[m.name]=ot}if(m.enum&&!m.enum.includes(String(h[m.name])))return{status:400,data:{error:"INVALID_VALUE",code:400,message:`Invalid value for ${m.name}: "${h[m.name]}". Expected one of: ${m.enum.join(", ")}`}};let w=m.pattern?Ti.get(m.pattern):void 0,S=m.format?Sn[m.format]:void 0,ut=w??S;if(ut&&typeof h[m.name]=="string"){let ot=h[m.name],tn=m.format?An[m.format]:void 0;if(!(ut.test(ot)&&(!w||!S||S.test(ot))&&(!tn||tn(ot)))){let en=(m.description??"").split(/\.\s/)[0].replace(/\.?\s*$/,""),uo=en?`. ${en}.`:".";return{status:400,data:{error:"INVALID_VALUE",code:400,message:`Invalid value for ${m.name}: "${String(ot).slice(0,80)}"${uo}`}}}}}}if(!f&&!r.baseURL)return Ri(r,"Brokerage API");if(!f&&!lr(p)){let m={...i,...s,...o};try{let h=await p(m,r),w=Er[t];return w&&(h=ee(h,w)),{status:200,data:h}}catch(h){if(h instanceof te)return{status:h.status,data:h.data};let w=h instanceof C?h.status:500,S=C.stripGrpcPrefix(h instanceof Error?h.message:String(h));return{status:w,data:{error:"HANDLER_ERROR",code:w,message:S}}}}let k=p,E=f?{origin:"AgentAPI",method:_.method,path:_.agentPath??_.path}:k.endpoint,A=f?void 0:k.requestMap,x=f?void 0:k.responseMap,G=f?void 0:k.responseUnwrap,U={...i,...o},K=br(U,A),{resolvedPath:R,remainingParams:P}=_a(E.path,K);if(R.includes("{"))return{status:400,data:{error:"MISSING_PATH_PARAMS",code:400,message:`Missing required param(s): ${(R.match(/\{([^}]+)\}/g)?.map(h=>h.slice(1,-1))??[]).join(", ")}`}};let H=E.method==="POST"||E.method==="PUT"||E.method==="DELETE"||E.method==="PATCH",V,Q=c??null,ge={...f?da(s,_.agentQueryTransforms):br(s,A)},O=f?u:E.baseURL??r.baseURL;if(!O)return Ri(r,f?"Agent API":"Brokerage API");if(H){V=ki(O,R);let m=f&&Object.keys(o).some(h=>Object.hasOwn(P,h));c&&d&&m?Q=new TextEncoder().encode(JSON.stringify(P)):!Q&&Object.keys(P).length>0&&(Q=new TextEncoder().encode(JSON.stringify(P)))}else Object.assign(ge,P),V=ki(O,R);let T=ua(ge);T&&(V+=T);let v;try{v=await r.doRequest({method:E.method,url:V,body:Q,headers:Object.keys(a).length>0?a:void 0})}catch(m){if(!f||_?.agentApi!=="eligible"||!la(m))throw m;let h=m instanceof Error?m.message:String(m);throw new Error(`${h}
48
+ Hint: ${hr}`)}let L=new TextDecoder().decode(v.body),F;try{F=JSON.parse(L)}catch{F=L}if(v.status>=400){let m=f&&_?.agentApi==="eligible"&&ga(v.status)?pa(F,v.status):F;return{status:v.status,data:m,headers:v.headers}}G&&(F=ma(F,G)),x&&(F=Oi(F,x));let Et=ya(t,G);return Et&&(F=ee(F,Et)),{status:v.status,data:F,headers:v.headers}}var Pi,Er,Ti,hr,Se=I(()=>{"use strict";g();l();Ot();yr();vi();mt();pt();Ct();tt();Pi=[...et.flatMap(t=>t.actions),...Object.values(rt)],Er={},Ti=new Map;for(let t of Pi){Er[t.id]=t.responseFields;for(let e of t.params)e.pattern&&Ti.set(e.pattern,new RegExp(e.pattern))}hr="To bypass the Agent API temporarily, retry with COINBASE_TRANSPORT=brokerage."});import{readFileSync as ba,writeFileSync as ha,mkdirSync as Ea}from"node:fs";import{join as Ai}from"node:path";function Si(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 Oa(t,e){let r=Si(t),n=Si(e);return n.major!==r.major?n.major>r.major:n.minor!==r.minor?n.minor>r.minor:n.patch>r.patch}function ka(t,e){let r=le===va?"":` --registry ${le}`;return`
49
49
  Update available: ${t} \u2192 ${e}
50
- Run: npm i -g ${Te}${r}
51
- `}function Ti(){return gt()}function pa(){try{return JSON.parse(oa(Oi(Ti(),Pi),"utf8"))}catch{return null}}function ma(t){try{let e=Ti();ca(e,{recursive:!0}),aa(Oi(e,Pi),JSON.stringify(t))}catch{}}async function fa(){try{let t=new AbortController,e=setTimeout(()=>t.abort(),3e3),r=await fetch(_a,{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 Si(){if(process.env.CI||process.env.COINBASE_NO_UPDATE_CHECK)return"";let t=pa();if(t&&Date.now()-t.checkedAt<la)return"";let e=await fa();return e?(ma({checkedAt:Date.now(),latestVersion:e}),ua(ct,e)?ga(ct,e):""):""}var Ri,ct,Te,_a,Pi,da,la,Se=I(()=>{"use strict";g();l();ge();tt();Ri="0.0.5";ct=Ri,Te=tn,_a=`${de}/${encodeURIComponent(Te)}`,Pi="version-check.json";da="https://registry.npmjs.org";la=1440*60*1e3});import{createSign as ya,createPrivateKey as ba,sign as ha,randomBytes as Ea}from"node:crypto";function hr(t){return Buffer.from(t).toString("base64url")}function xe(t){return hr(Buffer.from(JSON.stringify(t)))}function Ia(){return Ea(16).toString("hex")}function wi(t){return t.includes("-----BEGIN EC PRIVATE KEY-----")}function Ai(t){let e=Buffer.from(t,"base64");return e.length===32||e.length===64}function Er(t,e,r,n,i){let s=Math.floor(Date.now()/1e3),o=Ia(),a={sub:t,iss:"cdp",nbf:s,iat:s,exp:s+120},c=`${r} ${n}${i}`;if(r&&n&&i&&(a.uris=[c]),wi(e))return va(t,e,a,o);if(Ai(e))return Oa(t,e,a,o);throw new Error("invalid key format - must be either PEM EC key or base64 Ed25519 key")}function ka(t,e,r){let n=`${xe(t)}.${xe(e)}`,i=ya("SHA256");i.update(n);let s=i.sign(r);return`${n}.${hr(Ra(s))}`}function va(t,e,r,n){return ka({alg:"ES256",typ:"JWT",kid:t,nonce:n},r,e)}function Oa(t,e,r,n){let s=`${xe({alg:"EdDSA",typ:"JWT",kid:t,nonce:n})}.${xe(r)}`,o=Buffer.from(e,"base64"),a=ba({key:Buffer.concat([Buffer.from("302e020100300506032b657004220420","hex"),o.subarray(0,32)]),format:"der",type:"pkcs8"}),c=ha(null,Buffer.from(s),a);return`${s}.${hr(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=xi(n,32),s=xi(s,32),Buffer.concat([n,s])}function xi(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 Pa(t){return wi(t)?"ecdsa":Ai(t)?"ed25519":"unknown"}async function we(t){let e;if(t.keyId&&t.keySecret){let o=new URL(t.url);e=`Bearer ${Er(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(ct)},sdk_language=typescript,source=${encodeURIComponent(Te)}`,...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&&Pa(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 Ae=I(()=>{"use strict";g();l();Se()});function ja(t,e){return t.FORCE_HYPERLINK==="0"?!1:t.FORCE_HYPERLINK?!0:!e||t.CI?!1:!!(/ghostty|iterm|wezterm|hyper/i.test(t.TERM_PROGRAM||"")||t.WT_SESSION||parseInt(t.VTE_VERSION||"",10)>=5e3)}function mt(t){return t.replace(/\x1b\]8;;[^\x07]*\x07/g,"").replace(/\x1b\[[0-9;]*m/g,"").length}var ts,Ne=I(()=>{"use strict";g();l();ts=ja(process.env,!!process.stdout.isTTY)});function Ya(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]:"",o=s.toLowerCase()in Pr&&(r+1>=t.length||t[r+1]===" "||t[r+1]===" "||t[r+1]===")"||t[r+1]==="&"||t[r+1]==="|");if(s&&!o&&(s>="a"&&s<="z"||s>="A"&&s<="Z"||s==="-"))r=n;else{let a=parseFloat(i);r<t.length&&t[r].toLowerCase()in Pr&&(a*=Pr[t[r].toLowerCase()],r++),e.push({type:1,value:a,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 Qa(t){return t>=3&&t<=8}function Sr(t){let e=t.trim();if(e.length===0)throw new Error("Empty predicate");return new Tr(Ya(e)).parse()}function ne(t){switch(t.type){case"comparison":return t.product?[t.product]:[];case"and":case"or":return[...ne(t.left),...ne(t.right)]}}function ns(t,e){let r=[];function n(i){switch(i.type){case"comparison":{let s=e[i.field];if(!s){r.push({field:i.field,message:`Unknown field '${i.field}'`});return}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 Ja(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 Za(t,e){if(typeof e=="number"){if(typeof t=="number")return[t,e];if(typeof t=="string"&&Xa.test(t))return[parseFloat(t),e]}return null}function tc(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=Ja(n,t.field);if(i==null)return!1;let s=Za(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 Dt(t,e,r){switch(t.type){case"comparison":return tc(t,e,r);case"and":return Dt(t.left,e,r)&&Dt(t.right,e,r);case"or":return Dt(t.left,e,r)||Dt(t.right,e,r)}}function is(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,o]of Object.entries(t)){let a=o.enum?o.enum.join("|"):o.type;e.push(` ${s.padEnd(r)} ${a.padEnd(12)} ${o.description}`)}let n=Object.entries(t).filter(([,s])=>s.type==="number").map(([s])=>s),i=Object.entries(t).filter(([,s])=>s.enum).map(([s,o])=>({k:s,vals:o.enum}));if(e.push(""),e.push(" Examples:"),n.length>0&&e.push(` --until "${n[0]} > 70k"`),n.length>1&&e.push(` --until "${n[0]} >= 70k && ${n[0]} <= 75k"`),i.length>0){let s=i[0];e.push(` --until "${s.k} == \\"${s.vals[0]}\\""`)}return n.length>0&&e.push(` --until "(${n[0]} > 72k || ${n[0]} < 68k)"`),e.join(`
52
- `)}var Pr,Tr,Xa,xr=I(()=>{"use strict";g();l();Pr={k:1e3,m:1e6,b:1e9};Tr=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&&Qa(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()}};Xa=/^-?(\d+\.?\d*|\.\d+)([eE][+-]?\d+)?$/});function it(t){return rc[t]??null}var wr,ec,rc,ie=I(()=>{"use strict";g();l();wr="wss://advanced-trade-ws.coinbase.com",ec="wss://advanced-trade-ws-user.coinbase.com",rc={products_ticker:{name:"ticker",endpoint:wr,requiresAuth:!1,coalesce:!0},products_book:{name:"level2",wireName:"l2_data",endpoint:wr,requiresAuth:!1,coalesce:!0},orders_list:{name:"user",endpoint:ec,requiresAuth:!0,coalesce:!1},products_trades:{name:"market_trades",endpoint:wr,requiresAuth:!1,coalesce:!0}}});var q,nc,ic,De,Le=I(()=>{"use strict";g();l();q={CONNECTING:"CONNECTING",CONNECTED:"CONNECTED",SUBSCRIBED:"SUBSCRIBED",RECONNECTING:"RECONNECTING",FAILED:"FAILED"},nc=3e4,ic=1e3,De=class{url;opts;ws=null;_state=q.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(q.CONNECTING);try{this.ws=new this.WSClass(this.url)}catch{this.scheduleReconnect();return}this.resetHeartbeat(),this.ws.onopen=()=>{this.lastActivityTime=this.now(),this.setState(q.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(q.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===q.RECONNECTING&&!this.wasReconnecting&&(this.wasReconnecting=!0,this.opts.onDisconnect?.()),e===q.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(q.FAILED);return}this.setState(q.RECONNECTING);let e=Math.min(ic*Math.pow(2,this.retryCount),nc),r=500+Math.random()*(e-500);this.retryCount++,this.reconnectTimer=setTimeout(()=>{this.connect()},r)}}});var Me,ss=I(()=>{"use strict";g();l();Le();Me=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===q.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 De(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===q.CONNECTED||this.conn.state===q.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 Fe(t,e){return Er(t,e,"","","")}var Ar=I(()=>{"use strict";g();l();Ae()});var Ue,os=I(()=>{"use strict";g();l();Ue=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 Cr(t,e,r){if(!r||t===0)return"";let n=t>0?Mt:Ft;return e?`${Lt}${n}`:n}function gs(t,e,r){if(!r)return"";let n=t==="bid"||t==="BUY"?Mt:Ft;return e?`${Lt}${n}`:n}var $,Lt,Mt,Ft,as,B,cs,_s,us,ds,Ut=I(()=>{"use strict";g();l();$="\x1B[2m",Lt="\x1B[1m",Mt="\x1B[32m",Ft="\x1B[31m",as="\x1B[33m",B="\x1B[0m",cs="\x1B[?25l",_s="\x1B[?25h",us="\x1B[?1049h",ds="\x1B[?1049l"});var qt,ls=I(()=>{"use strict";g();l();Ut();qt=class{out;inAltScreen=!1;cursorHidden=!1;scrollRegionSet=!1;cleanedUp=!1;resizeHandlers=[];sigwinchHandler=null;sigintHandler=null;sigtermHandler=null;stdinHandler=null;constructor(e){this.out=e??process.stdout}enterAltScreen(){this.out.write(us),this.inAltScreen=!0}exitAltScreen(){this.out.write(ds),this.inAltScreen=!1}hideCursor(){this.out.write(cs),this.cursorHidden=!0}showCursor(){this.out.write(_s),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(B),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 se,ps=I(()=>{"use strict";g();l();se=class{flashes=new Map;offsets=new Map;now;constructor(e){this.now=e??Date.now}flash(e,r=600){this.flashes.set(e,this.now()+r)}isFlashing(e){let r=this.flashes.get(e);return r===void 0?!1:this.now()<r}expired(){let e=this.now(),r=[];for(let[n,i]of this.flashes)e>=i&&(r.push(n),this.flashes.delete(n),this.offsets.delete(n));return r}flashWithOffset(e,r,n=1500){let i=this.now()+n;this.flashes.set(e,i),this.offsets.set(e,{indexAtCreation:r,durationMs:n,expiry:i})}getRow(e,r,n){let i=this.offsets.get(e);if(!i)return null;if(this.now()>=i.expiry)return this.offsets.delete(e),null;let s=r-i.indexAtCreation-1;return n+s}clear(){this.flashes.clear(),this.offsets.clear()}}});function W(t,e){let r=mt(t);return r>=e?t.slice(0,t.length-(r-e)):t+" ".repeat(e-r)}function N(t,e){let r=mt(t);return r>=e?t.slice(0,t.length-(r-e)):" ".repeat(e-r)+t}function ft(t,e){let r="\u2500".repeat(t);return e?`${$}${r}${B}`:r}function Bt(t,e,r){let n=mt(t),i=mt(e);if(n+1+i>r){let a=r-i-1;return a>0?`${t.slice(0,a)} ${e}`:e.slice(0,r)}let o=r-n-i;return o<0?W(`${t} ${e}`,r):`${t}${" ".repeat(o)}${e}`}function zt(t,e){return e?t?`${Lt}\xB7${B}`:`${$}\xB7${B}`:""}function K(){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 oe=I(()=>{"use strict";g();l();Ne();Ut()});function j(t){let e=Math.abs(t);return e>=1e3?t.toLocaleString("en-US",{minimumFractionDigits:2,maximumFractionDigits:2}):e>=1?t.toFixed(2):t.toFixed(4)}function Wt(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 ms(t){return t>=1e9?`${(t/1e9).toFixed(1)}B`:t>=1e6?`${(t/1e6).toFixed(0)}M`:t>=1e3?`${(t/1e3).toFixed(0)}K`:t.toFixed(0)}function fs(t){return`${t>=0?"+":""}${t.toFixed(2)}%`}function ys(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 qe=I(()=>{"use strict";g();l()});function hs(t){let e=[],r=0;for(let n of sc){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 Es(){return{events:[],positions:new Map,openOrders:new Set,totalFees:0,lastClock:K(),netCash:0,fillCount:0,accounted:new Map,prependCount:0,heartbeat:!1,updateCount:0}}function oc(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 ac(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 Nr(t,e,r="live"){let n=t.events;if(!n)return{inserts:[],updates:[]};let i=[],s=[];for(let o of n){let a=o.orders;if(a)for(let c of a){let d={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:oc(c),creation_time:c.creation_time?String(c.creation_time):c.created_time?String(c.created_time):void 0},p=e.events.findIndex(_=>_.order_id===d.order_id);if(p>=0){let _=e.events[p],u=_.status!==d.status||_.filled_size!==d.filled_size||_.total_fees!==d.total_fees||_.average_filled_price!==d.average_filled_price;_.status=d.status,_.average_filled_price=d.average_filled_price,_.filled_size=d.filled_size,_.total_fees=d.total_fees,u&&(bs(e,d),s.push(_));continue}r==="backfill"?e.events.splice(ac(e.events,d),0,d):e.events.unshift(d),e.prependCount++,bs(e,d),i.push(d),e.events.length>1e4&&e.events.pop()}}return{inserts:i,updates:s}}function bs(t,e){t.updateCount++,t.lastClock=K();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,o=i*s,a=t.accounted.get(e.order_id)??{fees:0,size:0,value:0},c=n-a.fees,d=i-a.size,p=o-a.value;(d!==0||c!==0)&&(a.size===0&&i>0&&t.fillCount++,t.totalFees+=c,e.order_side==="BUY"?(t.netCash-=p,t.positions.set(e.product_id,(t.positions.get(e.product_id)??0)+d)):(t.netCash+=p,t.positions.set(e.product_id,(t.positions.get(e.product_id)??0)-d)),t.accounted.set(e.order_id,{fees:n,size:i,value:o}))}function cc(t,e,r,n,i){let s=e.order_side==="BUY"?"BUY":"SELL",o=gs(s,n,i),a=e.status.toUpperCase(),c=i?B:"",d=parseFloat(e.average_filled_price??"0"),p=parseFloat(e.filled_size??"0");switch(t){case"time":return W(ys(e.creation_time??new Date().toISOString()),r);case"status":return`${(a==="OPEN"||a==="PENDING")&&i?as:""}${W(a,r)}${c}`;case"product":return W(e.product_id,r);case"side":return`${o}${W(s,r)}${c}`;case"size":{let _=p>0?Wt(p):e.base_size??"-";return`${o}${N(_,r)}${c}`}case"price":return`${o}${N(d>0?j(d):"-",r)}${c}`;case"fee":{let _=parseFloat(e.total_fees??"0");return N(_>0?j(_):"-",r)}case"id":return`${i?$:""}${W(e.order_id.slice(0,r),r)}${c}`;default:return W("",r)}}function ae(t,e,r,n=80){return hs(n).map(i=>cc(i.key,t,i.width,e,r)).join(" ")}function _c(t,e=80){let r=new Set(["size","price","fee"]),i=hs(e).map(s=>r.has(s.key)?N(s.header,s.width):W(s.header,s.width)).join(" ");return t?`${$}${i}${B}`:i}function uc(t,e,r){let n=t.netCash>=0?r?Mt:"":r?Ft:"",i=r?B:"",s=`Fills:${t.fillCount}`,o=`Open:${t.openOrders.size}`,a=`Fees:${j(t.totalFees)}`,c=`Net:${t.netCash>=0?"+":""}${j(t.netCash)}`,d=`${n}${c}${i}`,_=`${zt(t.heartbeat,r)} ${t.lastClock}`,u=`\xB7 ${t.lastClock}`,f=`${s} ${o} ${a} ${c}`,O=`${s} ${o} ${a} ${d}`,E=new Map;for(let[R,P]of t.positions){if(Math.abs(P)<1e-9)continue;let V=(R.match(/-/g)??[]).length===1?R.slice(0,R.indexOf("-")):R;E.set(V,(E.get(V)??0)+P)}let x=[],w=[];for(let[R,P]of E){if(Math.abs(P)<1e-9)continue;let H=`${R}:${Wt(P)}`;x.push(H),w.push(H)}let G=e-f.length-u.length-6,F="";if(x.length>0&&G>8){let R="",P=0,H=0;for(let V=0;V<x.length;V++){let Q=H>0?" ":"";if(P+Q.length+w[V].length>G){let Ht=x.length-H;Ht>0&&(R+=` +${Ht}`);break}R+=Q+x[V],P+=Q.length+w[V].length,H++}F=R}let Y=F?`${O} ${F}`:O;return Bt(Y,_,e)}function Is(t,e,r,n,i){let s=i??e.events,o=t.cols,a=t.rows,c=a,d=a-1,p=a-2;n.inserts.forEach((_,u)=>{r.flashWithOffset(_.order_id,e.prependCount-1-u,1500),t.moveTo(Be,1),t.insertLine(),t.write(ae(_,!0,!0,t.cols)+"\x1B[K")});for(let _ of n.updates){let u=s.indexOf(_);if(u>=0){let f=Be+u;f<=p&&(r.flash(_.order_id,1500),t.moveTo(f,1),t.write(ae(_,!0,!0,t.cols)+"\x1B[K"))}}for(let _ of r.expired()){let u=s.findIndex(f=>f.order_id===_);if(u>=0){let f=Be+u;f<=p&&(t.moveTo(f,1),t.write(ae(s[u],!1,!0,t.cols)+"\x1B[K"))}}t.moveTo(d,1),t.write(ft(o,!0)),t.moveTo(c,1),t.write(uc(e,o-1,!0)+"\x1B[K")}function Gr(t){t.enterAltScreen(),t.hideCursor();let e=t.rows;t.setScrollRegion(Be,e-2),t.moveTo(1,1),t.write(_c(!0,t.cols)+"\x1B[K"),t.moveTo(2,1),t.write(ft(t.cols,!0))}function ze(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 ks(t,e,r){return JSON.stringify(ze(t,e,r))}var Be,sc,vs=I(()=>{"use strict";g();l();oe();Ut();qe();Be=3,sc=[{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 Os(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)),o=Math.round(s*(n-1)),a="";for(let c=0;c<n;c++)a+=c===o?"\u25CF":"\u2500";return a}function Rs(t,e,r){if(e<=0||t<=0)return"";let n=Math.max(0,Math.round(t/e*r));return"\u2588".repeat(n)}var Dr=I(()=>{"use strict";g();l()});function Ss(t){let e=[],r=0;for(let n of lc){if(r+n.width+1>t)break;e.push(n),r+=n.width+1}return e}function xs(){return{products:new Map,prevPrices:new Map,productOrder:[],heartbeat:!1,updateCount:0,lastClock:K()}}function ws(t,e){let r=t.events;if(!r)return[];let n=[];for(let i of r){let s=i.tickers;if(s)for(let o of s){let a={product_id:String(o.product_id??""),price:String(o.price??"0"),volume_24_h:String(o.volume_24_h??"0"),price_percent_chg_24_h:String(o.price_percent_chg_24_h??"0"),best_bid:String(o.best_bid??"0"),best_bid_quantity:String(o.best_bid_quantity??"0"),best_ask:String(o.best_ask??"0"),best_ask_quantity:String(o.best_ask_quantity??"0"),high_24_h:String(o.high_24_h??"0"),low_24_h:String(o.low_24_h??"0")},c=e.prevPrices.get(a.product_id),d=parseFloat(a.price),p=0;c!==void 0&&(d>c?p=1:d<c&&(p=-1)),e.prevPrices.set(a.product_id,d),e.products.set(a.product_id,a),e.productOrder.includes(a.product_id)||e.productOrder.push(a.product_id),e.updateCount++,e.lastClock=K(),n.push({ticker:a,direction:p})}}return n}function pc(t,e,r,n,i,s){let o=parseFloat(e.price),a=s?B:"";switch(t){case"symbol":return W(e.product_id,r);case"price":return`${Cr(n,i,s)}${N(j(o),r)}${a}`;case"pct":{let c=parseFloat(e.price_percent_chg_24_h),d=c>0?1:c<0?-1:0;return`${Cr(d,!1,s)}${N(fs(c),r)}${a}`}case"bid":return N(j(parseFloat(e.best_bid)),r);case"ask":return N(j(parseFloat(e.best_ask)),r);case"bidSz":return`${s?$:""}${N(Wt(parseFloat(e.best_bid_quantity)),r)}${a}`;case"askSz":return`${s?$:""}${N(Wt(parseFloat(e.best_ask_quantity)),r)}${a}`;case"low":return`${s?$:""}${N(j(parseFloat(e.low_24_h)),r)}${a}`;case"high":return`${s?$:""}${N(j(parseFloat(e.high_24_h)),r)}${a}`;case"range":return W(Os(o,parseFloat(e.low_24_h),parseFloat(e.high_24_h),r),r);case"vol":return`${s?$:""}${N(ms(parseFloat(e.volume_24_h)),r)}${a}`;default:return W("",r)}}function Ts(t,e,r,n,i=80){return Ss(i).map(o=>pc(o.key,t,o.width,e,r,n)).join(" ")}function mc(t,e=80){let n=Ss(e).map(i=>i.key==="symbol"||i.key==="range"?W(i.header,i.width):N(i.header,i.width)).join(" ");return t?`${$}${n}${B}`:n}function fc(t,e,r){let n=`${t.products.size} product${t.products.size!==1?"s":""}`,s=`${zt(t.heartbeat,r)} ${t.lastClock}`;return Bt(n,s,e)}function Lr(t){t.enterAltScreen(),t.hideCursor(),t.moveTo(dc,1),t.write(mc(!0,t.cols)+"\x1B[K"),t.moveTo(gc,1),t.write(ft(t.cols,!0))}function As(t,e,r,n,i){let s=t.cols,o=t.rows,a=o,c=o-1;for(let{ticker:d,direction:p}of n){let _=e.productOrder.indexOf(d.product_id);if(_<0)continue;let u=Ps+_;if(u>=c)continue;let f=i?.has(d.product_id)??!1,O=!f&&r.isFlashing(d.product_id);t.moveTo(u,1);let E=Ts(d,f?0:p,O,!0,s);t.write((f?$+E+B:E)+"\x1B[K")}for(let d of r.expired()){let p=e.productOrder.indexOf(d);if(p<0)continue;let _=Ps+p;if(_>=c)continue;let u=e.products.get(d);u&&(t.moveTo(_,1),t.write(Ts(u,0,!1,!0,s)+"\x1B[K"))}t.moveTo(c,1),t.write(ft(s,!0)),t.moveTo(a,1),t.write(fc(e,s-1,!0)+"\x1B[K")}function Mr(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 Cs(t,e,r){return JSON.stringify(Mr(t,e,r))}var dc,gc,Ps,lc,Ns=I(()=>{"use strict";g();l();oe();Ut();qe();Dr();dc=1,gc=2,Ps=3,lc=[{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 Ds(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:K()}}function Ls(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 o=s.type,a=s.updates;if(o==="snapshot"&&(e.bids.clear(),e.asks.clear()),!!a){for(let c of a){let d=String(c.side??"").toLowerCase(),p=parseFloat(String(c.price_level??"0")),_=parseFloat(String(c.new_quantity??"0"));if(p<=0)continue;let u=d==="bid"?e.bids:e.asks;_<=0?u.delete(p):u.set(p,_)}e.updateCount++,e.lastClock=K()}}}function We(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 $e(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 Gs(t,e,r,n,i,s,o){let a=o?i==="bid"?Mt:Ft:"",c=o?B:"",d=Rs(r,n,s),p=`${a}${d}${c}`;return[`${a}${N(j(t),yt[0])}${c}`,N(e.toFixed(4),yt[1]),N(r.toFixed(4),yt[2]),p].join(" ")}function hc(t,e,r){let n=$e(t),i=We(t),s=n.length>0?n[0].price:0,o=i.length>0?i[0].price:0,a=s-o,c=(s+o)/2,d=c>0?a/c*100:0,p=c>0?` Spread: ${j(a).padStart(10)} (${d.toFixed(3).padStart(6)}%) Mid: ${j(c).padStart(12)}`:" Waiting for data...",_=r?$:"",u=r?B:"";return`${_}${W(p,e)}${u}`}function Ec(t,e,r){let n=bc.map((c,d)=>d===3?W(c,yt[d]):N(c,yt[d])).join(" "),i=r?$:"",s=r?Lt:"",o=r?B:"",a=`${s}${t.productId}${o}`;return`${W(a,e)}
53
- ${i}${n}${o}`}function Ic(t,e,r){let n=We(t).reduce((p,_)=>p+_.size,0),i=$e(t).reduce((p,_)=>p+_.size,0),s=i>0?(n/i).toFixed(2):"-",a=`${t.depth?`Depth:${t.depth} `:""}B/A:${s} Rate:${t.msgRate}/s`,d=`${zt(t.heartbeat,r)} ${t.lastClock}`;return Bt(a,d,e)}function Fr(t,e){t.enterAltScreen(),t.hideCursor(),Ur(t,e)}function Ur(t,e){let r=t.cols,n=t.rows;if(n<4)return;let i=yt[0]+yt[1]+yt[2]+3,s=Math.max(4,r-i),o=$e(e),a=We(e),c=n-1,d=n,p=Math.max(0,n-4),_=Math.floor(p/2),u=p>_*2||_>0,f=e.depth?Math.min(_,e.depth):_,O=o.slice(0,f),E=a.slice(0,f),x=0,w=[];for(let P of O)x+=P.size,w.push(x);let G=0,F=[];for(let P of E)G+=P.size,F.push(G);let Y=Math.max(x,G),R=1;t.moveTo(R,1),t.write(Ec(e,r,!0)+"\x1B[K"),R=yc;for(let P=0;P<f&&R<c;P++,R++)if(t.moveTo(R,1),P<O.length){let H=O.length-1-P;t.write(Gs(O[H].price,O[H].size,w[H],Y,"ask",s,!0)+"\x1B[K")}else t.clearLine();u&&R<c&&(t.moveTo(R,1),t.write(hc(e,r,!0)+"\x1B[K"),R++);for(let P=0;P<f&&R<c;P++,R++)t.moveTo(R,1),P<E.length?t.write(Gs(E[P].price,E[P].size,F[P],Y,"bid",s,!0)+"\x1B[K"):t.clearLine();for(;R<c;)t.moveTo(R,1),t.clearLine(),R++;t.moveTo(c,1),t.write(ft(r,!0)),t.moveTo(d,1),t.write(Ic(e,r-1,!0)+"\x1B[K")}function qr(t,e,r){let n=We(t).map(a=>({price:a.price,size:a.size})),i=$e(t).map(a=>({price:a.price,size:a.size})),s=i.length>0?i[0].price:0,o=n.length>0?n[0].price:0;return{_ch:"level2",_seq:e,_ts:r,product_id:t.productId,spread:s-o,mid:(s+o)/2,bids:n,asks:i}}function Ms(t,e,r){return JSON.stringify(qr(t,e,r))}var yc,yt,bc,Fs=I(()=>{"use strict";g();l();oe();Ut();qe();Dr();yc=3,yt=[14,12,12,16],bc=["PRICE","SIZE","TOTAL","DEPTH"]});function Us(t,e,r,n,i){return new Br(t,e,r,n,i)}function qs(t,e,r){return new zr(t,e,r)}function Bs(t,e,r,n){return new Wr(t,e,r,n)}var Br,zr,Wr,zs=I(()=>{"use strict";g();l();Le();Ar();ls();ps();oe();vs();Ns();Fs();Pe();Br=class{productIds=[];screen;refreshJWT;state=Es();flash=new se;queryFilter;context;jwt;until;liveness=!1;connected=!1;constructor(e,r,n,i,s){this.context=r,this.jwt=n,this.until=s,this.queryFilter=e.flags.query,e.isTTY&&!e.untilActive&&(this.screen=new qt(e.out),Gr(this.screen),this.screen.onResize(()=>{Gr(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?Fe(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(),Is(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(ae(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=Nr(e,this.state);this.liveness=!this.liveness;let o={inserts:s.inserts.filter(c=>this.matchesFilter(c)),updates:s.updates.filter(c=>this.matchesFilter(c))};if(i){let c=this.visibleEvents().map(p=>p.order_id);c.length!==i.length||c.some((p,_)=>p!==i[_])?this.repaintFrame():this.render(o)}else this.render(o);return[...o.inserts,...o.updates].map(c=>({obj:ze(c,r,n),line:ks(c,r,n)}))}onHeartbeat(){this.liveness=!this.liveness,this.state.lastClock=K(),this.render({inserts:[],updates:[]})}onConnState(e){this.connected=e===q.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 Gt("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=Nr({events:[{orders:[n]}]},this.state,"backfill");if(this.until.active)for(let o of[...s.inserts,...s.updates]){let a=String(n.created_time??new Date().toISOString());if(this.until.check(ze(o,0,a)))return}}}}catch{}this.repaintFrame()}};zr=class{productIds;screen;state=xs();flash=new se;until;liveness=!1;connected=!1;constructor(e,r,n){this.until=n,this.productIds=r,e.isTTY&&!e.untilActive&&(this.screen=new qt(e.out),Lr(this.screen),this.screen.onResize(()=>{Lr(this.screen),this.repaintFrame()}))}syncHeartbeat(){this.state.heartbeat=this.connected&&this.liveness}render(e){this.screen&&(this.syncHeartbeat(),As(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=ws(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:Mr(s,r,n),line:Cs(s,r,n)}))}onHeartbeat(){this.liveness=!this.liveness,this.state.lastClock=K(),this.render([])}onConnState(e){this.connected=e===q.SUBSCRIBED,this.render([])}onGap(){}onReconnected(){}async setup(){}cleanup(){this.screen?.cleanup()}};Wr=class{productIds;screen;state;productId;liveness=!1;connected=!1;constructor(e,r,n,i){this.productId=r,this.productIds=[r],this.state=Ds(r,e.flags.depth??0),e.isTTY&&!e.untilActive&&(this.screen=new qt(e.out),Fr(this.screen,this.state),this.screen.onResize(()=>{Fr(this.screen,this.state),this.render()}))}syncHeartbeat(){this.state.heartbeat=this.connected&&this.liveness}render(){this.screen&&(this.syncHeartbeat(),Ur(this.screen,this.state))}onData(e,r,n){return Ls(e,this.state),this.liveness=!this.liveness,this.render(),[{obj:qr(this.state,r,n),line:Ms(this.state,r,n)}]}onHeartbeat(){this.liveness=!this.liveness,this.state.lastClock=K(),this.render()}onConnState(e){this.connected=e===q.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 Ws={};jt(Ws,{applyJQ:()=>$r});import{execFileSync as kc}from"node:child_process";function $r(t,e){try{return kc("jq",["-r",e],{input:t,encoding:"utf8",maxBuffer:10*1024*1024,env:or()}).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 Vr=I(()=>{"use strict";g();l();tt()});var Hr={};jt(Hr,{UntilController:()=>$t,__test:()=>Sc,startWatch:()=>Tc,surfaceForChannel:()=>bt});function Oc(t){return vc.find(e=>e.id===t)}function bt(t){switch(t.name){case"user":return"blotter";case"ticker":return"watchlist";case"level2":return"ladder";default:return null}}async function Pc(t,e){if(!e.requiresAuth)return;let n=t.env?.auth;if(!n)throw new Error("WebSocket channel requires authentication. Run: coinbase env <name> --key-file key.json");if(n.type==="oauth")throw new Error(`The --watch blotter requires CDP API key auth (WebSocket does not support OAuth).
54
- Set up a CDP key: coinbase env <name> --key-file key.json`);if(n.type==="cdp_key"&&n.key_id&&n.key_secret)return Fe(n.key_id,n.key_secret);throw new Error("Unsupported auth type for WebSocket")}async function Tc(t,e,r,n){let i=it(t);if(!i)throw new Error(`--watch is not supported for "${t.replace(/_/g," ")}"`);let s=bt(i);if(!s)throw new Error(`--watch is not yet implemented for channel "${i.name}"`);if(n.until){let c;try{c=Sr(n.until)}catch(_){throw new Error(`Invalid --until predicate: ${_.message}`)}let d=Oc(t);if(d?.watchFields){let _=ns(c,d.watchFields);if(_.length>0){let u=Object.keys(d.watchFields).join(", ");throw new Error(_.map(f=>f.message).join(`
50
+ Run: npm i -g ${Ae}${r}
51
+ `}function Ci(){return gt()}function Pa(){try{return JSON.parse(ba(Ai(Ci(),wi),"utf8"))}catch{return null}}function Ta(t){try{let e=Ci();Ea(e,{recursive:!0}),ha(Ai(e,wi),JSON.stringify(t))}catch{}}async function Sa(){try{let t=new AbortController,e=setTimeout(()=>t.abort(),3e3),r=await fetch(Ia,{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 Ni(){if(process.env.CI||process.env.COINBASE_NO_UPDATE_CHECK)return"";let t=Pa();if(t&&Date.now()-t.checkedAt<Ra)return"";let e=await Sa();return e?(Ta({checkedAt:Date.now(),latestVersion:e}),Oa(ct,e)?ka(ct,e):""):""}var xi,ct,Ae,Ia,wi,va,Ra,xe=I(()=>{"use strict";g();l();pe();tt();xi="0.0.7";ct=xi,Ae=rn,Ia=`${le}/${encodeURIComponent(Ae)}`,wi="version-check.json";va="https://registry.npmjs.org";Ra=1440*60*1e3});import{createSign as Aa,createPrivateKey as xa,sign as wa,randomBytes as Ca}from"node:crypto";function Ir(t){return Buffer.from(t).toString("base64url")}function we(t){return Ir(Buffer.from(JSON.stringify(t)))}function Na(){return Ca(16).toString("hex")}function Di(t){return t.includes("-----BEGIN EC PRIVATE KEY-----")}function Li(t){let e=Buffer.from(t,"base64");return e.length===32||e.length===64}function Or(t,e,r,n,i){let s=Math.floor(Date.now()/1e3),o=Na(),a={sub:t,iss:"cdp",nbf:s,iat:s,exp:s+120},c=`${r} ${n}${i}`;if(r&&n&&i&&(a.uris=[c]),Di(e))return Da(t,e,a,o);if(Li(e))return La(t,e,a,o);throw new Error("invalid key format - must be either PEM EC key or base64 Ed25519 key")}function Ga(t,e,r){let n=`${we(t)}.${we(e)}`,i=Aa("SHA256");i.update(n);let s=i.sign(r);return`${n}.${Ir(Ma(s))}`}function Da(t,e,r,n){return Ga({alg:"ES256",typ:"JWT",kid:t,nonce:n},r,e)}function La(t,e,r,n){let s=`${we({alg:"EdDSA",typ:"JWT",kid:t,nonce:n})}.${we(r)}`,o=Buffer.from(e,"base64"),a=xa({key:Buffer.concat([Buffer.from("302e020100300506032b657004220420","hex"),o.subarray(0,32)]),format:"der",type:"pkcs8"}),c=wa(null,Buffer.from(s),a);return`${s}.${Ir(c)}`}function Ma(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=Gi(n,32),s=Gi(s,32),Buffer.concat([n,s])}function Gi(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 Ua(t){return Di(t)?"ecdsa":Li(t)?"ed25519":"unknown"}async function Ce(t){let e;if(t.keyId&&t.keySecret){let o=new URL(t.url);e=`Bearer ${Or(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(ct)},sdk_language=typescript,source=${encodeURIComponent(Ae)}`,...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&&Ua(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 Ne=I(()=>{"use strict";g();l();xe()});function oc(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 ft(t){return t.replace(/\x1b\]8;;[^\x07]*\x07/g,"").replace(/\x1b\[[0-9;]*m/g,"").length}var is,De=I(()=>{"use strict";g();l();is=oc(process.env,!!process.stdout.isTTY)});function cc(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]:"",o=s.toLowerCase()in Sr&&(r+1>=t.length||t[r+1]===" "||t[r+1]===" "||t[r+1]===")"||t[r+1]==="&"||t[r+1]==="|");if(s&&!o&&(s>="a"&&s<="z"||s>="A"&&s<="Z"||s==="-"))r=n;else{let a=parseFloat(i);r<t.length&&t[r].toLowerCase()in Sr&&(a*=Sr[t[r].toLowerCase()],r++),e.push({type:1,value:a,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 _c(t){return t>=3&&t<=8}function xr(t){let e=t.trim();if(e.length===0)throw new Error("Empty predicate");return new Ar(cc(e)).parse()}function se(t){switch(t.type){case"comparison":return t.product?[t.product]:[];case"and":case"or":return[...se(t.left),...se(t.right)]}}function as(t,e){let r=[];function n(i){switch(i.type){case"comparison":{let s=e[i.field];if(!s){r.push({field:i.field,message:`Unknown field '${i.field}'`});return}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 uc(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 gc(t,e){if(typeof e=="number"){if(typeof t=="number")return[t,e];if(typeof t=="string"&&dc.test(t))return[parseFloat(t),e]}return null}function lc(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=uc(n,t.field);if(i==null)return!1;let s=gc(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 Lt(t,e,r){switch(t.type){case"comparison":return lc(t,e,r);case"and":return Lt(t.left,e,r)&&Lt(t.right,e,r);case"or":return Lt(t.left,e,r)||Lt(t.right,e,r)}}function cs(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,o]of Object.entries(t)){let a=o.enum?o.enum.join("|"):o.type;e.push(` ${s.padEnd(r)} ${a.padEnd(12)} ${o.description}`)}let n=Object.entries(t).filter(([,s])=>s.type==="number").map(([s])=>s),i=Object.entries(t).filter(([,s])=>s.enum).map(([s,o])=>({k:s,vals:o.enum}));if(e.push(""),e.push(" Examples:"),n.length>0&&e.push(` --until "${n[0]} > 70k"`),n.length>1&&e.push(` --until "${n[0]} >= 70k && ${n[0]} <= 75k"`),i.length>0){let s=i[0];e.push(` --until "${s.k} == \\"${s.vals[0]}\\""`)}return n.length>0&&e.push(` --until "(${n[0]} > 72k || ${n[0]} < 68k)"`),e.join(`
52
+ `)}var Sr,Ar,dc,wr=I(()=>{"use strict";g();l();Sr={k:1e3,m:1e6,b:1e9};Ar=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&&_c(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()}};dc=/^-?(\d+\.?\d*|\.\d+)([eE][+-]?\d+)?$/});function st(t){return mc[t]??null}var Cr,pc,mc,oe=I(()=>{"use strict";g();l();Cr="wss://advanced-trade-ws.coinbase.com",pc="wss://advanced-trade-ws-user.coinbase.com",mc={products_ticker:{name:"ticker",endpoint:Cr,requiresAuth:!1,coalesce:!0},products_book:{name:"level2",wireName:"l2_data",endpoint:Cr,requiresAuth:!1,coalesce:!0},orders_list:{name:"user",endpoint:pc,requiresAuth:!0,coalesce:!1},products_trades:{name:"market_trades",endpoint:Cr,requiresAuth:!1,coalesce:!0}}});var q,fc,yc,Me,Ue=I(()=>{"use strict";g();l();q={CONNECTING:"CONNECTING",CONNECTED:"CONNECTED",SUBSCRIBED:"SUBSCRIBED",RECONNECTING:"RECONNECTING",FAILED:"FAILED"},fc=3e4,yc=1e3,Me=class{url;opts;ws=null;_state=q.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(q.CONNECTING);try{this.ws=new this.WSClass(this.url)}catch{this.scheduleReconnect();return}this.resetHeartbeat(),this.ws.onopen=()=>{this.lastActivityTime=this.now(),this.setState(q.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(q.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===q.RECONNECTING&&!this.wasReconnecting&&(this.wasReconnecting=!0,this.opts.onDisconnect?.()),e===q.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(q.FAILED);return}this.setState(q.RECONNECTING);let e=Math.min(yc*Math.pow(2,this.retryCount),fc),r=500+Math.random()*(e-500);this.retryCount++,this.reconnectTimer=setTimeout(()=>{this.connect()},r)}}});var Fe,_s=I(()=>{"use strict";g();l();Ue();Fe=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===q.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 Me(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===q.CONNECTED||this.conn.state===q.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 qe(t,e){return Or(t,e,"","","")}var Nr=I(()=>{"use strict";g();l();Ne()});var Be,us=I(()=>{"use strict";g();l();Be=class{snapshots=new Map;timestamps=new Map;now;constructor(e){this.now=e??Date.now}update(e,r){this.snapshots.set(e,r),this.timestamps.set(e,this.now())}get(e){return this.snapshots.get(e)}all(){return this.snapshots}isStale(e,r){let n=this.timestamps.get(e);return n===void 0?!1:this.now()-n>r}staleProducts(e,r){let n=new Set;for(let i of e)this.isStale(i,r)&&n.add(i);return n}hasSeen(e){return this.timestamps.has(e)}age(e){let r=this.timestamps.get(e);if(r!==void 0)return this.now()-r}}});function Gr(t,e,r){if(!r||t===0)return"";let n=t>0?Ut:Ft;return e?`${Mt}${n}`:n}function fs(t,e,r){if(!r)return"";let n=t==="bid"||t==="BUY"?Ut:Ft;return e?`${Mt}${n}`:n}var $,Mt,Ut,Ft,ds,B,gs,ls,ps,ms,qt=I(()=>{"use strict";g();l();$="\x1B[2m",Mt="\x1B[1m",Ut="\x1B[32m",Ft="\x1B[31m",ds="\x1B[33m",B="\x1B[0m",gs="\x1B[?25l",ls="\x1B[?25h",ps="\x1B[?1049h",ms="\x1B[?1049l"});var Bt,ys=I(()=>{"use strict";g();l();qt();Bt=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(ps),this.inAltScreen=!0}exitAltScreen(){this.out.write(ms),this.inAltScreen=!1}hideCursor(){this.out.write(gs),this.cursorHidden=!0}showCursor(){this.out.write(ls),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(B),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 ae,bs=I(()=>{"use strict";g();l();ae=class{flashes=new Map;offsets=new Map;now;constructor(e){this.now=e??Date.now}flash(e,r=600){this.flashes.set(e,this.now()+r)}isFlashing(e){let r=this.flashes.get(e);return r===void 0?!1:this.now()<r}expired(){let e=this.now(),r=[];for(let[n,i]of this.flashes)e>=i&&(r.push(n),this.flashes.delete(n),this.offsets.delete(n));return r}flashWithOffset(e,r,n=1500){let i=this.now()+n;this.flashes.set(e,i),this.offsets.set(e,{indexAtCreation:r,durationMs:n,expiry:i})}getRow(e,r,n){let i=this.offsets.get(e);if(!i)return null;if(this.now()>=i.expiry)return this.offsets.delete(e),null;let s=r-i.indexAtCreation-1;return n+s}clear(){this.flashes.clear(),this.offsets.clear()}}});function W(t,e){let r=ft(t);return r>=e?t.slice(0,t.length-(r-e)):t+" ".repeat(e-r)}function N(t,e){let r=ft(t);return r>=e?t.slice(0,t.length-(r-e)):" ".repeat(e-r)+t}function yt(t,e){let r="\u2500".repeat(t);return e?`${$}${r}${B}`:r}function zt(t,e,r){let n=ft(t),i=ft(e);if(n+1+i>r){let a=r-i-1;return a>0?`${t.slice(0,a)} ${e}`:e.slice(0,r)}let o=r-n-i;return o<0?W(`${t} ${e}`,r):`${t}${" ".repeat(o)}${e}`}function Wt(t,e){return e?t?`${Mt}\xB7${B}`:`${$}\xB7${B}`:""}function Y(){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 ce=I(()=>{"use strict";g();l();De();qt()});function j(t){let e=Math.abs(t);return e>=1e3?t.toLocaleString("en-US",{minimumFractionDigits:2,maximumFractionDigits:2}):e>=1?t.toFixed(2):t.toFixed(4)}function $t(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 hs(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 Is(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 ze=I(()=>{"use strict";g();l()});function vs(t){let e=[],r=0;for(let n of bc){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 ks(){return{events:[],positions:new Map,openOrders:new Set,totalFees:0,lastClock:Y(),netCash:0,fillCount:0,accounted:new Map,prependCount:0,heartbeat:!1,updateCount:0}}function hc(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 Ec(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 Dr(t,e,r="live"){let n=t.events;if(!n)return{inserts:[],updates:[]};let i=[],s=[];for(let o of n){let a=o.orders;if(a)for(let c of a){let d={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:hc(c),creation_time:c.creation_time?String(c.creation_time):c.created_time?String(c.created_time):void 0},p=e.events.findIndex(_=>_.order_id===d.order_id);if(p>=0){let _=e.events[p],u=_.status!==d.status||_.filled_size!==d.filled_size||_.total_fees!==d.total_fees||_.average_filled_price!==d.average_filled_price;_.status=d.status,_.average_filled_price=d.average_filled_price,_.filled_size=d.filled_size,_.total_fees=d.total_fees,u&&(Os(e,d),s.push(_));continue}r==="backfill"?e.events.splice(Ec(e.events,d),0,d):e.events.unshift(d),e.prependCount++,Os(e,d),i.push(d),e.events.length>1e4&&e.events.pop()}}return{inserts:i,updates:s}}function Os(t,e){t.updateCount++,t.lastClock=Y();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,o=i*s,a=t.accounted.get(e.order_id)??{fees:0,size:0,value:0},c=n-a.fees,d=i-a.size,p=o-a.value;(d!==0||c!==0)&&(a.size===0&&i>0&&t.fillCount++,t.totalFees+=c,e.order_side==="BUY"?(t.netCash-=p,t.positions.set(e.product_id,(t.positions.get(e.product_id)??0)+d)):(t.netCash+=p,t.positions.set(e.product_id,(t.positions.get(e.product_id)??0)-d)),t.accounted.set(e.order_id,{fees:n,size:i,value:o}))}function Ic(t,e,r,n,i){let s=e.order_side==="BUY"?"BUY":"SELL",o=fs(s,n,i),a=e.status.toUpperCase(),c=i?B:"",d=parseFloat(e.average_filled_price??"0"),p=parseFloat(e.filled_size??"0");switch(t){case"time":return W(Is(e.creation_time??new Date().toISOString()),r);case"status":return`${(a==="OPEN"||a==="PENDING")&&i?ds:""}${W(a,r)}${c}`;case"product":return W(e.product_id,r);case"side":return`${o}${W(s,r)}${c}`;case"size":{let _=p>0?$t(p):e.base_size??"-";return`${o}${N(_,r)}${c}`}case"price":return`${o}${N(d>0?j(d):"-",r)}${c}`;case"fee":{let _=parseFloat(e.total_fees??"0");return N(_>0?j(_):"-",r)}case"id":return`${i?$:""}${W(e.order_id.slice(0,r),r)}${c}`;default:return W("",r)}}function _e(t,e,r,n=80){return vs(n).map(i=>Ic(i.key,t,i.width,e,r)).join(" ")}function Oc(t,e=80){let r=new Set(["size","price","fee"]),i=vs(e).map(s=>r.has(s.key)?N(s.header,s.width):W(s.header,s.width)).join(" ");return t?`${$}${i}${B}`:i}function vc(t,e,r){let n=t.netCash>=0?r?Ut:"":r?Ft:"",i=r?B:"",s=`Fills:${t.fillCount}`,o=`Open:${t.openOrders.size}`,a=`Fees:${j(t.totalFees)}`,c=`Net:${t.netCash>=0?"+":""}${j(t.netCash)}`,d=`${n}${c}${i}`,_=`${Wt(t.heartbeat,r)} ${t.lastClock}`,u=`\xB7 ${t.lastClock}`,f=`${s} ${o} ${a} ${c}`,k=`${s} ${o} ${a} ${d}`,E=new Map;for(let[R,P]of t.positions){if(Math.abs(P)<1e-9)continue;let V=(R.match(/-/g)??[]).length===1?R.slice(0,R.indexOf("-")):R;E.set(V,(E.get(V)??0)+P)}let A=[],x=[];for(let[R,P]of E){if(Math.abs(P)<1e-9)continue;let H=`${R}:${$t(P)}`;A.push(H),x.push(H)}let G=e-f.length-u.length-6,U="";if(A.length>0&&G>8){let R="",P=0,H=0;for(let V=0;V<A.length;V++){let Q=H>0?" ":"";if(P+Q.length+x[V].length>G){let jt=A.length-H;jt>0&&(R+=` +${jt}`);break}R+=Q+A[V],P+=Q.length+x[V].length,H++}U=R}let K=U?`${k} ${U}`:k;return zt(K,_,e)}function Rs(t,e,r,n,i){let s=i??e.events,o=t.cols,a=t.rows,c=a,d=a-1,p=a-2;n.inserts.forEach((_,u)=>{r.flashWithOffset(_.order_id,e.prependCount-1-u,1500),t.moveTo(We,1),t.insertLine(),t.write(_e(_,!0,!0,t.cols)+"\x1B[K")});for(let _ of n.updates){let u=s.indexOf(_);if(u>=0){let f=We+u;f<=p&&(r.flash(_.order_id,1500),t.moveTo(f,1),t.write(_e(_,!0,!0,t.cols)+"\x1B[K"))}}for(let _ of r.expired()){let u=s.findIndex(f=>f.order_id===_);if(u>=0){let f=We+u;f<=p&&(t.moveTo(f,1),t.write(_e(s[u],!1,!0,t.cols)+"\x1B[K"))}}t.moveTo(d,1),t.write(yt(o,!0)),t.moveTo(c,1),t.write(vc(e,o-1,!0)+"\x1B[K")}function Lr(t){t.enterAltScreen(),t.hideCursor();let e=t.rows;t.setScrollRegion(We,e-2),t.moveTo(1,1),t.write(Oc(!0,t.cols)+"\x1B[K"),t.moveTo(2,1),t.write(yt(t.cols,!0))}function $e(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 Ps(t,e,r){return JSON.stringify($e(t,e,r))}var We,bc,Ts=I(()=>{"use strict";g();l();ce();qt();ze();We=3,bc=[{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 Ss(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)),o=Math.round(s*(n-1)),a="";for(let c=0;c<n;c++)a+=c===o?"\u25CF":"\u2500";return a}function As(t,e,r){if(e<=0||t<=0)return"";let n=Math.max(0,Math.round(t/e*r));return"\u2588".repeat(n)}var Mr=I(()=>{"use strict";g();l()});function Cs(t){let e=[],r=0;for(let n of Pc){if(r+n.width+1>t)break;e.push(n),r+=n.width+1}return e}function Ns(){return{products:new Map,prevPrices:new Map,productOrder:[],heartbeat:!1,updateCount:0,lastClock:Y()}}function Gs(t,e){let r=t.events;if(!r)return[];let n=[];for(let i of r){let s=i.tickers;if(s)for(let o of s){let a={product_id:String(o.product_id??""),price:String(o.price??"0"),volume_24_h:String(o.volume_24_h??"0"),price_percent_chg_24_h:String(o.price_percent_chg_24_h??"0"),best_bid:String(o.best_bid??"0"),best_bid_quantity:String(o.best_bid_quantity??"0"),best_ask:String(o.best_ask??"0"),best_ask_quantity:String(o.best_ask_quantity??"0"),high_24_h:String(o.high_24_h??"0"),low_24_h:String(o.low_24_h??"0")},c=e.prevPrices.get(a.product_id),d=parseFloat(a.price),p=0;c!==void 0&&(d>c?p=1:d<c&&(p=-1)),e.prevPrices.set(a.product_id,d),e.products.set(a.product_id,a),e.productOrder.includes(a.product_id)||e.productOrder.push(a.product_id),e.updateCount++,e.lastClock=Y(),n.push({ticker:a,direction:p})}}return n}function Tc(t,e,r,n,i,s){let o=parseFloat(e.price),a=s?B:"";switch(t){case"symbol":return W(e.product_id,r);case"price":return`${Gr(n,i,s)}${N(j(o),r)}${a}`;case"pct":{let c=parseFloat(e.price_percent_chg_24_h),d=c>0?1:c<0?-1:0;return`${Gr(d,!1,s)}${N(Es(c),r)}${a}`}case"bid":return N(j(parseFloat(e.best_bid)),r);case"ask":return N(j(parseFloat(e.best_ask)),r);case"bidSz":return`${s?$:""}${N($t(parseFloat(e.best_bid_quantity)),r)}${a}`;case"askSz":return`${s?$:""}${N($t(parseFloat(e.best_ask_quantity)),r)}${a}`;case"low":return`${s?$:""}${N(j(parseFloat(e.low_24_h)),r)}${a}`;case"high":return`${s?$:""}${N(j(parseFloat(e.high_24_h)),r)}${a}`;case"range":return W(Ss(o,parseFloat(e.low_24_h),parseFloat(e.high_24_h),r),r);case"vol":return`${s?$:""}${N(hs(parseFloat(e.volume_24_h)),r)}${a}`;default:return W("",r)}}function ws(t,e,r,n,i=80){return Cs(i).map(o=>Tc(o.key,t,o.width,e,r,n)).join(" ")}function Sc(t,e=80){let n=Cs(e).map(i=>i.key==="symbol"||i.key==="range"?W(i.header,i.width):N(i.header,i.width)).join(" ");return t?`${$}${n}${B}`:n}function Ac(t,e,r){let n=`${t.products.size} product${t.products.size!==1?"s":""}`,s=`${Wt(t.heartbeat,r)} ${t.lastClock}`;return zt(n,s,e)}function Ur(t){t.enterAltScreen(),t.hideCursor(),t.moveTo(kc,1),t.write(Sc(!0,t.cols)+"\x1B[K"),t.moveTo(Rc,1),t.write(yt(t.cols,!0))}function Ds(t,e,r,n,i){let s=t.cols,o=t.rows,a=o,c=o-1;for(let{ticker:d,direction:p}of n){let _=e.productOrder.indexOf(d.product_id);if(_<0)continue;let u=xs+_;if(u>=c)continue;let f=i?.has(d.product_id)??!1,k=!f&&r.isFlashing(d.product_id);t.moveTo(u,1);let E=ws(d,f?0:p,k,!0,s);t.write((f?$+E+B:E)+"\x1B[K")}for(let d of r.expired()){let p=e.productOrder.indexOf(d);if(p<0)continue;let _=xs+p;if(_>=c)continue;let u=e.products.get(d);u&&(t.moveTo(_,1),t.write(ws(u,0,!1,!0,s)+"\x1B[K"))}t.moveTo(c,1),t.write(yt(s,!0)),t.moveTo(a,1),t.write(Ac(e,s-1,!0)+"\x1B[K")}function Fr(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 Ls(t,e,r){return JSON.stringify(Fr(t,e,r))}var kc,Rc,xs,Pc,Ms=I(()=>{"use strict";g();l();ce();qt();ze();Mr();kc=1,Rc=2,xs=3,Pc=[{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 Fs(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:Y()}}function qs(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 o=s.type,a=s.updates;if(o==="snapshot"&&(e.bids.clear(),e.asks.clear()),!!a){for(let c of a){let d=String(c.side??"").toLowerCase(),p=parseFloat(String(c.price_level??"0")),_=parseFloat(String(c.new_quantity??"0"));if(p<=0)continue;let u=d==="bid"?e.bids:e.asks;_<=0?u.delete(p):u.set(p,_)}e.updateCount++,e.lastClock=Y()}}}function Ve(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 He(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 Us(t,e,r,n,i,s,o){let a=o?i==="bid"?Ut:Ft:"",c=o?B:"",d=As(r,n,s),p=`${a}${d}${c}`;return[`${a}${N(j(t),bt[0])}${c}`,N(e.toFixed(4),bt[1]),N(r.toFixed(4),bt[2]),p].join(" ")}function Cc(t,e,r){let n=He(t),i=Ve(t),s=n.length>0?n[0].price:0,o=i.length>0?i[0].price:0,a=s-o,c=(s+o)/2,d=c>0?a/c*100:0,p=c>0?` Spread: ${j(a).padStart(10)} (${d.toFixed(3).padStart(6)}%) Mid: ${j(c).padStart(12)}`:" Waiting for data...",_=r?$:"",u=r?B:"";return`${_}${W(p,e)}${u}`}function Nc(t,e,r){let n=wc.map((c,d)=>d===3?W(c,bt[d]):N(c,bt[d])).join(" "),i=r?$:"",s=r?Mt:"",o=r?B:"",a=`${s}${t.productId}${o}`;return`${W(a,e)}
53
+ ${i}${n}${o}`}function Gc(t,e,r){let n=Ve(t).reduce((p,_)=>p+_.size,0),i=He(t).reduce((p,_)=>p+_.size,0),s=i>0?(n/i).toFixed(2):"-",a=`${t.depth?`Depth:${t.depth} `:""}B/A:${s} Rate:${t.msgRate}/s`,d=`${Wt(t.heartbeat,r)} ${t.lastClock}`;return zt(a,d,e)}function qr(t,e){t.enterAltScreen(),t.hideCursor(),Br(t,e)}function Br(t,e){let r=t.cols,n=t.rows;if(n<4)return;let i=bt[0]+bt[1]+bt[2]+3,s=Math.max(4,r-i),o=He(e),a=Ve(e),c=n-1,d=n,p=Math.max(0,n-4),_=Math.floor(p/2),u=p>_*2||_>0,f=e.depth?Math.min(_,e.depth):_,k=o.slice(0,f),E=a.slice(0,f),A=0,x=[];for(let P of k)A+=P.size,x.push(A);let G=0,U=[];for(let P of E)G+=P.size,U.push(G);let K=Math.max(A,G),R=1;t.moveTo(R,1),t.write(Nc(e,r,!0)+"\x1B[K"),R=xc;for(let P=0;P<f&&R<c;P++,R++)if(t.moveTo(R,1),P<k.length){let H=k.length-1-P;t.write(Us(k[H].price,k[H].size,x[H],K,"ask",s,!0)+"\x1B[K")}else t.clearLine();u&&R<c&&(t.moveTo(R,1),t.write(Cc(e,r,!0)+"\x1B[K"),R++);for(let P=0;P<f&&R<c;P++,R++)t.moveTo(R,1),P<E.length?t.write(Us(E[P].price,E[P].size,U[P],K,"bid",s,!0)+"\x1B[K"):t.clearLine();for(;R<c;)t.moveTo(R,1),t.clearLine(),R++;t.moveTo(c,1),t.write(yt(r,!0)),t.moveTo(d,1),t.write(Gc(e,r-1,!0)+"\x1B[K")}function zr(t,e,r){let n=Ve(t).map(a=>({price:a.price,size:a.size})),i=He(t).map(a=>({price:a.price,size:a.size})),s=i.length>0?i[0].price:0,o=n.length>0?n[0].price:0;return{_ch:"level2",_seq:e,_ts:r,product_id:t.productId,spread:s-o,mid:(s+o)/2,bids:n,asks:i}}function Bs(t,e,r){return JSON.stringify(zr(t,e,r))}var xc,bt,wc,zs=I(()=>{"use strict";g();l();ce();qt();ze();Mr();xc=3,bt=[14,12,12,16],wc=["PRICE","SIZE","TOTAL","DEPTH"]});function Ws(t,e,r,n,i){return new Wr(t,e,r,n,i)}function $s(t,e,r){return new $r(t,e,r)}function Vs(t,e,r,n){return new Vr(t,e,r,n)}var Wr,$r,Vr,Hs=I(()=>{"use strict";g();l();Ue();Nr();ys();bs();ce();Ts();Ms();zs();Se();Wr=class{productIds=[];screen;refreshJWT;state=ks();flash=new ae;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 Bt(e.out),Lr(this.screen),this.screen.onResize(()=>{Lr(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?qe(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(),Rs(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(_e(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=Dr(e,this.state);this.liveness=!this.liveness;let o={inserts:s.inserts.filter(c=>this.matchesFilter(c)),updates:s.updates.filter(c=>this.matchesFilter(c))};if(i){let c=this.visibleEvents().map(p=>p.order_id);c.length!==i.length||c.some((p,_)=>p!==i[_])?this.repaintFrame():this.render(o)}else this.render(o);return[...o.inserts,...o.updates].map(c=>({obj:$e(c,r,n),line:Ps(c,r,n)}))}onHeartbeat(){this.liveness=!this.liveness,this.state.lastClock=Y(),this.render({inserts:[],updates:[]})}onConnState(e){this.connected=e===q.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 Dt("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=Dr({events:[{orders:[n]}]},this.state,"backfill");if(this.until.active)for(let o of[...s.inserts,...s.updates]){let a=String(n.created_time??new Date().toISOString());if(this.until.check($e(o,0,a)))return}}}}catch{}this.repaintFrame()}};$r=class{productIds;screen;state=Ns();flash=new ae;until;liveness=!1;connected=!1;constructor(e,r,n){this.until=n,this.productIds=r,e.isTTY&&!e.untilActive&&(this.screen=new Bt(e.out),Ur(this.screen),this.screen.onResize(()=>{Ur(this.screen),this.repaintFrame()}))}syncHeartbeat(){this.state.heartbeat=this.connected&&this.liveness}render(e){this.screen&&(this.syncHeartbeat(),Ds(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=Gs(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:Fr(s,r,n),line:Ls(s,r,n)}))}onHeartbeat(){this.liveness=!this.liveness,this.state.lastClock=Y(),this.render([])}onConnState(e){this.connected=e===q.SUBSCRIBED,this.render([])}onGap(){}onReconnected(){}async setup(){}cleanup(){this.screen?.cleanup()}};Vr=class{productIds;screen;state;productId;liveness=!1;connected=!1;constructor(e,r,n,i){this.productId=r,this.productIds=[r],this.state=Fs(r,e.flags.depth??0),e.isTTY&&!e.untilActive&&(this.screen=new Bt(e.out),qr(this.screen,this.state),this.screen.onResize(()=>{qr(this.screen,this.state),this.render()}))}syncHeartbeat(){this.state.heartbeat=this.connected&&this.liveness}render(){this.screen&&(this.syncHeartbeat(),Br(this.screen,this.state))}onData(e,r,n){return qs(e,this.state),this.liveness=!this.liveness,this.render(),[{obj:zr(this.state,r,n),line:Bs(this.state,r,n)}]}onHeartbeat(){this.liveness=!this.liveness,this.state.lastClock=Y(),this.render()}onConnState(e){this.connected=e===q.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 js={};Yt(js,{applyJQ:()=>Hr});import{execFileSync as Dc}from"node:child_process";function Hr(t,e){try{return Dc("jq",["-r",e],{input:t,encoding:"utf8",maxBuffer:10*1024*1024,env:cr()}).trimEnd()}catch(r){if(r.code==="ENOENT")throw new Error("jq is not installed. Install it: https://jqlang.github.io/jq/download/");let n=(r.stderr??r.message??"").toString().trim();throw new Error(`jq: ${n}`)}}var jr=I(()=>{"use strict";g();l();tt()});var Yr={};Yt(Yr,{UntilController:()=>Vt,__test:()=>Bc,startWatch:()=>qc,surfaceForChannel:()=>ht});function Mc(t){return Lc.find(e=>e.id===t)}function ht(t){switch(t.name){case"user":return"blotter";case"ticker":return"watchlist";case"level2":return"ladder";default:return null}}async function Fc(t,e){if(!e.requiresAuth)return;let n=t.env?.auth;if(!n)throw new Error("WebSocket channel requires authentication. Run: coinbase env <name> --key-file key.json");if(n.type==="oauth")throw new Error(`The --watch blotter requires CDP API key auth (WebSocket does not support OAuth).
54
+ Set up a CDP key: coinbase env <name> --key-file key.json`);if(n.type==="cdp_key"&&n.key_id&&n.key_secret)return qe(n.key_id,n.key_secret);throw new Error("Unsupported auth type for WebSocket")}async function qc(t,e,r,n){let i=st(t);if(!i)throw new Error(`--watch is not supported for "${t.replace(/_/g," ")}"`);let s=ht(i);if(!s)throw new Error(`--watch is not yet implemented for channel "${i.name}"`);if(n.until){let c;try{c=xr(n.until)}catch(_){throw new Error(`Invalid --until predicate: ${_.message}`)}let d=Mc(t);if(d?.watchFields){let _=as(c,d.watchFields);if(_.length>0){let u=Object.keys(d.watchFields).join(", ");throw new Error(_.map(f=>f.message).join(`
55
55
  `)+`
56
- Available fields: ${u}`)}}let p=ne(c);if(p.length>0&&e.length>0){let _=p.filter(u=>!e.includes(u));if(_.length>0)throw new Error(`Predicate references product${_.length>1?"s":""} not in watch: ${_.join(", ")}
57
- Watching: ${e.join(", ")}`)}}let o=await Pc(r,i),a=!!process.stdout.isTTY;await wc(n),s==="blotter"?await Vs(i,o,r,n,a):s==="watchlist"?await Hs(i,e,o,n,a):s==="ladder"&&await js(i,e,o,n,a)}async function He(t,e,r,n,i,s){let o=n.start();await i.setup();let a=0,c;c=new Me({channel:t,WebSocketClass:s,onEvent:p=>{let _=p;a=_.sequence_num??a;let u=String(_.timestamp??new Date().toISOString()),f=i.onData(_,a,u);if(f.length!==0){if(!i.screen&&!n.active)for(let O of f)Ys(O.line,r);if(n.active){for(let O of f)if(n.check(O.obj))return}}},onHeartbeat:()=>i.onHeartbeat(),onSequenceGap:()=>{let p=i.onGap();p&&(c.unsubscribe(p.resubscribe),c.subscribe(p.resubscribe,i.refreshJWT?i.refreshJWT():e))},onError:i.screen?void 0:p=>process.stderr.write(`ws error: ${p}
58
- `),onStateChange:p=>{p===q.FAILED&&n.onFailed(),i.onConnState(p)},onDisconnect:()=>n.onDisconnect(),onReconnect:()=>n.onReconnect(),onReconnected:()=>i.onReconnected(),refreshJWT:i.refreshJWT}),c.connect(),c.subscribe(i.productIds,e);let d=await xc(o,i.screen);c.close(),Ks(d,i,r,n),d===null&&process.exit(process.exitCode??0)}async function Vs(t,e,r,n,i,s,o){let a=new $t(n),c=Us({isTTY:i,untilActive:a.active,flags:n,out:s?.out},r,e,t,a);await He(t,e,n,a,c,o)}async function Hs(t,e,r,n,i,s,o){if(e.length===0)throw new Error("--watch requires at least one product_id (e.g. BTC-USD)");let a=new $t(n),c=qs({isTTY:i,untilActive:a.active,flags:n,out:s?.out},e,a);await He(t,r,n,a,c,o)}async function js(t,e,r,n,i,s,o){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 a=e[0],c=new $t(n),d=Bs({isTTY:i,untilActive:c.active,flags:n,out:s?.out},a,r,c);await He(t,r,n,c,d,o)}function xc(t,e){return new Promise(r=>{let n=()=>{},i=s=>{n(),r(s)};if(e)e.installSignalHandlers(()=>i(null));else{let s=()=>i(null),o=()=>i(null);n=()=>{process.off("SIGINT",s),process.off("SIGTERM",o)},process.on("SIGINT",s),process.on("SIGTERM",o)}t.then(i)})}function Ks(t,e,r,n){if(e.cleanup(),n?.cleanup(),!!t)switch(t.type){case"matched":Ys(JSON.stringify(t.event),r??{}),process.exitCode=0;break;case"timeout":process.stderr.write(`error: --until timed out
56
+ Available fields: ${u}`)}}let p=se(c);if(p.length>0&&e.length>0){let _=p.filter(u=>!e.includes(u));if(_.length>0)throw new Error(`Predicate references product${_.length>1?"s":""} not in watch: ${_.join(", ")}
57
+ Watching: ${e.join(", ")}`)}}let o=await Fc(r,i),a=!!process.stdout.isTTY;await Wc(n),s==="blotter"?await Ks(i,o,r,n,a):s==="watchlist"?await Qs(i,e,o,n,a):s==="ladder"&&await Js(i,e,o,n,a)}async function Ye(t,e,r,n,i,s){let o=n.start();await i.setup();let a=0,c;c=new Fe({channel:t,WebSocketClass:s,onEvent:p=>{let _=p;a=_.sequence_num??a;let u=String(_.timestamp??new Date().toISOString()),f=i.onData(_,a,u);if(f.length!==0){if(!i.screen&&!n.active)for(let k of f)Zs(k.line,r);if(n.active){for(let k of f)if(n.check(k.obj))return}}},onHeartbeat:()=>i.onHeartbeat(),onSequenceGap:()=>{let p=i.onGap();p&&(c.unsubscribe(p.resubscribe),c.subscribe(p.resubscribe,i.refreshJWT?i.refreshJWT():e))},onError:i.screen?void 0:p=>process.stderr.write(`ws error: ${p}
58
+ `),onStateChange:p=>{p===q.FAILED&&n.onFailed(),i.onConnState(p)},onDisconnect:()=>n.onDisconnect(),onReconnect:()=>n.onReconnect(),onReconnected:()=>i.onReconnected(),refreshJWT:i.refreshJWT}),c.connect(),c.subscribe(i.productIds,e);let d=await zc(o,i.screen);c.close(),Xs(d,i,r,n),d===null&&process.exit(process.exitCode??0)}async function Ks(t,e,r,n,i,s,o){let a=new Vt(n),c=Ws({isTTY:i,untilActive:a.active,flags:n,out:s?.out},r,e,t,a);await Ye(t,e,n,a,c,o)}async function Qs(t,e,r,n,i,s,o){if(e.length===0)throw new Error("--watch requires at least one product_id (e.g. BTC-USD)");let a=new Vt(n),c=$s({isTTY:i,untilActive:a.active,flags:n,out:s?.out},e,a);await Ye(t,r,n,a,c,o)}async function Js(t,e,r,n,i,s,o){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 a=e[0],c=new Vt(n),d=Vs({isTTY:i,untilActive:c.active,flags:n,out:s?.out},a,r,c);await Ye(t,r,n,c,d,o)}function zc(t,e){return new Promise(r=>{let n=()=>{},i=s=>{n(),r(s)};if(e)e.installSignalHandlers(()=>i(null));else{let s=()=>i(null),o=()=>i(null);n=()=>{process.off("SIGINT",s),process.off("SIGTERM",o)},process.on("SIGINT",s),process.on("SIGTERM",o)}t.then(i)})}function Xs(t,e,r,n){if(e.cleanup(),n?.cleanup(),!!t)switch(t.type){case"matched":Zs(JSON.stringify(t.event),r??{}),process.exitCode=0;break;case"timeout":process.stderr.write(`error: --until timed out
59
59
  `),process.exitCode=124;break;case"failed":process.stderr.write(`error: WebSocket connection failed permanently
60
60
  `),process.exitCode=2;break;case"disconnect_budget_exceeded":process.stderr.write(`error: cumulative disconnection exceeded ${Math.round(t.totalMs/1e3)}s
61
- `),process.exitCode=2;break}}function Ys(t,e){if(e.jq)try{let{applyJQ:r}=Ve,n=r(new TextEncoder().encode(t),e.jq);process.stdout.write(n+`
61
+ `),process.exitCode=2;break}}function Zs(t,e){if(e.jq)try{let{applyJQ:r}=je,n=r(new TextEncoder().encode(t),e.jq);process.stdout.write(n+`
62
62
  `)}catch(r){process.stderr.write(`jq error: ${r.message??r}
63
63
  `)}else process.stdout.write(t+`
64
- `)}async function wc(t){if(t.jq&&!Ve){Ve=await Promise.resolve().then(()=>(Vr(),Ws));try{let{applyJQ:e}=Ve;e(new TextEncoder().encode("{}"),t.jq)}catch(e){throw new Error(`Invalid --jq expression: ${e.message??e}`)}}}var vc,Rc,$s,$t,Sc,Ve,ce=I(()=>{"use strict";g();l();ie();ss();Le();Ar();os();xr();Ct();zs();vc=[...rt.flatMap(t=>t.actions),...Object.values(nt)];Rc=300*1e3,$s=3e4,$t=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?Sr(e.until):null,this.timeoutMs=e.untilTimeout?e.untilTimeout*1e3:null,this.requiredProducts=this.predicate?[...new Set(ne(this.predicate))]:[],this.signals=r??new Ue}get active(){return this.predicate!==null}get stale(){return this.signals.staleProducts(this.requiredProducts,$s)}start(){return new Promise(e=>{this.resolve=e,this.active&&this.timeoutMs!==null&&(this.timeoutTimer=setTimeout(()=>{this.settle({type:"timeout"})},this.timeoutMs))})}check(e){if(!this.predicate||this.settled)return!1;let r=e.product_id;r&&(this.signals.update(r,e),this.reportedStale.delete(r)&&process.stderr.write(`notice: ${r} recovered
65
- `));for(let n of this.requiredProducts)if(this.signals.hasSeen(n)&&this.signals.isStale(n,$s))return this.reportedStale.has(n)||(this.reportedStale.add(n),process.stderr.write(`warning: ${n} stale (no update for ${Math.round(this.signals.age(n)/1e3)}s)
66
- `)),!1;return Dt(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:He,runBlotter:Vs,runWatchlist:Hs,runLadder:js,handleResult:Ks};Ve=null});var je={};jt(je,{bodyBytes:()=>Uc,hasBody:()=>Fc,isFieldArg:()=>Bc,parseFields:()=>Lc,setNested:()=>Yr});import{readFileSync as Ac,openSync as Cc,readSync as Nc,closeSync as Gc}from"node:fs";function Lc(t,e=Dc){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(Mc(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{Yr(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)):Yr(r.body,n.slice(0,i),n.slice(i+1))}return r}function Mc(t){let e=t.indexOf(":");return e<=0||t.slice(0,e).includes("=")?!1:t[0]>="A"&&t[0]<="Z"}function Fc(t){return Object.keys(t.body).length>0||t.rawBody!==null}function Uc(t){return t.rawBody?t.rawBody:Object.keys(t.body).length===0?null:new TextEncoder().encode(JSON.stringify(t.body))}function Bc(t){return!!(t.includes("=")||t.startsWith("@")||t.startsWith("-")||t.indexOf(":")>0&&t[0]>="A"&&t[0]<="Z")}function Yr(t,e,r){let n=e.split("."),i=t;for(let s=0;s<n.length;s++){let o=n[s];if(qc.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 Dc,qc,Ke=I(()=>{"use strict";g();l();Dc={readFile(t){try{return Ac(t)}catch(e){throw new Error(`reading file ${t}: ${e.message}`)}},readStdin(){let t=[],e=Buffer.alloc(65536),r;try{r=Cc("/dev/stdin","r")}catch{throw new Error("reading stdin: cannot open")}try{let n;for(;(n=Nc(r,e))>0;)t.push(Buffer.from(e.subarray(0,n)))}catch{}return Gc(r),Buffer.concat(t)}};qc=new Set(["__proto__","constructor","prototype"])});var to={};jt(to,{outputResult:()=>zc});function zc(t,e){let r=JSON.stringify(t.data),n=t.status>=400;if(e)try{process.stdout.write($r(new TextEncoder().encode(r),e)+`
64
+ `)}async function Wc(t){if(t.jq&&!je){je=await Promise.resolve().then(()=>(jr(),js));try{let{applyJQ:e}=je;e(new TextEncoder().encode("{}"),t.jq)}catch(e){throw new Error(`Invalid --jq expression: ${e.message??e}`)}}}var Lc,Uc,Ys,Vt,Bc,je,ue=I(()=>{"use strict";g();l();oe();_s();Ue();Nr();us();wr();Ct();Hs();Lc=[...et.flatMap(t=>t.actions),...Object.values(rt)];Uc=300*1e3,Ys=3e4,Vt=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?xr(e.until):null,this.timeoutMs=e.untilTimeout?e.untilTimeout*1e3:null,this.requiredProducts=this.predicate?[...new Set(se(this.predicate))]:[],this.signals=r??new Be}get active(){return this.predicate!==null}get stale(){return this.signals.staleProducts(this.requiredProducts,Ys)}start(){return new Promise(e=>{this.resolve=e,this.active&&this.timeoutMs!==null&&(this.timeoutTimer=setTimeout(()=>{this.settle({type:"timeout"})},this.timeoutMs))})}check(e){if(!this.predicate||this.settled)return!1;let r=e.product_id;r&&(this.signals.update(r,e),this.reportedStale.delete(r)&&process.stderr.write(`notice: ${r} recovered
65
+ `));for(let n of this.requiredProducts)if(this.signals.hasSeen(n)&&this.signals.isStale(n,Ys))return this.reportedStale.has(n)||(this.reportedStale.add(n),process.stderr.write(`warning: ${n} stale (no update for ${Math.round(this.signals.age(n)/1e3)}s)
66
+ `)),!1;return Lt(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>Uc&&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))}};Bc={runSurface:Ye,runBlotter:Ks,runWatchlist:Qs,runLadder:Js,handleResult:Xs};je=null});var Ke={};Yt(Ke,{bodyBytes:()=>Xc,hasBody:()=>Jc,isFieldArg:()=>t_,parseFields:()=>Kc,setNested:()=>Jr});import{readFileSync as $c,openSync as Vc,readSync as Hc,closeSync as jc}from"node:fs";function Kc(t,e=Yc){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(Qc(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{Jr(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)):Jr(r.body,n.slice(0,i),n.slice(i+1))}return r}function Qc(t){let e=t.indexOf(":");return e<=0||t.slice(0,e).includes("=")?!1:t[0]>="A"&&t[0]<="Z"}function Jc(t){return Object.keys(t.body).length>0||t.rawBody!==null}function Xc(t){return t.rawBody?t.rawBody:Object.keys(t.body).length===0?null:new TextEncoder().encode(JSON.stringify(t.body))}function t_(t){return!!(t.includes("=")||t.startsWith("@")||t.startsWith("-")||t.indexOf(":")>0&&t[0]>="A"&&t[0]<="Z")}function Jr(t,e,r){let n=e.split("."),i=t;for(let s=0;s<n.length;s++){let o=n[s];if(Zc.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 Yc,Zc,Qe=I(()=>{"use strict";g();l();Yc={readFile(t){try{return $c(t)}catch(e){throw new Error(`reading file ${t}: ${e.message}`)}},readStdin(){let t=[],e=Buffer.alloc(65536),r;try{r=Vc("/dev/stdin","r")}catch{throw new Error("reading stdin: cannot open")}try{let n;for(;(n=Hc(r,e))>0;)t.push(Buffer.from(e.subarray(0,n)))}catch{}return jc(r),Buffer.concat(t)}};Zc=new Set(["__proto__","constructor","prototype"])});var io={};Yt(io,{outputResult:()=>e_});function e_(t,e){let r=JSON.stringify(t.data),n=t.status>=400;if(e)try{process.stdout.write(Hr(new TextEncoder().encode(r),e)+`
67
67
  `)}catch(i){process.stdout.write(r+`
68
68
  `),process.stderr.write(`jq error: ${i.message}
69
69
  `)}else n&&process.stdout.isTTY||(process.stdout.isTTY?process.stdout.write(JSON.stringify(t.data,null,2)+`
70
70
  `):process.stdout.write(r+`
71
71
  `));if(n){let i=t.data?.message||t.data?.errorMessage||r.slice(0,200),s=t.data?.hint,o=t.data?.correlationId,a=t.headers?.get("trace-id"),c=[a?`trace ${a}`:"",o?`correlation ${o}`:""].filter(Boolean).join(", ");throw new Error(`${i} (HTTP ${t.status})${c?` [${c}]`:""}${s?`
72
- Hint: ${s}`:""}`)}}var eo=I(()=>{"use strict";g();l();Vr()});g();l();g();l();tt();Xe();import{createInterface as ur}from"node:readline/promises";import{readFileSync as So}from"node:fs";function At(t,e={}){ir(()=>{let r=J();t(r),ot(r,{allowPlaintext:e.allowPlaintext})})}function xo(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 _r(t,e){if(!e&&!ln())throw new Error(`OS keychain unavailable; refusing to persist secrets for "${t}".
73
- Re-run with --allow-plaintext-secrets to write secrets to ${et()} (file is mode 0600), or install/unlock your OS keychain (macOS Keychain, libsecret on Linux, Windows Credential Manager).`)}async function vn(t,e){xo(e);let r=J();if(t.length===0){let _=[...new Set([...Object.keys(r.environments),...Object.keys(X)])].sort();if(_.length===0){process.stderr.write(`No environments configured. Run: coinbase env <name>
74
- `);return}let u=Math.max(14,..._.map(E=>E.length)),f=45,O=E=>(E.length>f?E.slice(0,f-3)+"...":E).padEnd(f);process.stdout.write(`${"Environment".padEnd(u)} ${"Brokerage API".padEnd(f)} ${"Agent API".padEnd(f)} Key
75
- `);for(let E of _){let x=r.environments[E]??{},w=Z(x,E),G=lt(x,E),F=Yt(x),Y=F?.type==="cdp_key"?F.key_id:"(no key)",R=Y.length>60?Y.slice(0,57)+"...":Y;process.stdout.write(`${E===r.env?"* ":" "}${E.padEnd(u)} ${O(w||"\u2014")} ${O(G||"\u2014")} ${R}
76
- `)}return}let n=t[0];if(e.remove){At(_=>{delete _.environments[n],_.env===n&&(_.env="")}),nr(n),process.stderr.write(`Removed ${n}.
77
- `);return}let i=r.environments[n]??{};if(e.status){Co(n,i);return}let s=(_,u)=>{i.auth={type:"cdp_key",key_id:_,key_secret:u}},o=()=>{e.url&&(i.url=e.url,ke(e.url)||process.stderr.write(`warning: custom brokerage URL does not match a known endpoint
78
- `)),e.brokerageApiUrl&&(i.endpoints={...i.endpoints,brokerageApi:e.brokerageApiUrl}),e.agentApiUrl&&(i.endpoints={...i.endpoints,agentApi:e.agentApiUrl})};if(e.keyFile){_r(n,!!e.allowPlaintextSecrets);let _=No(e.keyFile);s(_.keyId,_.keySecret),o(),At(u=>{u.environments[n]=i,u.env=n},{allowPlaintext:e.allowPlaintextSecrets}),process.stderr.write(`Loaded key from ${e.keyFile}. Switched to ${n}.
79
- `);return}if(e.keyId||e.keySecret||e.url||e.brokerageApiUrl||e.agentApiUrl){let _=Yt(i),u=_?.type==="cdp_key"?_.key_id:"",f=_?.type==="cdp_key"?_.key_secret:"";(e.keyId||e.keySecret)&&(_r(n,!!e.allowPlaintextSecrets),s(e.keyId??u,e.keySecret??f)),o(),At(O=>{O.environments[n]=i,O.env=n},{allowPlaintext:e.allowPlaintextSecrets}),process.stderr.write(`Saved and switched to ${n}.
80
- `);return}if(Yt(i)){At(_=>{_.env=n}),process.stderr.write(`Switched to ${n}.
81
- `);return}if(r.environments[n]){At(_=>{_.env=n}),process.stderr.write(`Switched to ${n} (no credentials yet).
72
+ Hint: ${s}`:""}`)}}var so=I(()=>{"use strict";g();l();jr()});g();l();g();l();tt();tr();import{createInterface as gr}from"node:readline/promises";import{readFileSync as Co}from"node:fs";function wt(t,e={}){or(()=>{let r=J();t(r),at(r,{allowPlaintext:e.allowPlaintext})})}function No(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 dr(t,e){if(!e&&!mn())throw new Error(`OS keychain unavailable; refusing to persist secrets for "${t}".
73
+ Re-run with --allow-plaintext-secrets to write secrets to ${nt()} (file is mode 0600), or install/unlock your OS keychain (macOS Keychain, libsecret on Linux, Windows Credential Manager).`)}async function Rn(t,e){No(e);let r=J();if(t.length===0){let _=[...new Set([...Object.keys(r.environments),...Object.keys(X)])].sort();if(_.length===0){process.stderr.write(`No environments configured. Run: coinbase env <name>
74
+ `);return}let u=Math.max(14,..._.map(E=>E.length)),f=45,k=E=>(E.length>f?E.slice(0,f-3)+"...":E).padEnd(f);process.stdout.write(`${"Environment".padEnd(u)} ${"Brokerage API".padEnd(f)} ${"Agent API".padEnd(f)} Key
75
+ `);for(let E of _){let A=r.environments[E]??{},x=Z(A,E),G=lt(A,E),U=Qt(A),K=U?.type==="cdp_key"?U.key_id:"(no key)",R=K.length>60?K.slice(0,57)+"...":K;process.stdout.write(`${E===r.env?"* ":" "}${E.padEnd(u)} ${k(x||"\u2014")} ${k(G||"\u2014")} ${R}
76
+ `)}return}let n=t[0];if(e.remove){wt(_=>{delete _.environments[n],_.env===n&&(_.env="")}),sr(n),process.stderr.write(`Removed ${n}.
77
+ `);return}let i=r.environments[n]??{};if(e.status){Lo(n,i);return}let s=(_,u)=>{i.auth={type:"cdp_key",key_id:_,key_secret:u}},o=()=>{e.url&&(i.url=e.url,ke(e.url)||process.stderr.write(`warning: custom brokerage URL does not match a known endpoint
78
+ `)),e.brokerageApiUrl&&(i.endpoints={...i.endpoints,brokerageApi:e.brokerageApiUrl}),e.agentApiUrl&&(i.endpoints={...i.endpoints,agentApi:e.agentApiUrl})};if(e.keyFile){dr(n,!!e.allowPlaintextSecrets);let _=Mo(e.keyFile);s(_.keyId,_.keySecret),o(),wt(u=>{u.environments[n]=i,u.env=n},{allowPlaintext:e.allowPlaintextSecrets}),process.stderr.write(`Loaded key from ${e.keyFile}. Switched to ${n}.
79
+ `);return}if(e.keyId||e.keySecret||e.url||e.brokerageApiUrl||e.agentApiUrl){let _=Qt(i),u=_?.type==="cdp_key"?_.key_id:"",f=_?.type==="cdp_key"?_.key_secret:"";(e.keyId||e.keySecret)&&(dr(n,!!e.allowPlaintextSecrets),s(e.keyId??u,e.keySecret??f)),o(),wt(k=>{k.environments[n]=i,k.env=n},{allowPlaintext:e.allowPlaintextSecrets}),process.stderr.write(`Saved and switched to ${n}.
80
+ `);return}if(Qt(i)){wt(_=>{_.env=n}),process.stderr.write(`Switched to ${n}.
81
+ `);return}if(r.environments[n]){wt(_=>{_.env=n}),process.stderr.write(`Switched to ${n} (no credentials yet).
82
82
  `),process.stderr.write(` CDP key: coinbase env ${n} --key-file path/to/key.json
83
- `);return}if(!process.stdout.isTTY)throw new Error(`environment "${n}" needs API keys. Run: coinbase env ${n} --key-id=... --key-secret=...`);_r(n,!!e.allowPlaintextSecrets);let c="",d="",p=ur({input:process.stdin,output:process.stderr});try{if(!c){let _=await p.question("API Key ID: ");if(!_.trim())throw new Error("API Key ID is required");c=_.trim()}if(!d){p.close();let _=await wo("API Key Secret: ");if(!_.trim())throw new Error("API Key Secret is required");d=_.trim(),p=ur({input:process.stdin,output:process.stderr})}if(s(c,d),!Z(i,n)){let _=await p.question("Brokerage API URL (optional): ");_.trim()&&(i.endpoints={...i.endpoints,brokerageApi:_.trim()})}if(!lt(i,n)){let _=await p.question("Agent API URL (optional): ");_.trim()&&(i.endpoints={...i.endpoints,agentApi:_.trim()})}}finally{p.close()}At(_=>{_.environments[n]=i,_.env=n},{allowPlaintext:e.allowPlaintextSecrets}),process.stderr.write(`Saved. Switched to ${n}.
84
- `)}function wo(t){return process.stderr.write(t),process.stdin.isTTY?new Promise(e=>{let r=process.stdin;r.setRawMode(!0),r.resume(),r.setEncoding("utf8");let n="",i=s=>{s===`
83
+ `);return}if(!process.stdout.isTTY)throw new Error(`environment "${n}" needs API keys. Run: coinbase env ${n} --key-id=... --key-secret=...`);dr(n,!!e.allowPlaintextSecrets);let c="",d="",p=gr({input:process.stdin,output:process.stderr});try{if(!c){let _=await p.question("API Key ID: ");if(!_.trim())throw new Error("API Key ID is required");c=_.trim()}if(!d){p.close();let _=await Go("API Key Secret: ");if(!_.trim())throw new Error("API Key Secret is required");d=_.trim(),p=gr({input:process.stdin,output:process.stderr})}if(s(c,d),!Z(i,n)){let _=await p.question("Brokerage API URL (optional): ");_.trim()&&(i.endpoints={...i.endpoints,brokerageApi:_.trim()})}if(!lt(i,n)){let _=await p.question("Agent API URL (optional): ");_.trim()&&(i.endpoints={...i.endpoints,agentApi:_.trim()})}}finally{p.close()}wt(_=>{_.environments[n]=i,_.env=n},{allowPlaintext:e.allowPlaintextSecrets}),process.stderr.write(`Saved. Switched to ${n}.
84
+ `)}function Go(t){return process.stderr.write(t),process.stdin.isTTY?new Promise(e=>{let r=process.stdin;r.setRawMode(!0),r.resume(),r.setEncoding("utf8");let n="",i=s=>{s===`
85
85
  `||s==="\r"||s===""?(r.setRawMode(!1),r.pause(),r.removeListener("data",i),process.stderr.write(`
86
- `),e(n)):s==="\x7F"||s==="\b"?n=n.slice(0,-1):s===""?process.exit(1):n+=s};r.on("data",i)}):new Promise(e=>{let r=ur({input:process.stdin});r.once("line",n=>{r.close(),e(n)})})}function Ao(t){return t?t.length<=12?"***":t.slice(0,8)+"\u2026"+t.slice(-4):"(none)"}function Co(t,e){(!e.auth||e.auth.type!=="cdp_key")&&(process.stderr.write(`Environment "${t}" has no stored credentials.
86
+ `),e(n)):s==="\x7F"||s==="\b"?n=n.slice(0,-1):s===""?process.exit(1):n+=s};r.on("data",i)}):new Promise(e=>{let r=gr({input:process.stdin});r.once("line",n=>{r.close(),e(n)})})}function Do(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.
87
87
  `),process.exit(1)),process.stdout.write(`env: ${t}
88
88
  `),process.stdout.write(`brokerage_api: ${Z(e,t)||"(unset)"}
89
89
  `),process.stdout.write(`agent_api: ${lt(e,t)||"(unset)"}
90
90
  `),process.stdout.write(`auth: cdp_key
91
- `),process.stdout.write(`key_id: ${Ao(e.auth.key_id)}
92
- `)}function No(t){let e;try{e=So(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();Ct();Pe();mr();tt();Ae();import{createInterface as xa}from"node:readline";g();l();function Ce(){let t=process.env.COINBASE_TRANSPORT;if(!t||t==="auto")return"auto";if(t==="brokerage")return"brokerage";if(t==="agent")return"agent";throw new Error(`invalid COINBASE_TRANSPORT value "${t}"; expected "auto", "agent", or "brokerage"`)}Se();g();l();tt();pt();function M(t,e=!1){return{content:[{type:"text",text:t}],isError:e}}function Ci(t,e){return t===e?`coinbase_${t.replace(/-/g,"_")}`:`coinbase_${t.replace(/-/g,"_")}_${e.replace(/[-\s]/g,"_")}`}function Ni(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 u of n.params){let f={type:u.type,description:u.description};u.enum&&(f.enum=u.enum),u.pattern&&(f.pattern=u.pattern),u.format&&(f.format=u.format),u.example!==void 0&&(f.example=u.example),u.default!==void 0&&(f.default=u.default),i[u.name]=f,u.required&&s.push(u.name)}let o=n.params.filter(u=>u.in==="body").length,a=n.params.filter(u=>u.in==="body"&&u.required).length,c=o>0?a>0?` (${o} fields, ${a} required)`:` (${o} fields)`:"",p=[...new Set(n.params.map(u=>u.oneOf).filter(u=>!!u))].map(u=>` (one of: ${u.split("|").join(", ")})`).join(""),_=n.description||n.summary;e.push({name:Ci(r.name,n.name),description:`${n.method} ${n.path}${_?" \u2014 "+_:""}${c}${p}`,inputSchema:{type:"object",properties:i,required:s.length>0?s:void 0}})}return e}function Gi(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 M(`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?D.stripGrpcPrefix(t.data.message):t.data.error;return M(`Error: ${e}`,!0)}return M(JSON.stringify(t.data,null,2))}function Ir(t){let e=wt(t,""),r=Object.keys(t.environments??{}),n=[`Active: ${e||"(none)"}`,`Configured: ${r.length>0?r.join(", "):"(none)"}`];return e||n.push(`
91
+ `),process.stdout.write(`key_id: ${Do(e.auth.key_id)}
92
+ `)}function Mo(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();Ct();Se();yr();tt();Ne();import{createInterface as Ba}from"node:readline";g();l();function Ge(){let t=process.env.COINBASE_TRANSPORT;if(!t||t==="auto")return"auto";if(t==="brokerage")return"brokerage";if(t==="agent")return"agent";throw new Error(`invalid COINBASE_TRANSPORT value "${t}"; expected "auto", "agent", or "brokerage"`)}xe();g();l();tt();mt();function M(t,e=!1){return{content:[{type:"text",text:t}],isError:e}}function re(t,e){return t===e?`coinbase_${t.replace(/-/g,"_")}`:`coinbase_${t.replace(/-/g,"_")}_${e.replace(/[-\s]/g,"_")}`}function Mi(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 u of n.params){let f={type:u.type,description:u.description};u.enum&&(f.enum=u.enum),u.pattern&&(f.pattern=u.pattern),u.format&&(f.format=u.format),u.example!==void 0&&(f.example=u.example),u.default!==void 0&&(f.default=u.default),i[u.name]=f,u.required&&s.push(u.name)}let o=n.params.filter(u=>u.in==="body").length,a=n.params.filter(u=>u.in==="body"&&u.required).length,c=o>0?a>0?` (${o} fields, ${a} required)`:` (${o} fields)`:"",p=[...new Set(n.params.map(u=>u.oneOf).filter(u=>!!u))].map(u=>` (one of: ${u.split("|").join(", ")})`).join(""),_=n.description||n.summary;e.push({name:re(r.name,n.name),description:`${n.method} ${n.path}${_?" \u2014 "+_:""}${c}${p}`,inputSchema:{type:"object",properties:i,required:s.length>0?s:void 0}})}return e}function Ui(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 M(`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?C.stripGrpcPrefix(t.data.message):t.data.error;return M(`Error: ${e}`,!0)}return M(JSON.stringify(t.data,null,2))}function vr(t){let e=xt(t,""),r=Object.keys(t.environments??{}),n=[`Active: ${e||"(none)"}`,`Configured: ${r.length>0?r.join(", "):"(none)"}`];return e||n.push(`
93
93
  Run: coinbase env <name> --key-id=... --key-secret=... to configure.`),M(n.join(`
94
- `))}function Di(t,e){if(!e)return M("Environment name is required.",!0);let r=Object.keys(t.environments??{});return r.length===0?M("No environments configured. Run: coinbase env <name> --key-id=... --key-secret=... to configure.",!0):t.environments[e]?{cfg:{...t,env:e}}:M(`Unknown environment: "${e}". Available environments: ${r.join(", ")}`,!0)}function Li(t){return Ir(t)}function Ta(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 c=a.required?" (required)":"",d=a.description?` \u2014 ${a.description}`:"";n.push(` ${a.name} (${a.type})${c}${d}`)}}let o=r.filter(a=>a.in==="query");if(o.length>0){n.push("","Query parameters:");for(let a of o){let c=a.description?` \u2014 ${a.description}`:"";n.push(` ${a.name} (${a.type})${c}`)}}return M(n.join(`
95
- `))}function Mi(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(c=>c.name===e);return a?{act:a,toolName:Ci(o.name,a.name)}:M(`Unknown action: ${e}. Available for ${t}: ${o.actions.map(c=>c.name).join(", ")}`,!0)}}let i=r.map(o=>o.name),s=n?Object.keys(n):[];return M(`Not found. Resources: ${i.join(", ")}. Top-level actions: ${s.join(", ")}`,!0)}function Fi(t,e,r,n){if(!e)return M("action is required",!0);let i=Mi(t,e,r,n);return"isError"in i?i:Ta(i.act,i.toolName)}function Sa(t){let e=(t.params??[]).filter(i=>i.in==="body");if(e.length===0)return M("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 M(`Template:
94
+ `))}function Fi(t,e){if(!e)return M("Environment name is required.",!0);let r=Object.keys(t.environments??{});return r.length===0?M("No environments configured. Run: coinbase env <name> --key-id=... --key-secret=... to configure.",!0):t.environments[e]?{cfg:{...t,env:e}}:M(`Unknown environment: "${e}". Available environments: ${r.join(", ")}`,!0)}function qi(t){return vr(t)}function Fa(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 c=a.required?" (required)":"",d=a.description?` \u2014 ${a.description}`:"";n.push(` ${a.name} (${a.type})${c}${d}`)}}let o=r.filter(a=>a.in==="query");if(o.length>0){n.push("","Query parameters:");for(let a of o){let c=a.description?` \u2014 ${a.description}`:"";n.push(` ${a.name} (${a.type})${c}`)}}return M(n.join(`
95
+ `))}function Bi(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(c=>c.name===e);return a?{act:a,toolName:re(o.name,a.name)}:M(`Unknown action: ${e}. Available for ${t}: ${o.actions.map(c=>c.name).join(", ")}`,!0)}}let i=r.map(o=>o.name),s=n?Object.keys(n):[];return M(`Not found. Resources: ${i.join(", ")}. Top-level actions: ${s.join(", ")}`,!0)}function zi(t,e,r,n){if(!e)return M("action is required",!0);let i=Bi(t,e,r,n);return"isError"in i?i:Fa(i.act,i.toolName)}function qa(t){let e=(t.params??[]).filter(i=>i.in==="body");if(e.length===0)return M("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 M(`Template:
96
96
  ${JSON.stringify(r,null,2)}
97
97
 
98
98
  Fields:
99
99
  ${n.join(`
100
- `)}`)}function Ui(t,e,r,n){if(!e)return M("action is required",!0);let i=Mi(t,e,r,n);return"isError"in i?i:Sa(i.act)}function Bi(t){process.stdout.write(JSON.stringify({jsonrpc:"2.0",...t})+`
101
- `)}function ee(t,e){Bi({id:t,result:e})}function re(t,e,r){Bi({id:t,error:{code:e,message:r}})}function wa(){return rt}async function Aa(t,e){let r=wa();if(t==="coinbase_env")return Ir(J());if(t==="coinbase_set_env"){let n=J(),i=Di(n,e.name);return"isError"in i?i:(ot(i.cfg),sr(),Li(i.cfg))}return t==="coinbase_help"?Fi(String(e.resource??""),String(e.action??""),r,nt):t==="coinbase_template"?Ui(String(e.resource??""),String(e.action??""),r,nt):Ca(t,e)}async function Ca(t,e){let r=t.replace(/^coinbase_/,"");if(!Re(r))return M(`Unknown tool: ${t}`,!0);let n=J(),i;try{i=Jt(n,"")}catch(a){return M(`Environment error: ${a.message}
100
+ `)}`)}function Wi(t,e,r,n){if(!e)return M("action is required",!0);let i=Bi(t,e,r,n);return"isError"in i?i:qa(i.act)}var za=(()=>{let t={},e=(r,n)=>{let i=t[r];if(i!==void 0&&i!==n)throw new Error(`operationIdForTool collision: tool "${r}" maps to both "${i}" and "${n}"`);t[r]=n};for(let r of Object.values(rt))e(re(r.name,r.name),r.id);for(let r of et)for(let n of r.actions)e(re(r.name,n.name),n.id);return t})();function Vi(t){process.stdout.write(JSON.stringify({jsonrpc:"2.0",...t})+`
101
+ `)}function ne(t,e){Vi({id:t,result:e})}function ie(t,e,r){Vi({id:t,error:{code:e,message:r}})}function Wa(){return et}async function $a(t,e){let r=Wa();if(t==="coinbase_env")return vr(J());if(t==="coinbase_set_env"){let n=J(),i=Fi(n,e.name);return"isError"in i?i:(at(i.cfg),ar(),qi(i.cfg))}return t==="coinbase_help"?zi(String(e.resource??""),String(e.action??""),r,rt):t==="coinbase_template"?Wi(String(e.resource??""),String(e.action??""),r,rt):Va(t,e)}async function Va(t,e){let r=za[t];if(!r||!Te(r))return M(`Unknown tool: ${t}`,!0);let n=J(),i;try{i=Xt(n,"")}catch(a){return M(`Environment error: ${a.message}
102
102
 
103
- Run: coinbase env <name> --key-id=... --key-secret=...`,!0)}let{name:s,env:o}=i;try{let a=await Qt(s,o),c={envName:s,env:o,baseURL:Z(o,s),doRequest:p=>we({...p,...a}),transport:Ce()},d=await Gt(r,e,c);return Gi(d)}catch(a){return M(`Request failed: ${a.message}`,!0)}}var Na={name:"coinbase",version:ct},Ga={tools:{}},kr=null;function qi(){if(!kr){let t=[...rt];for(let[e,r]of Object.entries(nt))t.push({name:e,actions:[r]});kr=Ni(t)}return kr}async function Da(t){let{id:e,method:r,params:n}=t;switch(r){case"initialize":ee(e,{protocolVersion:"2024-11-05",serverInfo:Na,capabilities:Ga});break;case"notifications/initialized":break;case"tools/list":ee(e,{tools:qi()});break;case"tools/call":{let{name:i,arguments:s}=n??{};if(!i){re(e,-32602,"Missing tool name");return}if(!qi().find(a=>a.name===i)){re(e,-32602,`Unknown tool: ${i}`);return}try{let a=await Aa(i,s??{});ee(e,a)}catch(a){ee(e,M(`Internal error: ${a.message}`,!0))}break}case"ping":ee(e,{});break;default:e!=null&&re(e,-32601,`Method not found: ${r}`);break}}function zi(){let t=xa({input:process.stdin,terminal:!1}),e=new Set;t.on("line",r=>{if(r.trim())try{let n=JSON.parse(r),i=Da(n).catch(s=>{process.stderr.write(`MCP error: ${s.message}
104
- `),n.id!=null&&re(n.id,-32603,s.message)}).finally(()=>e.delete(i));e.add(i)}catch{re(null,-32700,"Parse error")}}),t.on("close",async()=>{await Promise.all(e),process.exit(0)}),process.stderr.write(`coinbase MCP server v${ct} ready
105
- `)}g();l();tt();function Wi(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=Xt(e,r.slice(0,i),r.slice(i+1))}else r?n=Xt(e,r):n=Xt(e);ot(e),process.stderr.write(`Cleared ${n} history ${n===1?"entry":"entries"}.
106
- `);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[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.
103
+ Run: coinbase env <name> --key-id=... --key-secret=...`,!0)}let{name:s,env:o}=i;try{let a=await Jt(s,o),c={envName:s,env:o,baseURL:Z(o,s),doRequest:p=>Ce({...p,...a}),transport:Ge()},d=await Dt(r,e,c);return Ui(d)}catch(a){return M(`Request failed: ${a.message}`,!0)}}var Ha={name:"coinbase",version:ct},ja={tools:{}},kr=null;function $i(){if(!kr){let t=[...et];for(let[e,r]of Object.entries(rt))t.push({name:e,actions:[r]});kr=Mi(t)}return kr}async function Ya(t){let{id:e,method:r,params:n}=t;switch(r){case"initialize":ne(e,{protocolVersion:"2024-11-05",serverInfo:Ha,capabilities:ja});break;case"notifications/initialized":break;case"tools/list":ne(e,{tools:$i()});break;case"tools/call":{let{name:i,arguments:s}=n??{};if(!i){ie(e,-32602,"Missing tool name");return}if(!$i().find(a=>a.name===i)){ie(e,-32602,`Unknown tool: ${i}`);return}try{let a=await $a(i,s??{});ne(e,a)}catch(a){ne(e,M(`Internal error: ${a.message}`,!0))}break}case"ping":ne(e,{});break;default:e!=null&&ie(e,-32601,`Method not found: ${r}`);break}}function Hi(){let t=Ba({input:process.stdin,terminal:!1}),e=new Set;t.on("line",r=>{if(r.trim())try{let n=JSON.parse(r),i=Ya(n).catch(s=>{process.stderr.write(`MCP error: ${s.message}
104
+ `),n.id!=null&&ie(n.id,-32603,s.message)}).finally(()=>e.delete(i));e.add(i)}catch{ie(null,-32700,"Parse error")}}),t.on("close",async()=>{await Promise.all(e),process.exit(0)}),process.stderr.write(`coinbase MCP server v${ct} ready
105
+ `)}g();l();tt();function ji(t){let e=J();if(t.length===0)return Ka(e);if(t[0]==="clear"){let r=t[1],n;if(r&&r.includes(".")){let i=r.indexOf(".");n=Zt(e,r.slice(0,i),r.slice(i+1))}else r?n=Zt(e,r):n=Zt(e);at(e),process.stderr.write(`Cleared ${n} history ${n===1?"entry":"entries"}.
106
+ `);return}throw new Error("usage: coinbase history [clear [env.action]]")}function Ka(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.
107
107
  `);return}e.sort((i,s)=>s.lastUsed.localeCompare(i.lastUsed));let r=Math.max(...e.map(i=>i.env.length))+2,n=Math.max(...e.map(i=>i.action.length))+2;for(let i of e){let s=i.lastUsed.slice(0,10);process.stdout.write(`${i.env.padEnd(r)}${i.action.padEnd(n)}${s} ${i.fields.join(", ")}
108
- `)}}g();l();tt();import{readFileSync as Ki,writeFileSync as Ma,mkdirSync as Yi,readdirSync as Qi,existsSync as Ot,cpSync as Fa,rmSync as Ua}from"node:fs";import $i,{join as _t,resolve as Vi}from"node:path";import{fileURLToPath as qa}from"node:url";import{homedir as Hi}from"node:os";import{createInterface as ji}from"node:readline";function Or(){try{return JSON.parse(Ki(et(),"utf8"))}catch{return{}}}function vr(t){let e=gt();Yi(e,{recursive:!0,mode:448}),Ma(et(),JSON.stringify(t,null,2)+`
109
- `,{mode:384})}function Ji(){let t=$i.dirname(qa(import.meta.url));return $i.join(t,"..","skills")}function Ba(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 Xi(t){let e=t??Ji();if(!Ot(e))return[];let r=[];for(let n of Qi(e,{withFileTypes:!0})){if(!n.isDirectory())continue;let i=_t(e,n.name,"SKILL.md");if(!Ot(i))continue;let s=Ki(i,"utf8"),o=Ba(s);r.push({name:o.name||n.name,description:o.description,dir:_t(e,n.name)})}return r.sort((n,i)=>n.name.localeCompare(i.name))}function za(t,e){if(!Ot(t))return 0;Yi(e,{recursive:!0});let r=0;for(let n of Qi(t,{withFileTypes:!0})){if(!n.isDirectory())continue;let i=_t(t,n.name,"SKILL.md");if(!Ot(i))continue;let s=_t(e,n.name);Fa(_t(t,n.name),s,{recursive:!0,force:!0}),r++}return r}async function Wa(){let t=process.platform==="win32"?_t(process.env.USERPROFILE??Hi(),".claude","skills"):_t(Hi(),".claude","skills");process.stderr.write(`Where should skills be installed?
108
+ `)}}g();l();tt();import{readFileSync as Xi,writeFileSync as Qa,mkdirSync as Zi,readdirSync as ts,existsSync as kt,cpSync as Ja,rmSync as Xa}from"node:fs";import Yi,{join as _t,resolve as Ki}from"node:path";import{fileURLToPath as Za}from"node:url";import{homedir as Qi}from"node:os";import{createInterface as Ji}from"node:readline";function Pr(){try{return JSON.parse(Xi(nt(),"utf8"))}catch{return{}}}function Rr(t){let e=gt();Zi(e,{recursive:!0,mode:448}),Qa(nt(),JSON.stringify(t,null,2)+`
109
+ `,{mode:384})}function es(){let t=Yi.dirname(Za(import.meta.url));return Yi.join(t,"..","skills")}function tc(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 rs(t){let e=t??es();if(!kt(e))return[];let r=[];for(let n of ts(e,{withFileTypes:!0})){if(!n.isDirectory())continue;let i=_t(e,n.name,"SKILL.md");if(!kt(i))continue;let s=Xi(i,"utf8"),o=tc(s);r.push({name:o.name||n.name,description:o.description,dir:_t(e,n.name)})}return r.sort((n,i)=>n.name.localeCompare(i.name))}function ec(t,e){if(!kt(t))return 0;Zi(e,{recursive:!0});let r=0;for(let n of ts(t,{withFileTypes:!0})){if(!n.isDirectory())continue;let i=_t(t,n.name,"SKILL.md");if(!kt(i))continue;let s=_t(e,n.name);Ja(_t(t,n.name),s,{recursive:!0,force:!0}),r++}return r}async function rc(){let t=process.platform==="win32"?_t(process.env.USERPROFILE??Qi(),".claude","skills"):_t(Qi(),".claude","skills");process.stderr.write(`Where should skills be installed?
110
110
  `),process.stderr.write(`Tip: Not sure where your agent looks for skills? Ask your agent.
111
111
 
112
112
  `),process.stderr.write(` 1) ${t} User \u2014 available across all projects (Recommended)
113
113
  `),process.stderr.write(` 2) Other Specify a custom path
114
114
 
115
- `);let e=ji({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=ji({input:process.stdin,output:process.stderr}),i=await new Promise(s=>{n.question("? Path: ",o=>{n.close(),s(o.trim())})});return i?Vi(i):(process.stderr.write(`No path provided, using default.
116
- `),t)}return Vi(r)}async function $a(t){let e=Or(),r=t||e.settings?.skillsDir,n=!1;r||(process.stdin.isTTY||(process.stderr.write(`error: no skills directory configured.
115
+ `);let e=Ji({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=Ji({input:process.stdin,output:process.stderr}),i=await new Promise(s=>{n.question("? Path: ",o=>{n.close(),s(o.trim())})});return i?Ki(i):(process.stderr.write(`No path provided, using default.
116
+ `),t)}return Ki(r)}async function nc(t){let e=Pr(),r=t||e.settings?.skillsDir,n=!1;r||(process.stdin.isTTY||(process.stderr.write(`error: no skills directory configured.
117
117
  Run: coinbase skills add --dir <path>
118
- `),process.exit(1)),r=await Wa(),n=!0),(!e.settings?.skillsDir||t&&e.settings.skillsDir!==r)&&(e.settings||(e.settings={}),e.settings.skillsDir=r,vr(e));let i=Ji(),s=za(i,r);process.stderr.write(`Installed ${s} skills to ${r}.
118
+ `),process.exit(1)),r=await rc(),n=!0),(!e.settings?.skillsDir||t&&e.settings.skillsDir!==r)&&(e.settings||(e.settings={}),e.settings.skillsDir=r,Rr(e));let i=es(),s=ec(i,r);process.stderr.write(`Installed ${s} skills to ${r}.
119
119
  `),n&&process.stderr.write(`Skills will auto-update on future installs.
120
- `)}function Va(){let e=Or().settings?.skillsDir,r=Xi();if(r.length===0){process.stderr.write(`No bundled skills found.
120
+ `)}function ic(){let e=Pr().settings?.skillsDir,r=rs();if(r.length===0){process.stderr.write(`No bundled skills found.
121
121
  `);return}let n=Math.max(...r.map(i=>i.name.length),4);process.stderr.write(`${"Name".padEnd(n+2)}${"Installed".padEnd(12)}Description
122
122
  `),process.stderr.write(`${"\u2500".repeat(n+2)}${"\u2500".repeat(12)}${"\u2500".repeat(40)}
123
- `);for(let i of r){let o=e&&Ot(_t(e,i.name,"SKILL.md"))?"yes":"no";process.stderr.write(`${i.name.padEnd(n+2)}${o.padEnd(12)}${i.description}
123
+ `);for(let i of r){let o=e&&kt(_t(e,i.name,"SKILL.md"))?"yes":"no";process.stderr.write(`${i.name.padEnd(n+2)}${o.padEnd(12)}${i.description}
124
124
  `)}process.stderr.write(`
125
125
  ${r.length} skills available.`),e?process.stderr.write(` Installed to: ${e}`):process.stderr.write(" Run: coinbase skills add"),process.stderr.write(`
126
- `)}function Ha(){let t=Or(),e=t.settings?.skillsDir;if(!e){process.stderr.write(`No skills directory configured. Nothing to remove.
127
- `);return}if(!Ot(e)){process.stderr.write(`Skills directory not found: ${e}
128
- `),t.settings&&delete t.settings.skillsDir,vr(t),process.stderr.write(`Cleared skillsDir from config.
129
- `);return}let r=Xi(),n=0;for(let i of r){let s=_t(e,i.name);Ot(s)&&(Ua(s,{recursive:!0,force:!0}),n++)}t.settings&&delete t.settings.skillsDir,vr(t),process.stderr.write(`Removed ${n} skills from ${e}.
126
+ `)}function sc(){let t=Pr(),e=t.settings?.skillsDir;if(!e){process.stderr.write(`No skills directory configured. Nothing to remove.
127
+ `);return}if(!kt(e)){process.stderr.write(`Skills directory not found: ${e}
128
+ `),t.settings&&delete t.settings.skillsDir,Rr(t),process.stderr.write(`Cleared skillsDir from config.
129
+ `);return}let r=rs(),n=0;for(let i of r){let s=_t(e,i.name);kt(s)&&(Xa(s,{recursive:!0,force:!0}),n++)}t.settings&&delete t.settings.skillsDir,Rr(t),process.stderr.write(`Removed ${n} skills from ${e}.
130
130
  `),process.stderr.write(`Cleared skillsDir from config.
131
- `)}async function Zi(t){let e=t[0];if(!e||e==="-h"||e==="--help"){process.stderr.write(`Manage CDP agent skills
131
+ `)}async function ns(t){let e=t[0];if(!e||e==="-h"||e==="--help"){process.stderr.write(`Manage CDP agent skills
132
132
 
133
133
  Usage:
134
134
  coinbase skills add Install/update skills to your skills directory
@@ -136,29 +136,29 @@ Usage:
136
136
  coinbase skills list List available skills from this package
137
137
  coinbase skills remove Remove installed skills and clear config
138
138
 
139
- `);return}let r,n=t.slice(1);for(let i=0;i<n.length;i++)if(n[i]==="--dir"&&n[i+1]){r=n[++i];break}else if(n[i].startsWith("--dir=")){r=n[i].slice(6);break}switch(e){case"add":await $a(r);break;case"list":Va();break;case"remove":Ha();break;default:process.stderr.write(`error: unknown skills subcommand: ${e}
139
+ `);return}let r,n=t.slice(1);for(let i=0;i<n.length;i++)if(n[i]==="--dir"&&n[i+1]){r=n[++i];break}else if(n[i].startsWith("--dir=")){r=n[i].slice(6);break}switch(e){case"add":await nc(r);break;case"list":ic();break;case"remove":sc();break;default:process.stderr.write(`error: unknown skills subcommand: ${e}
140
140
  Run: coinbase skills --help
141
- `),process.exit(1)}}g();l();Ct();g();l();Ne();function Ka(t,e,r){return r?`\x1B]8;;${e}\x07\x1B[4m${t}\x1B[24m\x1B]8;;\x07`:`${t} (${e})`}function es(t,e=ts){return t.replace(/\[([^\]]+)\]\(([^)]+)\)/g,(r,n,i)=>Ka(n,i,e))}function Rr(t){return t.replace(/\*\*(.+?)\*\*/g,"$1").replace(/__(.+?)__/g,"$1").replace(/\*(.+?)\*/g,"$1").replace(/_(.+?)_/g,"$1").replace(/\[([^\]]+)\]\([^)]+\)/g,"$1").replace(/^#{1,6}\s+/gm,"")}function rs(t,e){let r=e??process.stdout.columns??100;return t.replace(/\r\n/g,`
141
+ `),process.exit(1)}}g();l();Ct();g();l();De();function ac(t,e,r){return r?`\x1B]8;;${e}\x07\x1B[4m${t}\x1B[24m\x1B]8;;\x07`:`${t} (${e})`}function ss(t,e=is){return t.replace(/\[([^\]]+)\]\(([^)]+)\)/g,(r,n,i)=>ac(n,i,e))}function Tr(t){return t.replace(/\*\*(.+?)\*\*/g,"$1").replace(/__(.+?)__/g,"$1").replace(/\*(.+?)\*/g,"$1").replace(/_(.+?)_/g,"$1").replace(/\[([^\]]+)\]\([^)]+\)/g,"$1").replace(/^#{1,6}\s+/gm,"")}function os(t,e){let r=e??process.stdout.columns??100;return t.replace(/\r\n/g,`
142
142
  `).trim().split(`
143
- `).flatMap(n=>{n=Rr(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(`
143
+ `).flatMap(n=>{n=Tr(n).replace(/^\s*\*\s+/," - ").replace(/^\s*(\d+)\.\s+/," $1. ");let i=[];for(;n.length>r;){let s=n.lastIndexOf(" ",r);s<=0&&(s=r),i.push(n.slice(0,s)),n=n.slice(s+1)}return i.push(n),i}).join(`
144
144
  `)+`
145
- `}g();l();Ne();function Ge(t,e,r,n){let i=n??e.length,s=Math.max(20,(process.stdout.columns||80)-i),o=r.split(" "),a="",c=!0;for(let d of o){let p=mt(d),_=mt(a),u=d.includes("\x1B]8;;");(_+p+1>s||u&&_>0&&_+p+1>s*.6)&&a.length>0&&(t.write((c?e:" ".repeat(i))+a.trimEnd()+`
145
+ `}g();l();De();function Le(t,e,r,n){let i=n??e.length,s=Math.max(20,(process.stdout.columns||80)-i),o=r.split(" "),a="",c=!0;for(let d of o){let p=ft(d),_=ft(a),u=d.includes("\x1B]8;;");(_+p+1>s||u&&_>0&&_+p+1>s*.6)&&a.length>0&&(t.write((c?e:" ".repeat(i))+a.trimEnd()+`
146
146
  `),a="",c=!1),a+=(a?" ":"")+d}a&&t.write((c?e:" ".repeat(i))+a.trimEnd()+`
147
- `)}xr();ie();ce();function jr(){return rt}function Qs(t){return On.has(t)}function Js(t,e,r){for(let n of e.fields){let i=e.nested?.[n];t.write(`${r}${n}
148
- `),i&&Js(t,i,r+" ")}}function Kr(t,e){let r=process.stderr,n=it(e.id),i=n?bt(n):null;r.write(`${e.summary||e.name}
147
+ `)}wr();oe();ue();function Kr(){return et}function to(t){return Tn.has(t)}function eo(t,e,r){for(let n of e.fields){let i=e.nested?.[n];t.write(`${r}${n}
148
+ `),i&&eo(t,i,r+" ")}}function Qr(t,e){let r=process.stderr,n=st(e.id),i=n?ht(n):null;r.write(`${e.summary||e.name}
149
149
  `),e.description&&r.write(`
150
- `+rs(e.description));let s=t===e.name?`coinbase ${e.name}`:`coinbase ${t} ${e.name}`;for(let _ of e.pathParams)s+=` <${_}>`;r.write(`
150
+ `+os(e.description));let s=t===e.name?`coinbase ${e.name}`:`coinbase ${t} ${e.name}`;for(let _ of e.pathParams)s+=` <${_}>`;r.write(`
151
151
  Usage:
152
152
  ${s} [fields...]
153
153
  `);let o=e.params??[],a=o.filter(_=>_.in==="path");if(a.length>0){r.write(`
154
154
  Arguments:
155
- `);let _=Math.max(...a.map(u=>u.name.length));for(let u of a){let f=` <${u.name}>${" ".repeat(Math.max(1,_-u.name.length+2))}${u.type}${u.required?" required":""} `,O=/[.!?]$/.test(u.description)?u.description:`${u.description}.`,E=i==="watchlist"?`${O} With --watch, accepts multiple comma-separated pairs (e.g. BTC-USD,ETH-USD).`:u.description;Ge(r,f,E)}}let c=o.filter(_=>_.in==="body");if(c.length>0){r.write(`
155
+ `);let _=Math.max(...a.map(u=>u.name.length));for(let u of a){let f=` <${u.name}>${" ".repeat(Math.max(1,_-u.name.length+2))}${u.type}${u.required?" required":""} `,k=/[.!?]$/.test(u.description)?u.description:`${u.description}.`,E=i==="watchlist"?`${k} With --watch, accepts multiple comma-separated pairs (e.g. BTC-USD,ETH-USD).`:u.description;Le(r,f,E)}}let c=o.filter(_=>_.in==="body");if(c.length>0){r.write(`
156
156
  Fields:
157
- `);let _=Math.max(...c.map(u=>u.name.length));for(let u of c){let f=u.required?"required":"",O=" ".repeat(Math.max(1,_-u.name.length+2)),E=" ".repeat(Math.max(1,8-u.type.length)),x=f?" ":" ",w=u.type==="array"||u.type==="object"?" (use :=json)":"",G=es(Rr(u.description)),F=` ${u.name}${O}${u.type}${E}${f}${x}`;Ge(r,F,G+w)}}let d=o.filter(_=>_.in==="query");if(d.length>0){r.write(`
157
+ `);let _=Math.max(...c.map(u=>u.name.length));for(let u of c){let f=u.required?"required":"",k=" ".repeat(Math.max(1,_-u.name.length+2)),E=" ".repeat(Math.max(1,8-u.type.length)),A=f?" ":" ",x=u.type==="array"||u.type==="object"?" (use :=json)":"",G=ss(Tr(u.description)),U=` ${u.name}${k}${u.type}${E}${f}${A}`;Le(r,U,G+x)}}let d=o.filter(_=>_.in==="query");if(d.length>0){r.write(`
158
158
  Query params (use == syntax):
159
- `);let _=Math.max(...d.map(u=>u.name.length));for(let u of d){let f=u.description;u.enum?.length&&(f+=(f?" ":"")+`[${u.enum.join(", ")}]`);let O=` ${u.name}${" ".repeat(Math.max(1,_-u.name.length+2))}${u.type} `;Ge(r,O,f)}}e.responseFields&&(r.write(`
159
+ `);let _=Math.max(...d.map(u=>u.name.length));for(let u of d){let f=u.description;u.enum?.length&&(f+=(f?" ":"")+`[${u.enum.join(", ")}]`);let k=` ${u.name}${" ".repeat(Math.max(1,_-u.name.length+2))}${u.type} `;Le(r,k,f)}}e.responseFields&&(r.write(`
160
160
  Response:
161
- `),Js(r,e.responseFields," "));let p=c.length>0;if(r.write(`
161
+ `),eo(r,e.responseFields," "));let p=c.length>0;if(r.write(`
162
162
  Flags:
163
163
  `),p&&r.write(` --template Show request body template from spec
164
164
  `),r.write(` --dry-run Preview request without sending
@@ -167,17 +167,17 @@ Flags:
167
167
  `),e.streamable&&r.write(` --paginate Auto-paginate using nextPageToken
168
168
  `),i!==null&&(r.write(` --watch Live stream via WebSocket
169
169
  `),e.watchFields&&(r.write(`
170
- `+is(e.watchFields)+`
170
+ `+cs(e.watchFields)+`
171
171
  `),r.write(` --until-timeout <s> Exit 124 if predicate not matched within N seconds
172
172
  `))),p||d.length>0){r.write(`
173
173
  Example:
174
174
  `+s);for(let _ of c)_.example!==void 0&&r.write(` ${_.name}=${_.example}`);for(let _ of d)_.example!==void 0&&r.write(` ${_.name}==${_.example}`);r.write(`
175
- `)}}function Xs(t){let e=rt.find(n=>n.name===t);e||(process.stderr.write(`error: unknown resource: ${t}
175
+ `)}}function ro(t){let e=et.find(n=>n.name===t);e||(process.stderr.write(`error: unknown resource: ${t}
176
176
  Run: coinbase --help
177
177
  `),process.exit(1)),process.stderr.write(`Manage ${e.name}
178
178
 
179
179
  Available actions:
180
- `);let r=e.actions.some(n=>{let i=it(n.id);return i&&bt(i)!==null});for(let n of e.actions){let i=it(n.id),o=(i?bt(i):null)!==null?" [--watch]":"",a=n.pathParams.map(c=>` <${c}>`).join("");process.stderr.write(` coinbase ${e.name} ${n.name}${a}${o} ${n.summary}
180
+ `);let r=e.actions.some(n=>{let i=st(n.id);return i&&ht(i)!==null});for(let n of e.actions){let i=st(n.id),o=(i?ht(i):null)!==null?" [--watch]":"",a=n.pathParams.map(c=>` <${c}>`).join("");process.stderr.write(` coinbase ${e.name} ${n.name}${a}${o} ${n.summary}
181
181
  `)}process.stderr.write(`
182
182
  Flags:
183
183
  --template Show request body template from spec
@@ -185,41 +185,41 @@ Flags:
185
185
  --edit Open request body in $EDITOR
186
186
  --jq <expr> jq filter expression for response
187
187
  `),r&&process.stderr.write(` --watch Live stream watchable actions via WebSocket (add --until <predicate> to exit on a condition)
188
- `)}ie();ce();g();l();Pe();g();l();var Zs=t=>t?.has_next===!1?null:t?.cursor||null;tt();Ae();ie();function Wc(t,e,r,n){for(let i of e){let s=r[i];if(typeof s=="string"&&s.includes(",")){let o=t.replace(/_/g," ");return`'${s}' looks like multiple values, but \`coinbase ${o}\` takes a single ${i}.`+(n?`
188
+ `)}oe();ue();g();l();Se();g();l();var no=t=>t?.has_next===!1?null:t?.cursor||null;tt();Ne();oe();function r_(t,e,r,n){for(let i of e){let s=r[i];if(typeof s=="string"&&s.includes(",")){let o=t.replace(/_/g," ");return`'${s}' looks like multiple values, but \`coinbase ${o}\` takes a single ${i}.`+(n?`
189
189
  To stream several live, add --watch:
190
- coinbase ${o} ${s} --watch`:"")}}return null}function ro(t){return t.history!=="disabled"}async function Qr(t,e,r,n){if(r.flags.template){let k=e.template??{};process.stdout.write(JSON.stringify(k,null,2)+`
191
- `);return}let i=[],s=[],{isFieldArg:o}=await Promise.resolve().then(()=>(Ke(),je));for(let k of r.args)i.length<e.pathParams.length&&!o(k)?i.push(k):s.push(k);if(i.length<e.pathParams.length){let k=e.pathParams.slice(i.length);throw new Error(`Missing argument(s): ${k.map(T=>`<${T}>`).join(" ")}
190
+ coinbase ${o} ${s} --watch`:"")}}return null}function oo(t){return t.history!=="disabled"}async function Xr(t,e,r,n){if(r.flags.template){let O=e.template??{};process.stdout.write(JSON.stringify(O,null,2)+`
191
+ `);return}let i=[],s=[],{isFieldArg:o}=await Promise.resolve().then(()=>(Qe(),Ke));for(let O of r.args)i.length<e.pathParams.length&&!o(O)?i.push(O):s.push(O);if(i.length<e.pathParams.length){let O=e.pathParams.slice(i.length);throw new Error(`Missing argument(s): ${O.map(T=>`<${T}>`).join(" ")}
192
192
 
193
- Usage: coinbase ${t.replace(/_/g," ")} ${e.pathParams.map(T=>`<${T}>`).join(" ")} [fields...]`)}let{parseFields:a}=await Promise.resolve().then(()=>(Ke(),je)),c=a(s),d=!1,p={},_=J(),u=wt(_,n);if(ro(e)&&u&&ve(_)){let k=cr(_,u,t);if(k){let{setNested:T}=await Promise.resolve().then(()=>(Ke(),je));for(let[v,L]of Object.entries(k.values))try{T(p,v,JSON.parse(L))}catch{T(p,v,L)}d=!0}}let f=e.params??[];for(let k of Object.keys(c.body)){let T=f.find(v=>v.name===k);if(T?.oneOf)for(let v of f)v.oneOf===T.oneOf&&v.name!==k&&delete p[v.name]}let E=Object.keys(c.body).length>0?{...p,...c.body}:d?(process.stderr.write(`Using saved values from last ${t.replace(/_/g," ")} call. Pass fields to override.
194
- `),{...p}):{...c.body},x={};for(let[k,T]of c.query.entries())x[k]=T;let w={};for(let k=0;k<i.length;k++)w[e.pathParams[k]]=i[k];if(!r.flags.watch&&!r.flags.until){let T=e.pathParams.some(v=>typeof w[v]=="string"&&w[v].includes(","))?it(t):null;if(T){let{surfaceForChannel:v}=await Promise.resolve().then(()=>(ce(),Hr)),L=Wc(t,e.pathParams,w,v(T)==="watchlist");if(L)throw new Error(L)}}let G=f.filter(k=>k.in==="body"&&k.required&&k.type!=="object"&&k.type!=="array"),F=G.map(k=>k.name);if(F.length>0&&Object.keys(E).length===0&&!r.flags.edit&&!c.rawBody)if(process.stdin.isTTY)if(G.length<=3){let{createInterface:k}=await import("node:readline"),T=k({input:process.stdin,output:process.stderr});for(let v of G){let L=v.enum?` [${v.enum.join(", ")}]`:"",U=v.example?` (e.g. ${v.example})`:"",ht=await new Promise(m=>{T.question(`${v.name}${L}${U}: `,m)});ht&&(E[v.name]=ht)}T.close()}else process.stderr.write(`This action requires ${F.length} fields. Opening editor.
195
- `),r.flags.edit=!0;else{let k=F.join(", ");throw new Error(`Missing required field(s): ${k}
193
+ Usage: coinbase ${t.replace(/_/g," ")} ${e.pathParams.map(T=>`<${T}>`).join(" ")} [fields...]`)}let{parseFields:a}=await Promise.resolve().then(()=>(Qe(),Ke)),c=a(s),d=!1,p={},_=J(),u=xt(_,n);if(oo(e)&&u&&Re(_)){let O=ur(_,u,t);if(O){let{setNested:T}=await Promise.resolve().then(()=>(Qe(),Ke));for(let[v,L]of Object.entries(O.values))try{T(p,v,JSON.parse(L))}catch{T(p,v,L)}d=!0}}let f=e.params??[];for(let O of Object.keys(c.body)){let T=f.find(v=>v.name===O);if(T?.oneOf)for(let v of f)v.oneOf===T.oneOf&&v.name!==O&&delete p[v.name]}let E=Object.keys(c.body).length>0?{...p,...c.body}:d?(process.stderr.write(`Using saved values from last ${t.replace(/_/g," ")} call. Pass fields to override.
194
+ `),{...p}):{...c.body},A={};for(let[O,T]of c.query.entries())A[O]=T;let x={};for(let O=0;O<i.length;O++)x[e.pathParams[O]]=i[O];if(!r.flags.watch&&!r.flags.until){let T=e.pathParams.some(v=>typeof x[v]=="string"&&x[v].includes(","))?st(t):null;if(T){let{surfaceForChannel:v}=await Promise.resolve().then(()=>(ue(),Yr)),L=r_(t,e.pathParams,x,v(T)==="watchlist");if(L)throw new Error(L)}}let G=f.filter(O=>O.in==="body"&&O.required&&O.type!=="object"&&O.type!=="array"),U=G.map(O=>O.name);if(U.length>0&&Object.keys(E).length===0&&!r.flags.edit&&!c.rawBody)if(process.stdin.isTTY)if(G.length<=3){let{createInterface:O}=await import("node:readline"),T=O({input:process.stdin,output:process.stderr});for(let v of G){let L=v.enum?` [${v.enum.join(", ")}]`:"",F=v.example?` (e.g. ${v.example})`:"",Et=await new Promise(m=>{T.question(`${v.name}${L}${F}: `,m)});Et&&(E[v.name]=Et)}T.close()}else process.stderr.write(`This action requires ${U.length} fields. Opening editor.
195
+ `),r.flags.edit=!0;else{let O=U.join(", ");throw new Error(`Missing required field(s): ${O}
196
196
 
197
197
  Provide fields inline:
198
- coinbase ${t.replace(/_/g," ")} ${F.map(T=>`${T}=<value>`).join(" ")}
198
+ coinbase ${t.replace(/_/g," ")} ${U.map(T=>`${T}=<value>`).join(" ")}
199
199
 
200
200
  Or use --template to see the full body:
201
201
  coinbase ${t.replace(/_/g," ")} --template
202
- `)}if(r.flags.edit){let T={...e.template??{},...E},v=await Hc(JSON.stringify(T,null,2));for(let L of Object.keys(E))delete E[L];Object.assign(E,v)}if(r.flags["dry-run"]){process.stderr.write(`would execute ${t}
203
- `);let k={...w,...E,...Object.keys(x).length>0?{_query:x}:{}};process.stdout.write(JSON.stringify(k,null,2)+`
204
- `);return}let Y=Ce(),{name:R,env:P}=Jt(_,n),H=await Qt(R,P),V={envName:R,env:P,baseURL:Z(P,R),doRequest:k=>we({...k,...H}),transport:r.flags.watch||r.flags.until?"brokerage":Y};if(r.flags.watch||r.flags.until){let{startWatch:k}=await Promise.resolve().then(()=>(ce(),Hr)),T=i.length>0?i.flatMap(U=>U.split(",")).filter(Boolean):[],v=r.flags.depth?Number(r.flags.depth):void 0,L=r.flags["until-timeout"]?Number(r.flags["until-timeout"]):void 0;if(v!==void 0&&(!Number.isFinite(v)||v<1))throw new Error(`Invalid --depth value: ${r.flags.depth}`);if(L!==void 0&&(!Number.isFinite(L)||L<1))throw new Error(`Invalid --until-timeout value: ${r.flags["until-timeout"]}`);await k(t,T,V,{jq:r.flags.jq,depth:v,until:r.flags.until,untilTimeout:L,query:Object.keys(x).length>0?x:void 0});return}let Q={body:E,query:{...x},path:w,headers:c.headers,rawBody:c.rawBody??void 0},{outputResult:Ht}=await Promise.resolve().then(()=>(eo(),to)),ue=0;do{let k=await Gt(t,Q,V);if(Ht(k,r.flags.jq),ro(e)&&k.status<400&&Object.keys(E).length>0)try{if(u&&ve(_)){let v={};(function L(U,ht){for(let[m,h]of Object.entries(ht)){let A=U?`${U}.${m}`:m;typeof h=="object"&&h&&!Array.isArray(h)?L(A,h):v[A]=JSON.stringify(h)}})("",E),ar(_,u,t,v),ot(_)}}catch{}if(!r.flags.paginate)break;let T=Zs(k.data);if(!T||T===Q.query.cursor)break;if(Q.query.cursor=T,++ue>=100){process.stderr.write(`Pagination limit reached (100 pages)
205
- `);break}}while(!0)}function $c(){if(process.platform!=="win32")return"vi";try{let{execSync:t}=co("node:child_process");return t("where code",{stdio:"pipe"}),"code --wait"}catch{}return"notepad"}function Vc(t){return t.split(`
202
+ `)}if(r.flags.edit){let T={...e.template??{},...E},v=await s_(JSON.stringify(T,null,2));for(let L of Object.keys(E))delete E[L];Object.assign(E,v)}if(r.flags["dry-run"]){process.stderr.write(`would execute ${t}
203
+ `);let O={...x,...E,...Object.keys(A).length>0?{_query:A}:{}};process.stdout.write(JSON.stringify(O,null,2)+`
204
+ `);return}let K=Ge(),{name:R,env:P}=Xt(_,n),H=await Jt(R,P),V={envName:R,env:P,baseURL:Z(P,R),doRequest:O=>Ce({...O,...H}),transport:r.flags.watch||r.flags.until?"brokerage":K};if(r.flags.watch||r.flags.until){let{startWatch:O}=await Promise.resolve().then(()=>(ue(),Yr)),T=i.length>0?i.flatMap(F=>F.split(",")).filter(Boolean):[],v=r.flags.depth?Number(r.flags.depth):void 0,L=r.flags["until-timeout"]?Number(r.flags["until-timeout"]):void 0;if(v!==void 0&&(!Number.isFinite(v)||v<1))throw new Error(`Invalid --depth value: ${r.flags.depth}`);if(L!==void 0&&(!Number.isFinite(L)||L<1))throw new Error(`Invalid --until-timeout value: ${r.flags["until-timeout"]}`);await O(t,T,V,{jq:r.flags.jq,depth:v,until:r.flags.until,untilTimeout:L,query:Object.keys(A).length>0?A:void 0});return}let Q={body:E,query:{...A},path:x,headers:c.headers,rawBody:c.rawBody??void 0},{outputResult:jt}=await Promise.resolve().then(()=>(so(),io)),ge=0;do{let O=await Dt(t,Q,V);if(jt(O,r.flags.jq),oo(e)&&O.status<400&&Object.keys(E).length>0)try{if(u&&Re(_)){let v={};(function L(F,Et){for(let[m,h]of Object.entries(Et)){let w=F?`${F}.${m}`:m;typeof h=="object"&&h&&!Array.isArray(h)?L(w,h):v[w]=JSON.stringify(h)}})("",E),_r(_,u,t,v),at(_)}}catch{}if(!r.flags.paginate)break;let T=no(O.data);if(!T||T===Q.query.cursor)break;if(Q.query.cursor=T,++ge>=100){process.stderr.write(`Pagination limit reached (100 pages)
205
+ `);break}}while(!0)}function n_(){if(process.platform!=="win32")return"vi";try{let{execSync:t}=lo("node:child_process");return t("where code",{stdio:"pipe"}),"code --wait"}catch{}return"notepad"}function i_(t){return t.split(`
206
206
  `).filter(e=>!e.trimStart().startsWith("//")).join(`
207
- `)}async function Hc(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:c}=await Promise.resolve().then(()=>(tt(),kn));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 d=process.env.VISUAL??process.env.EDITOR??$c();(d.trim()==="code"||d.trim().endsWith("/code"))&&(d+=" --wait");let p=o(i(o(s(),"coinbase-")),"request.json");e(p,t);try{let[_,...u]=d.split(/\s+/);a(_,[...u,p],{stdio:"inherit",env:c()});let f=Vc(r(p,"utf8"));return JSON.parse(f)}catch(_){throw new Error(_.message?.includes("Unexpected")?`Edited file is not valid JSON: ${_.message}`:`Editor: ${_.message}`)}finally{try{n(p)}catch{}}}Ct();g();l();var _e=class extends Error{constructor(e){super(e),this.name="HelpExit"}};function no(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 io(t,e,r){let n=t,i,s=0,o=[],a=[];for(let _=0;_<e.length;_++){let u=e[_],f=n.children.get(u);if(f){a.push(u),o=[...n.children.keys()],n=f,n.action&&(i=n.action,s=a.length);continue}if(u.includes("=")){let O=u.split("=")[0],E=n.children.get(O);if(E?.action){let x=E.action.pathParams.map(G=>` <${G}>`).join(""),w=a.length>0?`coinbase ${r} ${a.join(" ")}`:`coinbase ${r}`;throw new Error(`Did you mean: ${w} ${E.action.name.split(" ").pop()}${x}`)}}break}if(i)return{action:i,remaining:e.slice(s),siblingNames:o};let c=e[a.length],d=a.length>0?`coinbase ${r} ${a.join(" ")}`:`coinbase ${r}`,p=jc(n,r);throw c&&c!=="--help"&&c!=="-h"?new Error(`unknown subcommand "${c}" for ${d}
207
+ `)}async function s_(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:c}=await Promise.resolve().then(()=>(tt(),kn));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 d=process.env.VISUAL??process.env.EDITOR??n_();(d.trim()==="code"||d.trim().endsWith("/code"))&&(d+=" --wait");let p=o(i(o(s(),"coinbase-")),"request.json");e(p,t);try{let[_,...u]=d.split(/\s+/);a(_,[...u,p],{stdio:"inherit",env:c()});let f=i_(r(p,"utf8"));return JSON.parse(f)}catch(_){throw new Error(_.message?.includes("Unexpected")?`Edited file is not valid JSON: ${_.message}`:`Editor: ${_.message}`)}finally{try{n(p)}catch{}}}Ct();g();l();var de=class extends Error{constructor(e){super(e),this.name="HelpExit"}};function ao(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 co(t,e,r){let n=t,i,s=0,o=[],a=[];for(let _=0;_<e.length;_++){let u=e[_],f=n.children.get(u);if(f){a.push(u),o=[...n.children.keys()],n=f,n.action&&(i=n.action,s=a.length);continue}if(u.includes("=")){let k=u.split("=")[0],E=n.children.get(k);if(E?.action){let A=E.action.pathParams.map(G=>` <${G}>`).join(""),x=a.length>0?`coinbase ${r} ${a.join(" ")}`:`coinbase ${r}`;throw new Error(`Did you mean: ${x} ${E.action.name.split(" ").pop()}${A}`)}}break}if(i)return{action:i,remaining:e.slice(s),siblingNames:o};let c=e[a.length],d=a.length>0?`coinbase ${r} ${a.join(" ")}`:`coinbase ${r}`,p=o_(n,r);throw c&&c!=="--help"&&c!=="-h"?new Error(`unknown subcommand "${c}" for ${d}
208
208
 
209
209
  Available actions:
210
- ${p}`):new _e(`${d}
210
+ ${p}`):new de(`${d}
211
211
 
212
212
  Available actions:
213
- ${p}`)}function jc(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(`
214
- `)}Se();ge();g();l();function Vt(t,e){let r={},n=[],i=!1,s=new Map;for(let[o,a,c]of e)s.set("--"+o,[o,c]),a&&s.set("-"+a,[o,c]);for(let o=0;o<t.length;o++){let a=t[o];if(a==="-h"||a==="--help"){i=!0;continue}let c=a.indexOf("=");if(c>0&&a.startsWith("--")){let p=s.get(a.slice(0,c));if(p){r[p[0]]=a.slice(c+1);continue}}let d=s.get(a);if(d){r[d[0]]=d[1]?t[++o]??"":!0;continue}if(a.length>2&&a[0]==="-"&&a[1]!=="-"){let p=s.get(a.slice(0,2));if(p?.[1]){r[p[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[Kc]=process.versions.node.split(".").map(Number);Kc<22&&(process.stderr.write(`coinbase requires Node.js ${22}+. You have: ${process.versions.node}
215
- `),process.exit(1));function Yc(){return`Coinbase CLI
213
+ ${p}`)}function o_(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(`
214
+ `)}xe();pe();g();l();function Ht(t,e){let r={},n=[],i=!1,s=new Map;for(let[o,a,c]of e)s.set("--"+o,[o,c]),a&&s.set("-"+a,[o,c]);for(let o=0;o<t.length;o++){let a=t[o];if(a==="-h"||a==="--help"){i=!0;continue}let c=a.indexOf("=");if(c>0&&a.startsWith("--")){let p=s.get(a.slice(0,c));if(p){r[p[0]]=a.slice(c+1);continue}}let d=s.get(a);if(d){r[d[0]]=d[1]?t[++o]??"":!0;continue}if(a.length>2&&a[0]==="-"&&a[1]!=="-"){let p=s.get(a.slice(0,2));if(p?.[1]){r[p[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[a_]=process.versions.node.split(".").map(Number);a_<22&&(process.stderr.write(`coinbase requires Node.js ${22}+. You have: ${process.versions.node}
215
+ `),process.exit(1));function c_(){return`Coinbase CLI
216
216
 
217
217
  Usage:
218
218
  coinbase <resource> <action> [fields...]
219
219
  coinbase <action> [fields...]
220
220
 
221
221
  Resources:
222
- ${jr().map(r=>` ${r.name.padEnd(20)}${r.actions.map(n=>{let i=it(n.id);return i&&bt(i)!==null?`${n.name} [--watch]`:n.name}).join(", ")}`).join(`
222
+ ${Kr().map(r=>` ${r.name.padEnd(20)}${r.actions.map(n=>{let i=st(n.id);return i&&ht(i)!==null?`${n.name} [--watch]`:n.name}).join(", ")}`).join(`
223
223
  `)}
224
224
 
225
225
  Actions:
@@ -239,8 +239,8 @@ Flags:
239
239
  -e, --env <name> Environment override
240
240
  -V, --version Show version
241
241
  -h, --help Show help
242
- `}async function Qc(){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 ${ct}
243
- `);return}if(Jr=Si(),r.length===0||r[0]==="-h"||r[0]==="--help"||r[0]==="help"){process.stderr.write(Yc());return}let[n,...i]=r;if(n==="env"){let s=Vt(i,[["key-id",null,!0],["key-secret",null,!0],["key-file","k",!0],["status",null,!1],["url",null,!0],["brokerage-api-url",null,!0],["agent-api-url",null,!0],["remove",null,!1],["allow-plaintext-secrets",null,!1]]);if(s.help){process.stderr.write(`Manage environments and credentials
242
+ `}async function __(){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 ${ct}
243
+ `);return}if(Zr=Ni(),r.length===0||r[0]==="-h"||r[0]==="--help"||r[0]==="help"){process.stderr.write(c_());return}let[n,...i]=r;if(n==="env"){let s=Ht(i,[["key-id",null,!0],["key-secret",null,!0],["key-file","k",!0],["status",null,!1],["url",null,!0],["brokerage-api-url",null,!0],["agent-api-url",null,!0],["remove",null,!1],["allow-plaintext-secrets",null,!1]]);if(s.help){process.stderr.write(`Manage environments and credentials
244
244
 
245
245
  Usage:
246
246
  coinbase env List all environments
@@ -261,14 +261,14 @@ Flags:
261
261
  --agent-api-url <url> First-party Agent API URL (includes /api)
262
262
  --remove Remove an environment
263
263
  --allow-plaintext-secrets Persist secrets to ~/.config/coinbase/config.json (mode 0600) when no OS keychain is available. Default: refuse and error.
264
- `);return}await vn(s.args,{keyId:s.flags["key-id"],keySecret:s.flags["key-secret"],keyFile:s.flags["key-file"],status:!!s.flags.status,url:s.flags.url,brokerageApiUrl:s.flags["brokerage-api-url"],agentApiUrl:s.flags["agent-api-url"],remove:!!s.flags.remove,allowPlaintextSecrets:!!s.flags["allow-plaintext-secrets"],envFlag:e})}else if(n==="history"){let s=Vt(i,[]);if(s.help){process.stderr.write(`View or clear saved request history
264
+ `);return}await Rn(s.args,{keyId:s.flags["key-id"],keySecret:s.flags["key-secret"],keyFile:s.flags["key-file"],status:!!s.flags.status,url:s.flags.url,brokerageApiUrl:s.flags["brokerage-api-url"],agentApiUrl:s.flags["agent-api-url"],remove:!!s.flags.remove,allowPlaintextSecrets:!!s.flags["allow-plaintext-secrets"],envFlag:e})}else if(n==="history"){let s=Ht(i,[]);if(s.help){process.stderr.write(`View or clear saved request history
265
265
 
266
266
  Usage:
267
267
  coinbase history Show all saved history
268
268
  coinbase history clear Clear all history
269
269
  coinbase history clear <env> Clear history for an environment
270
270
  coinbase history clear <env>.<action> Clear a specific entry
271
- `);return}Wi(s.args)}else if(n==="skills")await Zi(i);else if(n==="mcp"){if(Vt(i,[]).help){process.stderr.write(`MCP server for AI agent integration
271
+ `);return}ji(s.args)}else if(n==="skills")await ns(i);else if(n==="mcp"){if(Ht(i,[]).help){process.stderr.write(`MCP server for AI agent integration
272
272
 
273
273
  Usage:
274
274
  coinbase mcp Start MCP server over stdio
@@ -276,9 +276,9 @@ Usage:
276
276
  The MCP server implements the Model Context Protocol (JSON-RPC over
277
277
  stdin/stdout) and exposes brokerage and x402 API resources as tools. It is
278
278
  typically invoked automatically by AI agents, not run directly.
279
- `);return}zi()}else if(Qs(n)){let s=nt[n];s||(process.stderr.write(`error: "${n}" is not available
280
- `),process.exit(1));let o=Vt(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(o.help){Kr(n,s);return}await Qr(n,s,o,e)}else{let s=jr().find(p=>p.name===n);if(s||(process.stderr.write(`error: unknown command "${n}"
279
+ `);return}Hi()}else if(to(n)){let s=rt[n];s||(process.stderr.write(`error: "${n}" is not available
280
+ `),process.exit(1));let o=Ht(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(o.help){Qr(n,s);return}await Xr(n,s,o,e)}else{let s=Kr().find(p=>p.name===n);if(s||(process.stderr.write(`error: unknown command "${n}"
281
281
  Run: coinbase --help
282
- `),process.exit(1)),i.length===0||i[0]==="-h"||i[0]==="--help"){Xs(n);return}let o=no(s.actions),a=io(o,i,n),c=Vt(a.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){Kr(n,a.action);return}let d=a.action.id??`${n}_${a.action.name.replace(/[-\s]/g,"_")}`;await Qr(d,a.action,c,e)}}var Jr;Qc().catch(t=>{t instanceof _e&&(process.stderr.write(t.message+`
282
+ `),process.exit(1)),i.length===0||i[0]==="-h"||i[0]==="--help"){ro(n);return}let o=ao(s.actions),a=co(o,i,n),c=Ht(a.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){Qr(n,a.action);return}let d=a.action.id??`${n}_${a.action.name.replace(/[-\s]/g,"_")}`;await Xr(d,a.action,c,e)}}var Zr;__().catch(t=>{t instanceof de&&(process.stderr.write(t.message+`
283
283
  `),process.exit(0)),process.stderr.write(`error: ${t.message}
284
- `),process.exit(1)}).finally(async()=>{if(!Jr||!process.stderr.isTTY)return;let t=await Jr.catch(()=>"");t&&process.stderr.write(t)});
284
+ `),process.exit(1)}).finally(async()=>{if(!Zr||!process.stderr.isTTY)return;let t=await Zr.catch(()=>"");t&&process.stderr.write(t)});