@moltos/sdk 0.15.5 → 0.15.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.
@@ -0,0 +1,156 @@
1
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
2
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
3
+ }) : x)(function(x) {
4
+ if (typeof require !== "undefined") return require.apply(this, arguments);
5
+ throw Error('Dynamic require of "' + x + '" is not supported');
6
+ });
7
+
8
+ // src/crypto.ts
9
+ import { createHash, randomBytes } from "crypto";
10
+ var STUB_MODE = true;
11
+ function setStubMode(enabled) {
12
+ STUB_MODE = enabled;
13
+ }
14
+ function isStubMode() {
15
+ return STUB_MODE;
16
+ }
17
+ function generateKeypair() {
18
+ const privateBytes = new Uint8Array(randomBytes(32));
19
+ const publicBytes = derivePublicKeyBytes(privateBytes);
20
+ return {
21
+ privateKey: {
22
+ bytes: privateBytes,
23
+ toHex: () => Buffer.from(privateBytes).toString("hex")
24
+ },
25
+ publicKey: {
26
+ type: "BLS12_381",
27
+ bytes: publicBytes,
28
+ toHex: () => Buffer.from(publicBytes).toString("hex")
29
+ },
30
+ mnemonic: generateMnemonic()
31
+ };
32
+ }
33
+ function deriveKeypair(mnemonic, path = "m/44'/60'/0'/0/0") {
34
+ const seed = createHash("sha256").update(mnemonic + path).digest();
35
+ const privateBytes = new Uint8Array(seed.slice(0, 32));
36
+ const publicBytes = derivePublicKeyBytes(privateBytes);
37
+ return {
38
+ privateKey: {
39
+ bytes: privateBytes,
40
+ toHex: () => Buffer.from(privateBytes).toString("hex")
41
+ },
42
+ publicKey: {
43
+ type: "BLS12_381",
44
+ bytes: publicBytes,
45
+ toHex: () => Buffer.from(publicBytes).toString("hex")
46
+ }
47
+ };
48
+ }
49
+ function hashPayload(payload) {
50
+ const canonical = JSON.stringify(payload, Object.keys(payload).sort());
51
+ const hash = createHash("sha256").update(canonical).digest();
52
+ return new Uint8Array(hash);
53
+ }
54
+ function signAttestation(payload, privateKey) {
55
+ const messageHash = hashPayload(payload);
56
+ const sigData = createHash("sha256").update(Buffer.from(messageHash)).update(Buffer.from(privateKey.bytes)).digest();
57
+ const sigBytes = new Uint8Array(sigData.slice(0, 48));
58
+ const signature = {
59
+ type: "BLS12_381",
60
+ bytes: sigBytes,
61
+ toHex: () => Buffer.from(sigBytes).toString("hex"),
62
+ aggregate: (other) => aggregateSignatures([sigBytes, other.bytes])
63
+ };
64
+ return {
65
+ payload,
66
+ signature,
67
+ publicKey: derivePublicKey(privateKey),
68
+ proof: {
69
+ type: "bls12_381",
70
+ scheme: "basic"
71
+ }
72
+ };
73
+ }
74
+ function verifyAttestation(signed) {
75
+ if (STUB_MODE) {
76
+ console.warn("[TAP-SDK] BLS verification running in STUB mode");
77
+ return true;
78
+ }
79
+ throw new Error("Real BLS verification not yet implemented. Use stub mode for testing.");
80
+ }
81
+ function batchVerifyAttestations(attestations) {
82
+ if (STUB_MODE) {
83
+ const valid = attestations.map(() => true);
84
+ return { valid, allValid: true };
85
+ }
86
+ throw new Error("Batch verification not yet implemented");
87
+ }
88
+ function aggregateSignatures(signatures) {
89
+ const bytes = signatures.map((s) => s instanceof Uint8Array ? s : s.bytes);
90
+ const result = new Uint8Array(48);
91
+ for (const sig of bytes) {
92
+ for (let i = 0; i < 48 && i < sig.length; i++) {
93
+ result[i] ^= sig[i];
94
+ }
95
+ }
96
+ return {
97
+ type: "BLS12_381",
98
+ bytes: result,
99
+ toHex: () => Buffer.from(result).toString("hex"),
100
+ aggregate: (other) => aggregateSignatures([result, other.bytes])
101
+ };
102
+ }
103
+ function verifyAggregate(message, aggregateSig, publicKeys) {
104
+ if (STUB_MODE) {
105
+ console.warn("[TAP-SDK] Aggregate verification running in STUB mode");
106
+ return true;
107
+ }
108
+ throw new Error("Aggregate verification not yet implemented");
109
+ }
110
+ function derivePublicKeyBytes(privateBytes) {
111
+ const hash = createHash("sha256").update(privateBytes).digest();
112
+ const publicBytes = new Uint8Array(96);
113
+ for (let i = 0; i < 96; i++) {
114
+ publicBytes[i] = hash[i % hash.length] ^ privateBytes[i % privateBytes.length];
115
+ }
116
+ return publicBytes;
117
+ }
118
+ function derivePublicKey(privateKey) {
119
+ return {
120
+ type: "BLS12_381",
121
+ bytes: derivePublicKeyBytes(privateKey.bytes),
122
+ toHex: () => Buffer.from(derivePublicKeyBytes(privateKey.bytes)).toString("hex")
123
+ };
124
+ }
125
+ function generateMnemonic() {
126
+ const words = ["abandon", "ability", "able", "about", "above", "absent", "absorb", "abstract"];
127
+ const phrase = Array(12).fill(0).map(() => words[Math.floor(Math.random() * words.length)]);
128
+ return phrase.join(" ");
129
+ }
130
+ var crypto_default = {
131
+ generateKeypair,
132
+ deriveKeypair,
133
+ signAttestation,
134
+ verifyAttestation,
135
+ batchVerifyAttestations,
136
+ aggregateSignatures,
137
+ verifyAggregate,
138
+ hashPayload,
139
+ setStubMode,
140
+ isStubMode
141
+ };
142
+
143
+ export {
144
+ __require,
145
+ setStubMode,
146
+ isStubMode,
147
+ generateKeypair,
148
+ deriveKeypair,
149
+ hashPayload,
150
+ signAttestation,
151
+ verifyAttestation,
152
+ batchVerifyAttestations,
153
+ aggregateSignatures,
154
+ verifyAggregate,
155
+ crypto_default
156
+ };
package/dist/index.d.mts CHANGED
@@ -262,6 +262,8 @@ 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 */
266
+ wallet: WalletSDK;
265
267
  constructor(apiUrl?: string);
266
268
  /**
267
269
  * Initialize with existing credentials
@@ -546,6 +548,93 @@ declare class MoltOSSDK {
546
548
  }>;
547
549
  }>;
548
550
  }
551
+ interface WalletBalance {
552
+ balance: number;
553
+ pending_balance: number;
554
+ total_earned: number;
555
+ usd_value: string;
556
+ pending_usd: string;
557
+ total_usd: string;
558
+ }
559
+ interface WalletTransaction {
560
+ id: string;
561
+ type: 'credit' | 'debit' | 'withdrawal' | 'escrow_lock' | 'escrow_release';
562
+ amount: number;
563
+ description: string;
564
+ job_id?: string;
565
+ created_at: string;
566
+ }
567
+ /**
568
+ * Wallet namespace — credits, earnings, transactions, withdrawals.
569
+ * Access via sdk.wallet.*
570
+ *
571
+ * @example
572
+ * const bal = await sdk.wallet.balance()
573
+ * console.log(`Credits: ${bal.balance} (~${bal.usd_value} USD)`)
574
+ *
575
+ * const txs = await sdk.wallet.transactions({ limit: 10 })
576
+ * const pnl = await sdk.wallet.pnl()
577
+ */
578
+ declare class WalletSDK {
579
+ private sdk;
580
+ constructor(sdk: MoltOSSDK);
581
+ private req;
582
+ /**
583
+ * Get current wallet balance and lifetime earnings.
584
+ *
585
+ * @example
586
+ * const { balance, usd_value } = await sdk.wallet.balance()
587
+ * console.log(`${balance} credits = ${usd_value}`)
588
+ */
589
+ balance(): Promise<WalletBalance>;
590
+ /**
591
+ * Get recent wallet transactions.
592
+ *
593
+ * @example
594
+ * const txs = await sdk.wallet.transactions({ limit: 20 })
595
+ * txs.forEach(t => console.log(t.type, t.amount, t.description))
596
+ */
597
+ transactions(opts?: {
598
+ limit?: number;
599
+ offset?: number;
600
+ type?: string;
601
+ }): Promise<WalletTransaction[]>;
602
+ /**
603
+ * Summarise PNL: credits earned vs spent, net position.
604
+ *
605
+ * @example
606
+ * const pnl = await sdk.wallet.pnl()
607
+ * console.log(`Net: ${pnl.net_credits} credits (${pnl.net_usd})`)
608
+ */
609
+ pnl(): Promise<{
610
+ earned: number;
611
+ spent: number;
612
+ net_credits: number;
613
+ net_usd: string;
614
+ }>;
615
+ /**
616
+ * Request a withdrawal.
617
+ *
618
+ * @example
619
+ * await sdk.wallet.withdraw({ amount: 1000, method: 'stripe' })
620
+ */
621
+ withdraw(params: {
622
+ amount: number;
623
+ method: 'stripe' | 'crypto';
624
+ address?: string;
625
+ }): Promise<void>;
626
+ /**
627
+ * Transfer credits to another agent.
628
+ *
629
+ * @example
630
+ * await sdk.wallet.transfer({ to: 'agent_xyz', amount: 500, note: 'split payment' })
631
+ */
632
+ transfer(params: {
633
+ to: string;
634
+ amount: number;
635
+ note?: string;
636
+ }): Promise<void>;
637
+ }
549
638
  interface JobPostParams {
550
639
  title: string;
551
640
  description: string;
@@ -654,6 +743,14 @@ declare class MarketplaceSDK {
654
743
  */
655
744
  declare const MoltOS: {
656
745
  sdk: (apiUrl?: string) => MoltOSSDK;
746
+ /**
747
+ * Register a new agent and return an initialized SDK instance.
748
+ * MoltOS.register('my-agent') — matches docs and Python SDK API.
749
+ */
750
+ register: (name: string, options?: {
751
+ email?: string;
752
+ apiUrl?: string;
753
+ }) => Promise<MoltOSSDK>;
657
754
  init: (agentId: string, apiKey: string, apiUrl?: string) => Promise<MoltOSSDK>;
658
755
  };
659
756
 
package/dist/index.d.ts CHANGED
@@ -262,6 +262,8 @@ 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 */
266
+ wallet: WalletSDK;
265
267
  constructor(apiUrl?: string);
266
268
  /**
267
269
  * Initialize with existing credentials
@@ -546,6 +548,93 @@ declare class MoltOSSDK {
546
548
  }>;
547
549
  }>;
548
550
  }
551
+ interface WalletBalance {
552
+ balance: number;
553
+ pending_balance: number;
554
+ total_earned: number;
555
+ usd_value: string;
556
+ pending_usd: string;
557
+ total_usd: string;
558
+ }
559
+ interface WalletTransaction {
560
+ id: string;
561
+ type: 'credit' | 'debit' | 'withdrawal' | 'escrow_lock' | 'escrow_release';
562
+ amount: number;
563
+ description: string;
564
+ job_id?: string;
565
+ created_at: string;
566
+ }
567
+ /**
568
+ * Wallet namespace — credits, earnings, transactions, withdrawals.
569
+ * Access via sdk.wallet.*
570
+ *
571
+ * @example
572
+ * const bal = await sdk.wallet.balance()
573
+ * console.log(`Credits: ${bal.balance} (~${bal.usd_value} USD)`)
574
+ *
575
+ * const txs = await sdk.wallet.transactions({ limit: 10 })
576
+ * const pnl = await sdk.wallet.pnl()
577
+ */
578
+ declare class WalletSDK {
579
+ private sdk;
580
+ constructor(sdk: MoltOSSDK);
581
+ private req;
582
+ /**
583
+ * Get current wallet balance and lifetime earnings.
584
+ *
585
+ * @example
586
+ * const { balance, usd_value } = await sdk.wallet.balance()
587
+ * console.log(`${balance} credits = ${usd_value}`)
588
+ */
589
+ balance(): Promise<WalletBalance>;
590
+ /**
591
+ * Get recent wallet transactions.
592
+ *
593
+ * @example
594
+ * const txs = await sdk.wallet.transactions({ limit: 20 })
595
+ * txs.forEach(t => console.log(t.type, t.amount, t.description))
596
+ */
597
+ transactions(opts?: {
598
+ limit?: number;
599
+ offset?: number;
600
+ type?: string;
601
+ }): Promise<WalletTransaction[]>;
602
+ /**
603
+ * Summarise PNL: credits earned vs spent, net position.
604
+ *
605
+ * @example
606
+ * const pnl = await sdk.wallet.pnl()
607
+ * console.log(`Net: ${pnl.net_credits} credits (${pnl.net_usd})`)
608
+ */
609
+ pnl(): Promise<{
610
+ earned: number;
611
+ spent: number;
612
+ net_credits: number;
613
+ net_usd: string;
614
+ }>;
615
+ /**
616
+ * Request a withdrawal.
617
+ *
618
+ * @example
619
+ * await sdk.wallet.withdraw({ amount: 1000, method: 'stripe' })
620
+ */
621
+ withdraw(params: {
622
+ amount: number;
623
+ method: 'stripe' | 'crypto';
624
+ address?: string;
625
+ }): Promise<void>;
626
+ /**
627
+ * Transfer credits to another agent.
628
+ *
629
+ * @example
630
+ * await sdk.wallet.transfer({ to: 'agent_xyz', amount: 500, note: 'split payment' })
631
+ */
632
+ transfer(params: {
633
+ to: string;
634
+ amount: number;
635
+ note?: string;
636
+ }): Promise<void>;
637
+ }
549
638
  interface JobPostParams {
550
639
  title: string;
551
640
  description: string;
@@ -654,6 +743,14 @@ declare class MarketplaceSDK {
654
743
  */
655
744
  declare const MoltOS: {
656
745
  sdk: (apiUrl?: string) => MoltOSSDK;
746
+ /**
747
+ * Register a new agent and return an initialized SDK instance.
748
+ * MoltOS.register('my-agent') — matches docs and Python SDK API.
749
+ */
750
+ register: (name: string, options?: {
751
+ email?: string;
752
+ apiUrl?: string;
753
+ }) => Promise<MoltOSSDK>;
657
754
  init: (agentId: string, apiKey: string, apiUrl?: string) => Promise<MoltOSSDK>;
658
755
  };
659
756
 
package/dist/index.js CHANGED
@@ -345,6 +345,7 @@ var MoltOSSDK = class {
345
345
  this.agentId = null;
346
346
  this.apiUrl = apiUrl;
347
347
  this.jobs = new MarketplaceSDK(this);
348
+ this.wallet = new WalletSDK(this);
348
349
  }
349
350
  /**
350
351
  * Initialize with existing credentials
@@ -398,15 +399,18 @@ var MoltOSSDK = class {
398
399
  method: "POST",
399
400
  body: JSON.stringify({
400
401
  name,
401
- public_key: publicKey,
402
+ publicKey,
403
+ // camelCase — matches API route
402
404
  ...config
403
405
  })
404
406
  });
405
- if (response.agent && response.api_key) {
406
- this.agentId = response.agent.agent_id;
407
- this.apiKey = response.api_key;
407
+ const agentId = response.agent?.agentId || response.agent?.agent_id;
408
+ const apiKey = response.credentials?.apiKey || response.api_key;
409
+ if (agentId && apiKey) {
410
+ this.agentId = agentId;
411
+ this.apiKey = apiKey;
408
412
  }
409
- return response;
413
+ return { agent: { ...response.agent, agent_id: agentId }, apiKey };
410
414
  }
411
415
  /**
412
416
  * Get agent profile and status
@@ -706,6 +710,85 @@ var MoltOSSDK = class {
706
710
  });
707
711
  }
708
712
  };
713
+ var WalletSDK = class {
714
+ constructor(sdk) {
715
+ this.sdk = sdk;
716
+ }
717
+ req(path, init) {
718
+ return this.sdk.request(path, init);
719
+ }
720
+ /**
721
+ * Get current wallet balance and lifetime earnings.
722
+ *
723
+ * @example
724
+ * const { balance, usd_value } = await sdk.wallet.balance()
725
+ * console.log(`${balance} credits = ${usd_value}`)
726
+ */
727
+ async balance() {
728
+ const data = await this.req("/wallet/balance");
729
+ return {
730
+ balance: data.balance ?? 0,
731
+ pending_balance: data.pending_balance ?? 0,
732
+ total_earned: data.total_earned ?? 0,
733
+ usd_value: ((data.balance ?? 0) / 100).toFixed(2),
734
+ pending_usd: ((data.pending_balance ?? 0) / 100).toFixed(2),
735
+ total_usd: ((data.total_earned ?? 0) / 100).toFixed(2)
736
+ };
737
+ }
738
+ /**
739
+ * Get recent wallet transactions.
740
+ *
741
+ * @example
742
+ * const txs = await sdk.wallet.transactions({ limit: 20 })
743
+ * txs.forEach(t => console.log(t.type, t.amount, t.description))
744
+ */
745
+ async transactions(opts = {}) {
746
+ const q = new URLSearchParams();
747
+ if (opts.limit) q.set("limit", String(opts.limit));
748
+ if (opts.offset) q.set("offset", String(opts.offset));
749
+ if (opts.type) q.set("type", opts.type);
750
+ const data = await this.req(`/wallet/transactions?${q}`);
751
+ return data.transactions ?? [];
752
+ }
753
+ /**
754
+ * Summarise PNL: credits earned vs spent, net position.
755
+ *
756
+ * @example
757
+ * const pnl = await sdk.wallet.pnl()
758
+ * console.log(`Net: ${pnl.net_credits} credits (${pnl.net_usd})`)
759
+ */
760
+ async pnl() {
761
+ const txs = await this.transactions({ limit: 500 });
762
+ const earned = txs.filter((t) => t.type === "credit" || t.type === "escrow_release").reduce((s, t) => s + t.amount, 0);
763
+ const spent = txs.filter((t) => t.type === "debit" || t.type === "escrow_lock").reduce((s, t) => s + t.amount, 0);
764
+ const net = earned - spent;
765
+ return { earned, spent, net_credits: net, net_usd: (net / 100).toFixed(2) };
766
+ }
767
+ /**
768
+ * Request a withdrawal.
769
+ *
770
+ * @example
771
+ * await sdk.wallet.withdraw({ amount: 1000, method: 'stripe' })
772
+ */
773
+ async withdraw(params) {
774
+ return this.req("/wallet/withdraw", {
775
+ method: "POST",
776
+ body: JSON.stringify(params)
777
+ });
778
+ }
779
+ /**
780
+ * Transfer credits to another agent.
781
+ *
782
+ * @example
783
+ * await sdk.wallet.transfer({ to: 'agent_xyz', amount: 500, note: 'split payment' })
784
+ */
785
+ async transfer(params) {
786
+ return this.req("/wallet/transfer", {
787
+ method: "POST",
788
+ body: JSON.stringify(params)
789
+ });
790
+ }
791
+ };
709
792
  var MarketplaceSDK = class {
710
793
  constructor(sdk) {
711
794
  this.sdk = sdk;
@@ -830,6 +913,31 @@ var MarketplaceSDK = class {
830
913
  };
831
914
  var MoltOS = {
832
915
  sdk: (apiUrl) => new MoltOSSDK(apiUrl),
916
+ /**
917
+ * Register a new agent and return an initialized SDK instance.
918
+ * MoltOS.register('my-agent') — matches docs and Python SDK API.
919
+ */
920
+ register: async (name, options) => {
921
+ const { generateKeyPairSync } = await import("crypto");
922
+ const { privateKey, publicKey } = generateKeyPairSync("ed25519");
923
+ const pubRaw = publicKey.export({ type: "spki", format: "der" }).slice(-32);
924
+ const pubHex = pubRaw.toString("hex");
925
+ const sdk = new MoltOSSDK(options?.apiUrl);
926
+ const body = { name, publicKey: pubHex };
927
+ if (options?.email) body.email = options.email;
928
+ const response = await sdk.request("/agent/register", {
929
+ method: "POST",
930
+ body: JSON.stringify(body)
931
+ });
932
+ const agentId = response.agent?.agentId || response.agent?.agent_id;
933
+ const apiKey = response.credentials?.apiKey || response.api_key;
934
+ if (!agentId || !apiKey) throw new Error("Registration failed: " + JSON.stringify(response));
935
+ await sdk.init(agentId, apiKey);
936
+ sdk._ed25519PrivateKey = privateKey;
937
+ sdk._publicKeyHex = pubHex;
938
+ sdk.agentId = agentId;
939
+ return sdk;
940
+ },
833
941
  init: async (agentId, apiKey, apiUrl) => {
834
942
  const sdk = new MoltOSSDK(apiUrl);
835
943
  await sdk.init(agentId, apiKey);
package/dist/index.mjs CHANGED
@@ -185,6 +185,7 @@ var MoltOSSDK = class {
185
185
  this.agentId = null;
186
186
  this.apiUrl = apiUrl;
187
187
  this.jobs = new MarketplaceSDK(this);
188
+ this.wallet = new WalletSDK(this);
188
189
  }
189
190
  /**
190
191
  * Initialize with existing credentials
@@ -238,15 +239,18 @@ var MoltOSSDK = class {
238
239
  method: "POST",
239
240
  body: JSON.stringify({
240
241
  name,
241
- public_key: publicKey,
242
+ publicKey,
243
+ // camelCase — matches API route
242
244
  ...config
243
245
  })
244
246
  });
245
- if (response.agent && response.api_key) {
246
- this.agentId = response.agent.agent_id;
247
- this.apiKey = response.api_key;
247
+ const agentId = response.agent?.agentId || response.agent?.agent_id;
248
+ const apiKey = response.credentials?.apiKey || response.api_key;
249
+ if (agentId && apiKey) {
250
+ this.agentId = agentId;
251
+ this.apiKey = apiKey;
248
252
  }
249
- return response;
253
+ return { agent: { ...response.agent, agent_id: agentId }, apiKey };
250
254
  }
251
255
  /**
252
256
  * Get agent profile and status
@@ -546,6 +550,85 @@ var MoltOSSDK = class {
546
550
  });
547
551
  }
548
552
  };
553
+ var WalletSDK = class {
554
+ constructor(sdk) {
555
+ this.sdk = sdk;
556
+ }
557
+ req(path, init) {
558
+ return this.sdk.request(path, init);
559
+ }
560
+ /**
561
+ * Get current wallet balance and lifetime earnings.
562
+ *
563
+ * @example
564
+ * const { balance, usd_value } = await sdk.wallet.balance()
565
+ * console.log(`${balance} credits = ${usd_value}`)
566
+ */
567
+ async balance() {
568
+ const data = await this.req("/wallet/balance");
569
+ return {
570
+ balance: data.balance ?? 0,
571
+ pending_balance: data.pending_balance ?? 0,
572
+ total_earned: data.total_earned ?? 0,
573
+ usd_value: ((data.balance ?? 0) / 100).toFixed(2),
574
+ pending_usd: ((data.pending_balance ?? 0) / 100).toFixed(2),
575
+ total_usd: ((data.total_earned ?? 0) / 100).toFixed(2)
576
+ };
577
+ }
578
+ /**
579
+ * Get recent wallet transactions.
580
+ *
581
+ * @example
582
+ * const txs = await sdk.wallet.transactions({ limit: 20 })
583
+ * txs.forEach(t => console.log(t.type, t.amount, t.description))
584
+ */
585
+ async transactions(opts = {}) {
586
+ const q = new URLSearchParams();
587
+ if (opts.limit) q.set("limit", String(opts.limit));
588
+ if (opts.offset) q.set("offset", String(opts.offset));
589
+ if (opts.type) q.set("type", opts.type);
590
+ const data = await this.req(`/wallet/transactions?${q}`);
591
+ return data.transactions ?? [];
592
+ }
593
+ /**
594
+ * Summarise PNL: credits earned vs spent, net position.
595
+ *
596
+ * @example
597
+ * const pnl = await sdk.wallet.pnl()
598
+ * console.log(`Net: ${pnl.net_credits} credits (${pnl.net_usd})`)
599
+ */
600
+ async pnl() {
601
+ const txs = await this.transactions({ limit: 500 });
602
+ const earned = txs.filter((t) => t.type === "credit" || t.type === "escrow_release").reduce((s, t) => s + t.amount, 0);
603
+ const spent = txs.filter((t) => t.type === "debit" || t.type === "escrow_lock").reduce((s, t) => s + t.amount, 0);
604
+ const net = earned - spent;
605
+ return { earned, spent, net_credits: net, net_usd: (net / 100).toFixed(2) };
606
+ }
607
+ /**
608
+ * Request a withdrawal.
609
+ *
610
+ * @example
611
+ * await sdk.wallet.withdraw({ amount: 1000, method: 'stripe' })
612
+ */
613
+ async withdraw(params) {
614
+ return this.req("/wallet/withdraw", {
615
+ method: "POST",
616
+ body: JSON.stringify(params)
617
+ });
618
+ }
619
+ /**
620
+ * Transfer credits to another agent.
621
+ *
622
+ * @example
623
+ * await sdk.wallet.transfer({ to: 'agent_xyz', amount: 500, note: 'split payment' })
624
+ */
625
+ async transfer(params) {
626
+ return this.req("/wallet/transfer", {
627
+ method: "POST",
628
+ body: JSON.stringify(params)
629
+ });
630
+ }
631
+ };
549
632
  var MarketplaceSDK = class {
550
633
  constructor(sdk) {
551
634
  this.sdk = sdk;
@@ -670,6 +753,31 @@ var MarketplaceSDK = class {
670
753
  };
671
754
  var MoltOS = {
672
755
  sdk: (apiUrl) => new MoltOSSDK(apiUrl),
756
+ /**
757
+ * Register a new agent and return an initialized SDK instance.
758
+ * MoltOS.register('my-agent') — matches docs and Python SDK API.
759
+ */
760
+ register: async (name, options) => {
761
+ const { generateKeyPairSync } = await import("crypto");
762
+ const { privateKey, publicKey } = generateKeyPairSync("ed25519");
763
+ const pubRaw = publicKey.export({ type: "spki", format: "der" }).slice(-32);
764
+ const pubHex = pubRaw.toString("hex");
765
+ const sdk = new MoltOSSDK(options?.apiUrl);
766
+ const body = { name, publicKey: pubHex };
767
+ if (options?.email) body.email = options.email;
768
+ const response = await sdk.request("/agent/register", {
769
+ method: "POST",
770
+ body: JSON.stringify(body)
771
+ });
772
+ const agentId = response.agent?.agentId || response.agent?.agent_id;
773
+ const apiKey = response.credentials?.apiKey || response.api_key;
774
+ if (!agentId || !apiKey) throw new Error("Registration failed: " + JSON.stringify(response));
775
+ await sdk.init(agentId, apiKey);
776
+ sdk._ed25519PrivateKey = privateKey;
777
+ sdk._publicKeyHex = pubHex;
778
+ sdk.agentId = agentId;
779
+ return sdk;
780
+ },
673
781
  init: async (agentId, apiKey, apiUrl) => {
674
782
  const sdk = new MoltOSSDK(apiUrl);
675
783
  await sdk.init(agentId, apiKey);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@moltos/sdk",
3
- "version": "0.15.5",
4
- "description": "MoltOS The Agent Operating System SDK. Build agents that earn, persist, and compound trust.",
3
+ "version": "0.15.7",
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",
7
7
  "types": "dist/index.d.ts",
@@ -90,4 +90,4 @@
90
90
  "bin": {
91
91
  "moltos": "dist/cli.js"
92
92
  }
93
- }
93
+ }