@1sat/wallet-toolbox 0.0.9 → 0.0.11

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.
Files changed (39) hide show
  1. package/dist/api/balance/index.d.ts +20 -8
  2. package/dist/api/balance/index.js +104 -51
  3. package/dist/api/broadcast/index.d.ts +5 -3
  4. package/dist/api/broadcast/index.js +65 -37
  5. package/dist/api/index.d.ts +16 -15
  6. package/dist/api/index.js +42 -17
  7. package/dist/api/inscriptions/index.d.ts +9 -9
  8. package/dist/api/inscriptions/index.js +79 -31
  9. package/dist/api/locks/index.d.ts +15 -12
  10. package/dist/api/locks/index.js +252 -194
  11. package/dist/api/ordinals/index.d.ts +50 -35
  12. package/dist/api/ordinals/index.js +469 -349
  13. package/dist/api/payments/index.d.ts +15 -4
  14. package/dist/api/payments/index.js +147 -92
  15. package/dist/api/signing/index.d.ts +8 -5
  16. package/dist/api/signing/index.js +70 -33
  17. package/dist/api/skills/registry.d.ts +61 -0
  18. package/dist/api/skills/registry.js +74 -0
  19. package/dist/api/skills/types.d.ts +71 -0
  20. package/dist/api/skills/types.js +14 -0
  21. package/dist/api/sweep/index.d.ts +23 -0
  22. package/dist/api/sweep/index.js +221 -0
  23. package/dist/api/sweep/types.d.ts +30 -0
  24. package/dist/api/sweep/types.js +4 -0
  25. package/dist/api/tokens/index.d.ts +37 -38
  26. package/dist/api/tokens/index.js +398 -341
  27. package/dist/index.d.ts +2 -1
  28. package/dist/index.js +2 -0
  29. package/dist/services/client/OwnerClient.js +4 -0
  30. package/dist/wallet/factory.d.ts +64 -0
  31. package/dist/wallet/factory.js +163 -0
  32. package/dist/wallet/index.d.ts +1 -0
  33. package/dist/wallet/index.js +1 -0
  34. package/package.json +13 -4
  35. package/dist/OneSatWallet.d.ts +0 -316
  36. package/dist/OneSatWallet.js +0 -956
  37. package/dist/api/OneSatApi.d.ts +0 -100
  38. package/dist/api/OneSatApi.js +0 -156
  39. package/dist/indexers/TransactionParser.d.ts +0 -53
@@ -1,9 +1,9 @@
1
1
  /**
2
2
  * Payments Module
3
3
  *
4
- * Functions for sending BSV payments.
4
+ * Skills for sending BSV payments.
5
5
  */
6
- import { type WalletInterface } from "@bsv/sdk";
6
+ import type { Skill } from "../skills/types";
7
7
  export interface SendBsvRequest {
8
8
  /** Destination address (P2PKH) */
9
9
  address?: string;
@@ -27,11 +27,22 @@ export interface SendBsvResponse {
27
27
  rawtx?: string;
28
28
  error?: string;
29
29
  }
30
+ /** Input for sendBsv skill */
31
+ export interface SendBsvInput {
32
+ requests: SendBsvRequest[];
33
+ }
30
34
  /**
31
35
  * Send BSV to one or more destinations.
32
36
  */
33
- export declare function sendBsv(cwi: WalletInterface, requests: SendBsvRequest[]): Promise<SendBsvResponse>;
37
+ export declare const sendBsv: Skill<SendBsvInput, SendBsvResponse>;
38
+ /** Input for sendAllBsv skill */
39
+ export interface SendAllBsvInput {
40
+ /** Destination address to send all funds to */
41
+ destination: string;
42
+ }
34
43
  /**
35
44
  * Send all BSV to a destination address.
36
45
  */
37
- export declare function sendAllBsv(cwi: WalletInterface, destination: string): Promise<SendBsvResponse>;
46
+ export declare const sendAllBsv: Skill<SendAllBsvInput, SendBsvResponse>;
47
+ /** All payment skills for registry */
48
+ export declare const paymentsSkills: (Skill<SendBsvInput, SendBsvResponse> | Skill<SendAllBsvInput, SendBsvResponse>)[];
@@ -1,20 +1,17 @@
1
1
  /**
2
2
  * Payments Module
3
3
  *
4
- * Functions for sending BSV payments.
4
+ * Skills for sending BSV payments.
5
5
  */
6
- import { P2PKH, Script, Utils, } from "@bsv/sdk";
6
+ import { P2PKH, Script, Utils } from "@bsv/sdk";
7
7
  import { Inscription } from "@bopen-io/templates";
8
8
  import { FUNDING_BASKET } from "../constants";
9
- /**
10
- * Check if address is a paymail.
11
- */
9
+ // ============================================================================
10
+ // Internal helpers
11
+ // ============================================================================
12
12
  function isPaymail(address) {
13
13
  return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(address);
14
14
  }
15
- /**
16
- * Build an inscription locking script.
17
- */
18
15
  function buildInscriptionScript(address, base64Data, mimeType) {
19
16
  const content = Utils.toArray(base64Data, "base64");
20
17
  const inscription = Inscription.create(new Uint8Array(content), mimeType);
@@ -30,101 +27,159 @@ function buildInscriptionScript(address, base64Data, mimeType) {
30
27
  /**
31
28
  * Send BSV to one or more destinations.
32
29
  */
33
- export async function sendBsv(cwi, requests) {
34
- try {
35
- if (!requests || requests.length === 0) {
36
- return { error: "no-requests" };
37
- }
38
- const outputs = [];
39
- for (const req of requests) {
40
- let lockingScript;
41
- if (req.script) {
42
- lockingScript = Script.fromHex(req.script);
30
+ export const sendBsv = {
31
+ meta: {
32
+ name: "sendBsv",
33
+ description: "Send BSV to one or more destinations (addresses, scripts, or OP_RETURN)",
34
+ category: "payments",
35
+ inputSchema: {
36
+ type: "object",
37
+ properties: {
38
+ requests: {
39
+ type: "array",
40
+ description: "Array of payment requests",
41
+ items: {
42
+ type: "object",
43
+ properties: {
44
+ address: { type: "string", description: "Destination P2PKH address" },
45
+ paymail: { type: "string", description: "Destination paymail address" },
46
+ satoshis: { type: "integer", description: "Amount in satoshis" },
47
+ script: { type: "string", description: "Custom locking script (hex)" },
48
+ data: {
49
+ type: "array",
50
+ description: "OP_RETURN data elements",
51
+ items: { type: "string" },
52
+ },
53
+ },
54
+ required: ["satoshis"],
55
+ },
56
+ },
57
+ },
58
+ required: ["requests"],
59
+ },
60
+ },
61
+ async execute(ctx, input) {
62
+ try {
63
+ const { requests } = input;
64
+ if (!requests || requests.length === 0) {
65
+ return { error: "no-requests" };
43
66
  }
44
- else if (req.address) {
45
- if (req.inscription) {
46
- lockingScript = buildInscriptionScript(req.address, req.inscription.base64Data, req.inscription.mimeType);
67
+ const outputs = [];
68
+ for (const req of requests) {
69
+ let lockingScript;
70
+ if (req.script) {
71
+ lockingScript = Script.fromHex(req.script);
47
72
  }
48
- else {
49
- lockingScript = new P2PKH().lock(req.address);
73
+ else if (req.address) {
74
+ if (req.inscription) {
75
+ lockingScript = buildInscriptionScript(req.address, req.inscription.base64Data, req.inscription.mimeType);
76
+ }
77
+ else {
78
+ lockingScript = new P2PKH().lock(req.address);
79
+ }
50
80
  }
51
- }
52
- else if (req.data && req.data.length > 0) {
53
- try {
54
- lockingScript = Script.fromASM(`OP_0 OP_RETURN ${req.data.join(" ")}`);
81
+ else if (req.data && req.data.length > 0) {
82
+ try {
83
+ lockingScript = Script.fromASM(`OP_0 OP_RETURN ${req.data.join(" ")}`);
84
+ }
85
+ catch {
86
+ return { error: "invalid-data" };
87
+ }
55
88
  }
56
- catch {
57
- return { error: "invalid-data" };
89
+ else if (req.paymail) {
90
+ return { error: "paymail-not-yet-implemented" };
58
91
  }
92
+ else {
93
+ return { error: "invalid-request" };
94
+ }
95
+ outputs.push({
96
+ lockingScript: lockingScript.toHex(),
97
+ satoshis: req.satoshis,
98
+ outputDescription: `Payment of ${req.satoshis} sats`,
99
+ });
59
100
  }
60
- else if (req.paymail) {
61
- return { error: "paymail-not-yet-implemented" };
62
- }
63
- else {
64
- return { error: "invalid-request" };
65
- }
66
- outputs.push({
67
- lockingScript: lockingScript.toHex(),
68
- satoshis: req.satoshis,
69
- outputDescription: `Payment of ${req.satoshis} sats`,
101
+ const result = await ctx.wallet.createAction({
102
+ description: `Send ${requests.length} payment(s)`,
103
+ outputs,
104
+ options: { signAndProcess: true },
70
105
  });
106
+ if (!result.txid) {
107
+ return { error: "no-txid-returned" };
108
+ }
109
+ return { txid: result.txid, rawtx: result.tx ? Utils.toHex(result.tx) : undefined };
71
110
  }
72
- const result = await cwi.createAction({
73
- description: `Send ${requests.length} payment(s)`,
74
- outputs,
75
- options: { signAndProcess: true },
76
- });
77
- if (!result.txid) {
78
- return { error: "no-txid-returned" };
111
+ catch (error) {
112
+ return { error: error instanceof Error ? error.message : "unknown-error" };
79
113
  }
80
- return { txid: result.txid, rawtx: result.tx ? Utils.toHex(result.tx) : undefined };
81
- }
82
- catch (error) {
83
- return { error: error instanceof Error ? error.message : "unknown-error" };
84
- }
85
- }
114
+ },
115
+ };
86
116
  /**
87
117
  * Send all BSV to a destination address.
88
118
  */
89
- export async function sendAllBsv(cwi, destination) {
90
- try {
91
- if (isPaymail(destination)) {
92
- return { error: "paymail-not-yet-implemented" };
93
- }
94
- const listResult = await cwi.listOutputs({
95
- basket: FUNDING_BASKET,
96
- include: "locking scripts",
97
- limit: 10000,
98
- });
99
- if (!listResult.outputs || listResult.outputs.length === 0) {
100
- return { error: "no-funds" };
101
- }
102
- const totalSats = listResult.outputs.reduce((sum, o) => sum + o.satoshis, 0);
103
- const estimatedFee = Math.ceil((listResult.outputs.length * 150 + 44) * 1);
104
- const sendAmount = totalSats - estimatedFee;
105
- if (sendAmount <= 0) {
106
- return { error: "insufficient-funds-for-fee" };
119
+ export const sendAllBsv = {
120
+ meta: {
121
+ name: "sendAllBsv",
122
+ description: "Send all BSV from wallet to a single destination address",
123
+ category: "payments",
124
+ inputSchema: {
125
+ type: "object",
126
+ properties: {
127
+ destination: {
128
+ type: "string",
129
+ description: "Destination P2PKH address to send all funds to",
130
+ },
131
+ },
132
+ required: ["destination"],
133
+ },
134
+ },
135
+ async execute(ctx, input) {
136
+ try {
137
+ const { destination } = input;
138
+ if (isPaymail(destination)) {
139
+ return { error: "paymail-not-yet-implemented" };
140
+ }
141
+ const listResult = await ctx.wallet.listOutputs({
142
+ basket: FUNDING_BASKET,
143
+ include: "locking scripts",
144
+ limit: 10000,
145
+ });
146
+ if (!listResult.outputs || listResult.outputs.length === 0) {
147
+ return { error: "no-funds" };
148
+ }
149
+ const totalSats = listResult.outputs.reduce((sum, o) => sum + o.satoshis, 0);
150
+ const estimatedFee = Math.ceil((listResult.outputs.length * 150 + 44) * 1);
151
+ const sendAmount = totalSats - estimatedFee;
152
+ if (sendAmount <= 0) {
153
+ return { error: "insufficient-funds-for-fee" };
154
+ }
155
+ const inputs = listResult.outputs.map((o) => ({
156
+ outpoint: o.outpoint,
157
+ inputDescription: "Sweep funds",
158
+ }));
159
+ const result = await ctx.wallet.createAction({
160
+ description: "Send all BSV",
161
+ inputs,
162
+ outputs: [
163
+ {
164
+ lockingScript: new P2PKH().lock(destination).toHex(),
165
+ satoshis: sendAmount,
166
+ outputDescription: "Sweep all funds",
167
+ },
168
+ ],
169
+ options: { signAndProcess: true },
170
+ });
171
+ if (!result.txid) {
172
+ return { error: "no-txid-returned" };
173
+ }
174
+ return { txid: result.txid, rawtx: result.tx ? Utils.toHex(result.tx) : undefined };
107
175
  }
108
- const inputs = listResult.outputs.map((o) => ({
109
- outpoint: o.outpoint,
110
- inputDescription: "Sweep funds",
111
- }));
112
- const result = await cwi.createAction({
113
- description: "Send all BSV",
114
- inputs,
115
- outputs: [{
116
- lockingScript: new P2PKH().lock(destination).toHex(),
117
- satoshis: sendAmount,
118
- outputDescription: "Sweep all funds",
119
- }],
120
- options: { signAndProcess: true },
121
- });
122
- if (!result.txid) {
123
- return { error: "no-txid-returned" };
176
+ catch (error) {
177
+ return { error: error instanceof Error ? error.message : "unknown-error" };
124
178
  }
125
- return { txid: result.txid, rawtx: result.tx ? Utils.toHex(result.tx) : undefined };
126
- }
127
- catch (error) {
128
- return { error: error instanceof Error ? error.message : "unknown-error" };
129
- }
130
- }
179
+ },
180
+ };
181
+ // ============================================================================
182
+ // Module exports
183
+ // ============================================================================
184
+ /** All payment skills for registry */
185
+ export const paymentsSkills = [sendBsv, sendAllBsv];
@@ -1,9 +1,9 @@
1
1
  /**
2
2
  * Signing Module
3
3
  *
4
- * Functions for message signing.
4
+ * Skills for message signing.
5
5
  */
6
- import { type WalletInterface } from "@bsv/sdk";
6
+ import type { Skill } from "../skills/types";
7
7
  export interface SignMessageRequest {
8
8
  /** Message to sign */
9
9
  message: string;
@@ -24,9 +24,12 @@ export interface SignedMessage {
24
24
  sig: string;
25
25
  derivationTag?: SignMessageRequest["tag"];
26
26
  }
27
+ export interface SignMessageResponse extends Partial<SignedMessage> {
28
+ error?: string;
29
+ }
27
30
  /**
28
31
  * Sign a message using BSM (Bitcoin Signed Message) format.
29
32
  */
30
- export declare function signMessage(cwi: WalletInterface, request: SignMessageRequest): Promise<SignedMessage | {
31
- error: string;
32
- }>;
33
+ export declare const signMessage: Skill<SignMessageRequest, SignMessageResponse>;
34
+ /** All signing skills for registry */
35
+ export declare const signingSkills: Skill<SignMessageRequest, SignMessageResponse>[];
@@ -1,41 +1,78 @@
1
1
  /**
2
2
  * Signing Module
3
3
  *
4
- * Functions for message signing.
4
+ * Skills for message signing.
5
5
  */
6
- import { BigNumber, BSM, PublicKey, Signature, Utils, } from "@bsv/sdk";
6
+ import { BigNumber, BSM, PublicKey, Signature, Utils } from "@bsv/sdk";
7
7
  import { MESSAGE_SIGNING_PROTOCOL } from "../constants";
8
+ // ============================================================================
9
+ // Skills
10
+ // ============================================================================
8
11
  /**
9
12
  * Sign a message using BSM (Bitcoin Signed Message) format.
10
13
  */
11
- export async function signMessage(cwi, request) {
12
- try {
13
- const { message, encoding = "utf8", tag } = request;
14
- const messageBytes = Utils.toArray(message, encoding);
15
- const msgHash = BSM.magicHash(messageBytes);
16
- const keyID = tag ? `${tag.label}:${tag.id}:${tag.domain}` : "identity";
17
- const result = await cwi.createSignature({
18
- protocolID: MESSAGE_SIGNING_PROTOCOL,
19
- keyID,
20
- hashToDirectlySign: Array.from(msgHash),
21
- });
22
- const pubKeyResult = await cwi.getPublicKey({
23
- protocolID: MESSAGE_SIGNING_PROTOCOL,
24
- keyID,
25
- forSelf: true,
26
- });
27
- const publicKey = PublicKey.fromString(pubKeyResult.publicKey);
28
- const signature = Signature.fromDER(result.signature);
29
- const recovery = signature.CalculateRecoveryFactor(publicKey, new BigNumber(msgHash));
30
- return {
31
- address: publicKey.toAddress(),
32
- pubKey: publicKey.toString(),
33
- message,
34
- sig: signature.toCompact(recovery, true, "base64"),
35
- derivationTag: tag,
36
- };
37
- }
38
- catch (error) {
39
- return { error: error instanceof Error ? error.message : "unknown-error" };
40
- }
41
- }
14
+ export const signMessage = {
15
+ meta: {
16
+ name: "signMessage",
17
+ description: "Sign a message using BSM (Bitcoin Signed Message) format",
18
+ category: "signing",
19
+ inputSchema: {
20
+ type: "object",
21
+ properties: {
22
+ message: { type: "string", description: "Message to sign" },
23
+ encoding: {
24
+ type: "string",
25
+ description: "Message encoding (utf8, hex, base64)",
26
+ enum: ["utf8", "hex", "base64"],
27
+ },
28
+ tag: {
29
+ type: "object",
30
+ description: "Derivation tag for key selection",
31
+ properties: {
32
+ label: { type: "string" },
33
+ id: { type: "string" },
34
+ domain: { type: "string" },
35
+ meta: { type: "object" },
36
+ },
37
+ },
38
+ },
39
+ required: ["message"],
40
+ },
41
+ },
42
+ async execute(ctx, input) {
43
+ try {
44
+ const { message, encoding = "utf8", tag } = input;
45
+ const messageBytes = Utils.toArray(message, encoding);
46
+ const msgHash = BSM.magicHash(messageBytes);
47
+ const keyID = tag ? `${tag.label}:${tag.id}:${tag.domain}` : "identity";
48
+ const result = await ctx.wallet.createSignature({
49
+ protocolID: MESSAGE_SIGNING_PROTOCOL,
50
+ keyID,
51
+ hashToDirectlySign: Array.from(msgHash),
52
+ });
53
+ const pubKeyResult = await ctx.wallet.getPublicKey({
54
+ protocolID: MESSAGE_SIGNING_PROTOCOL,
55
+ keyID,
56
+ forSelf: true,
57
+ });
58
+ const publicKey = PublicKey.fromString(pubKeyResult.publicKey);
59
+ const signature = Signature.fromDER(result.signature);
60
+ const recovery = signature.CalculateRecoveryFactor(publicKey, new BigNumber(msgHash));
61
+ return {
62
+ address: publicKey.toAddress(),
63
+ pubKey: publicKey.toString(),
64
+ message,
65
+ sig: signature.toCompact(recovery, true, "base64"),
66
+ derivationTag: tag,
67
+ };
68
+ }
69
+ catch (error) {
70
+ return { error: error instanceof Error ? error.message : "unknown-error" };
71
+ }
72
+ },
73
+ };
74
+ // ============================================================================
75
+ // Module exports
76
+ // ============================================================================
77
+ /** All signing skills for registry */
78
+ export const signingSkills = [signMessage];
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Skill registry for runtime discovery and MCP integration.
3
+ */
4
+ import type { Skill, SkillCategory } from "./types";
5
+ type AnySkill = Skill<any, any>;
6
+ /**
7
+ * MCP-compatible tool definition.
8
+ */
9
+ export interface McpTool {
10
+ name: string;
11
+ description: string;
12
+ inputSchema: object;
13
+ }
14
+ /**
15
+ * Registry for collecting and discovering skills at runtime.
16
+ */
17
+ export declare class SkillRegistry {
18
+ private skills;
19
+ /**
20
+ * Register a skill.
21
+ */
22
+ register(skill: AnySkill): void;
23
+ /**
24
+ * Register multiple skills.
25
+ */
26
+ registerAll(skills: AnySkill[]): void;
27
+ /**
28
+ * Get a skill by name.
29
+ */
30
+ get(name: string): AnySkill | undefined;
31
+ /**
32
+ * Check if a skill exists.
33
+ */
34
+ has(name: string): boolean;
35
+ /**
36
+ * List all registered skills.
37
+ */
38
+ list(): Skill[];
39
+ /**
40
+ * List skills by category.
41
+ */
42
+ listByCategory(category: SkillCategory): Skill[];
43
+ /**
44
+ * Get skill names.
45
+ */
46
+ names(): string[];
47
+ /**
48
+ * Convert to MCP-compatible tool list.
49
+ * Prefixes names with "1sat__" for namespace isolation.
50
+ */
51
+ toMcpTools(): McpTool[];
52
+ /**
53
+ * Number of registered skills.
54
+ */
55
+ get size(): number;
56
+ }
57
+ /**
58
+ * Global skill registry singleton.
59
+ */
60
+ export declare const skillRegistry: SkillRegistry;
61
+ export {};
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Skill registry for runtime discovery and MCP integration.
3
+ */
4
+ /**
5
+ * Registry for collecting and discovering skills at runtime.
6
+ */
7
+ export class SkillRegistry {
8
+ skills = new Map();
9
+ /**
10
+ * Register a skill.
11
+ */
12
+ register(skill) {
13
+ this.skills.set(skill.meta.name, skill);
14
+ }
15
+ /**
16
+ * Register multiple skills.
17
+ */
18
+ registerAll(skills) {
19
+ for (const skill of skills) {
20
+ this.register(skill);
21
+ }
22
+ }
23
+ /**
24
+ * Get a skill by name.
25
+ */
26
+ get(name) {
27
+ return this.skills.get(name);
28
+ }
29
+ /**
30
+ * Check if a skill exists.
31
+ */
32
+ has(name) {
33
+ return this.skills.has(name);
34
+ }
35
+ /**
36
+ * List all registered skills.
37
+ */
38
+ list() {
39
+ return Array.from(this.skills.values());
40
+ }
41
+ /**
42
+ * List skills by category.
43
+ */
44
+ listByCategory(category) {
45
+ return this.list().filter((s) => s.meta.category === category);
46
+ }
47
+ /**
48
+ * Get skill names.
49
+ */
50
+ names() {
51
+ return Array.from(this.skills.keys());
52
+ }
53
+ /**
54
+ * Convert to MCP-compatible tool list.
55
+ * Prefixes names with "1sat__" for namespace isolation.
56
+ */
57
+ toMcpTools() {
58
+ return this.list().map((skill) => ({
59
+ name: `1sat__${skill.meta.name}`,
60
+ description: skill.meta.description,
61
+ inputSchema: skill.meta.inputSchema,
62
+ }));
63
+ }
64
+ /**
65
+ * Number of registered skills.
66
+ */
67
+ get size() {
68
+ return this.skills.size;
69
+ }
70
+ }
71
+ /**
72
+ * Global skill registry singleton.
73
+ */
74
+ export const skillRegistry = new SkillRegistry();
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Core types for the skill/action pattern.
3
+ */
4
+ import type { WalletInterface } from "@bsv/sdk";
5
+ import type { OneSatServices } from "../../services/OneSatServices";
6
+ /**
7
+ * Context passed to all skills.
8
+ * Contains the wallet and optional services for backend operations.
9
+ */
10
+ export interface OneSatContext {
11
+ /** BRC-100 compatible wallet interface */
12
+ wallet: WalletInterface;
13
+ /** Optional services for operations requiring backend (purchases, lookups) */
14
+ services?: OneSatServices;
15
+ /** Network chain */
16
+ chain: "main" | "test";
17
+ /** Optional WhatsOnChain API key */
18
+ wocApiKey?: string;
19
+ }
20
+ /**
21
+ * JSON Schema property definition for skill input schemas.
22
+ */
23
+ export interface JsonSchemaProperty {
24
+ type: "string" | "number" | "integer" | "boolean" | "object" | "array";
25
+ description?: string;
26
+ enum?: string[];
27
+ default?: unknown;
28
+ items?: JsonSchemaProperty;
29
+ properties?: Record<string, JsonSchemaProperty>;
30
+ required?: string[];
31
+ }
32
+ /**
33
+ * Skill category for grouping related operations.
34
+ */
35
+ export type SkillCategory = "balance" | "payments" | "ordinals" | "tokens" | "inscriptions" | "locks" | "signing" | "broadcast" | "sweep";
36
+ /**
37
+ * Metadata describing a skill for AI agents and tooling.
38
+ */
39
+ export interface SkillMetadata<TInput = unknown> {
40
+ /** Unique skill name */
41
+ name: string;
42
+ /** Human-readable description of what the skill does */
43
+ description: string;
44
+ /** Category for grouping */
45
+ category: SkillCategory;
46
+ /** JSON Schema for the input parameters (MCP-compatible) */
47
+ inputSchema: {
48
+ type: "object";
49
+ properties: Record<string, JsonSchemaProperty>;
50
+ required?: string[];
51
+ };
52
+ /** Whether this skill requires OneSatServices to be provided in context */
53
+ requiresServices?: boolean;
54
+ }
55
+ /**
56
+ * A skill is a self-describing action that can be executed with a context.
57
+ */
58
+ export interface Skill<TInput = unknown, TOutput = unknown> {
59
+ /** Metadata describing the skill */
60
+ meta: SkillMetadata<TInput>;
61
+ /** Execute the skill with context and input */
62
+ execute: (ctx: OneSatContext, input: TInput) => Promise<TOutput>;
63
+ }
64
+ /**
65
+ * Helper to create a context object from a wallet and options.
66
+ */
67
+ export declare function createContext(wallet: WalletInterface, options?: {
68
+ services?: OneSatServices;
69
+ chain?: "main" | "test";
70
+ wocApiKey?: string;
71
+ }): OneSatContext;
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Core types for the skill/action pattern.
3
+ */
4
+ /**
5
+ * Helper to create a context object from a wallet and options.
6
+ */
7
+ export function createContext(wallet, options) {
8
+ return {
9
+ wallet,
10
+ services: options?.services,
11
+ chain: options?.chain ?? "main",
12
+ wocApiKey: options?.wocApiKey,
13
+ };
14
+ }