@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.
- package/README.md +506 -74
- package/code.png +0 -0
- package/demo-output.txt +1 -0
- package/direct_direct_content_example.txt +1 -0
- package/dist/index.d.ts +55 -13
- package/dist/index.js +143 -18
- package/dist/utils/constants.d.ts +7 -3
- package/dist/utils/constants.js +41 -34
- package/dist/utils/file.d.ts +179 -0
- package/dist/utils/file.js +599 -31
- package/dist/utils/molecule.d.ts +3 -2
- package/dist/utils/molecule.js +22 -24
- package/dist/utils/transaction.d.ts +10 -4
- package/dist/utils/transaction.js +29 -27
- package/examples/example.txt +1 -0
- package/examples/identifier-test.ts +178 -0
- package/examples/index.ts +36 -24
- package/examples/publish.ts +39 -5
- package/examples/retrieve.ts +542 -77
- package/examples/witness-decode-demo.ts +190 -0
- package/identifier_direct_content_example.txt +1 -0
- package/package-lock.json +4978 -0
- package/package.json +3 -2
- package/src/index.ts +312 -96
- package/src/utils/constants.ts +77 -43
- package/src/utils/file.ts +864 -59
- package/src/utils/molecule.ts +41 -36
- package/src/utils/transaction.ts +172 -146
- package/traditional_direct_content_example.txt +1 -0
- package/typeid_direct_content_example.txt +1 -0
- package/.cursor/rules/typescript.mdc +0 -49
- package/ABC.LOGS +0 -1
- package/RFC.v2.md +0 -341
- package/append.txt +0 -1
- package/example.txt +0 -1
- package/publish-tx-hash-v1.txt +0 -1
- package/src/utils/createPublishTransaction +0 -24
- package/test-download.txt +0 -2
package/src/utils/transaction.ts
CHANGED
@@ -1,14 +1,15 @@
|
|
1
1
|
import { ccc, Transaction, Script, Signer } from "@ckb-ccc/core";
|
2
|
-
import { calculateChecksum, updateChecksum } from
|
3
|
-
import { CKBFSData, BackLinkType, CKBFSDataType } from
|
4
|
-
import { createChunkedCKBFSWitnesses } from
|
5
|
-
import {
|
6
|
-
getCKBFSScriptConfig,
|
7
|
-
NetworkType,
|
8
|
-
ProtocolVersion,
|
9
|
-
|
10
|
-
|
11
|
-
|
2
|
+
import { calculateChecksum, updateChecksum } from "./checksum";
|
3
|
+
import { CKBFSData, BackLinkType, CKBFSDataType } from "./molecule";
|
4
|
+
import { createChunkedCKBFSWitnesses } from "./witness";
|
5
|
+
import {
|
6
|
+
getCKBFSScriptConfig,
|
7
|
+
NetworkType,
|
8
|
+
ProtocolVersion,
|
9
|
+
ProtocolVersionType,
|
10
|
+
DEFAULT_NETWORK,
|
11
|
+
DEFAULT_VERSION,
|
12
|
+
} from "./constants";
|
12
13
|
|
13
14
|
/**
|
14
15
|
* Utility functions for CKB transaction creation and handling
|
@@ -23,7 +24,7 @@ export interface CKBFSCellOptions {
|
|
23
24
|
capacity?: bigint;
|
24
25
|
lock: Script;
|
25
26
|
network?: NetworkType;
|
26
|
-
version?:
|
27
|
+
version?: ProtocolVersionType;
|
27
28
|
useTypeID?: boolean;
|
28
29
|
}
|
29
30
|
|
@@ -49,7 +50,7 @@ export interface AppendOptions {
|
|
49
50
|
contentChunks: Uint8Array[];
|
50
51
|
feeRate?: number;
|
51
52
|
network?: NetworkType;
|
52
|
-
version?:
|
53
|
+
version?: ProtocolVersionType;
|
53
54
|
}
|
54
55
|
|
55
56
|
/**
|
@@ -57,8 +58,8 @@ export interface AppendOptions {
|
|
57
58
|
* @param value The string to ensure is hex prefixed
|
58
59
|
* @returns A hex prefixed string
|
59
60
|
*/
|
60
|
-
function ensureHexPrefix(value: string): `0x${string}` {
|
61
|
-
if (value.startsWith(
|
61
|
+
export function ensureHexPrefix(value: string): `0x${string}` {
|
62
|
+
if (value.startsWith("0x")) {
|
62
63
|
return value as `0x${string}`;
|
63
64
|
}
|
64
65
|
return `0x${value}` as `0x${string}`;
|
@@ -70,26 +71,26 @@ function ensureHexPrefix(value: string): `0x${string}` {
|
|
70
71
|
* @returns The created cell output
|
71
72
|
*/
|
72
73
|
export function createCKBFSCell(options: CKBFSCellOptions) {
|
73
|
-
const {
|
74
|
-
contentType,
|
75
|
-
filename,
|
76
|
-
capacity,
|
77
|
-
lock,
|
78
|
-
network = DEFAULT_NETWORK,
|
74
|
+
const {
|
75
|
+
contentType,
|
76
|
+
filename,
|
77
|
+
capacity,
|
78
|
+
lock,
|
79
|
+
network = DEFAULT_NETWORK,
|
79
80
|
version = DEFAULT_VERSION,
|
80
|
-
useTypeID = false
|
81
|
+
useTypeID = false,
|
81
82
|
} = options;
|
82
|
-
|
83
|
+
|
83
84
|
// Get CKBFS script config
|
84
85
|
const config = getCKBFSScriptConfig(network, version, useTypeID);
|
85
|
-
|
86
|
+
|
86
87
|
// Create pre CKBFS type script
|
87
88
|
const preCkbfsTypeScript = new Script(
|
88
89
|
ensureHexPrefix(config.codeHash),
|
89
90
|
config.hashType as any,
|
90
|
-
"0x0000000000000000000000000000000000000000000000000000000000000000"
|
91
|
+
"0x0000000000000000000000000000000000000000000000000000000000000000",
|
91
92
|
);
|
92
|
-
|
93
|
+
|
93
94
|
// Return the cell output
|
94
95
|
return {
|
95
96
|
lock,
|
@@ -105,130 +106,140 @@ export function createCKBFSCell(options: CKBFSCellOptions) {
|
|
105
106
|
* @returns Promise resolving to the created transaction
|
106
107
|
*/
|
107
108
|
export async function createPublishTransaction(
|
108
|
-
signer: Signer,
|
109
|
-
options: PublishOptions
|
109
|
+
signer: Signer,
|
110
|
+
options: PublishOptions,
|
110
111
|
): Promise<Transaction> {
|
111
|
-
const {
|
112
|
-
contentChunks,
|
113
|
-
contentType,
|
114
|
-
filename,
|
115
|
-
lock,
|
112
|
+
const {
|
113
|
+
contentChunks,
|
114
|
+
contentType,
|
115
|
+
filename,
|
116
|
+
lock,
|
116
117
|
capacity,
|
117
118
|
feeRate,
|
118
119
|
network = DEFAULT_NETWORK,
|
119
120
|
version = DEFAULT_VERSION,
|
120
|
-
useTypeID = false
|
121
|
+
useTypeID = false,
|
121
122
|
} = options;
|
122
|
-
|
123
|
+
|
123
124
|
// Calculate checksum for the combined content
|
124
125
|
const textEncoder = new TextEncoder();
|
125
126
|
const combinedContent = Buffer.concat(contentChunks);
|
126
127
|
const checksum = await calculateChecksum(combinedContent);
|
127
|
-
|
128
|
+
|
128
129
|
// Create CKBFS witnesses - each chunk already includes the CKBFS header
|
129
130
|
// Pass 0 as version byte - this is the protocol version byte in the witness header
|
130
131
|
// not to be confused with the Protocol Version (V1 vs V2)
|
131
132
|
const ckbfsWitnesses = createChunkedCKBFSWitnesses(contentChunks);
|
132
|
-
|
133
|
+
|
133
134
|
// Calculate the actual witness indices where our content is placed
|
134
135
|
// Index 0 is reserved for the secp256k1 witness for signing
|
135
136
|
// So our CKBFS data starts at index 1
|
136
137
|
const contentStartIndex = 1;
|
137
138
|
const witnessIndices = Array.from(
|
138
|
-
{ length: contentChunks.length },
|
139
|
-
(_, i) => contentStartIndex + i
|
139
|
+
{ length: contentChunks.length },
|
140
|
+
(_, i) => contentStartIndex + i,
|
140
141
|
);
|
141
|
-
|
142
|
+
|
142
143
|
// Create CKBFS cell output data based on version
|
143
144
|
let outputData: Uint8Array;
|
144
|
-
|
145
|
+
|
145
146
|
if (version === ProtocolVersion.V1) {
|
146
147
|
// V1 format: Single index field (a single number, not an array)
|
147
148
|
// For V1, use the first index where content is placed
|
148
|
-
outputData = CKBFSData.pack(
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
149
|
+
outputData = CKBFSData.pack(
|
150
|
+
{
|
151
|
+
index: contentStartIndex,
|
152
|
+
checksum,
|
153
|
+
contentType: contentType,
|
154
|
+
filename: filename,
|
155
|
+
backLinks: [],
|
156
|
+
},
|
157
|
+
version,
|
158
|
+
);
|
155
159
|
} else {
|
156
160
|
// V2 format: Multiple indexes (array of numbers)
|
157
161
|
// For V2, use all the indices where content is placed
|
158
|
-
outputData = CKBFSData.pack(
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
162
|
+
outputData = CKBFSData.pack(
|
163
|
+
{
|
164
|
+
indexes: witnessIndices,
|
165
|
+
checksum,
|
166
|
+
contentType,
|
167
|
+
filename,
|
168
|
+
backLinks: [],
|
169
|
+
},
|
170
|
+
version,
|
171
|
+
);
|
165
172
|
}
|
166
|
-
|
173
|
+
|
167
174
|
// Get CKBFS script config
|
168
175
|
const config = getCKBFSScriptConfig(network, version, useTypeID);
|
169
|
-
|
176
|
+
|
170
177
|
const preCkbfsTypeScript = new Script(
|
171
178
|
ensureHexPrefix(config.codeHash),
|
172
179
|
config.hashType as any,
|
173
|
-
"0x0000000000000000000000000000000000000000000000000000000000000000"
|
180
|
+
"0x0000000000000000000000000000000000000000000000000000000000000000",
|
174
181
|
);
|
175
|
-
const ckbfsCellSize =
|
182
|
+
const ckbfsCellSize =
|
183
|
+
BigInt(
|
184
|
+
outputData.length +
|
185
|
+
preCkbfsTypeScript.occupiedSize +
|
186
|
+
lock.occupiedSize +
|
187
|
+
8,
|
188
|
+
) * 100000000n;
|
176
189
|
// Create pre transaction without cell deps initially
|
177
190
|
const preTx = Transaction.from({
|
178
191
|
outputs: [
|
179
|
-
createCKBFSCell({
|
180
|
-
contentType,
|
181
|
-
filename,
|
182
|
-
lock,
|
183
|
-
network,
|
192
|
+
createCKBFSCell({
|
193
|
+
contentType,
|
194
|
+
filename,
|
195
|
+
lock,
|
196
|
+
network,
|
184
197
|
version,
|
185
198
|
useTypeID,
|
186
|
-
capacity: ckbfsCellSize || capacity
|
187
|
-
})
|
199
|
+
capacity: ckbfsCellSize || capacity,
|
200
|
+
}),
|
188
201
|
],
|
189
202
|
witnesses: [
|
190
203
|
[], // Empty secp witness for signing
|
191
|
-
...ckbfsWitnesses.map(w => `0x${Buffer.from(w).toString(
|
204
|
+
...ckbfsWitnesses.map((w) => `0x${Buffer.from(w).toString("hex")}`),
|
192
205
|
],
|
193
|
-
outputsData: [
|
194
|
-
outputData,
|
195
|
-
]
|
206
|
+
outputsData: [outputData],
|
196
207
|
});
|
197
|
-
|
208
|
+
|
198
209
|
// Add the CKBFS dep group cell dependency
|
199
210
|
preTx.addCellDeps({
|
200
211
|
outPoint: {
|
201
212
|
txHash: ensureHexPrefix(config.depTxHash),
|
202
213
|
index: config.depIndex || 0,
|
203
214
|
},
|
204
|
-
depType: "depGroup"
|
215
|
+
depType: "depGroup",
|
205
216
|
});
|
206
|
-
|
217
|
+
|
207
218
|
// Get the recommended address to ensure lock script cell deps are included
|
208
219
|
const address = await signer.getRecommendedAddressObj();
|
209
|
-
|
220
|
+
|
210
221
|
// Complete inputs by capacity
|
211
222
|
await preTx.completeInputsByCapacity(signer);
|
212
|
-
|
223
|
+
|
213
224
|
// Complete fee change to lock
|
214
225
|
await preTx.completeFeeChangeToLock(signer, lock, feeRate || 2000);
|
215
|
-
|
226
|
+
|
216
227
|
// Create type ID args
|
217
228
|
const args = ccc.hashTypeId(preTx.inputs[0], 0x0);
|
218
|
-
|
229
|
+
|
219
230
|
// Create CKBFS type script with type ID
|
220
231
|
const ckbfsTypeScript = new Script(
|
221
232
|
ensureHexPrefix(config.codeHash),
|
222
233
|
config.hashType as any,
|
223
|
-
args
|
234
|
+
args,
|
224
235
|
);
|
225
|
-
|
236
|
+
|
226
237
|
// Create final transaction with same cell deps as preTx
|
227
238
|
const tx = Transaction.from({
|
228
239
|
cellDeps: preTx.cellDeps,
|
229
240
|
witnesses: [
|
230
241
|
[], // Reset first witness for signing
|
231
|
-
...preTx.witnesses.slice(1)
|
242
|
+
...preTx.witnesses.slice(1),
|
232
243
|
],
|
233
244
|
outputsData: preTx.outputsData,
|
234
245
|
inputs: preTx.inputs,
|
@@ -238,10 +249,10 @@ export async function createPublishTransaction(
|
|
238
249
|
type: ckbfsTypeScript,
|
239
250
|
capacity: preTx.outputs[0].capacity,
|
240
251
|
},
|
241
|
-
...preTx.outputs.slice(1) // Include rest of outputs (e.g., change)
|
242
|
-
]
|
252
|
+
...preTx.outputs.slice(1), // Include rest of outputs (e.g., change)
|
253
|
+
],
|
243
254
|
});
|
244
|
-
|
255
|
+
|
245
256
|
return tx;
|
246
257
|
}
|
247
258
|
|
@@ -252,34 +263,36 @@ export async function createPublishTransaction(
|
|
252
263
|
* @returns Promise resolving to the created transaction
|
253
264
|
*/
|
254
265
|
export async function createAppendTransaction(
|
255
|
-
signer: Signer,
|
256
|
-
options: AppendOptions
|
266
|
+
signer: Signer,
|
267
|
+
options: AppendOptions,
|
257
268
|
): Promise<Transaction> {
|
258
|
-
const {
|
259
|
-
ckbfsCell,
|
260
|
-
contentChunks,
|
269
|
+
const {
|
270
|
+
ckbfsCell,
|
271
|
+
contentChunks,
|
261
272
|
feeRate,
|
262
273
|
network = DEFAULT_NETWORK,
|
263
|
-
version = DEFAULT_VERSION
|
274
|
+
version = DEFAULT_VERSION,
|
264
275
|
} = options;
|
265
276
|
const { outPoint, data, type, lock, capacity } = ckbfsCell;
|
266
|
-
|
277
|
+
|
267
278
|
// Get CKBFS script config early to use version info
|
268
279
|
const config = getCKBFSScriptConfig(network, version);
|
269
|
-
|
280
|
+
|
270
281
|
// Create CKBFS witnesses - each chunk already includes the CKBFS header
|
271
282
|
// Pass 0 as version byte - this is the protocol version byte in the witness header
|
272
283
|
// not to be confused with the Protocol Version (V1 vs V2)
|
273
284
|
const ckbfsWitnesses = createChunkedCKBFSWitnesses(contentChunks);
|
274
|
-
|
285
|
+
|
275
286
|
// Combine the new content chunks for checksum calculation
|
276
287
|
const combinedContent = Buffer.concat(contentChunks);
|
277
|
-
|
288
|
+
|
278
289
|
// Update the existing checksum with the new content - this matches Adler32's
|
279
290
|
// cumulative nature as required by Rule 11 in the RFC
|
280
291
|
const contentChecksum = await updateChecksum(data.checksum, combinedContent);
|
281
|
-
console.log(
|
282
|
-
|
292
|
+
console.log(
|
293
|
+
`Updated checksum from ${data.checksum} to ${contentChecksum} for appended content`,
|
294
|
+
);
|
295
|
+
|
283
296
|
// Get the recommended address to ensure lock script cell deps are included
|
284
297
|
const address = await signer.getRecommendedAddressObj();
|
285
298
|
|
@@ -288,19 +301,21 @@ export async function createAppendTransaction(
|
|
288
301
|
// else CKBFS data starts at index 0
|
289
302
|
const contentStartIndex = address.script.hash() === lock.hash() ? 1 : 0;
|
290
303
|
const witnessIndices = Array.from(
|
291
|
-
{ length: contentChunks.length },
|
292
|
-
(_, i) => contentStartIndex + i
|
304
|
+
{ length: contentChunks.length },
|
305
|
+
(_, i) => contentStartIndex + i,
|
293
306
|
);
|
294
|
-
|
307
|
+
|
295
308
|
// Create backlink for the current state based on version
|
296
309
|
let newBackLink: any;
|
297
|
-
|
310
|
+
|
298
311
|
if (version === ProtocolVersion.V1) {
|
299
312
|
// V1 format: Use index field (single number)
|
300
313
|
newBackLink = {
|
301
314
|
// In V1, field order is index, checksum, txHash
|
302
315
|
// and index is a single number value, not an array
|
303
|
-
index:
|
316
|
+
index:
|
317
|
+
data.index ||
|
318
|
+
(data.indexes && data.indexes.length > 0 ? data.indexes[0] : 0),
|
304
319
|
checksum: data.checksum,
|
305
320
|
txHash: outPoint.txHash,
|
306
321
|
};
|
@@ -314,51 +329,61 @@ export async function createAppendTransaction(
|
|
314
329
|
txHash: outPoint.txHash,
|
315
330
|
};
|
316
331
|
}
|
317
|
-
|
332
|
+
|
318
333
|
// Update backlinks - add the new one to the existing backlinks array
|
319
334
|
const backLinks = [...(data.backLinks || []), newBackLink];
|
320
|
-
|
335
|
+
|
321
336
|
// Define output data based on version
|
322
337
|
let outputData: Uint8Array;
|
323
|
-
|
338
|
+
|
324
339
|
if (version === ProtocolVersion.V1) {
|
325
340
|
// In V1, index is a single number, not an array
|
326
341
|
// The first witness index is used (V1 can only reference one witness)
|
327
|
-
outputData = CKBFSData.pack(
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
342
|
+
outputData = CKBFSData.pack(
|
343
|
+
{
|
344
|
+
index: witnessIndices[0], // Use only the first index as a number
|
345
|
+
checksum: contentChecksum,
|
346
|
+
contentType: data.contentType,
|
347
|
+
filename: data.filename,
|
348
|
+
backLinks,
|
349
|
+
},
|
350
|
+
ProtocolVersion.V1,
|
351
|
+
); // Explicitly use V1 for packing
|
334
352
|
} else {
|
335
353
|
// In V2, indexes is an array of witness indices
|
336
|
-
outputData = CKBFSData.pack(
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
354
|
+
outputData = CKBFSData.pack(
|
355
|
+
{
|
356
|
+
indexes: witnessIndices,
|
357
|
+
checksum: contentChecksum,
|
358
|
+
contentType: data.contentType,
|
359
|
+
filename: data.filename,
|
360
|
+
backLinks,
|
361
|
+
},
|
362
|
+
ProtocolVersion.V2,
|
363
|
+
); // Explicitly use V2 for packing
|
343
364
|
}
|
344
|
-
|
365
|
+
|
345
366
|
// Pack the original data to get its size - use the appropriate version
|
346
367
|
const originalData = CKBFSData.pack(data, version);
|
347
368
|
const originalDataSize = originalData.length;
|
348
|
-
|
369
|
+
|
349
370
|
// Get sizes and calculate capacity requirements
|
350
371
|
const newDataSize = outputData.length;
|
351
|
-
|
372
|
+
|
352
373
|
// Calculate the required capacity for the output cell
|
353
|
-
// This accounts for:
|
374
|
+
// This accounts for:
|
354
375
|
// 1. The output data size
|
355
376
|
// 2. The type script's occupied size
|
356
377
|
// 3. The lock script's occupied size
|
357
378
|
// 4. A constant of 8 bytes (for header overhead)
|
358
|
-
const ckbfsCellSize =
|
359
|
-
|
360
|
-
|
361
|
-
|
379
|
+
const ckbfsCellSize =
|
380
|
+
BigInt(outputData.length + type.occupiedSize + lock.occupiedSize + 8) *
|
381
|
+
100000000n;
|
382
|
+
|
383
|
+
console.log(
|
384
|
+
`Original capacity: ${capacity}, Calculated size: ${ckbfsCellSize}, Data size: ${outputData.length}`,
|
385
|
+
);
|
386
|
+
|
362
387
|
// Use the maximum value between calculated size and original capacity
|
363
388
|
// to ensure we have enough capacity but don't decrease capacity unnecessarily
|
364
389
|
const outputCapacity = ckbfsCellSize > capacity ? ckbfsCellSize : capacity;
|
@@ -372,56 +397,57 @@ export async function createAppendTransaction(
|
|
372
397
|
index: outPoint.index,
|
373
398
|
},
|
374
399
|
since: "0x0",
|
375
|
-
}
|
400
|
+
},
|
376
401
|
],
|
377
402
|
outputs: [
|
378
403
|
{
|
379
404
|
lock,
|
380
405
|
type,
|
381
406
|
capacity: outputCapacity,
|
382
|
-
}
|
407
|
+
},
|
383
408
|
],
|
384
|
-
outputsData: [
|
385
|
-
outputData,
|
386
|
-
]
|
409
|
+
outputsData: [outputData],
|
387
410
|
});
|
388
411
|
|
389
|
-
|
390
412
|
// Add the CKBFS dep group cell dependency
|
391
413
|
tx.addCellDeps({
|
392
414
|
outPoint: {
|
393
415
|
txHash: ensureHexPrefix(config.depTxHash),
|
394
416
|
index: config.depIndex || 0,
|
395
417
|
},
|
396
|
-
depType: "depGroup"
|
418
|
+
depType: "depGroup",
|
397
419
|
});
|
398
|
-
|
420
|
+
|
399
421
|
const inputsBefore = tx.inputs.length;
|
400
422
|
// If we need more capacity than the original cell had, add additional inputs
|
401
423
|
if (outputCapacity > capacity) {
|
402
|
-
console.log(
|
424
|
+
console.log(
|
425
|
+
`Need additional capacity: ${outputCapacity - capacity} shannons`,
|
426
|
+
);
|
403
427
|
// Add more inputs to cover the increased capacity
|
404
428
|
await tx.completeInputsByCapacity(signer);
|
405
429
|
}
|
406
430
|
|
407
|
-
const witnesses: any = []
|
431
|
+
const witnesses: any = [];
|
408
432
|
// add empty witness for signer if ckbfs's lock is the same as signer's lock
|
409
|
-
if(address.script.hash() === lock.hash()) {
|
410
|
-
witnesses.push(
|
433
|
+
if (address.script.hash() === lock.hash()) {
|
434
|
+
witnesses.push("0x");
|
411
435
|
}
|
412
436
|
// add ckbfs witnesses
|
413
|
-
witnesses.push(
|
437
|
+
witnesses.push(
|
438
|
+
...ckbfsWitnesses.map((w) => `0x${Buffer.from(w).toString("hex")}`),
|
439
|
+
);
|
414
440
|
|
415
441
|
// Add empty witnesses for signer's input
|
416
442
|
// This is to ensure that the transaction is valid and can be signed
|
417
|
-
for(let i = inputsBefore; i < tx.inputs.length; i++) {
|
418
|
-
witnesses.push(
|
443
|
+
for (let i = inputsBefore; i < tx.inputs.length; i++) {
|
444
|
+
witnesses.push("0x");
|
419
445
|
}
|
420
|
-
tx.witnesses = witnesses
|
446
|
+
tx.witnesses = witnesses;
|
421
447
|
|
422
448
|
// Complete fee
|
423
449
|
await tx.completeFeeChangeToLock(signer, address.script, feeRate || 2000);
|
424
|
-
|
450
|
+
|
425
451
|
return tx;
|
426
452
|
}
|
427
453
|
|
@@ -432,8 +458,8 @@ export async function createAppendTransaction(
|
|
432
458
|
* @returns Promise resolving to the signed transaction
|
433
459
|
*/
|
434
460
|
export async function publishCKBFS(
|
435
|
-
signer: Signer,
|
436
|
-
options: PublishOptions
|
461
|
+
signer: Signer,
|
462
|
+
options: PublishOptions,
|
437
463
|
): Promise<Transaction> {
|
438
464
|
const tx = await createPublishTransaction(signer, options);
|
439
465
|
return signer.signTransaction(tx);
|
@@ -446,9 +472,9 @@ export async function publishCKBFS(
|
|
446
472
|
* @returns Promise resolving to the signed transaction
|
447
473
|
*/
|
448
474
|
export async function appendCKBFS(
|
449
|
-
signer: Signer,
|
450
|
-
options: AppendOptions
|
475
|
+
signer: Signer,
|
476
|
+
options: AppendOptions,
|
451
477
|
): Promise<Transaction> {
|
452
478
|
const tx = await createAppendTransaction(signer, options);
|
453
479
|
return signer.signTransaction(tx);
|
454
|
-
}
|
480
|
+
}
|
@@ -0,0 +1 @@
|
|
1
|
+
Hello CKBFS from direct content!
|
@@ -0,0 +1 @@
|
|
1
|
+
Hello CKBFS from direct content!
|
@@ -1,49 +0,0 @@
|
|
1
|
-
---
|
2
|
-
description:
|
3
|
-
globs:
|
4
|
-
alwaysApply: true
|
5
|
-
---
|
6
|
-
|
7
|
-
You are an expert in TypeScript, Node.js, Next.js App Router, React, Shadcn UI, Radix UI and Tailwind.
|
8
|
-
|
9
|
-
Code Style and Structure
|
10
|
-
- Write concise, technical TypeScript code with accurate examples.
|
11
|
-
- Use functional and declarative programming patterns; avoid classes.
|
12
|
-
- Prefer iteration and modularization over code duplication.
|
13
|
-
- Use descriptive variable names with auxiliary verbs (e.g., isLoading, hasError).
|
14
|
-
- Structure files: exported component, subcomponents, helpers, static content, types.
|
15
|
-
|
16
|
-
Naming Conventions
|
17
|
-
- Use lowercase with dashes for directories (e.g., components/auth-wizard).
|
18
|
-
- Favor named exports for components.
|
19
|
-
|
20
|
-
TypeScript Usage
|
21
|
-
- Use TypeScript for all code; prefer interfaces over types.
|
22
|
-
- Avoid enums; use maps instead.
|
23
|
-
- Use functional components with TypeScript interfaces.
|
24
|
-
|
25
|
-
Syntax and Formatting
|
26
|
-
- Use the "function" keyword for pure functions.
|
27
|
-
- Avoid unnecessary curly braces in conditionals; use concise syntax for simple statements.
|
28
|
-
- Use declarative JSX.
|
29
|
-
|
30
|
-
UI and Styling
|
31
|
-
- Use Shadcn UI, Radix, and Tailwind for components and styling.
|
32
|
-
- Implement responsive design with Tailwind CSS; use a mobile-first approach.
|
33
|
-
|
34
|
-
Performance Optimization
|
35
|
-
- Minimize 'use client', 'useEffect', and 'setState'; favor React Server Components (RSC).
|
36
|
-
- Wrap client components in Suspense with fallback.
|
37
|
-
- Use dynamic loading for non-critical components.
|
38
|
-
- Optimize images: use WebP format, include size data, implement lazy loading.
|
39
|
-
|
40
|
-
Key Conventions
|
41
|
-
- Use 'nuqs' for URL search parameter state management.
|
42
|
-
- Optimize Web Vitals (LCP, CLS, FID).
|
43
|
-
- Limit 'use client':
|
44
|
-
- Favor server components and Next.js SSR.
|
45
|
-
- Use only for Web API access in small components.
|
46
|
-
- Avoid for data fetching or state management.
|
47
|
-
|
48
|
-
Follow Next.js docs for Data Fetching, Rendering, and Routing.
|
49
|
-
|
package/ABC.LOGS
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
MINT,TO:ckt1qzda0cr08m85hc8jlnfp3zer7xulejywt49kt2rr0vthywaa50xwsqdpallzwnhe64rqnqmev7hf98yrmh4yzucgdw7qwGIVE_NAME,NEW_NAME:NERVAPE_COOKIE
|