@sovereign-sdk/web3 0.13.1 → 0.14.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.
package/dist/index.js CHANGED
@@ -40,7 +40,6 @@ __export(src_exports, {
40
40
  StandardRollup: () => StandardRollup,
41
41
  VersionMismatchError: () => VersionMismatchError,
42
42
  addressFromPublicKey: () => addressFromPublicKey,
43
- createSolanaPreamble: () => createSolanaPreamble,
44
43
  createSolanaSignableRollup: () => createSolanaSignableRollup,
45
44
  createStandardRollup: () => createStandardRollup,
46
45
  standardTypeBuilder: () => standardTypeBuilder
@@ -170,7 +169,7 @@ var Rollup = class {
170
169
  * Retrieve dedup information about the provided address.
171
170
  *
172
171
  * @param publicKey - The public key to dedup.
173
- * TODO: How to add param for generation explicitly
172
+ * TODO: How to request a specific uniqueness strategy explicitly
174
173
  */
175
174
  async dedup(publicKey) {
176
175
  const credentialId = (0, import_utils2.bytesToHex)(publicKey);
@@ -479,21 +478,40 @@ async function createStandardRollup(rollupConfig, typeBuilderOverrides) {
479
478
 
480
479
  // src/rollup/solana-signable-rollup.ts
481
480
  var import_signers = require("@sovereign-sdk/signers");
481
+ var import_utils4 = require("@sovereign-sdk/utils");
482
+ var import_bs58 = __toESM(require("bs58"));
482
483
  var import_js_base642 = require("js-base64");
484
+ var MULTISIG_SIMPLE_DISCRIMINATOR = 128;
483
485
  var VEC_LENGTH_PREFIX_SIZE = 4;
484
486
  var CHAIN_HASH_SIZE = 32;
485
487
  var PUBKEY_SIZE = 32;
486
488
  var SIGNATURE_SIZE = 64;
487
- var PREAMBLE_LENGTH = 85;
489
+ var MULTISIG_PREAMBLE_FIXED_LENGTH = 53;
490
+ var MAX_MULTISIG_SIGNERS = 21;
488
491
  var SIGNING_DOMAIN = new Uint8Array([
489
492
  255,
490
493
  ...new TextEncoder().encode("solana offchain")
491
494
  ]);
492
495
  var HEADER_VERSION = 0;
493
496
  var MESSAGE_FORMAT = 0;
494
- var SINGLE_SIGNER_COUNT = 1;
495
- function createSolanaPreamble(pubkey, chainHash, messageLength) {
496
- const preamble = new Uint8Array(PREAMBLE_LENGTH);
497
+ function compareByteArrays(left, right) {
498
+ const minLength = Math.min(left.length, right.length);
499
+ for (let i = 0; i < minLength; i++) {
500
+ if (left[i] !== right[i]) {
501
+ return left[i] - right[i];
502
+ }
503
+ }
504
+ return left.length - right.length;
505
+ }
506
+ function createSolanaPreamble(pubkeys, chainHash, messageLength) {
507
+ if (pubkeys.length < 1 || pubkeys.length > MAX_MULTISIG_SIGNERS) {
508
+ throw new Error(
509
+ `Invalid signer count: expected 1-${MAX_MULTISIG_SIGNERS} signers, got ${pubkeys.length}`
510
+ );
511
+ }
512
+ const preamble = new Uint8Array(
513
+ MULTISIG_PREAMBLE_FIXED_LENGTH + pubkeys.length * PUBKEY_SIZE
514
+ );
497
515
  let offset = 0;
498
516
  preamble.set(SIGNING_DOMAIN, offset);
499
517
  offset += 16;
@@ -503,10 +521,17 @@ function createSolanaPreamble(pubkey, chainHash, messageLength) {
503
521
  offset += 32;
504
522
  preamble[offset] = MESSAGE_FORMAT;
505
523
  offset += 1;
506
- preamble[offset] = SINGLE_SIGNER_COUNT;
524
+ preamble[offset] = pubkeys.length;
507
525
  offset += 1;
508
- preamble.set(pubkey, offset);
509
- offset += 32;
526
+ for (const pubkey of pubkeys) {
527
+ if (pubkey.length !== PUBKEY_SIZE) {
528
+ throw new Error(
529
+ `Invalid public key length: expected ${PUBKEY_SIZE} bytes, got ${pubkey.length}`
530
+ );
531
+ }
532
+ preamble.set(pubkey, offset);
533
+ offset += PUBKEY_SIZE;
534
+ }
510
535
  new DataView(preamble.buffer, offset).setUint16(0, messageLength, true);
511
536
  return preamble;
512
537
  }
@@ -550,6 +575,13 @@ var SolanaSignableRollup = class {
550
575
  const serializedMessage = this.serializeSolanaSpecMessage(solanaMessage);
551
576
  return this.submitSerializedMessage(serializedMessage);
552
577
  }
578
+ /**
579
+ * Submits a Solana spec-compliant multisig message to the rollup.
580
+ */
581
+ async submitSolanaSpecMultisigMessage(solanaMessage) {
582
+ const serializedMessage = this.serializeSolanaSpecMultisigMessage(solanaMessage);
583
+ return this.submitSerializedMessage(serializedMessage);
584
+ }
553
585
  /**
554
586
  * Helper to build an unsigned transaction using the standard type builder.
555
587
  */
@@ -572,6 +604,45 @@ var SolanaSignableRollup = class {
572
604
  });
573
605
  return { response, transaction };
574
606
  }
607
+ /**
608
+ * Concatenates a Solana preamble with the message bytes it signs.
609
+ */
610
+ combinePreambleAndMessage(preamble, message) {
611
+ const signedMessage = new Uint8Array(preamble.length + message.length);
612
+ signedMessage.set(preamble, 0);
613
+ signedMessage.set(message, preamble.length);
614
+ return signedMessage;
615
+ }
616
+ /**
617
+ * Validates and canonicalizes the multisig pubkey list.
618
+ * The canonical order is lexicographic by raw pubkey bytes.
619
+ */
620
+ canonicalizeMultisigPubkeys(multisigPubkeys) {
621
+ if (!multisigPubkeys) {
622
+ throw new Error(
623
+ "multisigPubkeys is required for Solana multisig transactions"
624
+ );
625
+ }
626
+ if (multisigPubkeys.length < 2 || multisigPubkeys.length > MAX_MULTISIG_SIGNERS) {
627
+ throw new Error(
628
+ `Invalid multisig signer count: expected 2-${MAX_MULTISIG_SIGNERS} signers, got ${multisigPubkeys.length}`
629
+ );
630
+ }
631
+ const seenPubkeys = /* @__PURE__ */ new Set();
632
+ for (const pubkey of multisigPubkeys) {
633
+ if (pubkey.length !== PUBKEY_SIZE) {
634
+ throw new Error(
635
+ `Invalid public key length: expected ${PUBKEY_SIZE} bytes, got ${pubkey.length}`
636
+ );
637
+ }
638
+ const pubkeyHex = (0, import_utils4.bytesToHex)(pubkey);
639
+ if (seenPubkeys.has(pubkeyHex)) {
640
+ throw new Error(`Duplicate multisig public key provided: ${pubkeyHex}`);
641
+ }
642
+ seenPubkeys.add(pubkeyHex);
643
+ }
644
+ return [...multisigPubkeys].sort(compareByteArrays);
645
+ }
575
646
  /**
576
647
  * Helper to create and serialize a SolanaOffchainUnsignedTransaction to JSON bytes.
577
648
  */
@@ -613,12 +684,15 @@ var SolanaSignableRollup = class {
613
684
  const jsonBytes = await this.createSolanaJsonBytes(unsignedTx);
614
685
  const pubkey = await signer.publicKey();
615
686
  const chainHash = await this.inner.chainHash();
616
- const preamble = createSolanaPreamble(pubkey, chainHash, jsonBytes.length);
617
- const signedMessageWithPreamble = new Uint8Array(
618
- preamble.length + jsonBytes.length
687
+ const preamble = createSolanaPreamble(
688
+ [pubkey],
689
+ chainHash,
690
+ jsonBytes.length
691
+ );
692
+ const signedMessageWithPreamble = this.combinePreambleAndMessage(
693
+ preamble,
694
+ jsonBytes
619
695
  );
620
- signedMessageWithPreamble.set(preamble, 0);
621
- signedMessageWithPreamble.set(jsonBytes, preamble.length);
622
696
  const signature = await signer.sign(signedMessageWithPreamble);
623
697
  const solanaMessage = {
624
698
  signed_message_with_preamble: signedMessageWithPreamble,
@@ -692,6 +766,235 @@ var SolanaSignableRollup = class {
692
766
  throw new Error(`Unsupported authenticator: ${authenticator}`);
693
767
  }
694
768
  }
769
+ /**
770
+ * Creates V1 JSON bytes for a multisig transaction, including multisig_id and version.
771
+ * The resulting JSON is what each signer signs directly (no discriminator prefix).
772
+ */
773
+ async createMultisigJsonBytes(unsignedTx, multisigAddress) {
774
+ const serializer = await this.inner.serializer();
775
+ const schema = serializer.schema;
776
+ const chainName = schema.chain_data.chain_name || "";
777
+ const solanaUnsignedTx = {
778
+ runtime_call: unsignedTx.runtime_call,
779
+ uniqueness: unsignedTx.uniqueness,
780
+ details: unsignedTx.details,
781
+ chain_name: chainName,
782
+ // Hardcoded to base58 encoding, only correct for rollups using Base58Address as their
783
+ // primary address type. Will be replaced with rollup-aware address formatting once the
784
+ // SDK supports flexible address encoding (see #2673).
785
+ multisig_id: import_bs58.default.encode(multisigAddress),
786
+ version: 1
787
+ };
788
+ return new TextEncoder().encode(JSON.stringify(solanaUnsignedTx));
789
+ }
790
+ /**
791
+ * Creates the preamble+JSON bytes signed by every signer in a spec-compliant multisig flow.
792
+ */
793
+ async createSpecCompliantMultisigSignedMessage(unsignedTx, multisigAddress, multisigPubkeys) {
794
+ const jsonBytes = await this.createMultisigJsonBytes(
795
+ unsignedTx,
796
+ multisigAddress
797
+ );
798
+ const chainHash = await this.inner.chainHash();
799
+ const preamble = createSolanaPreamble(
800
+ multisigPubkeys,
801
+ chainHash,
802
+ jsonBytes.length
803
+ );
804
+ return this.combinePreambleAndMessage(preamble, jsonBytes);
805
+ }
806
+ /**
807
+ * Signs an unsigned transaction using Solana offchain simple multisig signing.
808
+ */
809
+ async signForSolanaSimpleMultisig(unsignedTx, signer, multisigAddress, multisigPubkeys) {
810
+ const pubkey = await signer.publicKey();
811
+ const signerPubkeyHex = (0, import_utils4.bytesToHex)(pubkey);
812
+ const multisigPubkeyHexes = multisigPubkeys.map(import_utils4.bytesToHex);
813
+ if (!multisigPubkeyHexes.includes(signerPubkeyHex)) {
814
+ throw new Error(
815
+ `Signer public key ${signerPubkeyHex} is not present in multisigPubkeys`
816
+ );
817
+ }
818
+ const jsonBytes = await this.createMultisigJsonBytes(
819
+ unsignedTx,
820
+ multisigAddress
821
+ );
822
+ const signature = await signer.sign(jsonBytes);
823
+ return this.typeBuilder.transaction({
824
+ unsignedTx,
825
+ sender: pubkey,
826
+ signature,
827
+ rollup: this.inner
828
+ });
829
+ }
830
+ /**
831
+ * Signs an unsigned transaction using the spec-compliant multisig preamble.
832
+ */
833
+ async signForSolanaSpecMultisig(unsignedTx, signer, multisigAddress, multisigPubkeys) {
834
+ const pubkey = await signer.publicKey();
835
+ const signerPubkeyHex = (0, import_utils4.bytesToHex)(pubkey);
836
+ const multisigPubkeyHexes = multisigPubkeys.map(import_utils4.bytesToHex);
837
+ if (!multisigPubkeyHexes.includes(signerPubkeyHex)) {
838
+ throw new Error(
839
+ `Signer public key ${signerPubkeyHex} is not present in multisigPubkeys`
840
+ );
841
+ }
842
+ const signedMessageWithPreamble = await this.createSpecCompliantMultisigSignedMessage(
843
+ unsignedTx,
844
+ multisigAddress,
845
+ multisigPubkeys
846
+ );
847
+ const signature = await signer.sign(signedMessageWithPreamble);
848
+ return this.typeBuilder.transaction({
849
+ unsignedTx,
850
+ sender: pubkey,
851
+ signature,
852
+ rollup: this.inner
853
+ });
854
+ }
855
+ /**
856
+ * Signs an unsigned transaction for use in a Solana offchain multisig.
857
+ *
858
+ * `authenticator: "standard"` delegates directly to the wrapped standard rollup.
859
+ * `authenticator: "solanaSimple"` signs the V1 JSON payload directly.
860
+ * `authenticator: "solana"` signs the spec-compliant preamble+JSON bytes.
861
+ * Solana multisig authenticators treat `multisigPubkeys` as an unordered set and
862
+ * canonicalize it before signing.
863
+ */
864
+ async signTransactionForMultisig(unsignedTx, params) {
865
+ switch (params.authenticator) {
866
+ case "standard":
867
+ return this.inner.signTransaction(unsignedTx, params.signer);
868
+ case "solanaSimple":
869
+ return this.signForSolanaSimpleMultisig(
870
+ unsignedTx,
871
+ params.signer,
872
+ params.multisigAddress,
873
+ this.canonicalizeMultisigPubkeys(params.multisigPubkeys)
874
+ );
875
+ case "solana":
876
+ return this.signForSolanaSpecMultisig(
877
+ unsignedTx,
878
+ params.signer,
879
+ params.multisigAddress,
880
+ this.canonicalizeMultisigPubkeys(params.multisigPubkeys)
881
+ );
882
+ }
883
+ }
884
+ /**
885
+ * Builds a spec-compliant multisig envelope from a V1 transaction and ordered multisig pubkeys.
886
+ */
887
+ buildSpecCompliantMultisigEnvelope(tx, signedMessageWithPreamble, multisigPubkeys) {
888
+ const multisigPubkeyHexes = multisigPubkeys.map(import_utils4.bytesToHex);
889
+ const indexByPubkey = /* @__PURE__ */ new Map();
890
+ multisigPubkeyHexes.forEach((pubkeyHex, index) => {
891
+ indexByPubkey.set(pubkeyHex, index);
892
+ });
893
+ const accountedPubkeys = /* @__PURE__ */ new Set();
894
+ const signaturesByIndex = /* @__PURE__ */ new Map();
895
+ let signerBitfield = 0;
896
+ for (const signer of tx.signatures) {
897
+ const signerIndex = indexByPubkey.get(signer.pub_key);
898
+ if (signerIndex === void 0) {
899
+ throw new Error(
900
+ `Signed pubkey ${signer.pub_key} is not present in multisigPubkeys`
901
+ );
902
+ }
903
+ if (accountedPubkeys.has(signer.pub_key)) {
904
+ throw new Error(
905
+ `Duplicate signed pubkey in multisig transaction: ${signer.pub_key}`
906
+ );
907
+ }
908
+ accountedPubkeys.add(signer.pub_key);
909
+ signaturesByIndex.set(signerIndex, (0, import_utils4.hexToBytes)(signer.signature));
910
+ signerBitfield = (signerBitfield | 1 << signerIndex) >>> 0;
911
+ }
912
+ for (const unusedPubkey of tx.unused_pub_keys) {
913
+ if (!indexByPubkey.has(unusedPubkey)) {
914
+ throw new Error(
915
+ `Unused pubkey ${unusedPubkey} is not present in multisigPubkeys`
916
+ );
917
+ }
918
+ if (accountedPubkeys.has(unusedPubkey)) {
919
+ throw new Error(
920
+ `Duplicate pubkey in multisig transaction payload: ${unusedPubkey}`
921
+ );
922
+ }
923
+ accountedPubkeys.add(unusedPubkey);
924
+ }
925
+ if (accountedPubkeys.size !== multisigPubkeys.length) {
926
+ throw new Error(
927
+ "multisigPubkeys must contain every signer and unused pubkey exactly once"
928
+ );
929
+ }
930
+ const orderedSignatures = Array.from(signaturesByIndex.entries()).sort(([leftIndex], [rightIndex]) => leftIndex - rightIndex).map(([, signature]) => signature);
931
+ return {
932
+ signed_message_with_preamble: signedMessageWithPreamble,
933
+ signatures: orderedSignatures,
934
+ signer_bitfield: signerBitfield,
935
+ min_signers: tx.min_signers
936
+ };
937
+ }
938
+ /**
939
+ * Submits a multisig transaction using the Solana offchain simple multisig format.
940
+ *
941
+ * Accepts the V1 transaction produced by `MultisigTransaction.asTransaction()`.
942
+ * `authenticator: "standard"` delegates directly to the wrapped standard rollup.
943
+ * Solana authenticators rebuild the appropriate Solana multisig envelope and
944
+ * submit it to the Solana offchain endpoint.
945
+ */
946
+ async submitMultisigTransaction(multisigTx, params) {
947
+ const { V1: tx } = multisigTx;
948
+ const unsignedTx = {
949
+ runtime_call: tx.runtime_call,
950
+ uniqueness: tx.uniqueness,
951
+ details: tx.details
952
+ };
953
+ switch (params.authenticator) {
954
+ case "standard":
955
+ return this.inner.submitTransaction(
956
+ multisigTx
957
+ );
958
+ case "solanaSimple": {
959
+ this.canonicalizeMultisigPubkeys(params.multisigPubkeys);
960
+ const jsonBytes = await this.createMultisigJsonBytes(
961
+ unsignedTx,
962
+ params.multisigAddress
963
+ );
964
+ const wireBytes = new Uint8Array(1 + jsonBytes.length);
965
+ wireBytes[0] = MULTISIG_SIMPLE_DISCRIMINATOR;
966
+ wireBytes.set(jsonBytes, 1);
967
+ const chainHash = await this.inner.chainHash();
968
+ const serialized = this.serializeSolanaMultisigMessage({
969
+ wire_bytes: wireBytes,
970
+ chain_hash: chainHash,
971
+ signatures: tx.signatures.map((s) => ({
972
+ signature: (0, import_utils4.hexToBytes)(s.signature),
973
+ pub_key: (0, import_utils4.hexToBytes)(s.pub_key)
974
+ })),
975
+ unused_pub_keys: tx.unused_pub_keys.map((pk) => (0, import_utils4.hexToBytes)(pk)),
976
+ min_signers: tx.min_signers
977
+ });
978
+ return this.submitSerializedMessage(serialized);
979
+ }
980
+ case "solana": {
981
+ const multisigPubkeys = this.canonicalizeMultisigPubkeys(
982
+ params.multisigPubkeys
983
+ );
984
+ const signedMessageWithPreamble = await this.createSpecCompliantMultisigSignedMessage(
985
+ unsignedTx,
986
+ params.multisigAddress,
987
+ multisigPubkeys
988
+ );
989
+ const message = this.buildSpecCompliantMultisigEnvelope(
990
+ tx,
991
+ signedMessageWithPreamble,
992
+ multisigPubkeys
993
+ );
994
+ return this.submitSolanaSpecMultisigMessage(message);
995
+ }
996
+ }
997
+ }
695
998
  /**
696
999
  * Submits a transaction with the specified authenticator.
697
1000
  *
@@ -813,6 +1116,102 @@ var SolanaSignableRollup = class {
813
1116
  buffer.set(message.signature, offset);
814
1117
  return buffer;
815
1118
  }
1119
+ /**
1120
+ * Serializes a SolanaOffchainSimpleMultisigMessage using borsh encoding.
1121
+ * Layout matches the Rust struct:
1122
+ * [u32 LE: wire_bytes.len][wire_bytes]
1123
+ * [32 bytes: chain_hash]
1124
+ * [u32 LE: signatures.len]
1125
+ * for each: [64 bytes: signature][32 bytes: pub_key]
1126
+ * [u32 LE: unused_pub_keys.len]
1127
+ * for each: [32 bytes: pub_key]
1128
+ * [u8: min_signers]
1129
+ */
1130
+ serializeSolanaMultisigMessage(message) {
1131
+ if (message.chain_hash.length !== CHAIN_HASH_SIZE) {
1132
+ throw new Error(
1133
+ `Invalid chain hash length: expected ${CHAIN_HASH_SIZE} bytes, got ${message.chain_hash.length}`
1134
+ );
1135
+ }
1136
+ const sigCount = message.signatures.length;
1137
+ const unusedCount = message.unused_pub_keys.length;
1138
+ const totalSize = VEC_LENGTH_PREFIX_SIZE + message.wire_bytes.length + CHAIN_HASH_SIZE + VEC_LENGTH_PREFIX_SIZE + sigCount * (SIGNATURE_SIZE + PUBKEY_SIZE) + VEC_LENGTH_PREFIX_SIZE + unusedCount * PUBKEY_SIZE + 1;
1139
+ const buffer = new Uint8Array(totalSize);
1140
+ const view = new DataView(buffer.buffer);
1141
+ let offset = 0;
1142
+ view.setUint32(offset, message.wire_bytes.length, true);
1143
+ offset += VEC_LENGTH_PREFIX_SIZE;
1144
+ buffer.set(message.wire_bytes, offset);
1145
+ offset += message.wire_bytes.length;
1146
+ buffer.set(message.chain_hash, offset);
1147
+ offset += CHAIN_HASH_SIZE;
1148
+ view.setUint32(offset, sigCount, true);
1149
+ offset += VEC_LENGTH_PREFIX_SIZE;
1150
+ for (const sig of message.signatures) {
1151
+ if (sig.signature.length !== SIGNATURE_SIZE) {
1152
+ throw new Error(
1153
+ `Invalid signature length: expected ${SIGNATURE_SIZE} bytes, got ${sig.signature.length}`
1154
+ );
1155
+ }
1156
+ if (sig.pub_key.length !== PUBKEY_SIZE) {
1157
+ throw new Error(
1158
+ `Invalid public key length: expected ${PUBKEY_SIZE} bytes, got ${sig.pub_key.length}`
1159
+ );
1160
+ }
1161
+ buffer.set(sig.signature, offset);
1162
+ offset += SIGNATURE_SIZE;
1163
+ buffer.set(sig.pub_key, offset);
1164
+ offset += PUBKEY_SIZE;
1165
+ }
1166
+ view.setUint32(offset, unusedCount, true);
1167
+ offset += VEC_LENGTH_PREFIX_SIZE;
1168
+ for (const pk of message.unused_pub_keys) {
1169
+ if (pk.length !== PUBKEY_SIZE) {
1170
+ throw new Error(
1171
+ `Invalid public key length: expected ${PUBKEY_SIZE} bytes, got ${pk.length}`
1172
+ );
1173
+ }
1174
+ buffer.set(pk, offset);
1175
+ offset += PUBKEY_SIZE;
1176
+ }
1177
+ buffer[offset] = message.min_signers;
1178
+ return buffer;
1179
+ }
1180
+ /**
1181
+ * Serializes a SolanaOffchainSpecCompliantMultisigMessage using borsh encoding.
1182
+ * Layout matches the Rust struct:
1183
+ * [u32 LE: signed_message_with_preamble.len][signed_message_with_preamble]
1184
+ * [u32 LE: signatures.len]
1185
+ * for each: [64 bytes: signature]
1186
+ * [u32 LE: signer_bitfield]
1187
+ * [u8: min_signers]
1188
+ */
1189
+ serializeSolanaSpecMultisigMessage(message) {
1190
+ const sigCount = message.signatures.length;
1191
+ const totalSize = VEC_LENGTH_PREFIX_SIZE + message.signed_message_with_preamble.length + VEC_LENGTH_PREFIX_SIZE + sigCount * SIGNATURE_SIZE + 4 + 1;
1192
+ const buffer = new Uint8Array(totalSize);
1193
+ const view = new DataView(buffer.buffer);
1194
+ let offset = 0;
1195
+ view.setUint32(offset, message.signed_message_with_preamble.length, true);
1196
+ offset += VEC_LENGTH_PREFIX_SIZE;
1197
+ buffer.set(message.signed_message_with_preamble, offset);
1198
+ offset += message.signed_message_with_preamble.length;
1199
+ view.setUint32(offset, sigCount, true);
1200
+ offset += VEC_LENGTH_PREFIX_SIZE;
1201
+ for (const signature of message.signatures) {
1202
+ if (signature.length !== SIGNATURE_SIZE) {
1203
+ throw new Error(
1204
+ `Invalid signature length: expected ${SIGNATURE_SIZE} bytes, got ${signature.length}`
1205
+ );
1206
+ }
1207
+ buffer.set(signature, offset);
1208
+ offset += SIGNATURE_SIZE;
1209
+ }
1210
+ view.setUint32(offset, message.signer_bitfield >>> 0, true);
1211
+ offset += 4;
1212
+ buffer[offset] = message.min_signers;
1213
+ return buffer;
1214
+ }
816
1215
  };
817
1216
  async function createSolanaSignableRollup(rollupConfig, solanaEndpoint = "/sequencer/accept-solana-offchain-tx") {
818
1217
  const standardRollup = await createStandardRollup(rollupConfig);
@@ -833,7 +1232,6 @@ var SovereignClient3 = __toESM(require("@sovereign-sdk/client"));
833
1232
  StandardRollup,
834
1233
  VersionMismatchError,
835
1234
  addressFromPublicKey,
836
- createSolanaPreamble,
837
1235
  createSolanaSignableRollup,
838
1236
  createStandardRollup,
839
1237
  standardTypeBuilder