@ckbfs/api 1.2.4 → 1.2.5

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.
@@ -1,4 +1,5 @@
1
1
  import { molecule, number } from "@ckb-lumos/codec";
2
+ import { ProtocolVersionType } from "./constants";
2
3
  /**
3
4
  * Molecule definitions for CKBFS data structures.
4
5
  */
@@ -70,8 +71,8 @@ export type CKBFSDataType = {
70
71
  backLinks: BackLinkType[];
71
72
  };
72
73
  export declare const CKBFSData: {
73
- pack: (data: CKBFSDataType, version?: string) => Uint8Array;
74
- unpack: (buf: Uint8Array, version?: string) => CKBFSDataType;
74
+ pack: (data: CKBFSDataType, version?: ProtocolVersionType) => Uint8Array;
75
+ unpack: (buf: Uint8Array, version?: ProtocolVersionType) => CKBFSDataType;
75
76
  };
76
77
  export declare const CKBFS_HEADER: Uint8Array<ArrayBuffer>;
77
78
  export declare const CKBFS_HEADER_STRING = "CKBFS";
@@ -45,13 +45,13 @@ exports.CKBFSDataV2 = codec_1.molecule.table({
45
45
  function getIndexes(data) {
46
46
  if (data.indexes)
47
47
  return data.indexes;
48
- if (typeof data.index === 'number')
48
+ if (typeof data.index === "number")
49
49
  return [data.index];
50
50
  return [];
51
51
  }
52
52
  // Helper function to get single index from data
53
53
  function getIndex(data) {
54
- if (typeof data.index === 'number')
54
+ if (typeof data.index === "number")
55
55
  return data.index;
56
56
  if (data.indexes && data.indexes.length > 0)
57
57
  return data.indexes[0];
@@ -59,7 +59,7 @@ function getIndex(data) {
59
59
  }
60
60
  // Helper function to safely get either index or indexes from BackLinkType for V1
61
61
  function getBackLinkIndex(bl) {
62
- if (typeof bl.index === 'number') {
62
+ if (typeof bl.index === "number") {
63
63
  return bl.index;
64
64
  }
65
65
  if (Array.isArray(bl.indexes) && bl.indexes.length > 0) {
@@ -72,7 +72,7 @@ function getBackLinkIndexes(bl) {
72
72
  if (Array.isArray(bl.indexes)) {
73
73
  return bl.indexes;
74
74
  }
75
- if (typeof bl.index === 'number') {
75
+ if (typeof bl.index === "number") {
76
76
  return [bl.index];
77
77
  }
78
78
  return [0];
@@ -85,11 +85,11 @@ exports.CKBFSData = {
85
85
  return exports.CKBFSDataV1.pack({
86
86
  index: getIndex(data),
87
87
  checksum: data.checksum,
88
- contentType: core_1.ccc.bytesFrom(data.contentType, 'utf8'),
89
- filename: core_1.ccc.bytesFrom(data.filename, 'utf8'),
90
- backLinks: data.backLinks.map(bl => {
88
+ contentType: core_1.ccc.bytesFrom(data.contentType, "utf8"),
89
+ filename: core_1.ccc.bytesFrom(data.filename, "utf8"),
90
+ backLinks: data.backLinks.map((bl) => {
91
91
  // Ensure txHash is in proper format for molecule encoding
92
- const txHash = typeof bl.txHash === 'string'
92
+ const txHash = typeof bl.txHash === "string"
93
93
  ? core_1.ccc.bytesFrom(bl.txHash)
94
94
  : bl.txHash;
95
95
  return {
@@ -105,13 +105,11 @@ exports.CKBFSData = {
105
105
  return exports.CKBFSDataV2.pack({
106
106
  indexes: getIndexes(data),
107
107
  checksum: data.checksum,
108
- contentType: core_1.ccc.bytesFrom(data.contentType, 'utf8'),
109
- filename: core_1.ccc.bytesFrom(data.filename, 'utf8'),
110
- backLinks: data.backLinks.map(bl => {
108
+ contentType: core_1.ccc.bytesFrom(data.contentType, "utf8"),
109
+ filename: core_1.ccc.bytesFrom(data.filename, "utf8"),
110
+ backLinks: data.backLinks.map((bl) => {
111
111
  // Ensure txHash is in proper format for molecule encoding
112
- const txHash = typeof bl.txHash === 'string'
113
- ? bl.txHash
114
- : bl.txHash;
112
+ const txHash = typeof bl.txHash === "string" ? bl.txHash : bl.txHash;
115
113
  return {
116
114
  indexes: getBackLinkIndexes(bl),
117
115
  checksum: bl.checksum,
@@ -128,9 +126,9 @@ exports.CKBFSData = {
128
126
  return {
129
127
  index: unpacked.index,
130
128
  checksum: unpacked.checksum,
131
- contentType: core_1.ccc.bytesTo(unpacked.contentType, 'utf8'),
132
- filename: core_1.ccc.bytesTo(unpacked.filename, 'utf8'),
133
- backLinks: unpacked.backLinks.map(bl => ({
129
+ contentType: core_1.ccc.bytesTo(unpacked.contentType, "utf8"),
130
+ filename: core_1.ccc.bytesTo(unpacked.filename, "utf8"),
131
+ backLinks: unpacked.backLinks.map((bl) => ({
134
132
  index: bl.index,
135
133
  checksum: bl.checksum,
136
134
  txHash: bl.txHash,
@@ -143,9 +141,9 @@ exports.CKBFSData = {
143
141
  return {
144
142
  indexes: unpacked.indexes,
145
143
  checksum: unpacked.checksum,
146
- contentType: core_1.ccc.bytesTo(unpacked.contentType, 'utf8'),
147
- filename: core_1.ccc.bytesTo(unpacked.filename, 'utf8'),
148
- backLinks: unpacked.backLinks.map(bl => ({
144
+ contentType: core_1.ccc.bytesTo(unpacked.contentType, "utf8"),
145
+ filename: core_1.ccc.bytesTo(unpacked.filename, "utf8"),
146
+ backLinks: unpacked.backLinks.map((bl) => ({
149
147
  indexes: bl.indexes,
150
148
  checksum: bl.checksum,
151
149
  txHash: bl.txHash,
@@ -154,11 +152,11 @@ exports.CKBFSData = {
154
152
  }
155
153
  }
156
154
  catch (error) {
157
- console.error('Error unpacking CKBFSData:', error);
158
- throw new Error('Failed to unpack CKBFSData: ' + error);
155
+ console.error("Error unpacking CKBFSData:", error);
156
+ throw new Error("Failed to unpack CKBFSData: " + error);
159
157
  }
160
- }
158
+ },
161
159
  };
162
160
  // Constants for CKBFS protocol
163
- exports.CKBFS_HEADER = new Uint8Array([0x43, 0x4B, 0x42, 0x46, 0x53]); // "CKBFS" in ASCII
161
+ exports.CKBFS_HEADER = new Uint8Array([0x43, 0x4b, 0x42, 0x46, 0x53]); // "CKBFS" in ASCII
164
162
  exports.CKBFS_HEADER_STRING = "CKBFS";
@@ -1,6 +1,6 @@
1
1
  import { ccc, Transaction, Script, Signer } from "@ckb-ccc/core";
2
- import { CKBFSDataType } from './molecule';
3
- import { NetworkType } from './constants';
2
+ import { CKBFSDataType } from "./molecule";
3
+ import { NetworkType, ProtocolVersionType } from "./constants";
4
4
  /**
5
5
  * Utility functions for CKB transaction creation and handling
6
6
  */
@@ -13,7 +13,7 @@ export interface CKBFSCellOptions {
13
13
  capacity?: bigint;
14
14
  lock: Script;
15
15
  network?: NetworkType;
16
- version?: string;
16
+ version?: ProtocolVersionType;
17
17
  useTypeID?: boolean;
18
18
  }
19
19
  /**
@@ -40,8 +40,14 @@ export interface AppendOptions {
40
40
  contentChunks: Uint8Array[];
41
41
  feeRate?: number;
42
42
  network?: NetworkType;
43
- version?: string;
43
+ version?: ProtocolVersionType;
44
44
  }
45
+ /**
46
+ * Ensures a string is prefixed with '0x'
47
+ * @param value The string to ensure is hex prefixed
48
+ * @returns A hex prefixed string
49
+ */
50
+ export declare function ensureHexPrefix(value: string): `0x${string}`;
45
51
  /**
46
52
  * Creates a CKBFS cell
47
53
  * @param options Options for creating the CKBFS cell
@@ -1,5 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ensureHexPrefix = ensureHexPrefix;
3
4
  exports.createCKBFSCell = createCKBFSCell;
4
5
  exports.createPublishTransaction = createPublishTransaction;
5
6
  exports.createAppendTransaction = createAppendTransaction;
@@ -16,7 +17,7 @@ const constants_1 = require("./constants");
16
17
  * @returns A hex prefixed string
17
18
  */
18
19
  function ensureHexPrefix(value) {
19
- if (value.startsWith('0x')) {
20
+ if (value.startsWith("0x")) {
20
21
  return value;
21
22
  }
22
23
  return `0x${value}`;
@@ -27,7 +28,7 @@ function ensureHexPrefix(value) {
27
28
  * @returns The created cell output
28
29
  */
29
30
  function createCKBFSCell(options) {
30
- const { contentType, filename, capacity, lock, network = constants_1.DEFAULT_NETWORK, version = constants_1.DEFAULT_VERSION, useTypeID = false } = options;
31
+ const { contentType, filename, capacity, lock, network = constants_1.DEFAULT_NETWORK, version = constants_1.DEFAULT_VERSION, useTypeID = false, } = options;
31
32
  // Get CKBFS script config
32
33
  const config = (0, constants_1.getCKBFSScriptConfig)(network, version, useTypeID);
33
34
  // Create pre CKBFS type script
@@ -46,7 +47,7 @@ function createCKBFSCell(options) {
46
47
  * @returns Promise resolving to the created transaction
47
48
  */
48
49
  async function createPublishTransaction(signer, options) {
49
- const { contentChunks, contentType, filename, lock, capacity, feeRate, network = constants_1.DEFAULT_NETWORK, version = constants_1.DEFAULT_VERSION, useTypeID = false } = options;
50
+ const { contentChunks, contentType, filename, lock, capacity, feeRate, network = constants_1.DEFAULT_NETWORK, version = constants_1.DEFAULT_VERSION, useTypeID = false, } = options;
50
51
  // Calculate checksum for the combined content
51
52
  const textEncoder = new TextEncoder();
52
53
  const combinedContent = Buffer.concat(contentChunks);
@@ -87,7 +88,10 @@ async function createPublishTransaction(signer, options) {
87
88
  // Get CKBFS script config
88
89
  const config = (0, constants_1.getCKBFSScriptConfig)(network, version, useTypeID);
89
90
  const preCkbfsTypeScript = new core_1.Script(ensureHexPrefix(config.codeHash), config.hashType, "0x0000000000000000000000000000000000000000000000000000000000000000");
90
- const ckbfsCellSize = BigInt(outputData.length + preCkbfsTypeScript.occupiedSize + lock.occupiedSize + 8) * 100000000n;
91
+ const ckbfsCellSize = BigInt(outputData.length +
92
+ preCkbfsTypeScript.occupiedSize +
93
+ lock.occupiedSize +
94
+ 8) * 100000000n;
91
95
  // Create pre transaction without cell deps initially
92
96
  const preTx = core_1.Transaction.from({
93
97
  outputs: [
@@ -98,16 +102,14 @@ async function createPublishTransaction(signer, options) {
98
102
  network,
99
103
  version,
100
104
  useTypeID,
101
- capacity: ckbfsCellSize || capacity
102
- })
105
+ capacity: ckbfsCellSize || capacity,
106
+ }),
103
107
  ],
104
108
  witnesses: [
105
109
  [], // Empty secp witness for signing
106
- ...ckbfsWitnesses.map(w => `0x${Buffer.from(w).toString('hex')}`),
110
+ ...ckbfsWitnesses.map((w) => `0x${Buffer.from(w).toString("hex")}`),
107
111
  ],
108
- outputsData: [
109
- outputData,
110
- ]
112
+ outputsData: [outputData],
111
113
  });
112
114
  // Add the CKBFS dep group cell dependency
113
115
  preTx.addCellDeps({
@@ -115,7 +117,7 @@ async function createPublishTransaction(signer, options) {
115
117
  txHash: ensureHexPrefix(config.depTxHash),
116
118
  index: config.depIndex || 0,
117
119
  },
118
- depType: "depGroup"
120
+ depType: "depGroup",
119
121
  });
120
122
  // Get the recommended address to ensure lock script cell deps are included
121
123
  const address = await signer.getRecommendedAddressObj();
@@ -132,7 +134,7 @@ async function createPublishTransaction(signer, options) {
132
134
  cellDeps: preTx.cellDeps,
133
135
  witnesses: [
134
136
  [], // Reset first witness for signing
135
- ...preTx.witnesses.slice(1)
137
+ ...preTx.witnesses.slice(1),
136
138
  ],
137
139
  outputsData: preTx.outputsData,
138
140
  inputs: preTx.inputs,
@@ -142,8 +144,8 @@ async function createPublishTransaction(signer, options) {
142
144
  type: ckbfsTypeScript,
143
145
  capacity: preTx.outputs[0].capacity,
144
146
  },
145
- ...preTx.outputs.slice(1) // Include rest of outputs (e.g., change)
146
- ]
147
+ ...preTx.outputs.slice(1), // Include rest of outputs (e.g., change)
148
+ ],
147
149
  });
148
150
  return tx;
149
151
  }
@@ -154,7 +156,7 @@ async function createPublishTransaction(signer, options) {
154
156
  * @returns Promise resolving to the created transaction
155
157
  */
156
158
  async function createAppendTransaction(signer, options) {
157
- const { ckbfsCell, contentChunks, feeRate, network = constants_1.DEFAULT_NETWORK, version = constants_1.DEFAULT_VERSION } = options;
159
+ const { ckbfsCell, contentChunks, feeRate, network = constants_1.DEFAULT_NETWORK, version = constants_1.DEFAULT_VERSION, } = options;
158
160
  const { outPoint, data, type, lock, capacity } = ckbfsCell;
159
161
  // Get CKBFS script config early to use version info
160
162
  const config = (0, constants_1.getCKBFSScriptConfig)(network, version);
@@ -182,7 +184,8 @@ async function createAppendTransaction(signer, options) {
182
184
  newBackLink = {
183
185
  // In V1, field order is index, checksum, txHash
184
186
  // and index is a single number value, not an array
185
- index: data.index || (data.indexes && data.indexes.length > 0 ? data.indexes[0] : 0),
187
+ index: data.index ||
188
+ (data.indexes && data.indexes.length > 0 ? data.indexes[0] : 0),
186
189
  checksum: data.checksum,
187
190
  txHash: outPoint.txHash,
188
191
  };
@@ -228,12 +231,13 @@ async function createAppendTransaction(signer, options) {
228
231
  // Get sizes and calculate capacity requirements
229
232
  const newDataSize = outputData.length;
230
233
  // Calculate the required capacity for the output cell
231
- // This accounts for:
234
+ // This accounts for:
232
235
  // 1. The output data size
233
236
  // 2. The type script's occupied size
234
237
  // 3. The lock script's occupied size
235
238
  // 4. A constant of 8 bytes (for header overhead)
236
- const ckbfsCellSize = BigInt(outputData.length + type.occupiedSize + lock.occupiedSize + 8) * 100000000n;
239
+ const ckbfsCellSize = BigInt(outputData.length + type.occupiedSize + lock.occupiedSize + 8) *
240
+ 100000000n;
237
241
  console.log(`Original capacity: ${capacity}, Calculated size: ${ckbfsCellSize}, Data size: ${outputData.length}`);
238
242
  // Use the maximum value between calculated size and original capacity
239
243
  // to ensure we have enough capacity but don't decrease capacity unnecessarily
@@ -247,18 +251,16 @@ async function createAppendTransaction(signer, options) {
247
251
  index: outPoint.index,
248
252
  },
249
253
  since: "0x0",
250
- }
254
+ },
251
255
  ],
252
256
  outputs: [
253
257
  {
254
258
  lock,
255
259
  type,
256
260
  capacity: outputCapacity,
257
- }
261
+ },
258
262
  ],
259
- outputsData: [
260
- outputData,
261
- ]
263
+ outputsData: [outputData],
262
264
  });
263
265
  // Add the CKBFS dep group cell dependency
264
266
  tx.addCellDeps({
@@ -266,7 +268,7 @@ async function createAppendTransaction(signer, options) {
266
268
  txHash: ensureHexPrefix(config.depTxHash),
267
269
  index: config.depIndex || 0,
268
270
  },
269
- depType: "depGroup"
271
+ depType: "depGroup",
270
272
  });
271
273
  const inputsBefore = tx.inputs.length;
272
274
  // If we need more capacity than the original cell had, add additional inputs
@@ -278,14 +280,14 @@ async function createAppendTransaction(signer, options) {
278
280
  const witnesses = [];
279
281
  // add empty witness for signer if ckbfs's lock is the same as signer's lock
280
282
  if (address.script.hash() === lock.hash()) {
281
- witnesses.push('0x');
283
+ witnesses.push("0x");
282
284
  }
283
285
  // add ckbfs witnesses
284
- witnesses.push(...ckbfsWitnesses.map(w => `0x${Buffer.from(w).toString('hex')}`));
286
+ witnesses.push(...ckbfsWitnesses.map((w) => `0x${Buffer.from(w).toString("hex")}`));
285
287
  // Add empty witnesses for signer's input
286
288
  // This is to ensure that the transaction is valid and can be signed
287
289
  for (let i = inputsBefore; i < tx.inputs.length; i++) {
288
- witnesses.push('0x');
290
+ witnesses.push("0x");
289
291
  }
290
292
  tx.witnesses = witnesses;
291
293
  // Complete fee
@@ -0,0 +1 @@
1
+ Hello CKBFS!
@@ -0,0 +1,178 @@
1
+ import {
2
+ parseIdentifier,
3
+ IdentifierType,
4
+ getFileContentFromChainByIdentifier,
5
+ saveFileFromChainByIdentifier,
6
+ decodeFileFromChainByIdentifier,
7
+ } from '../src/index';
8
+
9
+ /**
10
+ * Simple test script to verify generic identifier functionality
11
+ * This script demonstrates parsing and using different identifier formats
12
+ */
13
+
14
+ // Test identifiers
15
+ const testIdentifiers = [
16
+ // Type 1: Pure TypeID hex string
17
+ '0xbce89252cece632ef819943bed9cd0e2576f8ce26f9f02075b621b1c9a28056a',
18
+
19
+ // Type 2: CKBFS URI with TypeID
20
+ 'ckbfs://bce89252cece632ef819943bed9cd0e2576f8ce26f9f02075b621b1c9a28056a',
21
+
22
+ // Type 3: CKBFS URI with transaction hash and index
23
+ 'ckbfs://431c9d668c1815d26eb4f7ac6256eb350ab351474daea8d588400146ab228780i0',
24
+
25
+ // Invalid formats for testing
26
+ 'invalid-identifier',
27
+ 'ckbfs://invalid',
28
+ '0xinvalid'
29
+ ];
30
+
31
+ /**
32
+ * Test identifier parsing functionality
33
+ */
34
+ function testIdentifierParsing() {
35
+ console.log('=== Testing Identifier Parsing ===');
36
+
37
+ testIdentifiers.forEach((identifier, index) => {
38
+ console.log(`\nTest ${index + 1}: ${identifier}`);
39
+
40
+ try {
41
+ const parsed = parseIdentifier(identifier);
42
+ console.log(` Type: ${parsed.type}`);
43
+
44
+ if (parsed.type === IdentifierType.TypeID) {
45
+ console.log(` TypeID: ${parsed.typeId}`);
46
+ } else if (parsed.type === IdentifierType.OutPoint) {
47
+ console.log(` TxHash: ${parsed.txHash}`);
48
+ console.log(` Index: ${parsed.index}`);
49
+ } else {
50
+ console.log(` Status: Invalid identifier format`);
51
+ }
52
+
53
+ console.log(` Original: ${parsed.original}`);
54
+ } catch (error) {
55
+ console.error(` Error: ${error}`);
56
+ }
57
+ });
58
+ }
59
+
60
+ /**
61
+ * Test file retrieval with different identifier formats
62
+ * Note: This requires a real CKB client and valid identifiers
63
+ */
64
+ async function testFileRetrieval() {
65
+ console.log('\n=== Testing File Retrieval ===');
66
+ console.log('Note: This test requires valid identifiers and network connection');
67
+
68
+ // This is a mock test - in real usage you would:
69
+ // 1. Initialize a CKB client
70
+ // 2. Use real identifiers from actual transactions
71
+ // 3. Test the retrieval functions
72
+
73
+ const mockClient = null; // Replace with real client
74
+ const validIdentifier = testIdentifiers[0]; // Use a real identifier
75
+
76
+ if (!mockClient) {
77
+ console.log('Skipping file retrieval test - no client configured');
78
+ return;
79
+ }
80
+
81
+ try {
82
+ console.log(`Testing retrieval with: ${validIdentifier}`);
83
+
84
+ // Test generic identifier function
85
+ const fileData = await getFileContentFromChainByIdentifier(
86
+ mockClient,
87
+ validIdentifier,
88
+ {
89
+ network: 'testnet',
90
+ version: '20241025.db973a8e8032',
91
+ useTypeID: false
92
+ }
93
+ );
94
+
95
+ if (fileData) {
96
+ console.log(`✓ Retrieved: ${fileData.filename}`);
97
+ console.log(` Size: ${fileData.size} bytes`);
98
+ console.log(` Content Type: ${fileData.contentType}`);
99
+ console.log(` Parsed ID Type: ${fileData.parsedId.type}`);
100
+ } else {
101
+ console.log('✗ File not found');
102
+ }
103
+ } catch (error) {
104
+ console.error(`✗ Error: ${error}`);
105
+ }
106
+ }
107
+
108
+ /**
109
+ * Demonstrate identifier format conversion
110
+ */
111
+ function demonstrateFormatConversion() {
112
+ console.log('\n=== Demonstrating Format Conversion ===');
113
+
114
+ const typeId = 'bce89252cece632ef819943bed9cd0e2576f8ce26f9f02075b621b1c9a28056a';
115
+ const txHash = '431c9d668c1815d26eb4f7ac6256eb350ab351474daea8d588400146ab228780';
116
+ const index = 0;
117
+
118
+ console.log('Creating different formats from the same data:');
119
+ console.log(`1. TypeID hex: 0x${typeId}`);
120
+ console.log(`2. CKBFS TypeID URI: ckbfs://${typeId}`);
121
+ console.log(`3. CKBFS OutPoint URI: ckbfs://${txHash}i${index}`);
122
+
123
+ // Parse each format
124
+ const formats = [
125
+ `0x${typeId}`,
126
+ `ckbfs://${typeId}`,
127
+ `ckbfs://${txHash}i${index}`
128
+ ];
129
+
130
+ formats.forEach((format, index) => {
131
+ const parsed = parseIdentifier(format);
132
+ console.log(`\nFormat ${index + 1} parsed as: ${parsed.type}`);
133
+ });
134
+ }
135
+
136
+ /**
137
+ * Main test function
138
+ */
139
+ async function main() {
140
+ console.log('CKBFS Generic Identifier Test');
141
+ console.log('=============================');
142
+
143
+ try {
144
+ // Test identifier parsing
145
+ testIdentifierParsing();
146
+
147
+ // Demonstrate format conversion
148
+ demonstrateFormatConversion();
149
+
150
+ // Test file retrieval (requires real setup)
151
+ await testFileRetrieval();
152
+
153
+ console.log('\n=== Test Summary ===');
154
+ console.log('✓ Identifier parsing test completed');
155
+ console.log('✓ Format conversion demonstration completed');
156
+ console.log('ℹ File retrieval test requires real network setup');
157
+
158
+ console.log('\nTo test with real data:');
159
+ console.log('1. Set up a CKB client (testnet or mainnet)');
160
+ console.log('2. Replace mock identifiers with real ones');
161
+ console.log('3. Run the file retrieval tests');
162
+
163
+ } catch (error) {
164
+ console.error('Test failed:', error);
165
+ process.exit(1);
166
+ }
167
+ }
168
+
169
+ // Run tests if this file is executed directly
170
+ if (require.main === module) {
171
+ main().catch(console.error);
172
+ }
173
+
174
+ export {
175
+ testIdentifierParsing,
176
+ testFileRetrieval,
177
+ demonstrateFormatConversion
178
+ };
package/examples/index.ts CHANGED
@@ -1,43 +1,55 @@
1
- import { CKBFS, NetworkType, ProtocolVersion } from '../src/index';
1
+ import { CKBFS, NetworkType, ProtocolVersion } from "../src/index";
2
2
 
3
3
  /**
4
4
  * Main CKBFS Examples
5
- *
5
+ *
6
6
  * This file serves as the entry point for running all CKBFS SDK examples.
7
- *
7
+ *
8
8
  * To run all examples:
9
9
  * npm run example
10
- *
10
+ *
11
11
  * To run specific examples:
12
12
  * npm run example:publish
13
13
  * npm run example:append -- --txhash=0x123456...
14
14
  */
15
15
 
16
- console.log('CKBFS SDK Examples');
17
- console.log('=================');
18
- console.log('');
19
- console.log('Available examples:');
20
- console.log('1. Publish File Example - npm run example:publish');
21
- console.log('2. Append File Example - npm run example:append -- --txhash=0x123456...');
22
- console.log('');
23
- console.log('Run all examples with: npm run example');
24
- console.log('');
25
- console.log('Note: For the append example, you need to provide a transaction hash');
26
- console.log('of a previously published file using the --txhash parameter or');
27
- console.log('by setting the PUBLISH_TX_HASH environment variable.');
28
- console.log('');
16
+ console.log("CKBFS SDK Examples");
17
+ console.log("=================");
18
+ console.log("");
19
+ console.log("Available examples:");
20
+ console.log("1. Publish File Example - npm run example:publish");
21
+ console.log(
22
+ "2. Append File Example - npm run example:append -- --txhash=0x123456...",
23
+ );
24
+ console.log(
25
+ "3. Retrieve File Example - npm run example:retrieve -- --txhash=0x123456...",
26
+ );
27
+ console.log("");
28
+ console.log("Run all examples with: npm run example");
29
+ console.log("");
30
+ console.log(
31
+ "Note: For the append and retrieve examples, you need to provide a transaction hash",
32
+ );
33
+ console.log("of a previously published file using the --txhash parameter or");
34
+ console.log(
35
+ "by setting the PUBLISH_TX_HASH/TARGET_TX_HASH environment variable.",
36
+ );
37
+ console.log("");
29
38
 
30
39
  // Check if we should run all examples
31
- const runAll = process.argv.includes('--all');
40
+ const runAll = process.argv.includes("--all");
32
41
 
33
42
  if (runAll) {
34
- console.log('Running all examples is not recommended. Please run specific examples instead.');
35
- console.log('');
36
- console.log('For example:');
37
- console.log(' npm run example:publish');
38
- console.log(' npm run example:append -- --txhash=0x123456...');
43
+ console.log(
44
+ "Running all examples is not recommended. Please run specific examples instead.",
45
+ );
46
+ console.log("");
47
+ console.log("For example:");
48
+ console.log(" npm run example:publish");
49
+ console.log(" npm run example:append -- --txhash=0x123456...");
50
+ console.log(" npm run example:retrieve -- --txhash=0x123456...");
39
51
  process.exit(1);
40
52
  }
41
53
 
42
54
  // Default behavior - just show instructions
43
- console.log('For more information, see the README.md file.');
55
+ console.log("For more information, see the README.md file.");
@@ -1,4 +1,4 @@
1
- import { CKBFS, NetworkType, ProtocolVersion } from '../src/index';
1
+ import { CKBFS, NetworkType, ProtocolVersion, PublishContentOptions } from '../src/index';
2
2
 
3
3
  // Replace with your actual private key
4
4
  const privateKey = process.env.CKB_PRIVATE_KEY || 'your-private-key-here';
@@ -28,12 +28,12 @@ async function publishExample() {
28
28
  console.log('Using CKBFS config:', config);
29
29
 
30
30
  // Publish a text file to CKBFS
31
- const filePath = './example.txt';
31
+ const filePath = './code.png';
32
32
 
33
33
  // You can provide additional options
34
34
  const options = {
35
- contentType: 'text/plain',
36
- filename: 'example.txt',
35
+ contentType: 'image/png',
36
+ filename: 'code.png',
37
37
  // Specify capacity if needed (default is 200 CKB)
38
38
  // capacity: 250n * 100000000n
39
39
  };
@@ -52,6 +52,38 @@ async function publishExample() {
52
52
  }
53
53
  }
54
54
 
55
+ /**
56
+ * Example of publishing content directly (string) to CKBFS
57
+ */
58
+ async function publishContentExample() {
59
+ try {
60
+ // Get address info
61
+ const address = await ckbfs.getAddress();
62
+ console.log(`Using address for content publish: ${address.toString()}`);
63
+
64
+ // Define content and options (contentType and filename are required)
65
+ const content = "Hello CKBFS from direct content!";
66
+ const options: PublishContentOptions = {
67
+ contentType: 'text/plain',
68
+ filename: 'direct_content_example.txt',
69
+ // You can optionally specify feeRate, network, version, useTypeID
70
+ // feeRate: 3000
71
+ };
72
+
73
+ console.log(`Publishing direct content: "${content}"`);
74
+ const txHash = await ckbfs.publishContent(content, options);
75
+
76
+ console.log(`Direct content published successfully!`);
77
+ console.log(`Transaction Hash: ${txHash}`);
78
+ console.log(`View at: https://pudge.explorer.nervos.org/transaction/${txHash}`);
79
+
80
+ return txHash;
81
+ } catch (error) {
82
+ console.error('Error publishing direct content:', error);
83
+ throw error;
84
+ }
85
+ }
86
+
55
87
  /**
56
88
  * Main function to run the example
57
89
  */
@@ -62,6 +94,8 @@ async function main() {
62
94
 
63
95
  try {
64
96
  await publishExample();
97
+ console.log('----------------------------------');
98
+ await publishContentExample();
65
99
  console.log('Example completed successfully!');
66
100
  process.exit(0);
67
101
  } catch (error) {
@@ -73,4 +107,4 @@ async function main() {
73
107
  // Run the example if this file is executed directly
74
108
  if (require.main === module) {
75
109
  main().catch(console.error);
76
- }
110
+ }