@ckbfs/api 2.0.4 → 2.0.6

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/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { Script, Signer, Transaction } from "@ckb-ccc/core";
2
2
  import { calculateChecksum, verifyChecksum, updateChecksum, verifyWitnessChecksum, verifyV3WitnessChecksum, verifyV3WitnessChain } from "./utils/checksum";
3
- import { createCKBFSCell, createPublishTransaction as utilCreatePublishTransaction, preparePublishTransaction, createAppendTransaction as utilCreateAppendTransaction, prepareAppendTransaction, createAppendTransactionDry, publishCKBFS as utilPublishCKBFS, appendCKBFS as utilAppendCKBFS, CKBFSCellOptions, PublishOptions, AppendOptions, AppendV3Options, TransferV3Options } from "./utils/transaction";
3
+ import { createCKBFSCell, createPublishTransaction as utilCreatePublishTransaction, preparePublishTransaction, createAppendTransaction as utilCreateAppendTransaction, prepareAppendTransaction, createAppendTransactionDry, publishCKBFS as utilPublishCKBFS, appendCKBFS as utilAppendCKBFS, CKBFSCellOptions, PublishOptions, AppendOptions, AppendV3Options, TransferV3Options, createAppendV3Transaction } from "./utils/transaction";
4
4
  import { readFile, readFileAsText, readFileAsUint8Array, writeFile, getContentType, splitFileIntoChunks, combineChunksToFile, getFileContentFromChain, saveFileFromChain, getFileContentFromChainByTypeId, saveFileFromChainByTypeId, decodeFileFromChainByTypeId, getFileContentFromChainByIdentifier, saveFileFromChainByIdentifier, decodeFileFromChainByIdentifier, parseIdentifier, IdentifierType, decodeWitnessContent, decodeMultipleWitnessContents, extractFileFromWitnesses, decodeFileFromWitnessData, saveFileFromWitnessData, getFileContentFromChainV3, getFileContentFromChainByIdentifierV3, saveFileFromChainByIdentifierV3, resolveCKBFSCell } from "./utils/file";
5
5
  import { createCKBFSWitness, createTextCKBFSWitness, extractCKBFSWitnessContent, isCKBFSWitness, createChunkedCKBFSWitnesses, createCKBFSV3Witness, createChunkedCKBFSV3Witnesses, extractCKBFSV3WitnessContent, isCKBFSV3Witness, CKBFSV3WitnessOptions } from "./utils/witness";
6
6
  import { CKBFSData, BackLinkV1, BackLinkV2, CKBFSDataType, BackLinkType, CKBFS_HEADER, CKBFS_HEADER_STRING } from "./utils/molecule";
@@ -28,6 +28,7 @@ export type PublishContentOptions = Omit<FileOptions, "capacity" | "contentType"
28
28
  */
29
29
  export type AppendContentOptions = Omit<FileOptions, "contentType" | "filename" | "capacity"> & {
30
30
  capacity?: bigint;
31
+ witnessStartIndex?: number;
31
32
  };
32
33
  /**
33
34
  * Configuration options for the CKBFS SDK
@@ -96,6 +97,7 @@ export declare class CKBFS {
96
97
  previousTxHash?: string;
97
98
  previousWitnessIndex?: number;
98
99
  previousChecksum?: number;
100
+ witnessStartIndex?: number;
99
101
  }): Promise<string>;
100
102
  /**
101
103
  * Appends content (string or Uint8Array) directly to an existing CKBFS file
@@ -130,6 +132,7 @@ export declare class CKBFS {
130
132
  previousTxHash?: string;
131
133
  previousWitnessIndex?: number;
132
134
  previousChecksum?: number;
135
+ witnessStartIndex?: number;
133
136
  }): Promise<Transaction>;
134
137
  /**
135
138
  * Creates a new transaction for appending content (string or Uint8Array) directly, but doesn't sign or send it
@@ -194,4 +197,4 @@ export declare class CKBFS {
194
197
  */
195
198
  createPublishV3Transaction(filePath: string, options?: Omit<FileOptions, 'version'>): Promise<Transaction>;
196
199
  }
197
- export { calculateChecksum, verifyChecksum, updateChecksum, verifyWitnessChecksum, verifyV3WitnessChecksum, verifyV3WitnessChain, createCKBFSCell, utilCreatePublishTransaction as createPublishTransaction, preparePublishTransaction, utilCreateAppendTransaction as createAppendTransaction, prepareAppendTransaction, utilPublishCKBFS as publishCKBFS, utilAppendCKBFS as appendCKBFS, createAppendTransactionDry, readFile, readFileAsText, readFileAsUint8Array, writeFile, getContentType, splitFileIntoChunks, combineChunksToFile, getFileContentFromChain, saveFileFromChain, getFileContentFromChainByTypeId, saveFileFromChainByTypeId, decodeFileFromChainByTypeId, getFileContentFromChainByIdentifier, saveFileFromChainByIdentifier, decodeFileFromChainByIdentifier, parseIdentifier, IdentifierType, decodeWitnessContent, decodeMultipleWitnessContents, extractFileFromWitnesses, decodeFileFromWitnessData, saveFileFromWitnessData, getFileContentFromChainV3, getFileContentFromChainByIdentifierV3, saveFileFromChainByIdentifierV3, createCKBFSWitness, createTextCKBFSWitness, extractCKBFSWitnessContent, isCKBFSWitness, createChunkedCKBFSWitnesses, createCKBFSV3Witness, createChunkedCKBFSV3Witnesses, extractCKBFSV3WitnessContent, isCKBFSV3Witness, resolveCKBFSCell, CKBFSV3WitnessOptions, CKBFSData, BackLinkV1, BackLinkV2, CKBFSDataType, BackLinkType, CKBFSCellOptions, PublishOptions, AppendOptions, CKBFS_HEADER, CKBFS_HEADER_STRING, NetworkType, ProtocolVersion, ProtocolVersionType, DEFAULT_NETWORK, DEFAULT_VERSION, CKBFS_CODE_HASH, CKBFS_TYPE_ID, ADLER32_CODE_HASH, ADLER32_TYPE_ID, DEP_GROUP_TX_HASH, DEPLOY_TX_HASH, getCKBFSScriptConfig, CKBFSScriptConfig, };
200
+ export { calculateChecksum, verifyChecksum, updateChecksum, verifyWitnessChecksum, verifyV3WitnessChecksum, verifyV3WitnessChain, createCKBFSCell, utilCreatePublishTransaction as createPublishTransaction, preparePublishTransaction, utilCreateAppendTransaction as createAppendTransaction, prepareAppendTransaction, utilPublishCKBFS as publishCKBFS, utilAppendCKBFS as appendCKBFS, createAppendTransactionDry, createAppendV3Transaction, readFile, readFileAsText, readFileAsUint8Array, writeFile, getContentType, splitFileIntoChunks, combineChunksToFile, getFileContentFromChain, saveFileFromChain, getFileContentFromChainByTypeId, saveFileFromChainByTypeId, decodeFileFromChainByTypeId, getFileContentFromChainByIdentifier, saveFileFromChainByIdentifier, decodeFileFromChainByIdentifier, parseIdentifier, IdentifierType, decodeWitnessContent, decodeMultipleWitnessContents, extractFileFromWitnesses, decodeFileFromWitnessData, saveFileFromWitnessData, getFileContentFromChainV3, getFileContentFromChainByIdentifierV3, saveFileFromChainByIdentifierV3, createCKBFSWitness, createTextCKBFSWitness, extractCKBFSWitnessContent, isCKBFSWitness, createChunkedCKBFSWitnesses, createCKBFSV3Witness, createChunkedCKBFSV3Witnesses, extractCKBFSV3WitnessContent, isCKBFSV3Witness, resolveCKBFSCell, CKBFSV3WitnessOptions, CKBFSData, BackLinkV1, BackLinkV2, CKBFSDataType, BackLinkType, CKBFSCellOptions, PublishOptions, AppendOptions, CKBFS_HEADER, CKBFS_HEADER_STRING, NetworkType, ProtocolVersion, ProtocolVersionType, DEFAULT_NETWORK, DEFAULT_VERSION, CKBFS_CODE_HASH, CKBFS_TYPE_ID, ADLER32_CODE_HASH, ADLER32_TYPE_ID, DEP_GROUP_TX_HASH, DEPLOY_TX_HASH, getCKBFSScriptConfig, CKBFSScriptConfig, };
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.resolveCKBFSCell = exports.isCKBFSV3Witness = exports.extractCKBFSV3WitnessContent = exports.createChunkedCKBFSV3Witnesses = exports.createCKBFSV3Witness = exports.createChunkedCKBFSWitnesses = exports.isCKBFSWitness = exports.extractCKBFSWitnessContent = exports.createTextCKBFSWitness = exports.createCKBFSWitness = exports.saveFileFromChainByIdentifierV3 = exports.getFileContentFromChainByIdentifierV3 = exports.getFileContentFromChainV3 = exports.saveFileFromWitnessData = exports.decodeFileFromWitnessData = exports.extractFileFromWitnesses = exports.decodeMultipleWitnessContents = exports.decodeWitnessContent = exports.IdentifierType = exports.parseIdentifier = exports.decodeFileFromChainByIdentifier = exports.saveFileFromChainByIdentifier = exports.getFileContentFromChainByIdentifier = exports.decodeFileFromChainByTypeId = exports.saveFileFromChainByTypeId = exports.getFileContentFromChainByTypeId = exports.saveFileFromChain = exports.getFileContentFromChain = exports.combineChunksToFile = exports.splitFileIntoChunks = exports.getContentType = exports.writeFile = exports.readFileAsUint8Array = exports.readFileAsText = exports.readFile = exports.createAppendTransactionDry = exports.appendCKBFS = exports.publishCKBFS = exports.prepareAppendTransaction = exports.createAppendTransaction = exports.preparePublishTransaction = exports.createPublishTransaction = exports.createCKBFSCell = exports.verifyV3WitnessChain = exports.verifyV3WitnessChecksum = exports.verifyWitnessChecksum = exports.updateChecksum = exports.verifyChecksum = exports.calculateChecksum = exports.CKBFS = void 0;
4
- exports.getCKBFSScriptConfig = exports.DEPLOY_TX_HASH = exports.DEP_GROUP_TX_HASH = exports.ADLER32_TYPE_ID = exports.ADLER32_CODE_HASH = exports.CKBFS_TYPE_ID = exports.CKBFS_CODE_HASH = exports.DEFAULT_VERSION = exports.DEFAULT_NETWORK = exports.ProtocolVersion = exports.NetworkType = exports.CKBFS_HEADER_STRING = exports.CKBFS_HEADER = exports.BackLinkV2 = exports.BackLinkV1 = exports.CKBFSData = void 0;
3
+ exports.isCKBFSV3Witness = exports.extractCKBFSV3WitnessContent = exports.createChunkedCKBFSV3Witnesses = exports.createCKBFSV3Witness = exports.createChunkedCKBFSWitnesses = exports.isCKBFSWitness = exports.extractCKBFSWitnessContent = exports.createTextCKBFSWitness = exports.createCKBFSWitness = exports.saveFileFromChainByIdentifierV3 = exports.getFileContentFromChainByIdentifierV3 = exports.getFileContentFromChainV3 = exports.saveFileFromWitnessData = exports.decodeFileFromWitnessData = exports.extractFileFromWitnesses = exports.decodeMultipleWitnessContents = exports.decodeWitnessContent = exports.IdentifierType = exports.parseIdentifier = exports.decodeFileFromChainByIdentifier = exports.saveFileFromChainByIdentifier = exports.getFileContentFromChainByIdentifier = exports.decodeFileFromChainByTypeId = exports.saveFileFromChainByTypeId = exports.getFileContentFromChainByTypeId = exports.saveFileFromChain = exports.getFileContentFromChain = exports.combineChunksToFile = exports.splitFileIntoChunks = exports.getContentType = exports.writeFile = exports.readFileAsUint8Array = exports.readFileAsText = exports.readFile = exports.createAppendV3Transaction = exports.createAppendTransactionDry = exports.appendCKBFS = exports.publishCKBFS = exports.prepareAppendTransaction = exports.createAppendTransaction = exports.preparePublishTransaction = exports.createPublishTransaction = exports.createCKBFSCell = exports.verifyV3WitnessChain = exports.verifyV3WitnessChecksum = exports.verifyWitnessChecksum = exports.updateChecksum = exports.verifyChecksum = exports.calculateChecksum = exports.CKBFS = void 0;
4
+ exports.getCKBFSScriptConfig = exports.DEPLOY_TX_HASH = exports.DEP_GROUP_TX_HASH = exports.ADLER32_TYPE_ID = exports.ADLER32_CODE_HASH = exports.CKBFS_TYPE_ID = exports.CKBFS_CODE_HASH = exports.DEFAULT_VERSION = exports.DEFAULT_NETWORK = exports.ProtocolVersion = exports.NetworkType = exports.CKBFS_HEADER_STRING = exports.CKBFS_HEADER = exports.BackLinkV2 = exports.BackLinkV1 = exports.CKBFSData = exports.resolveCKBFSCell = void 0;
5
5
  const core_1 = require("@ckb-ccc/core");
6
6
  const checksum_1 = require("./utils/checksum");
7
7
  Object.defineProperty(exports, "calculateChecksum", { enumerable: true, get: function () { return checksum_1.calculateChecksum; } });
@@ -19,6 +19,7 @@ Object.defineProperty(exports, "prepareAppendTransaction", { enumerable: true, g
19
19
  Object.defineProperty(exports, "createAppendTransactionDry", { enumerable: true, get: function () { return transaction_1.createAppendTransactionDry; } });
20
20
  Object.defineProperty(exports, "publishCKBFS", { enumerable: true, get: function () { return transaction_1.publishCKBFS; } });
21
21
  Object.defineProperty(exports, "appendCKBFS", { enumerable: true, get: function () { return transaction_1.appendCKBFS; } });
22
+ Object.defineProperty(exports, "createAppendV3Transaction", { enumerable: true, get: function () { return transaction_1.createAppendV3Transaction; } });
22
23
  const file_1 = require("./utils/file");
23
24
  Object.defineProperty(exports, "readFile", { enumerable: true, get: function () { return file_1.readFile; } });
24
25
  Object.defineProperty(exports, "readFileAsText", { enumerable: true, get: function () { return file_1.readFileAsText; } });
@@ -478,6 +479,7 @@ class CKBFS {
478
479
  previousTxHash: options.previousTxHash,
479
480
  previousWitnessIndex: options.previousWitnessIndex,
480
481
  previousChecksum: options.previousChecksum,
482
+ witnessStartIndex: options.witnessStartIndex,
481
483
  });
482
484
  }
483
485
  else {
@@ -49,6 +49,7 @@ export interface BaseAppendOptions {
49
49
  network?: NetworkType;
50
50
  version?: ProtocolVersionType;
51
51
  from?: Transaction;
52
+ witnessStartIndex?: number;
52
53
  }
53
54
  /**
54
55
  * Common CKBFS cell creation options
@@ -33,6 +33,7 @@ export interface AppendV3Options {
33
33
  network?: NetworkType;
34
34
  version: typeof ProtocolVersion.V3;
35
35
  from?: Transaction;
36
+ witnessStartIndex?: number;
36
37
  previousTxHash: string;
37
38
  previousWitnessIndex: number;
38
39
  previousChecksum: number;
@@ -217,12 +217,12 @@ async function createPublishV3Transaction(signer, options) {
217
217
  * @returns Promise resolving to the prepared transaction and the output index of CKBFS Cell
218
218
  */
219
219
  async function prepareAppendV3Transaction(options) {
220
- const { from, ckbfsCell, contentChunks, network = constants_1.DEFAULT_NETWORK, previousTxHash, previousWitnessIndex, previousChecksum, } = options;
220
+ const { from, ckbfsCell, contentChunks, network = constants_1.DEFAULT_NETWORK, previousTxHash, previousWitnessIndex, previousChecksum, witnessStartIndex, } = options;
221
221
  // Calculate new checksum by updating from previous checksum
222
222
  const combinedContent = Buffer.concat(contentChunks);
223
223
  const newChecksum = await (0, checksum_1.updateChecksum)(previousChecksum, combinedContent);
224
224
  // Calculate the actual witness indices where our content is placed
225
- const contentStartIndex = from?.witnesses.length || 1;
225
+ const contentStartIndex = witnessStartIndex || from?.witnesses.length || 0;
226
226
  // Create CKBFS v3 witnesses with backlink info
227
227
  const ckbfsWitnesses = (0, witness_1.createChunkedCKBFSV3Witnesses)(contentChunks, {
228
228
  previousTxHash,
@@ -350,6 +350,7 @@ async function createAppendV3Transaction(signer, options) {
350
350
  // Add more inputs to cover the increased capacity
351
351
  await preTx.completeInputsByCapacity(signer);
352
352
  }
353
+ await preTx.completeInputsByCapacity(signer);
353
354
  const witnesses = [];
354
355
  // add empty witness for signer if ckbfs's lock is the same as signer's lock
355
356
  if (address.script.hash() === lock.hash()) {
@@ -161,9 +161,9 @@ function extractCKBFSV3WitnessContent(witness, isHeadWitness = true) {
161
161
  // Extract previous position
162
162
  const prevTxHashBytes = witness.slice(6, 38);
163
163
  const previousTxHash = '0x' + Array.from(prevTxHashBytes).map(b => b.toString(16).padStart(2, '0')).join('');
164
- const previousWitnessIndex = new DataView(witness.slice(38, 42).buffer).getUint32(0, true);
165
- const previousChecksum = new DataView(witness.slice(42, 46).buffer).getUint32(0, true);
166
- const nextIndex = new DataView(witness.slice(46, 50).buffer).getUint32(0, true);
164
+ const previousWitnessIndex = new DataView(witness.slice(38, 42).buffer.slice(witness.slice(38, 42).byteOffset, witness.slice(38, 42).byteOffset + 4)).getUint32(0, true);
165
+ const previousChecksum = new DataView(witness.slice(42, 46).buffer.slice(witness.slice(42, 46).byteOffset, witness.slice(42, 46).byteOffset + 4)).getUint32(0, true);
166
+ const nextIndex = new DataView(witness.slice(46, 50).buffer.slice(witness.slice(46, 50).byteOffset, witness.slice(46, 50).byteOffset + 4)).getUint32(0, true);
167
167
  const content = witness.slice(50);
168
168
  return {
169
169
  version,
@@ -18,7 +18,10 @@ import {
18
18
  ClientPublicTestnet,
19
19
  ClientPublicMainnet,
20
20
  Transaction,
21
- ccc
21
+ ccc,
22
+ SignerCkbPrivateKey,
23
+ fixedPointFrom,
24
+ Signer
22
25
  } from "@ckb-ccc/core";
23
26
  import {
24
27
  transferSpore
@@ -30,7 +33,7 @@ const client = new ClientPublicTestnet()
30
33
 
31
34
  export const TestnetTraceLockDep = {
32
35
  outPoint: {
33
- txHash: "0xf6d5b0c8c5221cc9d158fd8556a3772c25a295b9f894eeb86291a25522cf90b0",
36
+ txHash: "0x7a3e492188438ca4b260fed0f7a00d18ec9e4671a8c3b54fc2b3b49447ab2e2f",
34
37
  index: 0x0,
35
38
  },
36
39
  depType: "code",
@@ -66,7 +69,7 @@ const ShadowDep = TestnetShadowDep
66
69
 
67
70
  const TraceLogCodeHash = "0xbd7e56daaa4cc9ecf488a50d2f4db2a55a7c86eb2df2157d24a62be9be5b34ab"
68
71
  const ShadowSporeCodeHash = "0x6361d4b20d845953d9c9431bbba08905573005a71e2a2432e7e0e7c685666f24"
69
- const CKB_PRIVATE_KEY = "0x1733e6f7825f99eb41ca26f8569fa90c2cb8c5ae199bbd38a97562291f784983"
72
+ const CKB_PRIVATE_KEY = "0x620ab1e4273b937032380e9f851c3119427ba965805bebcdce60a4494fd3074d"
70
73
 
71
74
  const ckbfs = new CKBFS(
72
75
  CKB_PRIVATE_KEY,
@@ -113,13 +116,7 @@ export async function claim(to: string, sporeId: string, ckbfsId: string) {
113
116
 
114
117
  const content = `TRANSFER,FROM:${fromHash},TO:${toHash}\n`
115
118
 
116
- const previousData = {
117
- previousTxHash: ckbfsCell.outPoint.txHash,
118
- previousWitnessIndex: ckbfsCell.data?.index || 0,
119
- previousChecksum: ckbfsCell.data?.checksum || 0
120
- };
121
-
122
- let tx = await ckbfs.createAppendContentTransaction(content, ckbfsCell, previousData as any);
119
+ let tx = await ckbfs.createAppendContentTransaction(content, ckbfsCell);
123
120
  tx.addCellDeps(TraceLockDep)
124
121
 
125
122
  const sizeBefore = tx.outputs[0].lock.occupiedSize
@@ -167,19 +164,16 @@ export async function giveName(name: string, ckbfsId: string) {
167
164
  const content = `GIVE_NAME,NEW_NAME:${name}\n`
168
165
 
169
166
  console.log("ckbfsCell=", ckbfsCell)
170
-
171
- const previousData = {
172
- previousTxHash: ckbfsCell.outPoint.txHash,
173
- previousWitnessIndex: ckbfsCell.data?.index || 0,
174
- previousChecksum: ckbfsCell.data?.checksum || 0
175
- };
167
+
176
168
  const signer = ckbfs['signer']
177
169
  const address = await signer.getRecommendedAddress()
178
170
  const addressHash = await getAddressScriptHash(address)
179
171
  console.log("addressHash=", addressHash)
180
- let tx = await ckbfs.createAppendContentTransaction(content, ckbfsCell, previousData as any);
172
+ let tx = await ckbfs.createAppendContentTransaction(content, ckbfsCell, {
173
+ witnessStartIndex: 1,
174
+ });
181
175
  tx.addCellDeps(TestnetTraceLockDep)
182
- console.log(tx.stringify())
176
+ // console.log("tx=", JSON.stringify(JSON.parse(tx.stringify()), null, 2))
183
177
  const txHash = await signer.sendTransaction(tx)
184
178
  console.log(`File appended successfully! Transaction Hash: ${txHash}`);
185
179
  return { txHash, log: content }
@@ -387,11 +381,12 @@ async function testReresolve(ckbfsId: string) {
387
381
  return data
388
382
  }
389
383
 
384
+
390
385
  // mintAll()
391
386
 
392
- // mint("X30125NMNVAP000201").then(console.log)
387
+ //mint("X30125NMNVAP000201").then(console.log)
393
388
 
394
- // claim("ckt1qyq0zr47f0p8sm5d3cvtlpkljs7zvqcw7ngqnfscx0", "0xa3347c13f0419d9013a3f48a2b9ad993c2b6b5806827f3bf37480a58580d669d", "0x0084106b9bea08f512e35b725c4a710ebf09cb65c05601ebde8d911bc6c662bf")
389
+ //claim("ckt1qyq0zr47f0p8sm5d3cvtlpkljs7zvqcw7ngqnfscx0", "0xa3347c13f0419d9013a3f48a2b9ad993c2b6b5806827f3bf37480a58580d669d", "0x0084106b9bea08f512e35b725c4a710ebf09cb65c05601ebde8d911bc6c662bf")
395
390
 
396
391
  // getCkbfsCellInfo("0xdb0b0b637060d2f6c42c4429e712fa043c1937968c03c54a5014b4595f88413a").then((data) => {
397
392
  // console.log("ckbfs data=", data)
@@ -405,8 +400,9 @@ async function testReresolve(ckbfsId: string) {
405
400
  // })
406
401
 
407
402
 
408
- // getCellInfoFromV3Transaction("0x8dc79a7630145e2a220e2363beca2781c6a4f0f79ef7a01ab73f17dc90571fb7").then(console.log)
403
+ // getCellInfoFromV3Transaction("0x54c86dbdc6bdafb4616221d54cfc0ff186a4a772eba509838684f8e1ea271b40").then(console.log)
409
404
 
410
- // getCkbfsCellInfo("0x0084106b9bea08f512e35b725c4a710ebf09cb65c05601ebde8d911bc6c662bf").then(console.log)
405
+ //getCkbfsCellInfo("0xe58baa82c4844add60911bb890487fea3c45436b9d7b203cc1065301d0a9c503").then(console.log)
406
+ giveName("bbb", "0xe58baa82c4844add60911bb890487fea3c45436b9d7b203cc1065301d0a9c503").then(console.log)
411
407
 
412
408
  // testReresolve("0x0084106b9bea08f512e35b725c4a710ebf09cb65c05601ebde8d911bc6c662bf").then(console.log)
@@ -110,7 +110,7 @@ async function retrieveAndSaveFileV3Example() {
110
110
  async function retrieveFileByURIV3Example() {
111
111
  try {
112
112
  // Example CKBFS URI (replace with actual URI)
113
- const ckbfsUri = "ckbfs://d52d8536d3498bd68fa1e235f7e090c2d047154e22fcea5cfa54ccb58c236eb3";
113
+ const ckbfsUri = "ckbfs://d49b78d821a12da1fc484ef36f855109fc52b195af29cafda1c134656e940a35";
114
114
 
115
115
  console.log(`Retrieving CKBFS v3 file by URI: ${ckbfsUri}`);
116
116
 
@@ -242,10 +242,10 @@ async function main() {
242
242
  // Uncomment to test different retrieval methods:
243
243
  //await retrieveFileByTypeIdV3Example();
244
244
  // await retrieveAndSaveFileV3Example();
245
- // await retrieveFileByURIV3Example();
245
+ await retrieveFileByURIV3Example();
246
246
  // //await retrieveFileByOutPointV3Example();
247
247
 
248
- await testReresolve("0x0084106b9bea08f512e35b725c4a710ebf09cb65c05601ebde8d911bc6c662bf").then(console.log)
248
+ // await testReresolve("0x0084106b9bea08f512e35b725c4a710ebf09cb65c05601ebde8d911bc6c662bf").then(console.log)
249
249
 
250
250
  // console.log('Retrieval example structure completed successfully!');
251
251
  // console.log('Update the identifiers and uncomment methods to test.');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ckbfs/api",
3
- "version": "2.0.4",
3
+ "version": "2.0.6",
4
4
  "description": "SDK for CKBFS protocol on CKB",
5
5
  "license": "MIT",
6
6
  "author": "Code Monad<code@lab-11.org>",
package/src/index.ts CHANGED
@@ -142,6 +142,7 @@ export type AppendContentOptions = Omit<
142
142
  "contentType" | "filename" | "capacity"
143
143
  > & {
144
144
  capacity?: bigint;
145
+ witnessStartIndex?: number;
145
146
  };
146
147
 
147
148
  /**
@@ -395,6 +396,7 @@ export class CKBFS {
395
396
  previousTxHash?: string;
396
397
  previousWitnessIndex?: number;
397
398
  previousChecksum?: number;
399
+ witnessStartIndex?: number;
398
400
  } = {},
399
401
  ): Promise<string> {
400
402
  // Read the file and split into chunks
@@ -638,6 +640,7 @@ export class CKBFS {
638
640
  previousTxHash?: string;
639
641
  previousWitnessIndex?: number;
640
642
  previousChecksum?: number;
643
+ witnessStartIndex?: number;
641
644
  } = {},
642
645
  ): Promise<Transaction> {
643
646
  // Read the file and split into chunks
@@ -666,6 +669,7 @@ export class CKBFS {
666
669
  previousTxHash: options.previousTxHash,
667
670
  previousWitnessIndex: options.previousWitnessIndex,
668
671
  previousChecksum: options.previousChecksum,
672
+ witnessStartIndex: options.witnessStartIndex,
669
673
  });
670
674
  } else {
671
675
  // Legacy V1/V2 behavior or when V3 backlink params are missing
@@ -1005,6 +1009,7 @@ export {
1005
1009
  utilPublishCKBFS as publishCKBFS,
1006
1010
  utilAppendCKBFS as appendCKBFS,
1007
1011
  createAppendTransactionDry,
1012
+ createAppendV3Transaction,
1008
1013
  // File utilities
1009
1014
  readFile,
1010
1015
  readFileAsText,
@@ -56,6 +56,7 @@ export interface BaseAppendOptions {
56
56
  network?: NetworkType;
57
57
  version?: ProtocolVersionType;
58
58
  from?: Transaction;
59
+ witnessStartIndex?: number;
59
60
  }
60
61
 
61
62
  /**
@@ -29,7 +29,8 @@ export interface PublishOptions extends BasePublishOptions {}
29
29
  /**
30
30
  * Options for appending content to a CKBFS file (V1/V2)
31
31
  */
32
- export interface AppendOptions extends BaseAppendOptions {}
32
+ export interface AppendOptions extends BaseAppendOptions {
33
+ }
33
34
 
34
35
  /**
35
36
  * Creates a CKBFS cell
@@ -1,6 +1,6 @@
1
1
  import { ccc, Transaction, Script, Signer } from "@ckb-ccc/core";
2
2
  import { calculateChecksum, updateChecksum } from "../checksum";
3
- import { CKBFSData, CKBFSDataType } from "../molecule";
3
+ import { CKBFSData, CKBFSDataType, CKBFSDataV3 } from "../molecule";
4
4
  import { createChunkedCKBFSV3Witnesses, CKBFSV3WitnessOptions } from "../witness";
5
5
  import {
6
6
  getCKBFSScriptConfig,
@@ -45,6 +45,7 @@ export interface AppendV3Options {
45
45
  network?: NetworkType;
46
46
  version: typeof ProtocolVersion.V3;
47
47
  from?: Transaction;
48
+ witnessStartIndex?: number;
48
49
  previousTxHash: string;
49
50
  previousWitnessIndex: number;
50
51
  previousChecksum: number;
@@ -357,6 +358,7 @@ export async function prepareAppendV3Transaction(
357
358
  previousTxHash,
358
359
  previousWitnessIndex,
359
360
  previousChecksum,
361
+ witnessStartIndex,
360
362
  } = options;
361
363
 
362
364
  // Calculate new checksum by updating from previous checksum
@@ -364,7 +366,7 @@ export async function prepareAppendV3Transaction(
364
366
  const newChecksum = await updateChecksum(previousChecksum, combinedContent);
365
367
 
366
368
  // Calculate the actual witness indices where our content is placed
367
- const contentStartIndex = from?.witnesses.length || 1;
369
+ const contentStartIndex = witnessStartIndex || from?.witnesses.length || 0;
368
370
 
369
371
  // Create CKBFS v3 witnesses with backlink info
370
372
  const ckbfsWitnesses = createChunkedCKBFSV3Witnesses(contentChunks, {
@@ -517,6 +519,8 @@ export async function createAppendV3Transaction(
517
519
  await preTx.completeInputsByCapacity(signer);
518
520
  }
519
521
 
522
+ await preTx.completeInputsByCapacity(signer);
523
+
520
524
  const witnesses: any = [];
521
525
  // add empty witness for signer if ckbfs's lock is the same as signer's lock
522
526
  if (address.script.hash() === lock.hash()) {
@@ -208,10 +208,9 @@ export function extractCKBFSV3WitnessContent(witness: Uint8Array, isHeadWitness:
208
208
  // Extract previous position
209
209
  const prevTxHashBytes = witness.slice(6, 38);
210
210
  const previousTxHash = '0x' + Array.from(prevTxHashBytes).map(b => b.toString(16).padStart(2, '0')).join('');
211
-
212
- const previousWitnessIndex = new DataView(witness.slice(38, 42).buffer).getUint32(0, true);
213
- const previousChecksum = new DataView(witness.slice(42, 46).buffer).getUint32(0, true);
214
- const nextIndex = new DataView(witness.slice(46, 50).buffer).getUint32(0, true);
211
+ const previousWitnessIndex = new DataView(witness.slice(38, 42).buffer.slice(witness.slice(38, 42).byteOffset, witness.slice(38, 42).byteOffset + 4)).getUint32(0, true);
212
+ const previousChecksum = new DataView(witness.slice(42, 46).buffer.slice(witness.slice(42, 46).byteOffset, witness.slice(42, 46).byteOffset + 4)).getUint32(0, true);
213
+ const nextIndex = new DataView(witness.slice(46, 50).buffer.slice(witness.slice(46, 50).byteOffset, witness.slice(46, 50).byteOffset + 4)).getUint32(0, true);
215
214
  const content = witness.slice(50);
216
215
 
217
216
  return {