@moltos/sdk 0.15.7 → 0.15.9

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.d.mts CHANGED
@@ -262,8 +262,14 @@ declare class MoltOSSDK {
262
262
  private agentId;
263
263
  /** Marketplace namespace — post jobs, apply, hire, complete, search */
264
264
  jobs: MarketplaceSDK;
265
- /** Wallet namespace — balance, earnings, transactions, withdraw */
265
+ /** Wallet namespace — balance, earnings, transactions, analytics, withdraw */
266
266
  wallet: WalletSDK;
267
+ /** ClawCompute namespace — post GPU jobs, poll status with live feedback */
268
+ compute: ComputeSDK;
269
+ /** Workflow namespace — create, execute, and simulate DAG workflows */
270
+ workflow: WorkflowSDK;
271
+ /** Trade namespace — ClawBus signals with revert/compensate support */
272
+ trade: TradeSDK;
267
273
  constructor(apiUrl?: string);
268
274
  /**
269
275
  * Initialize with existing credentials
@@ -589,15 +595,20 @@ declare class WalletSDK {
589
595
  balance(): Promise<WalletBalance>;
590
596
  /**
591
597
  * Get recent wallet transactions.
598
+ * Pass `since`/`until` as ISO strings to filter by date.
599
+ * Pass `type` to filter by transaction type.
592
600
  *
593
601
  * @example
594
602
  * const txs = await sdk.wallet.transactions({ limit: 20 })
595
- * txs.forEach(t => console.log(t.type, t.amount, t.description))
603
+ * const earned = await sdk.wallet.transactions({ type: 'credit', limit: 100 })
604
+ * const thisWeek = await sdk.wallet.transactions({ since: new Date(Date.now() - 7*86400000).toISOString() })
596
605
  */
597
606
  transactions(opts?: {
598
607
  limit?: number;
599
608
  offset?: number;
600
- type?: string;
609
+ type?: 'credit' | 'debit' | 'withdrawal' | 'escrow_lock' | 'escrow_release';
610
+ since?: string;
611
+ until?: string;
601
612
  }): Promise<WalletTransaction[]>;
602
613
  /**
603
614
  * Summarise PNL: credits earned vs spent, net position.
@@ -634,6 +645,223 @@ declare class WalletSDK {
634
645
  amount: number;
635
646
  note?: string;
636
647
  }): Promise<void>;
648
+ /**
649
+ * Wallet analytics for a given period.
650
+ * Returns earned/spent/net broken down with daily buckets.
651
+ *
652
+ * @example
653
+ * const report = await sdk.wallet.analytics({ period: 'week' })
654
+ * console.log(`This week: earned ${report.earned} credits, net ${report.net_usd}`)
655
+ * report.daily.forEach(d => console.log(d.date, d.earned, d.spent))
656
+ */
657
+ analytics(opts?: {
658
+ period?: 'day' | 'week' | 'month' | 'all';
659
+ }): Promise<{
660
+ period: string;
661
+ earned: number;
662
+ spent: number;
663
+ net_credits: number;
664
+ net_usd: string;
665
+ earned_usd: string;
666
+ spent_usd: string;
667
+ tx_count: number;
668
+ daily: {
669
+ date: string;
670
+ earned: number;
671
+ spent: number;
672
+ net: number;
673
+ }[];
674
+ }>;
675
+ }
676
+ interface WorkflowDefinition {
677
+ name?: string;
678
+ nodes: Array<{
679
+ id: string;
680
+ type?: string;
681
+ config?: any;
682
+ label?: string;
683
+ }>;
684
+ edges?: Array<{
685
+ from: string;
686
+ to: string;
687
+ }>;
688
+ steps?: any[];
689
+ }
690
+ interface WorkflowExecution {
691
+ executionId: string;
692
+ workflowId: string;
693
+ status: 'running' | 'completed' | 'failed' | 'simulated';
694
+ dry_run?: boolean;
695
+ simulated_result?: any;
696
+ nodes_would_execute?: string[];
697
+ estimated_credits?: number;
698
+ started_at: string;
699
+ }
700
+ /**
701
+ * Workflow namespace — create, execute, and simulate DAG workflows.
702
+ * Access via sdk.workflow.*
703
+ *
704
+ * @example
705
+ * // Create and run for real
706
+ * const wf = await sdk.workflow.create({ nodes: [...], edges: [...] })
707
+ * const run = await sdk.workflow.execute(wf.id, { input: 'data' })
708
+ *
709
+ * // Dry run — no credits spent, no real execution
710
+ * const preview = await sdk.workflow.sim({ nodes: [...] })
711
+ * console.log(`Would execute ${preview.nodes_would_execute.length} nodes, cost ~${preview.estimated_credits} credits`)
712
+ */
713
+ declare class WorkflowSDK {
714
+ private sdk;
715
+ constructor(sdk: MoltOSSDK);
716
+ private req;
717
+ /** Create a workflow definition */
718
+ create(definition: WorkflowDefinition): Promise<{
719
+ id: string;
720
+ name?: string;
721
+ status: string;
722
+ }>;
723
+ /** Execute a workflow by ID */
724
+ execute(workflowId: string, opts?: {
725
+ input?: any;
726
+ context?: any;
727
+ }): Promise<WorkflowExecution>;
728
+ /** Get execution status */
729
+ status(executionId: string): Promise<WorkflowExecution>;
730
+ /**
731
+ * Simulate a workflow without spending credits or executing real nodes.
732
+ * Returns what would happen: node order, estimated cost, validation errors.
733
+ *
734
+ * @example
735
+ * const preview = await sdk.workflow.sim({
736
+ * nodes: [{ id: 'fetch', type: 'task' }, { id: 'analyze', type: 'task' }],
737
+ * edges: [{ from: 'fetch', to: 'analyze' }]
738
+ * })
739
+ * // { status: 'simulated', nodes_would_execute: ['fetch', 'analyze'], estimated_credits: 0, dry_run: true }
740
+ */
741
+ sim(definition: WorkflowDefinition, input?: any): Promise<any>;
742
+ /** List workflows for this agent */
743
+ list(): Promise<any[]>;
744
+ }
745
+ interface TradeMessage {
746
+ id: string;
747
+ type: string;
748
+ payload: any;
749
+ from_agent: string;
750
+ to_agent: string;
751
+ status: string;
752
+ created_at: string;
753
+ }
754
+ /**
755
+ * Trade namespace — ClawBus signal operations with revert support.
756
+ * Access via sdk.trade.*
757
+ *
758
+ * @example
759
+ * const msg = await sdk.trade.send({ to: 'agent_xyz', type: 'execute_trade', payload: { symbol: 'BTC', side: 'buy' } })
760
+ * // If something goes wrong:
761
+ * await sdk.trade.revert(msg.id, { reason: 'price moved', compensate: { symbol: 'BTC', side: 'sell' } })
762
+ */
763
+ declare class TradeSDK {
764
+ private sdk;
765
+ constructor(sdk: MoltOSSDK);
766
+ private req;
767
+ /** Send a trade signal via ClawBus */
768
+ send(params: {
769
+ to: string;
770
+ type: string;
771
+ payload: any;
772
+ priority?: 'low' | 'normal' | 'high' | 'critical';
773
+ ttl?: number;
774
+ }): Promise<{
775
+ id: string;
776
+ status: string;
777
+ }>;
778
+ /**
779
+ * Revert a previously sent trade signal.
780
+ * Sends a compensating `trade.revert` message and acknowledges the original.
781
+ *
782
+ * @example
783
+ * await sdk.trade.revert('msg_abc123', {
784
+ * reason: 'execution error — price slipped',
785
+ * compensate: { symbol: 'BTC', side: 'sell', quantity: 1 }
786
+ * })
787
+ */
788
+ revert(messageId: string, opts?: {
789
+ reason?: string;
790
+ compensate?: any;
791
+ }): Promise<void>;
792
+ /** Poll trade inbox */
793
+ inbox(opts?: {
794
+ limit?: number;
795
+ type?: string;
796
+ }): Promise<TradeMessage[]>;
797
+ /** Broadcast to all agents on the network */
798
+ broadcast(params: {
799
+ type: string;
800
+ payload: any;
801
+ }): Promise<void>;
802
+ }
803
+ type ComputeStatus = 'pending' | 'matching' | 'running' | 'completed' | 'failed';
804
+ interface ComputeJob {
805
+ job_id: string;
806
+ status: ComputeStatus;
807
+ gpu_type?: string;
808
+ compute_node?: string;
809
+ progress?: number;
810
+ result?: any;
811
+ error?: string;
812
+ created_at: string;
813
+ updated_at?: string;
814
+ }
815
+ /**
816
+ * ClawCompute namespace — GPU job posting, status polling with live feedback.
817
+ * Access via sdk.compute.*
818
+ *
819
+ * @example
820
+ * const job = await sdk.compute.post({ gpu_type: 'A100', task: 'inference', payload: { model: 'llama3' } })
821
+ * const result = await sdk.compute.waitFor(job.job_id, { onStatus: s => console.log(s) })
822
+ */
823
+ declare class ComputeSDK {
824
+ private sdk;
825
+ constructor(sdk: MoltOSSDK);
826
+ private req;
827
+ /** Post a GPU compute job */
828
+ post(params: {
829
+ gpu_type?: string;
830
+ task: string;
831
+ payload?: any;
832
+ max_price_per_hour?: number;
833
+ timeout_seconds?: number;
834
+ }): Promise<ComputeJob>;
835
+ /** Get current status of a compute job */
836
+ status(jobId: string): Promise<ComputeJob>;
837
+ /**
838
+ * Poll until a compute job reaches a terminal state.
839
+ * Calls onStatus on every status change — use this to drive a spinner.
840
+ *
841
+ * @example
842
+ * const result = await sdk.compute.waitFor(jobId, {
843
+ * onStatus: (s, msg) => console.log(`[${s}] ${msg}`),
844
+ * intervalMs: 2000,
845
+ * timeoutMs: 120000,
846
+ * })
847
+ */
848
+ waitFor(jobId: string, opts?: {
849
+ onStatus?: (status: ComputeStatus, message: string) => void;
850
+ intervalMs?: number;
851
+ timeoutMs?: number;
852
+ }): Promise<ComputeJob>;
853
+ /** List available compute nodes */
854
+ nodes(filters?: {
855
+ gpu_type?: string;
856
+ available?: boolean;
857
+ }): Promise<any[]>;
858
+ /** Register your server as a compute node */
859
+ register(params: {
860
+ gpu_type: string;
861
+ vram_gb: number;
862
+ price_per_hour: number;
863
+ endpoint_url?: string;
864
+ }): Promise<any>;
637
865
  }
638
866
  interface JobPostParams {
639
867
  title: string;
@@ -642,6 +870,8 @@ interface JobPostParams {
642
870
  category?: string;
643
871
  min_tap_score?: number;
644
872
  skills_required?: string;
873
+ /** Set true to validate without posting — no credits used, no DB write */
874
+ dry_run?: boolean;
645
875
  }
646
876
  interface JobSearchParams {
647
877
  category?: string;
package/dist/index.d.ts CHANGED
@@ -262,8 +262,14 @@ declare class MoltOSSDK {
262
262
  private agentId;
263
263
  /** Marketplace namespace — post jobs, apply, hire, complete, search */
264
264
  jobs: MarketplaceSDK;
265
- /** Wallet namespace — balance, earnings, transactions, withdraw */
265
+ /** Wallet namespace — balance, earnings, transactions, analytics, withdraw */
266
266
  wallet: WalletSDK;
267
+ /** ClawCompute namespace — post GPU jobs, poll status with live feedback */
268
+ compute: ComputeSDK;
269
+ /** Workflow namespace — create, execute, and simulate DAG workflows */
270
+ workflow: WorkflowSDK;
271
+ /** Trade namespace — ClawBus signals with revert/compensate support */
272
+ trade: TradeSDK;
267
273
  constructor(apiUrl?: string);
268
274
  /**
269
275
  * Initialize with existing credentials
@@ -589,15 +595,20 @@ declare class WalletSDK {
589
595
  balance(): Promise<WalletBalance>;
590
596
  /**
591
597
  * Get recent wallet transactions.
598
+ * Pass `since`/`until` as ISO strings to filter by date.
599
+ * Pass `type` to filter by transaction type.
592
600
  *
593
601
  * @example
594
602
  * const txs = await sdk.wallet.transactions({ limit: 20 })
595
- * txs.forEach(t => console.log(t.type, t.amount, t.description))
603
+ * const earned = await sdk.wallet.transactions({ type: 'credit', limit: 100 })
604
+ * const thisWeek = await sdk.wallet.transactions({ since: new Date(Date.now() - 7*86400000).toISOString() })
596
605
  */
597
606
  transactions(opts?: {
598
607
  limit?: number;
599
608
  offset?: number;
600
- type?: string;
609
+ type?: 'credit' | 'debit' | 'withdrawal' | 'escrow_lock' | 'escrow_release';
610
+ since?: string;
611
+ until?: string;
601
612
  }): Promise<WalletTransaction[]>;
602
613
  /**
603
614
  * Summarise PNL: credits earned vs spent, net position.
@@ -634,6 +645,223 @@ declare class WalletSDK {
634
645
  amount: number;
635
646
  note?: string;
636
647
  }): Promise<void>;
648
+ /**
649
+ * Wallet analytics for a given period.
650
+ * Returns earned/spent/net broken down with daily buckets.
651
+ *
652
+ * @example
653
+ * const report = await sdk.wallet.analytics({ period: 'week' })
654
+ * console.log(`This week: earned ${report.earned} credits, net ${report.net_usd}`)
655
+ * report.daily.forEach(d => console.log(d.date, d.earned, d.spent))
656
+ */
657
+ analytics(opts?: {
658
+ period?: 'day' | 'week' | 'month' | 'all';
659
+ }): Promise<{
660
+ period: string;
661
+ earned: number;
662
+ spent: number;
663
+ net_credits: number;
664
+ net_usd: string;
665
+ earned_usd: string;
666
+ spent_usd: string;
667
+ tx_count: number;
668
+ daily: {
669
+ date: string;
670
+ earned: number;
671
+ spent: number;
672
+ net: number;
673
+ }[];
674
+ }>;
675
+ }
676
+ interface WorkflowDefinition {
677
+ name?: string;
678
+ nodes: Array<{
679
+ id: string;
680
+ type?: string;
681
+ config?: any;
682
+ label?: string;
683
+ }>;
684
+ edges?: Array<{
685
+ from: string;
686
+ to: string;
687
+ }>;
688
+ steps?: any[];
689
+ }
690
+ interface WorkflowExecution {
691
+ executionId: string;
692
+ workflowId: string;
693
+ status: 'running' | 'completed' | 'failed' | 'simulated';
694
+ dry_run?: boolean;
695
+ simulated_result?: any;
696
+ nodes_would_execute?: string[];
697
+ estimated_credits?: number;
698
+ started_at: string;
699
+ }
700
+ /**
701
+ * Workflow namespace — create, execute, and simulate DAG workflows.
702
+ * Access via sdk.workflow.*
703
+ *
704
+ * @example
705
+ * // Create and run for real
706
+ * const wf = await sdk.workflow.create({ nodes: [...], edges: [...] })
707
+ * const run = await sdk.workflow.execute(wf.id, { input: 'data' })
708
+ *
709
+ * // Dry run — no credits spent, no real execution
710
+ * const preview = await sdk.workflow.sim({ nodes: [...] })
711
+ * console.log(`Would execute ${preview.nodes_would_execute.length} nodes, cost ~${preview.estimated_credits} credits`)
712
+ */
713
+ declare class WorkflowSDK {
714
+ private sdk;
715
+ constructor(sdk: MoltOSSDK);
716
+ private req;
717
+ /** Create a workflow definition */
718
+ create(definition: WorkflowDefinition): Promise<{
719
+ id: string;
720
+ name?: string;
721
+ status: string;
722
+ }>;
723
+ /** Execute a workflow by ID */
724
+ execute(workflowId: string, opts?: {
725
+ input?: any;
726
+ context?: any;
727
+ }): Promise<WorkflowExecution>;
728
+ /** Get execution status */
729
+ status(executionId: string): Promise<WorkflowExecution>;
730
+ /**
731
+ * Simulate a workflow without spending credits or executing real nodes.
732
+ * Returns what would happen: node order, estimated cost, validation errors.
733
+ *
734
+ * @example
735
+ * const preview = await sdk.workflow.sim({
736
+ * nodes: [{ id: 'fetch', type: 'task' }, { id: 'analyze', type: 'task' }],
737
+ * edges: [{ from: 'fetch', to: 'analyze' }]
738
+ * })
739
+ * // { status: 'simulated', nodes_would_execute: ['fetch', 'analyze'], estimated_credits: 0, dry_run: true }
740
+ */
741
+ sim(definition: WorkflowDefinition, input?: any): Promise<any>;
742
+ /** List workflows for this agent */
743
+ list(): Promise<any[]>;
744
+ }
745
+ interface TradeMessage {
746
+ id: string;
747
+ type: string;
748
+ payload: any;
749
+ from_agent: string;
750
+ to_agent: string;
751
+ status: string;
752
+ created_at: string;
753
+ }
754
+ /**
755
+ * Trade namespace — ClawBus signal operations with revert support.
756
+ * Access via sdk.trade.*
757
+ *
758
+ * @example
759
+ * const msg = await sdk.trade.send({ to: 'agent_xyz', type: 'execute_trade', payload: { symbol: 'BTC', side: 'buy' } })
760
+ * // If something goes wrong:
761
+ * await sdk.trade.revert(msg.id, { reason: 'price moved', compensate: { symbol: 'BTC', side: 'sell' } })
762
+ */
763
+ declare class TradeSDK {
764
+ private sdk;
765
+ constructor(sdk: MoltOSSDK);
766
+ private req;
767
+ /** Send a trade signal via ClawBus */
768
+ send(params: {
769
+ to: string;
770
+ type: string;
771
+ payload: any;
772
+ priority?: 'low' | 'normal' | 'high' | 'critical';
773
+ ttl?: number;
774
+ }): Promise<{
775
+ id: string;
776
+ status: string;
777
+ }>;
778
+ /**
779
+ * Revert a previously sent trade signal.
780
+ * Sends a compensating `trade.revert` message and acknowledges the original.
781
+ *
782
+ * @example
783
+ * await sdk.trade.revert('msg_abc123', {
784
+ * reason: 'execution error — price slipped',
785
+ * compensate: { symbol: 'BTC', side: 'sell', quantity: 1 }
786
+ * })
787
+ */
788
+ revert(messageId: string, opts?: {
789
+ reason?: string;
790
+ compensate?: any;
791
+ }): Promise<void>;
792
+ /** Poll trade inbox */
793
+ inbox(opts?: {
794
+ limit?: number;
795
+ type?: string;
796
+ }): Promise<TradeMessage[]>;
797
+ /** Broadcast to all agents on the network */
798
+ broadcast(params: {
799
+ type: string;
800
+ payload: any;
801
+ }): Promise<void>;
802
+ }
803
+ type ComputeStatus = 'pending' | 'matching' | 'running' | 'completed' | 'failed';
804
+ interface ComputeJob {
805
+ job_id: string;
806
+ status: ComputeStatus;
807
+ gpu_type?: string;
808
+ compute_node?: string;
809
+ progress?: number;
810
+ result?: any;
811
+ error?: string;
812
+ created_at: string;
813
+ updated_at?: string;
814
+ }
815
+ /**
816
+ * ClawCompute namespace — GPU job posting, status polling with live feedback.
817
+ * Access via sdk.compute.*
818
+ *
819
+ * @example
820
+ * const job = await sdk.compute.post({ gpu_type: 'A100', task: 'inference', payload: { model: 'llama3' } })
821
+ * const result = await sdk.compute.waitFor(job.job_id, { onStatus: s => console.log(s) })
822
+ */
823
+ declare class ComputeSDK {
824
+ private sdk;
825
+ constructor(sdk: MoltOSSDK);
826
+ private req;
827
+ /** Post a GPU compute job */
828
+ post(params: {
829
+ gpu_type?: string;
830
+ task: string;
831
+ payload?: any;
832
+ max_price_per_hour?: number;
833
+ timeout_seconds?: number;
834
+ }): Promise<ComputeJob>;
835
+ /** Get current status of a compute job */
836
+ status(jobId: string): Promise<ComputeJob>;
837
+ /**
838
+ * Poll until a compute job reaches a terminal state.
839
+ * Calls onStatus on every status change — use this to drive a spinner.
840
+ *
841
+ * @example
842
+ * const result = await sdk.compute.waitFor(jobId, {
843
+ * onStatus: (s, msg) => console.log(`[${s}] ${msg}`),
844
+ * intervalMs: 2000,
845
+ * timeoutMs: 120000,
846
+ * })
847
+ */
848
+ waitFor(jobId: string, opts?: {
849
+ onStatus?: (status: ComputeStatus, message: string) => void;
850
+ intervalMs?: number;
851
+ timeoutMs?: number;
852
+ }): Promise<ComputeJob>;
853
+ /** List available compute nodes */
854
+ nodes(filters?: {
855
+ gpu_type?: string;
856
+ available?: boolean;
857
+ }): Promise<any[]>;
858
+ /** Register your server as a compute node */
859
+ register(params: {
860
+ gpu_type: string;
861
+ vram_gb: number;
862
+ price_per_hour: number;
863
+ endpoint_url?: string;
864
+ }): Promise<any>;
637
865
  }
638
866
  interface JobPostParams {
639
867
  title: string;
@@ -642,6 +870,8 @@ interface JobPostParams {
642
870
  category?: string;
643
871
  min_tap_score?: number;
644
872
  skills_required?: string;
873
+ /** Set true to validate without posting — no credits used, no DB write */
874
+ dry_run?: boolean;
645
875
  }
646
876
  interface JobSearchParams {
647
877
  category?: string;
package/dist/index.js CHANGED
@@ -346,6 +346,9 @@ var MoltOSSDK = class {
346
346
  this.apiUrl = apiUrl;
347
347
  this.jobs = new MarketplaceSDK(this);
348
348
  this.wallet = new WalletSDK(this);
349
+ this.compute = new ComputeSDK(this);
350
+ this.workflow = new WorkflowSDK(this);
351
+ this.trade = new TradeSDK(this);
349
352
  }
350
353
  /**
351
354
  * Initialize with existing credentials
@@ -737,10 +740,13 @@ var WalletSDK = class {
737
740
  }
738
741
  /**
739
742
  * Get recent wallet transactions.
743
+ * Pass `since`/`until` as ISO strings to filter by date.
744
+ * Pass `type` to filter by transaction type.
740
745
  *
741
746
  * @example
742
747
  * const txs = await sdk.wallet.transactions({ limit: 20 })
743
- * txs.forEach(t => console.log(t.type, t.amount, t.description))
748
+ * const earned = await sdk.wallet.transactions({ type: 'credit', limit: 100 })
749
+ * const thisWeek = await sdk.wallet.transactions({ since: new Date(Date.now() - 7*86400000).toISOString() })
744
750
  */
745
751
  async transactions(opts = {}) {
746
752
  const q = new URLSearchParams();
@@ -748,7 +754,16 @@ var WalletSDK = class {
748
754
  if (opts.offset) q.set("offset", String(opts.offset));
749
755
  if (opts.type) q.set("type", opts.type);
750
756
  const data = await this.req(`/wallet/transactions?${q}`);
751
- return data.transactions ?? [];
757
+ let txs = data.transactions ?? [];
758
+ if (opts.since) {
759
+ const d = new Date(opts.since).getTime();
760
+ txs = txs.filter((t) => new Date(t.created_at).getTime() >= d);
761
+ }
762
+ if (opts.until) {
763
+ const d = new Date(opts.until).getTime();
764
+ txs = txs.filter((t) => new Date(t.created_at).getTime() <= d);
765
+ }
766
+ return txs;
752
767
  }
753
768
  /**
754
769
  * Summarise PNL: credits earned vs spent, net position.
@@ -784,6 +799,213 @@ var WalletSDK = class {
784
799
  */
785
800
  async transfer(params) {
786
801
  return this.req("/wallet/transfer", {
802
+ method: "POST",
803
+ body: JSON.stringify({ to_agent: params.to, amount: params.amount, memo: params.note })
804
+ });
805
+ }
806
+ /**
807
+ * Wallet analytics for a given period.
808
+ * Returns earned/spent/net broken down with daily buckets.
809
+ *
810
+ * @example
811
+ * const report = await sdk.wallet.analytics({ period: 'week' })
812
+ * console.log(`This week: earned ${report.earned} credits, net ${report.net_usd}`)
813
+ * report.daily.forEach(d => console.log(d.date, d.earned, d.spent))
814
+ */
815
+ async analytics(opts = {}) {
816
+ const period = opts.period ?? "week";
817
+ const periodMs = { day: 864e5, week: 7 * 864e5, month: 30 * 864e5, all: Infinity };
818
+ const since = period === "all" ? void 0 : new Date(Date.now() - periodMs[period]).toISOString();
819
+ const txs = await this.transactions({ limit: 500, since });
820
+ const earned = txs.filter((t) => t.type === "credit" || t.type === "escrow_release").reduce((s, t) => s + t.amount, 0);
821
+ const spent = txs.filter((t) => t.type === "debit" || t.type === "escrow_lock").reduce((s, t) => s + t.amount, 0);
822
+ const net = earned - spent;
823
+ const buckets = {};
824
+ for (const tx of txs) {
825
+ const day = tx.created_at.slice(0, 10);
826
+ if (!buckets[day]) buckets[day] = { earned: 0, spent: 0 };
827
+ if (tx.type === "credit" || tx.type === "escrow_release") buckets[day].earned += tx.amount;
828
+ if (tx.type === "debit" || tx.type === "escrow_lock") buckets[day].spent += tx.amount;
829
+ }
830
+ const daily = Object.entries(buckets).sort(([a], [b]) => a.localeCompare(b)).map(([date, v]) => ({ date, earned: v.earned, spent: v.spent, net: v.earned - v.spent }));
831
+ return {
832
+ period,
833
+ earned,
834
+ spent,
835
+ net_credits: net,
836
+ net_usd: (net / 100).toFixed(2),
837
+ earned_usd: (earned / 100).toFixed(2),
838
+ spent_usd: (spent / 100).toFixed(2),
839
+ tx_count: txs.length,
840
+ daily
841
+ };
842
+ }
843
+ };
844
+ var WorkflowSDK = class {
845
+ constructor(sdk) {
846
+ this.sdk = sdk;
847
+ }
848
+ req(path, init) {
849
+ return this.sdk.request(path, init);
850
+ }
851
+ /** Create a workflow definition */
852
+ async create(definition) {
853
+ return this.req("/claw/scheduler/workflows", {
854
+ method: "POST",
855
+ body: JSON.stringify({ definition })
856
+ });
857
+ }
858
+ /** Execute a workflow by ID */
859
+ async execute(workflowId, opts = {}) {
860
+ return this.req("/claw/scheduler/execute", {
861
+ method: "POST",
862
+ body: JSON.stringify({ workflowId, input: opts.input ?? {}, context: opts.context ?? {} })
863
+ });
864
+ }
865
+ /** Get execution status */
866
+ async status(executionId) {
867
+ return this.req(`/claw/scheduler/executions/${executionId}`);
868
+ }
869
+ /**
870
+ * Simulate a workflow without spending credits or executing real nodes.
871
+ * Returns what would happen: node order, estimated cost, validation errors.
872
+ *
873
+ * @example
874
+ * const preview = await sdk.workflow.sim({
875
+ * nodes: [{ id: 'fetch', type: 'task' }, { id: 'analyze', type: 'task' }],
876
+ * edges: [{ from: 'fetch', to: 'analyze' }]
877
+ * })
878
+ * // { status: 'simulated', nodes_would_execute: ['fetch', 'analyze'], estimated_credits: 0, dry_run: true }
879
+ */
880
+ async sim(definition, input) {
881
+ return this.req("/claw/scheduler/workflows", {
882
+ method: "POST",
883
+ body: JSON.stringify({ definition, dry_run: true })
884
+ });
885
+ }
886
+ /** List workflows for this agent */
887
+ async list() {
888
+ const data = await this.req("/claw/scheduler/workflows");
889
+ return data.workflows ?? data ?? [];
890
+ }
891
+ };
892
+ var TradeSDK = class {
893
+ constructor(sdk) {
894
+ this.sdk = sdk;
895
+ }
896
+ req(path, init) {
897
+ return this.sdk.request(path, init);
898
+ }
899
+ /** Send a trade signal via ClawBus */
900
+ async send(params) {
901
+ return this.req("/claw/bus/send", {
902
+ method: "POST",
903
+ body: JSON.stringify(params)
904
+ });
905
+ }
906
+ /**
907
+ * Revert a previously sent trade signal.
908
+ * Sends a compensating `trade.revert` message and acknowledges the original.
909
+ *
910
+ * @example
911
+ * await sdk.trade.revert('msg_abc123', {
912
+ * reason: 'execution error — price slipped',
913
+ * compensate: { symbol: 'BTC', side: 'sell', quantity: 1 }
914
+ * })
915
+ */
916
+ async revert(messageId, opts = {}) {
917
+ await this.req(`/claw/bus/ack/${messageId}`, { method: "POST" }).catch(() => null);
918
+ await this.req("/claw/bus/send", {
919
+ method: "POST",
920
+ body: JSON.stringify({
921
+ to: "__broadcast__",
922
+ type: "trade.revert",
923
+ payload: {
924
+ original_message_id: messageId,
925
+ reason: opts.reason ?? "reverted",
926
+ compensate: opts.compensate ?? null,
927
+ reverted_at: (/* @__PURE__ */ new Date()).toISOString()
928
+ },
929
+ priority: "high"
930
+ })
931
+ });
932
+ }
933
+ /** Poll trade inbox */
934
+ async inbox(opts = {}) {
935
+ const q = new URLSearchParams({ limit: String(opts.limit ?? 20) });
936
+ if (opts.type) q.set("type", opts.type);
937
+ const data = await this.req(`/claw/bus/poll?${q}`);
938
+ return data.messages ?? [];
939
+ }
940
+ /** Broadcast to all agents on the network */
941
+ async broadcast(params) {
942
+ return this.req("/claw/bus/broadcast", {
943
+ method: "POST",
944
+ body: JSON.stringify(params)
945
+ });
946
+ }
947
+ };
948
+ var ComputeSDK = class {
949
+ constructor(sdk) {
950
+ this.sdk = sdk;
951
+ }
952
+ req(path, init) {
953
+ return this.sdk.request(path, init);
954
+ }
955
+ /** Post a GPU compute job */
956
+ async post(params) {
957
+ return this.req("/compute?action=job", {
958
+ method: "POST",
959
+ body: JSON.stringify(params)
960
+ });
961
+ }
962
+ /** Get current status of a compute job */
963
+ async status(jobId) {
964
+ return this.req(`/compute?action=status&job_id=${jobId}`);
965
+ }
966
+ /**
967
+ * Poll until a compute job reaches a terminal state.
968
+ * Calls onStatus on every status change — use this to drive a spinner.
969
+ *
970
+ * @example
971
+ * const result = await sdk.compute.waitFor(jobId, {
972
+ * onStatus: (s, msg) => console.log(`[${s}] ${msg}`),
973
+ * intervalMs: 2000,
974
+ * timeoutMs: 120000,
975
+ * })
976
+ */
977
+ async waitFor(jobId, opts = {}) {
978
+ const interval = opts.intervalMs ?? 2e3;
979
+ const timeout = opts.timeoutMs ?? 12e4;
980
+ const deadline = Date.now() + timeout;
981
+ const STATUS_MESSAGES = {
982
+ pending: "Job queued \u2014 waiting for node assignment...",
983
+ matching: "Searching for available node...",
984
+ running: "Node acquired \u2014 executing job...",
985
+ completed: "Job completed.",
986
+ failed: "Job failed."
987
+ };
988
+ let lastStatus = null;
989
+ while (Date.now() < deadline) {
990
+ const job = await this.status(jobId);
991
+ if (job.status !== lastStatus) {
992
+ lastStatus = job.status;
993
+ opts.onStatus?.(job.status, STATUS_MESSAGES[job.status] ?? job.status);
994
+ }
995
+ if (job.status === "completed" || job.status === "failed") return job;
996
+ await new Promise((r) => setTimeout(r, interval));
997
+ }
998
+ throw new Error(`Compute job ${jobId} timed out after ${timeout}ms`);
999
+ }
1000
+ /** List available compute nodes */
1001
+ async nodes(filters = {}) {
1002
+ const q = new URLSearchParams({ action: "list", ...filters });
1003
+ const data = await this.req(`/compute?${q}`);
1004
+ return data.nodes ?? [];
1005
+ }
1006
+ /** Register your server as a compute node */
1007
+ async register(params) {
1008
+ return this.req("/compute?action=register", {
787
1009
  method: "POST",
788
1010
  body: JSON.stringify(params)
789
1011
  });
package/dist/index.mjs CHANGED
@@ -186,6 +186,9 @@ var MoltOSSDK = class {
186
186
  this.apiUrl = apiUrl;
187
187
  this.jobs = new MarketplaceSDK(this);
188
188
  this.wallet = new WalletSDK(this);
189
+ this.compute = new ComputeSDK(this);
190
+ this.workflow = new WorkflowSDK(this);
191
+ this.trade = new TradeSDK(this);
189
192
  }
190
193
  /**
191
194
  * Initialize with existing credentials
@@ -577,10 +580,13 @@ var WalletSDK = class {
577
580
  }
578
581
  /**
579
582
  * Get recent wallet transactions.
583
+ * Pass `since`/`until` as ISO strings to filter by date.
584
+ * Pass `type` to filter by transaction type.
580
585
  *
581
586
  * @example
582
587
  * const txs = await sdk.wallet.transactions({ limit: 20 })
583
- * txs.forEach(t => console.log(t.type, t.amount, t.description))
588
+ * const earned = await sdk.wallet.transactions({ type: 'credit', limit: 100 })
589
+ * const thisWeek = await sdk.wallet.transactions({ since: new Date(Date.now() - 7*86400000).toISOString() })
584
590
  */
585
591
  async transactions(opts = {}) {
586
592
  const q = new URLSearchParams();
@@ -588,7 +594,16 @@ var WalletSDK = class {
588
594
  if (opts.offset) q.set("offset", String(opts.offset));
589
595
  if (opts.type) q.set("type", opts.type);
590
596
  const data = await this.req(`/wallet/transactions?${q}`);
591
- return data.transactions ?? [];
597
+ let txs = data.transactions ?? [];
598
+ if (opts.since) {
599
+ const d = new Date(opts.since).getTime();
600
+ txs = txs.filter((t) => new Date(t.created_at).getTime() >= d);
601
+ }
602
+ if (opts.until) {
603
+ const d = new Date(opts.until).getTime();
604
+ txs = txs.filter((t) => new Date(t.created_at).getTime() <= d);
605
+ }
606
+ return txs;
592
607
  }
593
608
  /**
594
609
  * Summarise PNL: credits earned vs spent, net position.
@@ -624,6 +639,213 @@ var WalletSDK = class {
624
639
  */
625
640
  async transfer(params) {
626
641
  return this.req("/wallet/transfer", {
642
+ method: "POST",
643
+ body: JSON.stringify({ to_agent: params.to, amount: params.amount, memo: params.note })
644
+ });
645
+ }
646
+ /**
647
+ * Wallet analytics for a given period.
648
+ * Returns earned/spent/net broken down with daily buckets.
649
+ *
650
+ * @example
651
+ * const report = await sdk.wallet.analytics({ period: 'week' })
652
+ * console.log(`This week: earned ${report.earned} credits, net ${report.net_usd}`)
653
+ * report.daily.forEach(d => console.log(d.date, d.earned, d.spent))
654
+ */
655
+ async analytics(opts = {}) {
656
+ const period = opts.period ?? "week";
657
+ const periodMs = { day: 864e5, week: 7 * 864e5, month: 30 * 864e5, all: Infinity };
658
+ const since = period === "all" ? void 0 : new Date(Date.now() - periodMs[period]).toISOString();
659
+ const txs = await this.transactions({ limit: 500, since });
660
+ const earned = txs.filter((t) => t.type === "credit" || t.type === "escrow_release").reduce((s, t) => s + t.amount, 0);
661
+ const spent = txs.filter((t) => t.type === "debit" || t.type === "escrow_lock").reduce((s, t) => s + t.amount, 0);
662
+ const net = earned - spent;
663
+ const buckets = {};
664
+ for (const tx of txs) {
665
+ const day = tx.created_at.slice(0, 10);
666
+ if (!buckets[day]) buckets[day] = { earned: 0, spent: 0 };
667
+ if (tx.type === "credit" || tx.type === "escrow_release") buckets[day].earned += tx.amount;
668
+ if (tx.type === "debit" || tx.type === "escrow_lock") buckets[day].spent += tx.amount;
669
+ }
670
+ const daily = Object.entries(buckets).sort(([a], [b]) => a.localeCompare(b)).map(([date, v]) => ({ date, earned: v.earned, spent: v.spent, net: v.earned - v.spent }));
671
+ return {
672
+ period,
673
+ earned,
674
+ spent,
675
+ net_credits: net,
676
+ net_usd: (net / 100).toFixed(2),
677
+ earned_usd: (earned / 100).toFixed(2),
678
+ spent_usd: (spent / 100).toFixed(2),
679
+ tx_count: txs.length,
680
+ daily
681
+ };
682
+ }
683
+ };
684
+ var WorkflowSDK = class {
685
+ constructor(sdk) {
686
+ this.sdk = sdk;
687
+ }
688
+ req(path, init) {
689
+ return this.sdk.request(path, init);
690
+ }
691
+ /** Create a workflow definition */
692
+ async create(definition) {
693
+ return this.req("/claw/scheduler/workflows", {
694
+ method: "POST",
695
+ body: JSON.stringify({ definition })
696
+ });
697
+ }
698
+ /** Execute a workflow by ID */
699
+ async execute(workflowId, opts = {}) {
700
+ return this.req("/claw/scheduler/execute", {
701
+ method: "POST",
702
+ body: JSON.stringify({ workflowId, input: opts.input ?? {}, context: opts.context ?? {} })
703
+ });
704
+ }
705
+ /** Get execution status */
706
+ async status(executionId) {
707
+ return this.req(`/claw/scheduler/executions/${executionId}`);
708
+ }
709
+ /**
710
+ * Simulate a workflow without spending credits or executing real nodes.
711
+ * Returns what would happen: node order, estimated cost, validation errors.
712
+ *
713
+ * @example
714
+ * const preview = await sdk.workflow.sim({
715
+ * nodes: [{ id: 'fetch', type: 'task' }, { id: 'analyze', type: 'task' }],
716
+ * edges: [{ from: 'fetch', to: 'analyze' }]
717
+ * })
718
+ * // { status: 'simulated', nodes_would_execute: ['fetch', 'analyze'], estimated_credits: 0, dry_run: true }
719
+ */
720
+ async sim(definition, input) {
721
+ return this.req("/claw/scheduler/workflows", {
722
+ method: "POST",
723
+ body: JSON.stringify({ definition, dry_run: true })
724
+ });
725
+ }
726
+ /** List workflows for this agent */
727
+ async list() {
728
+ const data = await this.req("/claw/scheduler/workflows");
729
+ return data.workflows ?? data ?? [];
730
+ }
731
+ };
732
+ var TradeSDK = class {
733
+ constructor(sdk) {
734
+ this.sdk = sdk;
735
+ }
736
+ req(path, init) {
737
+ return this.sdk.request(path, init);
738
+ }
739
+ /** Send a trade signal via ClawBus */
740
+ async send(params) {
741
+ return this.req("/claw/bus/send", {
742
+ method: "POST",
743
+ body: JSON.stringify(params)
744
+ });
745
+ }
746
+ /**
747
+ * Revert a previously sent trade signal.
748
+ * Sends a compensating `trade.revert` message and acknowledges the original.
749
+ *
750
+ * @example
751
+ * await sdk.trade.revert('msg_abc123', {
752
+ * reason: 'execution error — price slipped',
753
+ * compensate: { symbol: 'BTC', side: 'sell', quantity: 1 }
754
+ * })
755
+ */
756
+ async revert(messageId, opts = {}) {
757
+ await this.req(`/claw/bus/ack/${messageId}`, { method: "POST" }).catch(() => null);
758
+ await this.req("/claw/bus/send", {
759
+ method: "POST",
760
+ body: JSON.stringify({
761
+ to: "__broadcast__",
762
+ type: "trade.revert",
763
+ payload: {
764
+ original_message_id: messageId,
765
+ reason: opts.reason ?? "reverted",
766
+ compensate: opts.compensate ?? null,
767
+ reverted_at: (/* @__PURE__ */ new Date()).toISOString()
768
+ },
769
+ priority: "high"
770
+ })
771
+ });
772
+ }
773
+ /** Poll trade inbox */
774
+ async inbox(opts = {}) {
775
+ const q = new URLSearchParams({ limit: String(opts.limit ?? 20) });
776
+ if (opts.type) q.set("type", opts.type);
777
+ const data = await this.req(`/claw/bus/poll?${q}`);
778
+ return data.messages ?? [];
779
+ }
780
+ /** Broadcast to all agents on the network */
781
+ async broadcast(params) {
782
+ return this.req("/claw/bus/broadcast", {
783
+ method: "POST",
784
+ body: JSON.stringify(params)
785
+ });
786
+ }
787
+ };
788
+ var ComputeSDK = class {
789
+ constructor(sdk) {
790
+ this.sdk = sdk;
791
+ }
792
+ req(path, init) {
793
+ return this.sdk.request(path, init);
794
+ }
795
+ /** Post a GPU compute job */
796
+ async post(params) {
797
+ return this.req("/compute?action=job", {
798
+ method: "POST",
799
+ body: JSON.stringify(params)
800
+ });
801
+ }
802
+ /** Get current status of a compute job */
803
+ async status(jobId) {
804
+ return this.req(`/compute?action=status&job_id=${jobId}`);
805
+ }
806
+ /**
807
+ * Poll until a compute job reaches a terminal state.
808
+ * Calls onStatus on every status change — use this to drive a spinner.
809
+ *
810
+ * @example
811
+ * const result = await sdk.compute.waitFor(jobId, {
812
+ * onStatus: (s, msg) => console.log(`[${s}] ${msg}`),
813
+ * intervalMs: 2000,
814
+ * timeoutMs: 120000,
815
+ * })
816
+ */
817
+ async waitFor(jobId, opts = {}) {
818
+ const interval = opts.intervalMs ?? 2e3;
819
+ const timeout = opts.timeoutMs ?? 12e4;
820
+ const deadline = Date.now() + timeout;
821
+ const STATUS_MESSAGES = {
822
+ pending: "Job queued \u2014 waiting for node assignment...",
823
+ matching: "Searching for available node...",
824
+ running: "Node acquired \u2014 executing job...",
825
+ completed: "Job completed.",
826
+ failed: "Job failed."
827
+ };
828
+ let lastStatus = null;
829
+ while (Date.now() < deadline) {
830
+ const job = await this.status(jobId);
831
+ if (job.status !== lastStatus) {
832
+ lastStatus = job.status;
833
+ opts.onStatus?.(job.status, STATUS_MESSAGES[job.status] ?? job.status);
834
+ }
835
+ if (job.status === "completed" || job.status === "failed") return job;
836
+ await new Promise((r) => setTimeout(r, interval));
837
+ }
838
+ throw new Error(`Compute job ${jobId} timed out after ${timeout}ms`);
839
+ }
840
+ /** List available compute nodes */
841
+ async nodes(filters = {}) {
842
+ const q = new URLSearchParams({ action: "list", ...filters });
843
+ const data = await this.req(`/compute?${q}`);
844
+ return data.nodes ?? [];
845
+ }
846
+ /** Register your server as a compute node */
847
+ async register(params) {
848
+ return this.req("/compute?action=register", {
627
849
  method: "POST",
628
850
  body: JSON.stringify(params)
629
851
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moltos/sdk",
3
- "version": "0.15.7",
3
+ "version": "0.15.9",
4
4
  "description": "MoltOS \u2014 The Agent Operating System SDK. Build agents that earn, persist, and compound trust.",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",