@1sat/wallet-toolbox 0.0.9 → 0.0.10
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/api/balance/index.d.ts +20 -8
- package/dist/api/balance/index.js +104 -51
- package/dist/api/broadcast/index.d.ts +5 -3
- package/dist/api/broadcast/index.js +65 -37
- package/dist/api/index.d.ts +15 -15
- package/dist/api/index.js +38 -17
- package/dist/api/inscriptions/index.d.ts +9 -9
- package/dist/api/inscriptions/index.js +79 -31
- package/dist/api/locks/index.d.ts +15 -12
- package/dist/api/locks/index.js +252 -194
- package/dist/api/ordinals/index.d.ts +50 -35
- package/dist/api/ordinals/index.js +469 -349
- package/dist/api/payments/index.d.ts +15 -4
- package/dist/api/payments/index.js +147 -92
- package/dist/api/signing/index.d.ts +8 -5
- package/dist/api/signing/index.js +70 -33
- package/dist/api/skills/registry.d.ts +61 -0
- package/dist/api/skills/registry.js +74 -0
- package/dist/api/skills/types.d.ts +71 -0
- package/dist/api/skills/types.js +14 -0
- package/dist/api/tokens/index.d.ts +37 -38
- package/dist/api/tokens/index.js +398 -341
- package/dist/index.d.ts +1 -0
- package/dist/index.js +2 -0
- package/dist/wallet/factory.d.ts +64 -0
- package/dist/wallet/factory.js +129 -0
- package/dist/wallet/index.d.ts +1 -0
- package/dist/wallet/index.js +1 -0
- package/package.json +10 -1
- package/dist/OneSatWallet.d.ts +0 -316
- package/dist/OneSatWallet.js +0 -956
- package/dist/api/OneSatApi.d.ts +0 -100
- package/dist/api/OneSatApi.js +0 -156
- package/dist/indexers/TransactionParser.d.ts +0 -53
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Balance Module
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* Skills for querying wallet balance and payment UTXOs.
|
|
5
5
|
*/
|
|
6
|
-
import type {
|
|
6
|
+
import type { Skill } from "../skills/types";
|
|
7
7
|
export interface Balance {
|
|
8
8
|
/** Balance in satoshis */
|
|
9
9
|
satoshis: number;
|
|
@@ -18,21 +18,33 @@ export interface PaymentUtxo {
|
|
|
18
18
|
satoshis: number;
|
|
19
19
|
script: string;
|
|
20
20
|
}
|
|
21
|
+
/** Input for getBalance skill (no required params) */
|
|
22
|
+
export type GetBalanceInput = Record<string, never>;
|
|
21
23
|
/**
|
|
22
24
|
* Get wallet balance with USD conversion.
|
|
23
25
|
*/
|
|
24
|
-
export declare
|
|
26
|
+
export declare const getBalance: Skill<GetBalanceInput, Balance>;
|
|
27
|
+
/** Input for getPaymentUtxos skill (no required params) */
|
|
28
|
+
export type GetPaymentUtxosInput = Record<string, never>;
|
|
25
29
|
/**
|
|
26
30
|
* Get payment UTXOs for external use.
|
|
27
31
|
*/
|
|
28
|
-
export declare
|
|
32
|
+
export declare const getPaymentUtxos: Skill<GetPaymentUtxosInput, PaymentUtxo[]>;
|
|
33
|
+
/** Input for getExchangeRate skill (no required params) */
|
|
34
|
+
export type GetExchangeRateInput = Record<string, never>;
|
|
29
35
|
/**
|
|
30
36
|
* Get current BSV/USD exchange rate.
|
|
31
37
|
*/
|
|
32
|
-
export declare
|
|
38
|
+
export declare const getExchangeRate: Skill<GetExchangeRateInput, number>;
|
|
39
|
+
/** Input for getChainInfo skill (no required params) */
|
|
40
|
+
export type GetChainInfoInput = Record<string, never>;
|
|
41
|
+
/** Output for getChainInfo skill */
|
|
42
|
+
export interface ChainInfo {
|
|
43
|
+
blocks: number;
|
|
44
|
+
}
|
|
33
45
|
/**
|
|
34
46
|
* Get chain info from WhatsOnChain.
|
|
35
47
|
*/
|
|
36
|
-
export declare
|
|
37
|
-
|
|
38
|
-
|
|
48
|
+
export declare const getChainInfo: Skill<GetChainInfoInput, ChainInfo | null>;
|
|
49
|
+
/** All balance skills for registry */
|
|
50
|
+
export declare const balanceSkills: (Skill<GetBalanceInput, Balance> | Skill<GetPaymentUtxosInput, PaymentUtxo[]> | Skill<GetExchangeRateInput, number> | Skill<GetChainInfoInput, ChainInfo | null>)[];
|
|
@@ -1,47 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Balance Module
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* Skills for querying wallet balance and payment UTXOs.
|
|
5
5
|
*/
|
|
6
6
|
import { FUNDING_BASKET, WOC_MAINNET_URL, WOC_TESTNET_URL, EXCHANGE_RATE_CACHE_TTL } from "../constants";
|
|
7
7
|
// Module-level cache for exchange rate
|
|
8
8
|
let exchangeRateCache = null;
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
const exchangeRate = await getExchangeRate(chain, wocApiKey);
|
|
14
|
-
const result = await cwi.listOutputs({ basket: FUNDING_BASKET, limit: 10000 });
|
|
15
|
-
console.log(`[getBalance] Found ${result.outputs.length} outputs in "${FUNDING_BASKET}" basket, total: ${result.totalOutputs}`);
|
|
16
|
-
const satoshis = result.outputs.reduce((sum, o) => sum + o.satoshis, 0);
|
|
17
|
-
console.log(`[getBalance] Total satoshis: ${satoshis}`);
|
|
18
|
-
const bsv = satoshis / 100_000_000;
|
|
19
|
-
const usdInCents = Math.round(bsv * exchangeRate * 100);
|
|
20
|
-
return { satoshis, bsv, usdInCents };
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* Get payment UTXOs for external use.
|
|
24
|
-
*/
|
|
25
|
-
export async function getPaymentUtxos(cwi) {
|
|
26
|
-
const result = await cwi.listOutputs({
|
|
27
|
-
basket: FUNDING_BASKET,
|
|
28
|
-
include: "locking scripts",
|
|
29
|
-
limit: 10000,
|
|
30
|
-
});
|
|
31
|
-
return result.outputs.map((o) => {
|
|
32
|
-
const [txid, voutStr] = o.outpoint.split(".");
|
|
33
|
-
return {
|
|
34
|
-
txid,
|
|
35
|
-
vout: parseInt(voutStr, 10),
|
|
36
|
-
satoshis: o.satoshis,
|
|
37
|
-
script: o.lockingScript || "",
|
|
38
|
-
};
|
|
39
|
-
});
|
|
40
|
-
}
|
|
41
|
-
/**
|
|
42
|
-
* Get current BSV/USD exchange rate.
|
|
43
|
-
*/
|
|
44
|
-
export async function getExchangeRate(chain = "main", wocApiKey) {
|
|
9
|
+
// ============================================================================
|
|
10
|
+
// Internal helpers
|
|
11
|
+
// ============================================================================
|
|
12
|
+
async function fetchExchangeRate(chain, wocApiKey) {
|
|
45
13
|
if (exchangeRateCache && Date.now() - exchangeRateCache.timestamp < EXCHANGE_RATE_CACHE_TTL) {
|
|
46
14
|
return exchangeRateCache.rate;
|
|
47
15
|
}
|
|
@@ -62,21 +30,106 @@ export async function getExchangeRate(chain = "main", wocApiKey) {
|
|
|
62
30
|
return exchangeRateCache?.rate ?? 0;
|
|
63
31
|
}
|
|
64
32
|
}
|
|
33
|
+
/**
|
|
34
|
+
* Get wallet balance with USD conversion.
|
|
35
|
+
*/
|
|
36
|
+
export const getBalance = {
|
|
37
|
+
meta: {
|
|
38
|
+
name: "getBalance",
|
|
39
|
+
description: "Get wallet balance in satoshis, BSV, and USD cents",
|
|
40
|
+
category: "balance",
|
|
41
|
+
inputSchema: {
|
|
42
|
+
type: "object",
|
|
43
|
+
properties: {},
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
async execute(ctx) {
|
|
47
|
+
const exchangeRate = await fetchExchangeRate(ctx.chain, ctx.wocApiKey);
|
|
48
|
+
const result = await ctx.wallet.listOutputs({ basket: FUNDING_BASKET, limit: 10000 });
|
|
49
|
+
const satoshis = result.outputs.reduce((sum, o) => sum + o.satoshis, 0);
|
|
50
|
+
const bsv = satoshis / 100_000_000;
|
|
51
|
+
const usdInCents = Math.round(bsv * exchangeRate * 100);
|
|
52
|
+
return { satoshis, bsv, usdInCents };
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* Get payment UTXOs for external use.
|
|
57
|
+
*/
|
|
58
|
+
export const getPaymentUtxos = {
|
|
59
|
+
meta: {
|
|
60
|
+
name: "getPaymentUtxos",
|
|
61
|
+
description: "Get payment UTXOs from the wallet for external use",
|
|
62
|
+
category: "balance",
|
|
63
|
+
inputSchema: {
|
|
64
|
+
type: "object",
|
|
65
|
+
properties: {},
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
async execute(ctx) {
|
|
69
|
+
const result = await ctx.wallet.listOutputs({
|
|
70
|
+
basket: FUNDING_BASKET,
|
|
71
|
+
include: "locking scripts",
|
|
72
|
+
limit: 10000,
|
|
73
|
+
});
|
|
74
|
+
return result.outputs.map((o) => {
|
|
75
|
+
const [txid, voutStr] = o.outpoint.split(".");
|
|
76
|
+
return {
|
|
77
|
+
txid,
|
|
78
|
+
vout: Number.parseInt(voutStr, 10),
|
|
79
|
+
satoshis: o.satoshis,
|
|
80
|
+
script: o.lockingScript || "",
|
|
81
|
+
};
|
|
82
|
+
});
|
|
83
|
+
},
|
|
84
|
+
};
|
|
85
|
+
/**
|
|
86
|
+
* Get current BSV/USD exchange rate.
|
|
87
|
+
*/
|
|
88
|
+
export const getExchangeRate = {
|
|
89
|
+
meta: {
|
|
90
|
+
name: "getExchangeRate",
|
|
91
|
+
description: "Get current BSV/USD exchange rate from WhatsOnChain",
|
|
92
|
+
category: "balance",
|
|
93
|
+
inputSchema: {
|
|
94
|
+
type: "object",
|
|
95
|
+
properties: {},
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
async execute(ctx) {
|
|
99
|
+
return fetchExchangeRate(ctx.chain, ctx.wocApiKey);
|
|
100
|
+
},
|
|
101
|
+
};
|
|
65
102
|
/**
|
|
66
103
|
* Get chain info from WhatsOnChain.
|
|
67
104
|
*/
|
|
68
|
-
export
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
105
|
+
export const getChainInfo = {
|
|
106
|
+
meta: {
|
|
107
|
+
name: "getChainInfo",
|
|
108
|
+
description: "Get current chain info (block height) from WhatsOnChain",
|
|
109
|
+
category: "balance",
|
|
110
|
+
inputSchema: {
|
|
111
|
+
type: "object",
|
|
112
|
+
properties: {},
|
|
113
|
+
},
|
|
114
|
+
},
|
|
115
|
+
async execute(ctx) {
|
|
116
|
+
const baseUrl = ctx.chain === "main" ? WOC_MAINNET_URL : WOC_TESTNET_URL;
|
|
117
|
+
const headers = {};
|
|
118
|
+
if (ctx.wocApiKey)
|
|
119
|
+
headers["woc-api-key"] = ctx.wocApiKey;
|
|
120
|
+
try {
|
|
121
|
+
const response = await fetch(`${baseUrl}/chain/info`, { headers });
|
|
122
|
+
if (!response.ok)
|
|
123
|
+
return null;
|
|
124
|
+
return await response.json();
|
|
125
|
+
}
|
|
126
|
+
catch {
|
|
76
127
|
return null;
|
|
77
|
-
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
128
|
+
}
|
|
129
|
+
},
|
|
130
|
+
};
|
|
131
|
+
// ============================================================================
|
|
132
|
+
// Module exports
|
|
133
|
+
// ============================================================================
|
|
134
|
+
/** All balance skills for registry */
|
|
135
|
+
export const balanceSkills = [getBalance, getPaymentUtxos, getExchangeRate, getChainInfo];
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Broadcast Module
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* Skills for broadcasting transactions.
|
|
5
5
|
*/
|
|
6
|
-
import {
|
|
6
|
+
import type { Skill } from "../skills/types";
|
|
7
7
|
export interface BroadcastRequest {
|
|
8
8
|
/** Raw transaction hex */
|
|
9
9
|
rawtx: string;
|
|
@@ -19,4 +19,6 @@ export interface BroadcastResponse {
|
|
|
19
19
|
/**
|
|
20
20
|
* Broadcast a transaction and internalize it into the wallet.
|
|
21
21
|
*/
|
|
22
|
-
export declare
|
|
22
|
+
export declare const broadcast: Skill<BroadcastRequest, BroadcastResponse>;
|
|
23
|
+
/** All broadcast skills for registry */
|
|
24
|
+
export declare const broadcastSkills: Skill<BroadcastRequest, BroadcastResponse>[];
|
|
@@ -1,45 +1,73 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Broadcast Module
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* Skills for broadcasting transactions.
|
|
5
5
|
*/
|
|
6
|
-
import { Beef, Transaction
|
|
6
|
+
import { Beef, Transaction } from "@bsv/sdk";
|
|
7
|
+
// ============================================================================
|
|
8
|
+
// Skills
|
|
9
|
+
// ============================================================================
|
|
7
10
|
/**
|
|
8
11
|
* Broadcast a transaction and internalize it into the wallet.
|
|
9
12
|
*/
|
|
10
|
-
export
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
beef.mergeTransaction(tx);
|
|
26
|
-
const outputs = tx.outputs.map((_, index) => ({
|
|
27
|
-
outputIndex: index,
|
|
28
|
-
protocol: "wallet payment",
|
|
29
|
-
paymentRemittance: {
|
|
30
|
-
derivationPrefix: "default",
|
|
31
|
-
derivationSuffix: `${txid}.${index}`,
|
|
32
|
-
senderIdentityKey: "",
|
|
13
|
+
export const broadcast = {
|
|
14
|
+
meta: {
|
|
15
|
+
name: "broadcast",
|
|
16
|
+
description: "Broadcast a transaction and internalize it into the wallet",
|
|
17
|
+
category: "broadcast",
|
|
18
|
+
inputSchema: {
|
|
19
|
+
type: "object",
|
|
20
|
+
properties: {
|
|
21
|
+
rawtx: { type: "string", description: "Raw transaction hex" },
|
|
22
|
+
format: {
|
|
23
|
+
type: "string",
|
|
24
|
+
description: "Transaction format (tx, beef, ef)",
|
|
25
|
+
enum: ["tx", "beef", "ef"],
|
|
26
|
+
},
|
|
27
|
+
description: { type: "string", description: "Description for wallet records" },
|
|
33
28
|
},
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
29
|
+
required: ["rawtx"],
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
async execute(ctx, input) {
|
|
33
|
+
try {
|
|
34
|
+
let tx;
|
|
35
|
+
switch (input.format) {
|
|
36
|
+
case "beef":
|
|
37
|
+
tx = Transaction.fromHexBEEF(input.rawtx);
|
|
38
|
+
break;
|
|
39
|
+
case "ef":
|
|
40
|
+
tx = Transaction.fromHexEF(input.rawtx);
|
|
41
|
+
break;
|
|
42
|
+
default:
|
|
43
|
+
tx = Transaction.fromHex(input.rawtx);
|
|
44
|
+
}
|
|
45
|
+
const txid = tx.id("hex");
|
|
46
|
+
const beef = new Beef();
|
|
47
|
+
beef.mergeTransaction(tx);
|
|
48
|
+
const outputs = tx.outputs.map((_, index) => ({
|
|
49
|
+
outputIndex: index,
|
|
50
|
+
protocol: "wallet payment",
|
|
51
|
+
paymentRemittance: {
|
|
52
|
+
derivationPrefix: "default",
|
|
53
|
+
derivationSuffix: `${txid}.${index}`,
|
|
54
|
+
senderIdentityKey: "",
|
|
55
|
+
},
|
|
56
|
+
}));
|
|
57
|
+
await ctx.wallet.internalizeAction({
|
|
58
|
+
tx: Array.from(beef.toBinary()),
|
|
59
|
+
outputs,
|
|
60
|
+
description: input.description || "Broadcast transaction",
|
|
61
|
+
});
|
|
62
|
+
return { txid };
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
return { error: error instanceof Error ? error.message : "Unknown error" };
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
};
|
|
69
|
+
// ============================================================================
|
|
70
|
+
// Module exports
|
|
71
|
+
// ============================================================================
|
|
72
|
+
/** All broadcast skills for registry */
|
|
73
|
+
export const broadcastSkills = [broadcast];
|
package/dist/api/index.d.ts
CHANGED
|
@@ -1,29 +1,29 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* 1Sat Wallet Toolbox API Layer
|
|
3
3
|
*
|
|
4
|
-
* This module provides
|
|
5
|
-
* All
|
|
4
|
+
* This module provides skills (self-describing actions) for interacting with the 1Sat ecosystem.
|
|
5
|
+
* All skills work with any BRC-100 compatible wallet interface via OneSatContext.
|
|
6
6
|
*
|
|
7
7
|
* Usage:
|
|
8
8
|
* ```typescript
|
|
9
|
-
* import {
|
|
9
|
+
* import { createContext, transferOrdinal, skillRegistry } from '@1sat/wallet-toolbox/api';
|
|
10
10
|
*
|
|
11
|
-
* // Create
|
|
12
|
-
* const
|
|
11
|
+
* // Create context with a BRC-100 compatible wallet
|
|
12
|
+
* const ctx = createContext(wallet, { services, chain: 'main' });
|
|
13
13
|
*
|
|
14
|
-
* //
|
|
15
|
-
* const
|
|
16
|
-
* const ordinals = await api.listOrdinals();
|
|
17
|
-
* const result = await api.sendBsv([{ address: '...', satoshis: 1000 }]);
|
|
18
|
-
* ```
|
|
14
|
+
* // Execute skills directly
|
|
15
|
+
* const result = await transferOrdinal.execute(ctx, { outpoint: '...', address: '...' });
|
|
19
16
|
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
17
|
+
* // Or via registry (useful for AI agents)
|
|
18
|
+
* const skill = skillRegistry.get('transferOrdinal');
|
|
19
|
+
* const result = await skill.execute(ctx, { outpoint: '...', address: '...' });
|
|
20
|
+
*
|
|
21
|
+
* // Get MCP-compatible tool list
|
|
22
|
+
* const tools = skillRegistry.toMcpTools();
|
|
24
23
|
* ```
|
|
25
24
|
*/
|
|
26
|
-
export {
|
|
25
|
+
export { type OneSatContext, type Skill, type SkillMetadata, type SkillCategory, type JsonSchemaProperty, createContext, } from "./skills/types";
|
|
26
|
+
export { SkillRegistry, skillRegistry, type McpTool } from "./skills/registry";
|
|
27
27
|
export * from "./constants";
|
|
28
28
|
export * from "./balance";
|
|
29
29
|
export * from "./payments";
|
package/dist/api/index.js
CHANGED
|
@@ -1,33 +1,34 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* 1Sat Wallet Toolbox API Layer
|
|
3
3
|
*
|
|
4
|
-
* This module provides
|
|
5
|
-
* All
|
|
4
|
+
* This module provides skills (self-describing actions) for interacting with the 1Sat ecosystem.
|
|
5
|
+
* All skills work with any BRC-100 compatible wallet interface via OneSatContext.
|
|
6
6
|
*
|
|
7
7
|
* Usage:
|
|
8
8
|
* ```typescript
|
|
9
|
-
* import {
|
|
9
|
+
* import { createContext, transferOrdinal, skillRegistry } from '@1sat/wallet-toolbox/api';
|
|
10
10
|
*
|
|
11
|
-
* // Create
|
|
12
|
-
* const
|
|
11
|
+
* // Create context with a BRC-100 compatible wallet
|
|
12
|
+
* const ctx = createContext(wallet, { services, chain: 'main' });
|
|
13
13
|
*
|
|
14
|
-
* //
|
|
15
|
-
* const
|
|
16
|
-
* const ordinals = await api.listOrdinals();
|
|
17
|
-
* const result = await api.sendBsv([{ address: '...', satoshis: 1000 }]);
|
|
18
|
-
* ```
|
|
14
|
+
* // Execute skills directly
|
|
15
|
+
* const result = await transferOrdinal.execute(ctx, { outpoint: '...', address: '...' });
|
|
19
16
|
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
17
|
+
* // Or via registry (useful for AI agents)
|
|
18
|
+
* const skill = skillRegistry.get('transferOrdinal');
|
|
19
|
+
* const result = await skill.execute(ctx, { outpoint: '...', address: '...' });
|
|
20
|
+
*
|
|
21
|
+
* // Get MCP-compatible tool list
|
|
22
|
+
* const tools = skillRegistry.toMcpTools();
|
|
24
23
|
* ```
|
|
25
24
|
*/
|
|
26
|
-
// Export
|
|
27
|
-
export {
|
|
25
|
+
// Export skill types and helpers
|
|
26
|
+
export { createContext, } from "./skills/types";
|
|
27
|
+
// Export skill registry
|
|
28
|
+
export { SkillRegistry, skillRegistry } from "./skills/registry";
|
|
28
29
|
// Export constants
|
|
29
30
|
export * from "./constants";
|
|
30
|
-
// Export module
|
|
31
|
+
// Export module skills and types
|
|
31
32
|
export * from "./balance";
|
|
32
33
|
export * from "./payments";
|
|
33
34
|
export * from "./ordinals";
|
|
@@ -36,3 +37,23 @@ export * from "./inscriptions";
|
|
|
36
37
|
export * from "./locks";
|
|
37
38
|
export * from "./signing";
|
|
38
39
|
export * from "./broadcast";
|
|
40
|
+
// Register all skills with the global registry
|
|
41
|
+
import { skillRegistry } from "./skills/registry";
|
|
42
|
+
import { balanceSkills } from "./balance";
|
|
43
|
+
import { paymentsSkills } from "./payments";
|
|
44
|
+
import { ordinalsSkills } from "./ordinals";
|
|
45
|
+
import { tokensSkills } from "./tokens";
|
|
46
|
+
import { inscriptionsSkills } from "./inscriptions";
|
|
47
|
+
import { locksSkills } from "./locks";
|
|
48
|
+
import { signingSkills } from "./signing";
|
|
49
|
+
import { broadcastSkills } from "./broadcast";
|
|
50
|
+
skillRegistry.registerAll([
|
|
51
|
+
...balanceSkills,
|
|
52
|
+
...paymentsSkills,
|
|
53
|
+
...ordinalsSkills,
|
|
54
|
+
...tokensSkills,
|
|
55
|
+
...inscriptionsSkills,
|
|
56
|
+
...locksSkills,
|
|
57
|
+
...signingSkills,
|
|
58
|
+
...broadcastSkills,
|
|
59
|
+
]);
|
|
@@ -1,18 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Inscriptions Module
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* Skills for creating inscriptions.
|
|
5
5
|
*/
|
|
6
|
-
import {
|
|
6
|
+
import type { Skill } from "../skills/types";
|
|
7
7
|
export interface InscribeRequest {
|
|
8
|
-
/** Base64 encoded
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
|
|
8
|
+
/** Base64 encoded content */
|
|
9
|
+
base64Content: string;
|
|
10
|
+
/** Content type (MIME type) */
|
|
11
|
+
contentType: string;
|
|
12
12
|
/** Optional MAP metadata */
|
|
13
13
|
map?: Record<string, string>;
|
|
14
|
-
/** Destination address for the inscription (required - use a derived address) */
|
|
15
|
-
destination: string;
|
|
16
14
|
}
|
|
17
15
|
export interface InscribeResponse {
|
|
18
16
|
txid?: string;
|
|
@@ -22,4 +20,6 @@ export interface InscribeResponse {
|
|
|
22
20
|
/**
|
|
23
21
|
* Create an inscription.
|
|
24
22
|
*/
|
|
25
|
-
export declare
|
|
23
|
+
export declare const inscribe: Skill<InscribeRequest, InscribeResponse>;
|
|
24
|
+
/** All inscription skills for registry */
|
|
25
|
+
export declare const inscriptionsSkills: Skill<InscribeRequest, InscribeResponse>[];
|
|
@@ -1,17 +1,21 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Inscriptions Module
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* Skills for creating inscriptions.
|
|
5
5
|
*/
|
|
6
|
-
import { P2PKH, Script, Utils
|
|
6
|
+
import { P2PKH, PublicKey, Script, Utils } from "@bsv/sdk";
|
|
7
7
|
import { Inscription } from "@bopen-io/templates";
|
|
8
|
-
import { MAX_INSCRIPTION_BYTES } from "../constants";
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
8
|
+
import { MAX_INSCRIPTION_BYTES, ORDINALS_BASKET } from "../constants";
|
|
9
|
+
// ============================================================================
|
|
10
|
+
// Constants
|
|
11
|
+
// ============================================================================
|
|
12
|
+
const ORDINAL_PROTOCOL = [1, "ordinal"];
|
|
13
|
+
// ============================================================================
|
|
14
|
+
// Internal helpers
|
|
15
|
+
// ============================================================================
|
|
16
|
+
function buildInscriptionScript(address, base64Content, contentType) {
|
|
17
|
+
const content = Utils.toArray(base64Content, "base64");
|
|
18
|
+
const inscription = Inscription.create(new Uint8Array(content), contentType);
|
|
15
19
|
const inscriptionScript = inscription.lock();
|
|
16
20
|
const p2pkhScript = new P2PKH().lock(address);
|
|
17
21
|
const combined = new Script();
|
|
@@ -21,30 +25,74 @@ function buildInscriptionScript(address, base64Data, mimeType) {
|
|
|
21
25
|
combined.chunks.push(chunk);
|
|
22
26
|
return combined;
|
|
23
27
|
}
|
|
28
|
+
// ============================================================================
|
|
29
|
+
// Skills
|
|
30
|
+
// ============================================================================
|
|
24
31
|
/**
|
|
25
32
|
* Create an inscription.
|
|
26
33
|
*/
|
|
27
|
-
export
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
34
|
+
export const inscribe = {
|
|
35
|
+
meta: {
|
|
36
|
+
name: "inscribe",
|
|
37
|
+
description: "Create a new inscription with the given content and type",
|
|
38
|
+
category: "inscriptions",
|
|
39
|
+
inputSchema: {
|
|
40
|
+
type: "object",
|
|
41
|
+
properties: {
|
|
42
|
+
base64Content: { type: "string", description: "Base64 encoded content" },
|
|
43
|
+
contentType: { type: "string", description: "Content type (MIME type)" },
|
|
44
|
+
map: {
|
|
45
|
+
type: "object",
|
|
46
|
+
description: "Optional MAP metadata",
|
|
47
|
+
properties: {},
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
required: ["base64Content", "contentType"],
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
async execute(ctx, input) {
|
|
54
|
+
try {
|
|
55
|
+
const decoded = Utils.toArray(input.base64Content, "base64");
|
|
56
|
+
if (decoded.length > MAX_INSCRIPTION_BYTES) {
|
|
57
|
+
return { error: `Inscription data too large: ${decoded.length} bytes (max ${MAX_INSCRIPTION_BYTES})` };
|
|
58
|
+
}
|
|
59
|
+
const keyID = Date.now().toString();
|
|
60
|
+
const { publicKey } = await ctx.wallet.getPublicKey({
|
|
61
|
+
protocolID: ORDINAL_PROTOCOL,
|
|
62
|
+
keyID,
|
|
63
|
+
counterparty: "self",
|
|
64
|
+
forSelf: true,
|
|
65
|
+
});
|
|
66
|
+
const address = PublicKey.fromString(publicKey).toAddress();
|
|
67
|
+
const lockingScript = buildInscriptionScript(address, input.base64Content, input.contentType);
|
|
68
|
+
const result = await ctx.wallet.createAction({
|
|
69
|
+
description: "Create inscription",
|
|
70
|
+
outputs: [
|
|
71
|
+
{
|
|
72
|
+
lockingScript: lockingScript.toHex(),
|
|
73
|
+
satoshis: 1,
|
|
74
|
+
outputDescription: "Inscription",
|
|
75
|
+
basket: ORDINALS_BASKET,
|
|
76
|
+
tags: [`type:${input.contentType}`],
|
|
77
|
+
customInstructions: JSON.stringify({
|
|
78
|
+
protocolID: ORDINAL_PROTOCOL,
|
|
79
|
+
keyID,
|
|
80
|
+
}),
|
|
81
|
+
},
|
|
82
|
+
],
|
|
83
|
+
});
|
|
84
|
+
if (!result.txid) {
|
|
85
|
+
return { error: "no-txid-returned" };
|
|
86
|
+
}
|
|
87
|
+
return { txid: result.txid, rawtx: result.tx ? Utils.toHex(result.tx) : undefined };
|
|
32
88
|
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
description: "Create inscription",
|
|
36
|
-
outputs: [{
|
|
37
|
-
lockingScript: lockingScript.toHex(),
|
|
38
|
-
satoshis: 1,
|
|
39
|
-
outputDescription: "Inscription",
|
|
40
|
-
}],
|
|
41
|
-
});
|
|
42
|
-
if (!result.txid) {
|
|
43
|
-
return { error: "no-txid-returned" };
|
|
89
|
+
catch (error) {
|
|
90
|
+
return { error: error instanceof Error ? error.message : "unknown-error" };
|
|
44
91
|
}
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
92
|
+
},
|
|
93
|
+
};
|
|
94
|
+
// ============================================================================
|
|
95
|
+
// Module exports
|
|
96
|
+
// ============================================================================
|
|
97
|
+
/** All inscription skills for registry */
|
|
98
|
+
export const inscriptionsSkills = [inscribe];
|