@ckb-ccc/core 1.22.0 → 2.0.0-next.1

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 +61 -1
  2. package/dist/advanced.d.mts +1 -1
  3. package/dist/advanced.mjs +1 -1
  4. package/{dist.commonjs/advancedBarrel-CJL3rfuW.d.ts → dist/advancedBarrel-DfFMFhdl.d.mts} +934 -567
  5. package/dist/advancedBarrel-DfFMFhdl.d.mts.map +1 -0
  6. package/dist/advancedBarrel.d.mts +1 -1
  7. package/dist/advancedBarrel.mjs +1 -1
  8. package/dist/barrel-ONYEMVg5.mjs +7 -0
  9. package/dist/barrel-ONYEMVg5.mjs.map +1 -0
  10. package/dist/barrel.d.mts +2 -2
  11. package/dist/barrel.mjs +1 -1
  12. package/dist/index.d.mts +2 -2
  13. package/dist/index.mjs +1 -1
  14. package/dist/transformers-CduZ1Js5.mjs +2 -0
  15. package/dist/transformers-CduZ1Js5.mjs.map +1 -0
  16. package/dist.commonjs/advanced.d.ts +1 -1
  17. package/dist.commonjs/advanced.js +1 -1
  18. package/{dist/advancedBarrel-Daj_LJkz.d.mts → dist.commonjs/advancedBarrel-Dl0mM9JO.d.ts} +935 -566
  19. package/dist.commonjs/advancedBarrel-Dl0mM9JO.d.ts.map +1 -0
  20. package/dist.commonjs/advancedBarrel.d.ts +1 -1
  21. package/dist.commonjs/advancedBarrel.js +1 -1
  22. package/dist.commonjs/{barrel-DZkApbAR.js → barrel-HfgYMxP_.js} +10 -10
  23. package/dist.commonjs/barrel-HfgYMxP_.js.map +1 -0
  24. package/dist.commonjs/barrel.d.ts +2 -2
  25. package/dist.commonjs/barrel.js +1 -1
  26. package/dist.commonjs/index.d.ts +2 -2
  27. package/dist.commonjs/index.js +1 -1
  28. package/dist.commonjs/transformers-BUlLwiyt.js +2 -0
  29. package/dist.commonjs/transformers-BUlLwiyt.js.map +1 -0
  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 +192 -195
  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/advancedBarrel-Daj_LJkz.d.mts.map +0 -1
  48. package/dist/barrel-CFOWSjcM.mjs +0 -7
  49. package/dist/barrel-CFOWSjcM.mjs.map +0 -1
  50. package/dist/transformers-DAMi6ZOq.mjs +0 -2
  51. package/dist/transformers-DAMi6ZOq.mjs.map +0 -1
  52. package/dist.commonjs/advancedBarrel-CJL3rfuW.d.ts.map +0 -1
  53. package/dist.commonjs/barrel-DZkApbAR.js.map +0 -1
  54. package/dist.commonjs/transformers-C6jbFO7W.js +0 -2
  55. package/dist.commonjs/transformers-C6jbFO7W.js.map +0 -1
@@ -7,7 +7,13 @@ import {
7
7
  type ClientBlockHeaderLike,
8
8
  } from "../client/clientTypes.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(
@@ -697,27 +688,33 @@ export type SinceLike =
697
688
  value: NumLike;
698
689
  }
699
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
+
700
698
  /**
701
699
  * @public
702
700
  */
703
- @codec(
704
- mol.Uint64.mapIn((encodable: SinceLike) => Since.from(encodable).toNum()),
705
- )
701
+ @codec(SinceCodec)
706
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
+
707
707
  /**
708
708
  * Creates an instance of Since.
709
709
  *
710
- * @param relative - Absolute or relative
711
- * @param metric - The metric of since
712
- * @param value - The value of since
710
+ * @param num - The since representation value.
713
711
  */
714
-
715
- constructor(
716
- public relative: "absolute" | "relative",
717
- public metric: "blockNumber" | "epoch" | "timestamp",
718
- public value: Num,
719
- ) {
712
+ constructor({ relative, metric, value }: DecodedType<typeof SinceCodec>) {
720
713
  super();
714
+
715
+ this.relative = relative;
716
+ this.metric = metric;
717
+ this.value = value;
721
718
  }
722
719
 
723
720
  /**
@@ -755,7 +752,11 @@ export class Since extends Entity.Base<SinceLike, Since>() {
755
752
  }
756
753
 
757
754
  if (typeof since === "object" && "relative" in since) {
758
- 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
+ });
759
760
  }
760
761
 
761
762
  return Since.fromNum(since);
@@ -771,7 +772,6 @@ export class Since extends Entity.Base<SinceLike, Since>() {
771
772
  * const num = since.toNum();
772
773
  * ```
773
774
  */
774
-
775
775
  toNum(): Num {
776
776
  return (
777
777
  this.value |
@@ -795,7 +795,6 @@ export class Since extends Entity.Base<SinceLike, Since>() {
795
795
  * const since = Since.fromNum("0x0");
796
796
  * ```
797
797
  */
798
-
799
798
  static fromNum(numLike: NumLike): Since {
800
799
  const num = numFrom(numLike);
801
800
 
@@ -805,10 +804,17 @@ export class Since extends Entity.Base<SinceLike, Since>() {
805
804
  ];
806
805
  const value = num & numFrom("0x00ffffffffffffff");
807
806
 
808
- return new Since(relative, metric, value);
807
+ return new Since({ relative, metric, value });
809
808
  }
810
809
  }
811
810
 
811
+ /**
812
+ * @public
813
+ */
814
+ const CellInputCodec = mol.struct({
815
+ since: Since,
816
+ previousOutput: OutPoint,
817
+ });
812
818
  /**
813
819
  * @public
814
820
  */
@@ -826,14 +832,14 @@ export type CellInputLike = (
826
832
  * @public
827
833
  */
828
834
  @codec(
829
- mol
830
- .struct({
831
- since: Since,
832
- previousOutput: OutPoint,
833
- })
834
- .mapIn((encodable: CellInputLike) => CellInput.from(encodable)),
835
+ CellInputCodec.mapIn((encodable: CellInputLike) => CellInput.from(encodable)),
835
836
  )
836
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
+
837
843
  /**
838
844
  * Creates an instance of CellInput.
839
845
  *
@@ -842,14 +848,21 @@ export class CellInput extends Entity.Base<CellInputLike, CellInput>() {
842
848
  * @param cellOutput - The optional cell output associated with the cell input.
843
849
  * @param outputData - The optional output data associated with the cell input.
844
850
  */
845
-
846
- constructor(
847
- public previousOutput: OutPoint,
848
- public since: Num,
849
- public cellOutput?: CellOutput,
850
- public outputData?: Hex,
851
- ) {
851
+ constructor({
852
+ previousOutput,
853
+ since,
854
+ cellOutput,
855
+ outputData,
856
+ }: DecodedType<typeof CellInputCodec> & {
857
+ cellOutput?: CellOutput;
858
+ outputData?: Hex;
859
+ }) {
852
860
  super();
861
+
862
+ this.previousOutput = previousOutput;
863
+ this.since = Since.from(since).toNum();
864
+ this.cellOutput = cellOutput;
865
+ this.outputData = outputData;
853
866
  }
854
867
 
855
868
  /**
@@ -871,16 +884,16 @@ export class CellInput extends Entity.Base<CellInputLike, CellInput>() {
871
884
  return cellInput;
872
885
  }
873
886
 
874
- return new CellInput(
875
- OutPoint.from(
887
+ return new CellInput({
888
+ previousOutput: OutPoint.from(
876
889
  "previousOutput" in cellInput
877
890
  ? cellInput.previousOutput
878
891
  : cellInput.outPoint,
879
892
  ),
880
- Since.from(cellInput.since ?? 0).toNum(),
881
- apply(CellOutput.from, cellInput.cellOutput),
882
- apply(hexFrom, cellInput.outputData),
883
- );
893
+ since: Since.from(cellInput.since ?? 0),
894
+ cellOutput: apply(CellOutput.from, cellInput.cellOutput),
895
+ outputData: apply(hexFrom, cellInput.outputData),
896
+ });
884
897
  }
885
898
 
886
899
  async getCell(client: Client): Promise<Cell> {
@@ -955,58 +968,33 @@ export const CellInputVec = mol.vector(CellInput);
955
968
  /**
956
969
  * @public
957
970
  */
958
- export type CellDepLike = {
959
- outPoint: OutPointLike;
960
- depType: DepTypeLike;
961
- };
971
+ const CellDepCodec = mol.struct({
972
+ outPoint: OutPoint,
973
+ depType: DepTypeCodec,
974
+ });
962
975
  /**
963
976
  * @public
964
977
  */
965
- @codec(
966
- mol.struct({
967
- outPoint: OutPoint,
968
- depType: DepTypeCodec,
969
- }),
970
- )
978
+ export type CellDepLike = EncodableType<typeof CellDepCodec>;
979
+ /**
980
+ * @public
981
+ */
982
+ @codec(CellDepCodec)
971
983
  export class CellDep extends Entity.Base<CellDepLike, CellDep>() {
984
+ public outPoint: OutPoint;
985
+ public depType: DepType;
986
+
972
987
  /**
973
988
  * Creates an instance of CellDep.
974
989
  *
975
990
  * @param outPoint - The outpoint of the cell dependency.
976
991
  * @param depType - The dependency type.
977
992
  */
978
-
979
- constructor(
980
- public outPoint: OutPoint,
981
- public depType: DepType,
982
- ) {
993
+ constructor({ outPoint, depType }: DecodedType<typeof CellDepCodec>) {
983
994
  super();
984
- }
985
-
986
- /**
987
- * Creates a CellDep instance from a CellDepLike object.
988
- *
989
- * @param cellDep - A CellDepLike object or an instance of CellDep.
990
- * @returns A CellDep instance.
991
- *
992
- * @example
993
- * ```typescript
994
- * const cellDep = CellDep.from({
995
- * outPoint: { txHash: "0x...", index: 0 },
996
- * depType: "depGroup"
997
- * });
998
- * ```
999
- */
1000
-
1001
- static from(cellDep: CellDepLike): CellDep {
1002
- if (cellDep instanceof CellDep) {
1003
- return cellDep;
1004
- }
1005
995
 
1006
- return new CellDep(
1007
- OutPoint.from(cellDep.outPoint),
1008
- depTypeFrom(cellDep.depType),
1009
- );
996
+ this.outPoint = outPoint;
997
+ this.depType = depType;
1010
998
  }
1011
999
 
1012
1000
  /**
@@ -1031,22 +1019,24 @@ export const CellDepVec = mol.vector(CellDep);
1031
1019
  /**
1032
1020
  * @public
1033
1021
  */
1034
- export type WitnessArgsLike = {
1035
- lock?: HexLike | null;
1036
- inputType?: HexLike | null;
1037
- outputType?: HexLike | null;
1038
- };
1022
+ const WitnessArgsCodec = mol.table({
1023
+ lock: mol.BytesOpt,
1024
+ inputType: mol.BytesOpt,
1025
+ outputType: mol.BytesOpt,
1026
+ });
1039
1027
  /**
1040
1028
  * @public
1041
1029
  */
1042
- @codec(
1043
- mol.table({
1044
- lock: mol.BytesOpt,
1045
- inputType: mol.BytesOpt,
1046
- outputType: mol.BytesOpt,
1047
- }),
1048
- )
1030
+ export type WitnessArgsLike = EncodableType<typeof WitnessArgsCodec>;
1031
+ /**
1032
+ * @public
1033
+ */
1034
+ @codec(WitnessArgsCodec)
1049
1035
  export class WitnessArgs extends Entity.Base<WitnessArgsLike, WitnessArgs>() {
1036
+ public lock?: Hex;
1037
+ public inputType?: Hex;
1038
+ public outputType?: Hex;
1039
+
1050
1040
  /**
1051
1041
  * Creates an instance of WitnessArgs.
1052
1042
  *
@@ -1054,41 +1044,16 @@ export class WitnessArgs extends Entity.Base<WitnessArgsLike, WitnessArgs>() {
1054
1044
  * @param inputType - The optional input type field of the witness.
1055
1045
  * @param outputType - The optional output type field of the witness.
1056
1046
  */
1057
-
1058
- constructor(
1059
- public lock?: Hex,
1060
- public inputType?: Hex,
1061
- public outputType?: Hex,
1062
- ) {
1047
+ constructor({
1048
+ lock,
1049
+ inputType,
1050
+ outputType,
1051
+ }: DecodedType<typeof WitnessArgsCodec>) {
1063
1052
  super();
1064
- }
1065
-
1066
- /**
1067
- * Creates a WitnessArgs instance from a WitnessArgsLike object.
1068
- *
1069
- * @param witnessArgs - A WitnessArgsLike object or an instance of WitnessArgs.
1070
- * @returns A WitnessArgs instance.
1071
- *
1072
- * @example
1073
- * ```typescript
1074
- * const witnessArgs = WitnessArgs.from({
1075
- * lock: "0x...",
1076
- * inputType: "0x...",
1077
- * outputType: "0x..."
1078
- * });
1079
- * ```
1080
- */
1081
-
1082
- static from(witnessArgs: WitnessArgsLike): WitnessArgs {
1083
- if (witnessArgs instanceof WitnessArgs) {
1084
- return witnessArgs;
1085
- }
1086
1053
 
1087
- return new WitnessArgs(
1088
- apply(hexFrom, witnessArgs.lock),
1089
- apply(hexFrom, witnessArgs.inputType),
1090
- apply(hexFrom, witnessArgs.outputType),
1091
- );
1054
+ this.lock = lock;
1055
+ this.inputType = inputType;
1056
+ this.outputType = outputType;
1092
1057
  }
1093
1058
  }
1094
1059
 
@@ -1145,6 +1110,14 @@ export type TransactionLike = {
1145
1110
  .mapOut((tx) => Transaction.from({ ...tx.raw, witnesses: tx.witnesses })),
1146
1111
  )
1147
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
+
1148
1121
  /**
1149
1122
  * Creates an instance of Transaction.
1150
1123
  *
@@ -1156,17 +1129,32 @@ export class Transaction extends Entity.Base<TransactionLike, Transaction>() {
1156
1129
  * @param outputsData - The data associated with the outputs.
1157
1130
  * @param witnesses - The witnesses of the transaction.
1158
1131
  */
1159
-
1160
- constructor(
1161
- public version: Num,
1162
- public cellDeps: CellDep[],
1163
- public headerDeps: Hex[],
1164
- public inputs: CellInput[],
1165
- public outputs: CellOutput[],
1166
- public outputsData: Hex[],
1167
- public witnesses: Hex[],
1168
- ) {
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
+ }) {
1169
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;
1170
1158
  }
1171
1159
 
1172
1160
  /**
@@ -1277,7 +1265,6 @@ export class Transaction extends Entity.Base<TransactionLike, Transaction>() {
1277
1265
  * });
1278
1266
  * ```
1279
1267
  */
1280
-
1281
1268
  static from(tx: TransactionLike): Transaction {
1282
1269
  if (tx instanceof Transaction) {
1283
1270
  tx.outputs.forEach((output, i) => {
@@ -1298,15 +1285,15 @@ export class Transaction extends Entity.Base<TransactionLike, Transaction>() {
1298
1285
  );
1299
1286
  }
1300
1287
 
1301
- return new Transaction(
1302
- numFrom(tx.version ?? 0),
1303
- tx.cellDeps?.map((cellDep) => CellDep.from(cellDep)) ?? [],
1304
- tx.headerDeps?.map(hexFrom) ?? [],
1305
- 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)) ?? [],
1306
1293
  outputs,
1307
1294
  outputsData,
1308
- tx.witnesses?.map(hexFrom) ?? [],
1309
- );
1295
+ witnesses: tx.witnesses?.map(hexFrom) ?? [],
1296
+ });
1310
1297
  }
1311
1298
 
1312
1299
  /**
@@ -1736,7 +1723,10 @@ export class Transaction extends Entity.Base<TransactionLike, Transaction>() {
1736
1723
  * ```
1737
1724
  */
1738
1725
  addInput(inputLike: CellInputLike): number {
1739
- if (this.witnesses.length > this.inputs.length) {
1726
+ if (
1727
+ this.witnesses.length > this.inputs.length &&
1728
+ this.inputs.length >= this.outputs.length
1729
+ ) {
1740
1730
  this.witnesses.splice(this.inputs.length, 0, "0x");
1741
1731
  }
1742
1732
 
@@ -1838,6 +1828,13 @@ export class Transaction extends Entity.Base<TransactionLike, Transaction>() {
1838
1828
  outputData: outputDataLike,
1839
1829
  });
1840
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
+
1841
1838
  const len = this.outputs.push(cell.cellOutput);
1842
1839
  this.setOutputData(len - 1, cell.outputData);
1843
1840
 
@@ -103,7 +103,7 @@ export abstract class Client {
103
103
 
104
104
  abstract getFeeRateStatistics(
105
105
  blockRange?: NumLike,
106
- ): Promise<{ mean: Num; median: Num }>;
106
+ ): Promise<{ mean?: Num; median?: Num }>;
107
107
  /**
108
108
  * Get the recommended transaction fee rate based on recent blocks.
109
109
  * Returns the median fee rate, clamped between min and max fee rates.
@@ -128,7 +128,7 @@ export abstract class Client {
128
128
  options?: { maxFeeRate?: NumLike },
129
129
  ): Promise<Num> {
130
130
  const feeRate = numMax(
131
- (await this.getFeeRateStatistics(blockRange)).median,
131
+ (await this.getFeeRateStatistics(blockRange)).median ?? Zero,
132
132
  DEFAULT_MIN_FEE_RATE,
133
133
  );
134
134
 
@@ -13,7 +13,6 @@ import { Num, NumLike, numFrom, numToHex } from "../../num/index.js";
13
13
  import { Owner, apply } from "../../utils/index.js";
14
14
  import type { ClientConfig } from "../client.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,
@@ -179,12 +178,9 @@ export abstract class ClientJsonRpc extends Client {
179
178
  getFeeRateStatistics = this.buildSender(
180
179
  "get_fee_rate_statistics",
181
180
  [(n: NumLike) => apply(numFrom, n)],
182
- // TODO: This is a temporary workaround for the fact that the node may return null for fee rate statistics.
183
- // We should change the method signature to return null instead of falling back to the default value,
184
- // but this would be a breaking change.
185
- (res: { mean: NumLike; median: NumLike } | null) => ({
186
- mean: numFrom(res?.mean ?? DEFAULT_MIN_FEE_RATE),
187
- median: numFrom(res?.median ?? DEFAULT_MIN_FEE_RATE),
181
+ (res: { mean: NumLike; median: NumLike } | null | undefined) => ({
182
+ mean: apply(numFrom, res?.mean),
183
+ median: apply(numFrom, res?.median),
188
184
  }),
189
185
  ) as Client["getFeeRateStatistics"];
190
186