@ckbfs/api 1.3.0 → 1.4.0

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,7 +40,7 @@ export interface AppendOptions {
40
40
  contentChunks: Uint8Array[];
41
41
  feeRate?: number;
42
42
  network?: NetworkType;
43
- version?: string;
43
+ version?: ProtocolVersionType;
44
44
  }
45
45
  /**
46
46
  * Ensures a string is prefixed with '0x'
@@ -17,7 +17,7 @@ const constants_1 = require("./constants");
17
17
  * @returns A hex prefixed string
18
18
  */
19
19
  function ensureHexPrefix(value) {
20
- if (value.startsWith('0x')) {
20
+ if (value.startsWith("0x")) {
21
21
  return value;
22
22
  }
23
23
  return `0x${value}`;
@@ -28,7 +28,7 @@ function ensureHexPrefix(value) {
28
28
  * @returns The created cell output
29
29
  */
30
30
  function createCKBFSCell(options) {
31
- 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;
32
32
  // Get CKBFS script config
33
33
  const config = (0, constants_1.getCKBFSScriptConfig)(network, version, useTypeID);
34
34
  // Create pre CKBFS type script
@@ -47,7 +47,7 @@ function createCKBFSCell(options) {
47
47
  * @returns Promise resolving to the created transaction
48
48
  */
49
49
  async function createPublishTransaction(signer, options) {
50
- 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;
51
51
  // Calculate checksum for the combined content
52
52
  const textEncoder = new TextEncoder();
53
53
  const combinedContent = Buffer.concat(contentChunks);
@@ -88,7 +88,10 @@ async function createPublishTransaction(signer, options) {
88
88
  // Get CKBFS script config
89
89
  const config = (0, constants_1.getCKBFSScriptConfig)(network, version, useTypeID);
90
90
  const preCkbfsTypeScript = new core_1.Script(ensureHexPrefix(config.codeHash), config.hashType, "0x0000000000000000000000000000000000000000000000000000000000000000");
91
- 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;
92
95
  // Create pre transaction without cell deps initially
93
96
  const preTx = core_1.Transaction.from({
94
97
  outputs: [
@@ -99,16 +102,14 @@ async function createPublishTransaction(signer, options) {
99
102
  network,
100
103
  version,
101
104
  useTypeID,
102
- capacity: ckbfsCellSize || capacity
103
- })
105
+ capacity: ckbfsCellSize || capacity,
106
+ }),
104
107
  ],
105
108
  witnesses: [
106
109
  [], // Empty secp witness for signing
107
- ...ckbfsWitnesses.map(w => `0x${Buffer.from(w).toString('hex')}`),
110
+ ...ckbfsWitnesses.map((w) => `0x${Buffer.from(w).toString("hex")}`),
108
111
  ],
109
- outputsData: [
110
- outputData,
111
- ]
112
+ outputsData: [outputData],
112
113
  });
113
114
  // Add the CKBFS dep group cell dependency
114
115
  preTx.addCellDeps({
@@ -116,7 +117,7 @@ async function createPublishTransaction(signer, options) {
116
117
  txHash: ensureHexPrefix(config.depTxHash),
117
118
  index: config.depIndex || 0,
118
119
  },
119
- depType: "depGroup"
120
+ depType: "depGroup",
120
121
  });
121
122
  // Get the recommended address to ensure lock script cell deps are included
122
123
  const address = await signer.getRecommendedAddressObj();
@@ -133,7 +134,7 @@ async function createPublishTransaction(signer, options) {
133
134
  cellDeps: preTx.cellDeps,
134
135
  witnesses: [
135
136
  [], // Reset first witness for signing
136
- ...preTx.witnesses.slice(1)
137
+ ...preTx.witnesses.slice(1),
137
138
  ],
138
139
  outputsData: preTx.outputsData,
139
140
  inputs: preTx.inputs,
@@ -143,8 +144,8 @@ async function createPublishTransaction(signer, options) {
143
144
  type: ckbfsTypeScript,
144
145
  capacity: preTx.outputs[0].capacity,
145
146
  },
146
- ...preTx.outputs.slice(1) // Include rest of outputs (e.g., change)
147
- ]
147
+ ...preTx.outputs.slice(1), // Include rest of outputs (e.g., change)
148
+ ],
148
149
  });
149
150
  return tx;
150
151
  }
@@ -155,7 +156,7 @@ async function createPublishTransaction(signer, options) {
155
156
  * @returns Promise resolving to the created transaction
156
157
  */
157
158
  async function createAppendTransaction(signer, options) {
158
- 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;
159
160
  const { outPoint, data, type, lock, capacity } = ckbfsCell;
160
161
  // Get CKBFS script config early to use version info
161
162
  const config = (0, constants_1.getCKBFSScriptConfig)(network, version);
@@ -183,7 +184,8 @@ async function createAppendTransaction(signer, options) {
183
184
  newBackLink = {
184
185
  // In V1, field order is index, checksum, txHash
185
186
  // and index is a single number value, not an array
186
- 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),
187
189
  checksum: data.checksum,
188
190
  txHash: outPoint.txHash,
189
191
  };
@@ -229,12 +231,13 @@ async function createAppendTransaction(signer, options) {
229
231
  // Get sizes and calculate capacity requirements
230
232
  const newDataSize = outputData.length;
231
233
  // Calculate the required capacity for the output cell
232
- // This accounts for:
234
+ // This accounts for:
233
235
  // 1. The output data size
234
236
  // 2. The type script's occupied size
235
237
  // 3. The lock script's occupied size
236
238
  // 4. A constant of 8 bytes (for header overhead)
237
- const ckbfsCellSize = BigInt(outputData.length + type.occupiedSize + lock.occupiedSize + 8) * 100000000n;
239
+ const ckbfsCellSize = BigInt(outputData.length + type.occupiedSize + lock.occupiedSize + 8) *
240
+ 100000000n;
238
241
  console.log(`Original capacity: ${capacity}, Calculated size: ${ckbfsCellSize}, Data size: ${outputData.length}`);
239
242
  // Use the maximum value between calculated size and original capacity
240
243
  // to ensure we have enough capacity but don't decrease capacity unnecessarily
@@ -248,18 +251,16 @@ async function createAppendTransaction(signer, options) {
248
251
  index: outPoint.index,
249
252
  },
250
253
  since: "0x0",
251
- }
254
+ },
252
255
  ],
253
256
  outputs: [
254
257
  {
255
258
  lock,
256
259
  type,
257
260
  capacity: outputCapacity,
258
- }
261
+ },
259
262
  ],
260
- outputsData: [
261
- outputData,
262
- ]
263
+ outputsData: [outputData],
263
264
  });
264
265
  // Add the CKBFS dep group cell dependency
265
266
  tx.addCellDeps({
@@ -267,7 +268,7 @@ async function createAppendTransaction(signer, options) {
267
268
  txHash: ensureHexPrefix(config.depTxHash),
268
269
  index: config.depIndex || 0,
269
270
  },
270
- depType: "depGroup"
271
+ depType: "depGroup",
271
272
  });
272
273
  const inputsBefore = tx.inputs.length;
273
274
  // If we need more capacity than the original cell had, add additional inputs
@@ -279,14 +280,14 @@ async function createAppendTransaction(signer, options) {
279
280
  const witnesses = [];
280
281
  // add empty witness for signer if ckbfs's lock is the same as signer's lock
281
282
  if (address.script.hash() === lock.hash()) {
282
- witnesses.push('0x');
283
+ witnesses.push("0x");
283
284
  }
284
285
  // add ckbfs witnesses
285
- witnesses.push(...ckbfsWitnesses.map(w => `0x${Buffer.from(w).toString('hex')}`));
286
+ witnesses.push(...ckbfsWitnesses.map((w) => `0x${Buffer.from(w).toString("hex")}`));
286
287
  // Add empty witnesses for signer's input
287
288
  // This is to ensure that the transaction is valid and can be signed
288
289
  for (let i = inputsBefore; i < tx.inputs.length; i++) {
289
- witnesses.push('0x');
290
+ witnesses.push("0x");
290
291
  }
291
292
  tx.witnesses = witnesses;
292
293
  // Complete fee
@@ -1,4 +1,4 @@
1
- import { CKBFS, NetworkType, ProtocolVersion, CKBFSDataType, extractCKBFSWitnessContent, isCKBFSWitness, CKBFSData, AppendContentOptions } from '../src/index';
1
+ import { CKBFS, NetworkType, ProtocolVersion, CKBFSDataType, extractCKBFSWitnessContent, isCKBFSWitness, CKBFSData } from '../src/index';
2
2
  import { Script, ClientPublicTestnet, Transaction, ccc } from "@ckb-ccc/core";
3
3
 
4
4
  // Replace with your actual private key
@@ -169,37 +169,6 @@ async function appendExample() {
169
169
  }
170
170
  }
171
171
 
172
- /**
173
- * Example of appending content directly (string) to an existing CKBFS file
174
- * @param previousAppendTxHash The transaction hash from the previous append operation
175
- */
176
- async function appendContentExample(previousAppendTxHash: string) {
177
- try {
178
- console.log(`Getting cell info from previous append transaction: ${previousAppendTxHash}`);
179
- const ckbfsCell = await getCellInfoFromTransaction(previousAppendTxHash);
180
-
181
- const contentToAppend = "\nAnd this is more content appended directly as a string!";
182
- const options: AppendContentOptions = {
183
- // You can optionally specify feeRate, network, version
184
- // feeRate: 3000
185
- };
186
-
187
- console.log(`Appending direct content: "${contentToAppend}"`);
188
-
189
- // Append the string content
190
- const txHash = await ckbfs.appendContent(contentToAppend, ckbfsCell, options);
191
-
192
- console.log(`Direct content appended successfully!`);
193
- console.log(`Transaction Hash: ${txHash}`);
194
- console.log(`View at: https://pudge.explorer.nervos.org/transaction/${txHash}`);
195
-
196
- return txHash;
197
- } catch (error) {
198
- console.error('Error appending direct content:', error);
199
- throw error;
200
- }
201
- }
202
-
203
172
  /**
204
173
  * Main function to run the example
205
174
  */
@@ -209,13 +178,7 @@ async function main() {
209
178
  console.log(`Using CKBFS protocol version: ${ProtocolVersion.V2}`);
210
179
 
211
180
  try {
212
- // Run the file append first
213
- const firstAppendTxHash = await appendExample();
214
- console.log('-------------------------------');
215
-
216
- // Now run the content append, using the output from the first append
217
- await appendContentExample(firstAppendTxHash);
218
-
181
+ await appendExample();
219
182
  console.log('Example completed successfully!');
220
183
  process.exit(0);
221
184
  } catch (error) {
@@ -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.");
@@ -6,7 +6,7 @@ const privateKey = process.env.CKB_PRIVATE_KEY || 'your-private-key-here';
6
6
  // Initialize the SDK with network and version options
7
7
  const ckbfs = new CKBFS(
8
8
  privateKey,
9
- NetworkType.Testnet, // Use testnet
9
+ NetworkType.Mainnet, // Use testnet
10
10
  {
11
11
  version: ProtocolVersion.V2, // Use the latest version (V2)
12
12
  chunkSize: 30 * 1024, // 30KB chunks
@@ -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
  };
@@ -107,4 +107,4 @@ async function main() {
107
107
  // Run the example if this file is executed directly
108
108
  if (require.main === module) {
109
109
  main().catch(console.error);
110
- }
110
+ }