@ckb-ccc/core 1.18.1 → 2.0.0-next.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.
Files changed (55) hide show
  1. package/CHANGELOG.md +42 -0
  2. package/dist/address.advanced-LxntWbev.mjs +2 -0
  3. package/dist/address.advanced-LxntWbev.mjs.map +1 -0
  4. package/dist/advanced.d.mts +1 -1
  5. package/dist/advanced.mjs +1 -1
  6. package/{dist.commonjs/advancedBarrel-CJAh6sm8.d.ts → dist/advancedBarrel-BHwnMJqR.d.mts} +749 -382
  7. package/dist/advancedBarrel-BHwnMJqR.d.mts.map +1 -0
  8. package/dist/advancedBarrel.d.mts +1 -1
  9. package/dist/advancedBarrel.mjs +1 -1
  10. package/dist/barrel-C-BaV9Pe.mjs +7 -0
  11. package/dist/barrel-C-BaV9Pe.mjs.map +1 -0
  12. package/dist/barrel.d.mts +2 -2
  13. package/dist/barrel.mjs +1 -1
  14. package/dist/index.d.mts +2 -2
  15. package/dist/index.mjs +1 -1
  16. package/dist.commonjs/address.advanced-BqcYOpZn.js +2 -0
  17. package/dist.commonjs/address.advanced-BqcYOpZn.js.map +1 -0
  18. package/dist.commonjs/advanced.d.ts +1 -1
  19. package/dist.commonjs/advanced.js +1 -1
  20. package/{dist/advancedBarrel-BbbHx4z4.d.mts → dist.commonjs/advancedBarrel-DNdhwiU0.d.ts} +750 -381
  21. package/dist.commonjs/advancedBarrel-DNdhwiU0.d.ts.map +1 -0
  22. package/dist.commonjs/advancedBarrel.d.ts +1 -1
  23. package/dist.commonjs/advancedBarrel.js +1 -1
  24. package/dist.commonjs/{barrel-C_zSgXKn.js → barrel-BBOmj4RJ.js} +10 -10
  25. package/dist.commonjs/barrel-BBOmj4RJ.js.map +1 -0
  26. package/dist.commonjs/barrel.d.ts +2 -2
  27. package/dist.commonjs/barrel.js +1 -1
  28. package/dist.commonjs/index.d.ts +2 -2
  29. package/dist.commonjs/index.js +1 -1
  30. package/package.json +1 -1
  31. package/src/ckb/epoch.ts +44 -26
  32. package/src/ckb/script.ts +23 -46
  33. package/src/ckb/transaction.ts +200 -196
  34. package/src/client/client.ts +2 -2
  35. package/src/client/jsonRpc/client.ts +3 -7
  36. package/src/codec/codec.ts +65 -40
  37. package/src/codec/entity.ts +95 -67
  38. package/src/codec/predefined.ts +11 -0
  39. package/src/molecule/codec.ts +116 -8
  40. package/src/molecule/predefined.ts +1 -0
  41. package/src/signer/ckb/signerMultisigCkbReadonly.ts +36 -24
  42. package/src/signer/ckb/verifyJoyId.ts +39 -11
  43. package/src/signer/index.ts +17 -0
  44. package/src/signer/signer/index.ts +11 -0
  45. package/src/signer/signerFromSignature.ts +65 -0
  46. package/src/utils/index.ts +108 -26
  47. package/dist/address.advanced-Dw4qPDGb.mjs +0 -2
  48. package/dist/address.advanced-Dw4qPDGb.mjs.map +0 -1
  49. package/dist/advancedBarrel-BbbHx4z4.d.mts.map +0 -1
  50. package/dist/barrel-BsC1djHG.mjs +0 -7
  51. package/dist/barrel-BsC1djHG.mjs.map +0 -1
  52. package/dist.commonjs/address.advanced-DG1gpW7t.js +0 -2
  53. package/dist.commonjs/address.advanced-DG1gpW7t.js.map +0 -1
  54. package/dist.commonjs/advancedBarrel-CJAh6sm8.d.ts.map +0 -1
  55. package/dist.commonjs/barrel-C_zSgXKn.js.map +0 -1
@@ -7,7 +7,13 @@ import {
7
7
  type ClientBlockHeaderLike,
8
8
  } from "../client/index.js";
9
9
  import { KnownScript } from "../client/knownScript.js";
10
- import { Codec, Entity, codec } from "../codec/index.js";
10
+ import {
11
+ Codec,
12
+ DecodedType,
13
+ EncodableType,
14
+ Entity,
15
+ codec,
16
+ } from "../codec/index.js";
11
17
  import { Zero, fixedPointFrom } from "../fixedPoint/index.js";
12
18
  import { Hasher, HasherCkb, hashCkb } from "../hasher/index.js";
13
19
  import { Hex, HexLike, hexFrom } from "../hex/index.js";
@@ -144,50 +150,33 @@ export function depTypeFromBytes(bytes: BytesLike): DepType {
144
150
  /**
145
151
  * @public
146
152
  */
147
- export type OutPointLike = {
148
- txHash: HexLike;
149
- index: NumLike;
150
- };
153
+ const OutPointCodec = mol.struct({
154
+ txHash: mol.Byte32,
155
+ index: mol.Uint32,
156
+ });
151
157
  /**
152
158
  * @public
153
159
  */
154
- @codec(
155
- mol.struct({
156
- txHash: mol.Byte32,
157
- index: mol.Uint32,
158
- }),
159
- )
160
+ export type OutPointLike = EncodableType<typeof OutPointCodec>;
161
+ /**
162
+ * @public
163
+ */
164
+ @codec(OutPointCodec)
160
165
  export class OutPoint extends Entity.Base<OutPointLike, OutPoint>() {
166
+ public txHash: Hex;
167
+ public index: Num;
168
+
161
169
  /**
162
170
  * Creates an instance of OutPoint.
163
171
  *
164
172
  * @param txHash - The transaction hash.
165
173
  * @param index - The index of the output in the transaction.
166
174
  */
167
-
168
- constructor(
169
- public txHash: Hex,
170
- public index: Num,
171
- ) {
175
+ constructor({ txHash, index }: DecodedType<typeof OutPointCodec>) {
172
176
  super();
173
- }
174
177
 
175
- /**
176
- * Creates an OutPoint instance from an OutPointLike object.
177
- *
178
- * @param outPoint - An OutPointLike object or an instance of OutPoint.
179
- * @returns An OutPoint instance.
180
- *
181
- * @example
182
- * ```typescript
183
- * const outPoint = OutPoint.from({ txHash: "0x...", index: 0 });
184
- * ```
185
- */
186
- static from(outPoint: OutPointLike): OutPoint {
187
- if (outPoint instanceof OutPoint) {
188
- return outPoint;
189
- }
190
- return new OutPoint(hexFrom(outPoint.txHash), numFrom(outPoint.index));
178
+ this.txHash = txHash;
179
+ this.index = numFrom(index);
191
180
  }
192
181
 
193
182
  /**
@@ -224,6 +213,14 @@ export class OutPoint extends Entity.Base<OutPointLike, OutPoint>() {
224
213
  }
225
214
  }
226
215
 
216
+ /**
217
+ * @public
218
+ */
219
+ const CellOutputCodec = mol.table({
220
+ capacity: mol.Uint64,
221
+ lock: Script,
222
+ type: ScriptOpt,
223
+ });
227
224
  /**
228
225
  * @public
229
226
  */
@@ -235,14 +232,12 @@ export type CellOutputLike = {
235
232
  /**
236
233
  * @public
237
234
  */
238
- @codec(
239
- mol.table({
240
- capacity: mol.Uint64,
241
- lock: Script,
242
- type: ScriptOpt,
243
- }),
244
- )
235
+ @codec(CellOutputCodec)
245
236
  export class CellOutput extends Entity.Base<CellOutputLike, CellOutput>() {
237
+ public capacity: Num;
238
+ public lock: Script;
239
+ public type?: Script;
240
+
246
241
  /**
247
242
  * Creates an instance of CellOutput.
248
243
  *
@@ -250,13 +245,12 @@ export class CellOutput extends Entity.Base<CellOutputLike, CellOutput>() {
250
245
  * @param lock - The lock script of the cell.
251
246
  * @param type - The optional type script of the cell.
252
247
  */
253
-
254
- constructor(
255
- public capacity: Num,
256
- public lock: Script,
257
- public type?: Script,
258
- ) {
248
+ constructor({ capacity, lock, type }: DecodedType<typeof CellOutputCodec>) {
259
249
  super();
250
+
251
+ this.capacity = capacity;
252
+ this.lock = lock;
253
+ this.type = type;
260
254
  }
261
255
 
262
256
  get occupiedSize(): number {
@@ -292,16 +286,13 @@ export class CellOutput extends Entity.Base<CellOutputLike, CellOutput>() {
292
286
  cellOutput: CellOutputLike,
293
287
  outputData?: HexLike | null,
294
288
  ): CellOutput {
295
- const output = (() => {
296
- if (cellOutput instanceof CellOutput) {
297
- return cellOutput;
298
- }
299
- return new CellOutput(
300
- numFrom(cellOutput.capacity ?? 0),
301
- Script.from(cellOutput.lock),
302
- apply(Script.from, cellOutput.type),
303
- );
304
- })();
289
+ const output =
290
+ cellOutput instanceof CellOutput
291
+ ? cellOutput
292
+ : super.from({
293
+ ...cellOutput,
294
+ capacity: cellOutput.capacity ?? 0,
295
+ });
305
296
 
306
297
  if (outputData != null) {
307
298
  output.capacity = numMax(
@@ -398,6 +389,7 @@ export class CellAny {
398
389
  */
399
390
  static from(cell: CellAnyLike): CellAny {
400
391
  if (cell instanceof CellAny) {
392
+ cell.cellOutput = CellOutput.from(cell.cellOutput, cell.outputData);
401
393
  return cell;
402
394
  }
403
395
 
@@ -558,6 +550,7 @@ export class Cell extends CellAny {
558
550
 
559
551
  static from(cell: CellLike): Cell {
560
552
  if (cell instanceof Cell) {
553
+ cell.cellOutput = CellOutput.from(cell.cellOutput, cell.outputData);
561
554
  return cell;
562
555
  }
563
556
 
@@ -695,27 +688,33 @@ export type SinceLike =
695
688
  value: NumLike;
696
689
  }
697
690
  | NumLike;
691
+
692
+ const SinceCodec = mol.Uint64.map({
693
+ inMap: (encodable: SinceLike) => Since.from(encodable).toNum(),
694
+ outMap: (num: Num): Pick<Since, "relative" | "metric" | "value"> =>
695
+ Since.fromNum(num),
696
+ });
697
+
698
698
  /**
699
699
  * @public
700
700
  */
701
- @codec(
702
- mol.Uint64.mapIn((encodable: SinceLike) => Since.from(encodable).toNum()),
703
- )
701
+ @codec(SinceCodec)
704
702
  export class Since extends Entity.Base<SinceLike, Since>() {
703
+ public relative: "absolute" | "relative";
704
+ public metric: "blockNumber" | "epoch" | "timestamp";
705
+ public value: Num;
706
+
705
707
  /**
706
708
  * Creates an instance of Since.
707
709
  *
708
- * @param relative - Absolute or relative
709
- * @param metric - The metric of since
710
- * @param value - The value of since
710
+ * @param num - The since representation value.
711
711
  */
712
-
713
- constructor(
714
- public relative: "absolute" | "relative",
715
- public metric: "blockNumber" | "epoch" | "timestamp",
716
- public value: Num,
717
- ) {
712
+ constructor({ relative, metric, value }: DecodedType<typeof SinceCodec>) {
718
713
  super();
714
+
715
+ this.relative = relative;
716
+ this.metric = metric;
717
+ this.value = value;
719
718
  }
720
719
 
721
720
  /**
@@ -753,7 +752,11 @@ export class Since extends Entity.Base<SinceLike, Since>() {
753
752
  }
754
753
 
755
754
  if (typeof since === "object" && "relative" in since) {
756
- return new Since(since.relative, since.metric, numFrom(since.value));
755
+ return new Since({
756
+ relative: since.relative,
757
+ metric: since.metric,
758
+ value: numFrom(since.value),
759
+ });
757
760
  }
758
761
 
759
762
  return Since.fromNum(since);
@@ -769,7 +772,6 @@ export class Since extends Entity.Base<SinceLike, Since>() {
769
772
  * const num = since.toNum();
770
773
  * ```
771
774
  */
772
-
773
775
  toNum(): Num {
774
776
  return (
775
777
  this.value |
@@ -793,7 +795,6 @@ export class Since extends Entity.Base<SinceLike, Since>() {
793
795
  * const since = Since.fromNum("0x0");
794
796
  * ```
795
797
  */
796
-
797
798
  static fromNum(numLike: NumLike): Since {
798
799
  const num = numFrom(numLike);
799
800
 
@@ -803,10 +804,17 @@ export class Since extends Entity.Base<SinceLike, Since>() {
803
804
  ];
804
805
  const value = num & numFrom("0x00ffffffffffffff");
805
806
 
806
- return new Since(relative, metric, value);
807
+ return new Since({ relative, metric, value });
807
808
  }
808
809
  }
809
810
 
811
+ /**
812
+ * @public
813
+ */
814
+ const CellInputCodec = mol.struct({
815
+ since: Since,
816
+ previousOutput: OutPoint,
817
+ });
810
818
  /**
811
819
  * @public
812
820
  */
@@ -824,14 +832,14 @@ export type CellInputLike = (
824
832
  * @public
825
833
  */
826
834
  @codec(
827
- mol
828
- .struct({
829
- since: Since,
830
- previousOutput: OutPoint,
831
- })
832
- .mapIn((encodable: CellInputLike) => CellInput.from(encodable)),
835
+ CellInputCodec.mapIn((encodable: CellInputLike) => CellInput.from(encodable)),
833
836
  )
834
837
  export class CellInput extends Entity.Base<CellInputLike, CellInput>() {
838
+ public previousOutput: OutPoint;
839
+ public since: Num;
840
+ public cellOutput?: CellOutput;
841
+ public outputData?: Hex;
842
+
835
843
  /**
836
844
  * Creates an instance of CellInput.
837
845
  *
@@ -840,14 +848,21 @@ export class CellInput extends Entity.Base<CellInputLike, CellInput>() {
840
848
  * @param cellOutput - The optional cell output associated with the cell input.
841
849
  * @param outputData - The optional output data associated with the cell input.
842
850
  */
843
-
844
- constructor(
845
- public previousOutput: OutPoint,
846
- public since: Num,
847
- public cellOutput?: CellOutput,
848
- public outputData?: Hex,
849
- ) {
851
+ constructor({
852
+ previousOutput,
853
+ since,
854
+ cellOutput,
855
+ outputData,
856
+ }: DecodedType<typeof CellInputCodec> & {
857
+ cellOutput?: CellOutput;
858
+ outputData?: Hex;
859
+ }) {
850
860
  super();
861
+
862
+ this.previousOutput = previousOutput;
863
+ this.since = Since.from(since).toNum();
864
+ this.cellOutput = cellOutput;
865
+ this.outputData = outputData;
851
866
  }
852
867
 
853
868
  /**
@@ -869,16 +884,16 @@ export class CellInput extends Entity.Base<CellInputLike, CellInput>() {
869
884
  return cellInput;
870
885
  }
871
886
 
872
- return new CellInput(
873
- OutPoint.from(
887
+ return new CellInput({
888
+ previousOutput: OutPoint.from(
874
889
  "previousOutput" in cellInput
875
890
  ? cellInput.previousOutput
876
891
  : cellInput.outPoint,
877
892
  ),
878
- Since.from(cellInput.since ?? 0).toNum(),
879
- apply(CellOutput.from, cellInput.cellOutput),
880
- apply(hexFrom, cellInput.outputData),
881
- );
893
+ since: Since.from(cellInput.since ?? 0),
894
+ cellOutput: apply(CellOutput.from, cellInput.cellOutput),
895
+ outputData: apply(hexFrom, cellInput.outputData),
896
+ });
882
897
  }
883
898
 
884
899
  async getCell(client: Client): Promise<Cell> {
@@ -953,58 +968,33 @@ export const CellInputVec = mol.vector(CellInput);
953
968
  /**
954
969
  * @public
955
970
  */
956
- export type CellDepLike = {
957
- outPoint: OutPointLike;
958
- depType: DepTypeLike;
959
- };
971
+ const CellDepCodec = mol.struct({
972
+ outPoint: OutPoint,
973
+ depType: DepTypeCodec,
974
+ });
960
975
  /**
961
976
  * @public
962
977
  */
963
- @codec(
964
- mol.struct({
965
- outPoint: OutPoint,
966
- depType: DepTypeCodec,
967
- }),
968
- )
978
+ export type CellDepLike = EncodableType<typeof CellDepCodec>;
979
+ /**
980
+ * @public
981
+ */
982
+ @codec(CellDepCodec)
969
983
  export class CellDep extends Entity.Base<CellDepLike, CellDep>() {
984
+ public outPoint: OutPoint;
985
+ public depType: DepType;
986
+
970
987
  /**
971
988
  * Creates an instance of CellDep.
972
989
  *
973
990
  * @param outPoint - The outpoint of the cell dependency.
974
991
  * @param depType - The dependency type.
975
992
  */
976
-
977
- constructor(
978
- public outPoint: OutPoint,
979
- public depType: DepType,
980
- ) {
993
+ constructor({ outPoint, depType }: DecodedType<typeof CellDepCodec>) {
981
994
  super();
982
- }
983
995
 
984
- /**
985
- * Creates a CellDep instance from a CellDepLike object.
986
- *
987
- * @param cellDep - A CellDepLike object or an instance of CellDep.
988
- * @returns A CellDep instance.
989
- *
990
- * @example
991
- * ```typescript
992
- * const cellDep = CellDep.from({
993
- * outPoint: { txHash: "0x...", index: 0 },
994
- * depType: "depGroup"
995
- * });
996
- * ```
997
- */
998
-
999
- static from(cellDep: CellDepLike): CellDep {
1000
- if (cellDep instanceof CellDep) {
1001
- return cellDep;
1002
- }
1003
-
1004
- return new CellDep(
1005
- OutPoint.from(cellDep.outPoint),
1006
- depTypeFrom(cellDep.depType),
1007
- );
996
+ this.outPoint = outPoint;
997
+ this.depType = depType;
1008
998
  }
1009
999
 
1010
1000
  /**
@@ -1029,22 +1019,24 @@ export const CellDepVec = mol.vector(CellDep);
1029
1019
  /**
1030
1020
  * @public
1031
1021
  */
1032
- export type WitnessArgsLike = {
1033
- lock?: HexLike | null;
1034
- inputType?: HexLike | null;
1035
- outputType?: HexLike | null;
1036
- };
1022
+ const WitnessArgsCodec = mol.table({
1023
+ lock: mol.BytesOpt,
1024
+ inputType: mol.BytesOpt,
1025
+ outputType: mol.BytesOpt,
1026
+ });
1037
1027
  /**
1038
1028
  * @public
1039
1029
  */
1040
- @codec(
1041
- mol.table({
1042
- lock: mol.BytesOpt,
1043
- inputType: mol.BytesOpt,
1044
- outputType: mol.BytesOpt,
1045
- }),
1046
- )
1030
+ export type WitnessArgsLike = EncodableType<typeof WitnessArgsCodec>;
1031
+ /**
1032
+ * @public
1033
+ */
1034
+ @codec(WitnessArgsCodec)
1047
1035
  export class WitnessArgs extends Entity.Base<WitnessArgsLike, WitnessArgs>() {
1036
+ public lock?: Hex;
1037
+ public inputType?: Hex;
1038
+ public outputType?: Hex;
1039
+
1048
1040
  /**
1049
1041
  * Creates an instance of WitnessArgs.
1050
1042
  *
@@ -1052,41 +1044,16 @@ export class WitnessArgs extends Entity.Base<WitnessArgsLike, WitnessArgs>() {
1052
1044
  * @param inputType - The optional input type field of the witness.
1053
1045
  * @param outputType - The optional output type field of the witness.
1054
1046
  */
1055
-
1056
- constructor(
1057
- public lock?: Hex,
1058
- public inputType?: Hex,
1059
- public outputType?: Hex,
1060
- ) {
1047
+ constructor({
1048
+ lock,
1049
+ inputType,
1050
+ outputType,
1051
+ }: DecodedType<typeof WitnessArgsCodec>) {
1061
1052
  super();
1062
- }
1063
-
1064
- /**
1065
- * Creates a WitnessArgs instance from a WitnessArgsLike object.
1066
- *
1067
- * @param witnessArgs - A WitnessArgsLike object or an instance of WitnessArgs.
1068
- * @returns A WitnessArgs instance.
1069
- *
1070
- * @example
1071
- * ```typescript
1072
- * const witnessArgs = WitnessArgs.from({
1073
- * lock: "0x...",
1074
- * inputType: "0x...",
1075
- * outputType: "0x..."
1076
- * });
1077
- * ```
1078
- */
1079
-
1080
- static from(witnessArgs: WitnessArgsLike): WitnessArgs {
1081
- if (witnessArgs instanceof WitnessArgs) {
1082
- return witnessArgs;
1083
- }
1084
1053
 
1085
- return new WitnessArgs(
1086
- apply(hexFrom, witnessArgs.lock),
1087
- apply(hexFrom, witnessArgs.inputType),
1088
- apply(hexFrom, witnessArgs.outputType),
1089
- );
1054
+ this.lock = lock;
1055
+ this.inputType = inputType;
1056
+ this.outputType = outputType;
1090
1057
  }
1091
1058
  }
1092
1059
 
@@ -1143,6 +1110,14 @@ export type TransactionLike = {
1143
1110
  .mapOut((tx) => Transaction.from({ ...tx.raw, witnesses: tx.witnesses })),
1144
1111
  )
1145
1112
  export class Transaction extends Entity.Base<TransactionLike, Transaction>() {
1113
+ public version: Num;
1114
+ public cellDeps: CellDep[];
1115
+ public headerDeps: Hex[];
1116
+ public inputs: CellInput[];
1117
+ public outputs: CellOutput[];
1118
+ public outputsData: Hex[];
1119
+ public witnesses: Hex[];
1120
+
1146
1121
  /**
1147
1122
  * Creates an instance of Transaction.
1148
1123
  *
@@ -1154,17 +1129,32 @@ export class Transaction extends Entity.Base<TransactionLike, Transaction>() {
1154
1129
  * @param outputsData - The data associated with the outputs.
1155
1130
  * @param witnesses - The witnesses of the transaction.
1156
1131
  */
1157
-
1158
- constructor(
1159
- public version: Num,
1160
- public cellDeps: CellDep[],
1161
- public headerDeps: Hex[],
1162
- public inputs: CellInput[],
1163
- public outputs: CellOutput[],
1164
- public outputsData: Hex[],
1165
- public witnesses: Hex[],
1166
- ) {
1132
+ constructor({
1133
+ version,
1134
+ cellDeps,
1135
+ headerDeps,
1136
+ inputs,
1137
+ outputs,
1138
+ outputsData,
1139
+ witnesses,
1140
+ }: {
1141
+ version: Num;
1142
+ cellDeps: CellDep[];
1143
+ headerDeps: Hex[];
1144
+ inputs: CellInput[];
1145
+ outputs: CellOutput[];
1146
+ outputsData: Hex[];
1147
+ witnesses: Hex[];
1148
+ }) {
1167
1149
  super();
1150
+
1151
+ this.version = version;
1152
+ this.cellDeps = cellDeps;
1153
+ this.headerDeps = headerDeps;
1154
+ this.inputs = inputs;
1155
+ this.outputs = outputs;
1156
+ this.outputsData = outputsData;
1157
+ this.witnesses = witnesses;
1168
1158
  }
1169
1159
 
1170
1160
  /**
@@ -1275,9 +1265,11 @@ export class Transaction extends Entity.Base<TransactionLike, Transaction>() {
1275
1265
  * });
1276
1266
  * ```
1277
1267
  */
1278
-
1279
1268
  static from(tx: TransactionLike): Transaction {
1280
1269
  if (tx instanceof Transaction) {
1270
+ tx.outputs.forEach((output, i) => {
1271
+ tx.outputs[i] = CellOutput.from(output, tx.outputsData[i] ?? "0x");
1272
+ });
1281
1273
  return tx;
1282
1274
  }
1283
1275
  const outputs =
@@ -1293,15 +1285,15 @@ export class Transaction extends Entity.Base<TransactionLike, Transaction>() {
1293
1285
  );
1294
1286
  }
1295
1287
 
1296
- return new Transaction(
1297
- numFrom(tx.version ?? 0),
1298
- tx.cellDeps?.map((cellDep) => CellDep.from(cellDep)) ?? [],
1299
- tx.headerDeps?.map(hexFrom) ?? [],
1300
- tx.inputs?.map((input) => CellInput.from(input)) ?? [],
1288
+ return new Transaction({
1289
+ version: numFrom(tx.version ?? 0),
1290
+ cellDeps: tx.cellDeps?.map((cellDep) => CellDep.from(cellDep)) ?? [],
1291
+ headerDeps: tx.headerDeps?.map(hexFrom) ?? [],
1292
+ inputs: tx.inputs?.map((input) => CellInput.from(input)) ?? [],
1301
1293
  outputs,
1302
1294
  outputsData,
1303
- tx.witnesses?.map(hexFrom) ?? [],
1304
- );
1295
+ witnesses: tx.witnesses?.map(hexFrom) ?? [],
1296
+ });
1305
1297
  }
1306
1298
 
1307
1299
  /**
@@ -1682,7 +1674,9 @@ export class Transaction extends Entity.Base<TransactionLike, Transaction>() {
1682
1674
  );
1683
1675
  }
1684
1676
 
1685
- this.outputsData[i] = hexFrom(data);
1677
+ const outputData = hexFrom(data);
1678
+ this.outputs[i] = CellOutput.from(this.outputs[i], outputData);
1679
+ this.outputsData[i] = outputData;
1686
1680
  }
1687
1681
 
1688
1682
  /**
@@ -1729,7 +1723,10 @@ export class Transaction extends Entity.Base<TransactionLike, Transaction>() {
1729
1723
  * ```
1730
1724
  */
1731
1725
  addInput(inputLike: CellInputLike): number {
1732
- if (this.witnesses.length > this.inputs.length) {
1726
+ if (
1727
+ this.witnesses.length > this.inputs.length &&
1728
+ this.inputs.length >= this.outputs.length
1729
+ ) {
1733
1730
  this.witnesses.splice(this.inputs.length, 0, "0x");
1734
1731
  }
1735
1732
 
@@ -1831,6 +1828,13 @@ export class Transaction extends Entity.Base<TransactionLike, Transaction>() {
1831
1828
  outputData: outputDataLike,
1832
1829
  });
1833
1830
 
1831
+ if (
1832
+ this.witnesses.length > this.outputs.length &&
1833
+ this.outputs.length >= this.inputs.length
1834
+ ) {
1835
+ this.witnesses.splice(this.outputs.length, 0, "0x");
1836
+ }
1837
+
1834
1838
  const len = this.outputs.push(cell.cellOutput);
1835
1839
  this.setOutputData(len - 1, cell.outputData);
1836
1840
 
@@ -79,7 +79,7 @@ export abstract class Client {
79
79
 
80
80
  abstract getFeeRateStatistics(
81
81
  blockRange?: NumLike,
82
- ): Promise<{ mean: Num; median: Num }>;
82
+ ): Promise<{ mean?: Num; median?: Num }>;
83
83
  /**
84
84
  * Get the recommended transaction fee rate based on recent blocks.
85
85
  * Returns the median fee rate, clamped between min and max fee rates.
@@ -102,7 +102,7 @@ export abstract class Client {
102
102
  options?: { maxFeeRate?: NumLike },
103
103
  ): Promise<Num> {
104
104
  const feeRate = numMax(
105
- (await this.getFeeRateStatistics(blockRange)).median,
105
+ (await this.getFeeRateStatistics(blockRange)).median ?? Zero,
106
106
  DEFAULT_MIN_FEE_RATE,
107
107
  );
108
108
 
@@ -13,7 +13,6 @@ import { Num, NumLike, numFrom, numToHex } from "../../num/index.js";
13
13
  import { apply } from "../../utils/index.js";
14
14
  import { ClientCache } from "../cache/index.js";
15
15
  import { Client } from "../client.js";
16
- import { DEFAULT_MIN_FEE_RATE } from "../clientTypes.advanced.js";
17
16
  import {
18
17
  ClientFindCellsResponse,
19
18
  ClientIndexerSearchKeyLike,
@@ -132,12 +131,9 @@ export abstract class ClientJsonRpc extends Client {
132
131
  getFeeRateStatistics = this.buildSender(
133
132
  "get_fee_rate_statistics",
134
133
  [(n: NumLike) => apply(numFrom, n)],
135
- // TODO: This is a temporary workaround for the fact that the node may return null for fee rate statistics.
136
- // We should change the method signature to return null instead of falling back to the default value,
137
- // but this would be a breaking change.
138
- (res: { mean: NumLike; median: NumLike } | null) => ({
139
- mean: numFrom(res?.mean ?? DEFAULT_MIN_FEE_RATE),
140
- median: numFrom(res?.median ?? DEFAULT_MIN_FEE_RATE),
134
+ (res: { mean: NumLike; median: NumLike } | null | undefined) => ({
135
+ mean: apply(numFrom, res?.mean),
136
+ median: apply(numFrom, res?.median),
141
137
  }),
142
138
  ) as Client["getFeeRateStatistics"];
143
139