@leofcoin/chain 1.10.12 → 1.10.14

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 (52) hide show
  1. package/exports/beacon-envelope.js +2 -2
  2. package/exports/beacon-epoch.js +1 -1
  3. package/exports/beacon-lifecycle.js +2 -2
  4. package/exports/beacon-round.js +1 -1
  5. package/exports/beacon.js +1 -1
  6. package/exports/browser/beacon-envelope.js +79 -3
  7. package/exports/browser/beacon-epoch.js +2 -1
  8. package/exports/browser/beacon-lifecycle.js +3 -2
  9. package/exports/browser/beacon-round.js +2 -1
  10. package/exports/browser/beacon-wire.js +3 -3
  11. package/exports/browser/beacon.js +3 -2
  12. package/exports/browser/{browser-DvU1xNFS-sdlKNCJc.js → browser-DvU1xNFS-4-PGqr4c.js} +4 -4
  13. package/exports/browser/browser-DvU1xNFS-BJCQsckZ.js +151 -0
  14. package/exports/browser/browser-DvU1xNFS-D9eSzJGJ.js +151 -0
  15. package/exports/browser/browser-crypto-BHeOz9rj.js +8893 -0
  16. package/exports/browser/browser-crypto-CTP3Yk4M.js +8893 -0
  17. package/exports/browser/{proposal.proto-BcUgd885.js → browser-crypto-Yk_e6OHw.js} +35 -6
  18. package/exports/browser/chain.js +63 -321
  19. package/exports/browser/{client-B-jyclOB-CsNYfj4Z.js → client-DDC8C510-CUi3_3uT.js} +36 -12
  20. package/exports/browser/client-DDC8C510-DbIdQjhy.js +2225 -0
  21. package/exports/browser/client-DDC8C510-ZN_MLo1Y.js +2225 -0
  22. package/exports/browser/connection-monitor-BjXI0nBP.js +453 -0
  23. package/exports/browser/connection-monitor-Cf0vNDCA.js +453 -0
  24. package/exports/browser/connection-monitor-pdopeM1I.js +453 -0
  25. package/exports/browser/hkdf-B9AXp_7K.js +222 -0
  26. package/exports/browser/hkdf-CnZvwpZ9.js +222 -0
  27. package/exports/browser/{index-Bxr5Iztg-C6xBk0rK.js → index-Bxr5Iztg-AmkW0EHS.js} +4 -4
  28. package/exports/browser/index-Bxr5Iztg-Bdpw_E83.js +40 -0
  29. package/exports/browser/index-Bxr5Iztg-CxXVYm3t.js +40 -0
  30. package/exports/browser/{index-D7FUx7Dd.js → index-CPQ5yvZ2.js} +5 -6
  31. package/exports/browser/index-C_RakUAS.js +4995 -0
  32. package/exports/browser/index-uFaocBqT.js +4995 -0
  33. package/exports/browser/{messages-FMRAS8QX-CvlZBzy5.js → messages-DH0tgNM9-BRp0gcJh.js} +4 -4
  34. package/exports/browser/messages-DH0tgNM9-CZwrcL37.js +208 -0
  35. package/exports/browser/messages-DH0tgNM9-DkNnpePH.js +208 -0
  36. package/exports/browser/{node-browser-xlqSBOaN.js → node-browser-1VSuCeew.js} +6 -6
  37. package/exports/browser/node-browser-CQugE1WZ.js +17880 -0
  38. package/exports/browser/node-browser-wDmRaOEo.js +17880 -0
  39. package/exports/browser/node-browser.js +4 -4
  40. package/exports/browser/sha2-Dkoic3vb.js +602 -0
  41. package/exports/browser/sha2-piimb6xL.js +614 -0
  42. package/exports/browser/weierstrass-HGdA_prK.js +2156 -0
  43. package/exports/browser/{weierstrass-C-jX_jly.js → weierstrass-Q0QND1ZT.js} +1 -1
  44. package/exports/browser/workers/machine-worker.js +419 -147
  45. package/exports/chain.js +56 -313
  46. package/exports/connection-monitor.js +324 -0
  47. package/exports/node.js +2 -0
  48. package/exports/workers/machine-worker.js +419 -147
  49. package/package.json +4 -4
  50. package/exports/browser/browser-CWeoyGUw-BabtHowB.js +0 -57
  51. package/exports/browser/constants-Cv0p224A.js +0 -130
  52. package/exports/browser/hkdf-DhdhLAAv.js +0 -147
@@ -1,4 +1,5 @@
1
1
  import { a as index$4, b as base58$1, i as index$5, f as fromBase58, c as fromHex, d as fromArrayLike, e as toBase32, t as toBase58, g as toHex } from './index-CvKt4UDE.js';
2
+ import { s as sha256 } from './sha2-Dkoic3vb.js';
2
3
 
3
4
  var isHex = string => /^[A-F0-9]+$/i.test(
4
5
  string.startsWith('0x') ?
@@ -7065,20 +7066,20 @@ const getTokens = (proto) => {
7065
7066
  return tokens;
7066
7067
  };
7067
7068
 
7068
- const encoder = new TextEncoder();
7069
+ const encoder$1 = new TextEncoder();
7069
7070
  const toType = (data) => {
7070
7071
  if (data instanceof Uint8Array)
7071
7072
  return data;
7072
7073
  if (data instanceof ArrayBuffer)
7073
7074
  return new Uint8Array(data);
7074
7075
  if (typeof data === 'bigint')
7075
- return encoder.encode(data.toString());
7076
+ return encoder$1.encode(data.toString());
7076
7077
  if (typeof data === 'string')
7077
- return encoder.encode(data);
7078
+ return encoder$1.encode(data);
7078
7079
  if (typeof data === 'object')
7079
- return encoder.encode(JSON.stringify(data, jsonStringifyBigInt$1));
7080
+ return encoder$1.encode(JSON.stringify(data, jsonStringifyBigInt$1));
7080
7081
  if (typeof data === 'number' || typeof data === 'boolean')
7081
- return encoder.encode(data.toString());
7082
+ return encoder$1.encode(data.toString());
7082
7083
  throw new Error(`unsuported type ${typeof data || data}`);
7083
7084
  };
7084
7085
  const encode = (proto, input, compress) => {
@@ -8861,4 +8862,32 @@ var proto = {
8861
8862
  signature: String()
8862
8863
  };
8863
8864
 
8864
- export { ContractMessage as C, FormatInterface as F, TransactionMessage as T, proto$1 as a, proto as b, jsonParseBigInt$1 as c, Codec as d, proto$3 as e, index$1 as f, createRIPEMD160 as g, createHMAC as h, index$2 as i, jsonStringifyBigInt$1 as j, createSHA512 as k, createKeccak as l, index$3 as m, proto$7 as n, proto$8 as o, proto$2 as p, proto$5 as q };
8865
+ const encoder = new TextEncoder();
8866
+ const normalizeInput = (value) => {
8867
+ if (typeof value === "string") return encoder.encode(value);
8868
+ if (value instanceof Uint8Array) return value;
8869
+ if (ArrayBuffer.isView(value)) return new Uint8Array(value.buffer, value.byteOffset, value.byteLength);
8870
+ return new Uint8Array(value);
8871
+ };
8872
+ const createHash = (algorithm) => {
8873
+ if (algorithm !== "sha256") throw new Error(`Unsupported hash algorithm: ${algorithm}`);
8874
+ const chunks = [];
8875
+ return {
8876
+ update(data) {
8877
+ chunks.push(normalizeInput(data));
8878
+ return this;
8879
+ },
8880
+ digest() {
8881
+ const length = chunks.reduce((total, chunk) => total + chunk.length, 0);
8882
+ const input = new Uint8Array(length);
8883
+ let offset = 0;
8884
+ for (const chunk of chunks) {
8885
+ input.set(chunk, offset);
8886
+ offset += chunk.length;
8887
+ }
8888
+ return sha256(input);
8889
+ }
8890
+ };
8891
+ };
8892
+
8893
+ export { ContractMessage as C, FormatInterface as F, TransactionMessage as T, proto$1 as a, proto as b, jsonParseBigInt$1 as c, Codec as d, proto$3 as e, index$1 as f, createRIPEMD160 as g, createHMAC as h, index$2 as i, jsonStringifyBigInt$1 as j, createSHA512 as k, createKeccak as l, index$3 as m, createHash as n, proto$7 as o, proto$2 as p, proto$8 as q, proto$5 as r };
@@ -1,9 +1,9 @@
1
- import { F as FormatInterface, p as proto, a as proto$1, b as proto$2, T as TransactionMessage, j as jsonStringifyBigInt, c as jsonParseBigInt, C as ContractMessage, d as Codec } from './proposal.proto-BcUgd885.js';
2
- import { B as BlockMessage, L as LastBlockMessage, P as PROTOCOL_VERSION, R as REACHED_ONE_ZERO_ZERO, a as BWMessage, S as StateMessage } from './constants-Cv0p224A.js';
3
- import { M as MAX_TRANSACTION_BYTES, a as MAX_BLOCK_TRANSACTION_BYTES, b as MAX_BLOCK_TRANSACTIONS, c as MultiWallet, d as createTransactionHash, e as calculateFee, f as createContractMessage, s as signTransaction, r as randombytes, g as distributeTransactionFee, h as supportsTransactionFees, i as supportsMonetaryPolicy, v as validateBlockResourceLimits, j as calculateMonetaryPolicy, k as distributeAmount, l as aggregateValidatorFees, m as MONETARY_POLICY_AUTHORITY, n as contractFactoryMessage, o as nativeTokenMessage, p as validatorsMessage, q as nameServiceMessage, t as parseUnits, u as formatUnits } from './index-D7FUx7Dd.js';
1
+ import { F as FormatInterface, p as proto, a as proto$1, b as proto$2, T as TransactionMessage, j as jsonStringifyBigInt, c as jsonParseBigInt, C as ContractMessage, d as Codec } from './browser-crypto-CTP3Yk4M.js';
2
+ import { B as BlockMessage, L as LastBlockMessage, P as PROTOCOL_VERSION, R as REACHED_ONE_ZERO_ZERO, C as ConnectionMonitor, a as BWMessage, S as StateMessage } from './connection-monitor-pdopeM1I.js';
3
+ import { M as MAX_TRANSACTION_BYTES, a as MAX_BLOCK_TRANSACTION_BYTES, b as MAX_BLOCK_TRANSACTIONS, c as MultiWallet, d as createTransactionHash, e as calculateFee, f as createContractMessage, s as signTransaction, r as randombytes, g as distributeTransactionFee, h as supportsTransactionFees, i as supportsMonetaryPolicy, v as validateBlockResourceLimits, j as calculateMonetaryPolicy, k as distributeAmount, l as aggregateValidatorFees, m as MONETARY_POLICY_AUTHORITY, n as contractFactoryMessage, o as nativeTokenMessage, p as validatorsMessage, q as nameServiceMessage, t as parseUnits, u as formatUnits } from './index-C_RakUAS.js';
4
4
  import { f as fromBase58 } from './index-CvKt4UDE.js';
5
5
  import { q as quorumThreshold } from './quorum-S_qdgiAY.js';
6
- import 'crypto';
6
+ import './sha2-piimb6xL.js';
7
7
 
8
8
  const getTargets = () => Array.from([]);
9
9
  const isEnabled = (target) => {
@@ -77,10 +77,10 @@ class ProposalMessage extends FormatInterface {
77
77
  }
78
78
  }
79
79
 
80
- var contractFactory$1 = "IHNY2GQHEXFPAUV5P5OG2WZYNQWNGSIERMIEPUBADCXQC2YZKTURUKZVCBQ";
81
- var nativeToken$1 = "IHNY2GQGADDXKNDM5TMPIFQYYEM25UTJEPXPOI24F25HKCZESWWMATYQ7D6";
82
- var nameService$1 = "IHNY2GQH4M6MOAMLB6I773D3WSAAO4UPD6ATFGZ3OJCO2KY4OYHWWYLV5IH";
83
- var validators$1 = "IHNY2GQG6IF5P2UTCD2CAZNKNG64BSGL3GNRJU3GQNUSLJI6MLLECYY3EP7";
80
+ var contractFactory$1 = "IHNY2GQG2XOULCWHDBW6MDLOPW35MCZC6KT6B6IBHIVWA3QJR56UFM2EVDG";
81
+ var nativeToken$1 = "IHNY2GQG5V74HIRRP6YPMZYDZ7YM3SR3MQX63XSYEZIZ7TWHBPDWRWVA2XA";
82
+ var nameService$1 = "IHNY2GQGQQKXPAEB2OKLN6BQ2JA2DJBV7BF3BHFKPBFJ6DCEJDDKSPKOZE6";
83
+ var validators$1 = "IHNY2GQH432JU2JPBPU5C6QXGLMDFLXBRNL4QA34I5BFJNSO6Y42B3POXJD";
84
84
  var addresses$1 = {
85
85
  contractFactory: contractFactory$1,
86
86
  nativeToken: nativeToken$1,
@@ -2941,6 +2941,27 @@ class Protocol {
2941
2941
  }
2942
2942
  }
2943
2943
 
2944
+ const waitForCanonicalTransaction = (pubsub, transactionPool, hash) => new Promise((resolve, reject) => {
2945
+ const completionTopic = `transaction.completed.${hash}`;
2946
+ const cleanup = () => {
2947
+ pubsub.unsubscribe("block-processed", blockProcessed);
2948
+ pubsub.unsubscribe(completionTopic, transactionCompleted);
2949
+ };
2950
+ const blockProcessed = (block) => {
2951
+ if (!Array.isArray(block?.transactions) || !block.transactions.includes(hash)) return;
2952
+ cleanup();
2953
+ resolve(hash);
2954
+ };
2955
+ const transactionCompleted = async (result) => {
2956
+ if (result?.status === "fulfilled") return;
2957
+ await transactionPool.delete(hash);
2958
+ cleanup();
2959
+ reject({ hash, error: result?.error });
2960
+ };
2961
+ pubsub.subscribe("block-processed", blockProcessed);
2962
+ pubsub.subscribe(completionTopic, transactionCompleted);
2963
+ });
2964
+
2944
2965
  class Transaction extends Protocol {
2945
2966
  #pendingNonces = /* @__PURE__ */ new Map();
2946
2967
  #maxPendingNonce = /* @__PURE__ */ new Map();
@@ -3142,26 +3163,7 @@ class Transaction extends Protocol {
3142
3163
  const hash = await message.hash();
3143
3164
  try {
3144
3165
  let data;
3145
- const wait = new Promise(async (resolve, reject) => {
3146
- if (pubsub.hasSubscribers(`transaction.completed.${hash}`)) {
3147
- const result = pubsub.getValue(`transaction.completed.${hash}`);
3148
- if (result.status !== "fulfilled") {
3149
- await transactionPoolStore.delete(hash);
3150
- }
3151
- result.status === "fulfilled" ? resolve(result.hash) : reject({ hash: result.hash, error: result.error });
3152
- } else {
3153
- const completed = async (result) => {
3154
- if (result.status !== "fulfilled") {
3155
- await transactionPoolStore.delete(hash);
3156
- }
3157
- result.status === "fulfilled" ? resolve(result.hash) : reject({ hash: result.hash, error: result.error });
3158
- setTimeout(async () => {
3159
- pubsub.unsubscribe(`transaction.completed.${hash}`, completed);
3160
- }, 1e4);
3161
- };
3162
- pubsub.subscribe(`transaction.completed.${hash}`, completed);
3163
- }
3164
- });
3166
+ const wait = waitForCanonicalTransaction(pubsub, transactionPoolStore, hash);
3165
3167
  await globalThis.transactionPoolStore.put(hash, message.encoded);
3166
3168
  this.addPendingNonce(message.decoded.from, message.decoded.nonce);
3167
3169
  try {
@@ -4690,6 +4692,12 @@ class State extends Contract {
4690
4692
  const localIndex = localBlock ? Number(localBlock.index) : -1;
4691
4693
  const remoteIndex = Number(lastBlock.index);
4692
4694
  const remoteBlockHash = lastBlock.hash;
4695
+ globalThis.pubsub.publish("sync-progress", {
4696
+ phase: "syncing",
4697
+ startIndex: localIndex,
4698
+ localIndex,
4699
+ targetIndex: remoteIndex
4700
+ });
4693
4701
  let localStateHash = "0x0";
4694
4702
  try {
4695
4703
  localStateHash = new TextDecoder().decode(await globalThis.chainStore.get("lastBlock"));
@@ -4749,6 +4757,12 @@ class State extends Contract {
4749
4757
  } else {
4750
4758
  debug$1(`Block already in local state. Remote hash: ${remoteBlockHash} matches local state`);
4751
4759
  }
4760
+ globalThis.pubsub.publish("sync-progress", {
4761
+ phase: "synced",
4762
+ startIndex: localIndex,
4763
+ localIndex: remoteIndex,
4764
+ targetIndex: remoteIndex
4765
+ });
4752
4766
  } catch (error) {
4753
4767
  console.log(error);
4754
4768
  throw error;
@@ -5035,297 +5049,6 @@ class VersionControl extends State {
5035
5049
  }
5036
5050
  }
5037
5051
 
5038
- class ConnectionMonitor {
5039
- #isMonitoring = false;
5040
- #checkInterval = null;
5041
- #reconnectDelay = 5e3;
5042
- #reconnectTimer = null;
5043
- #healthCheckInterval = 6e4;
5044
- #version;
5045
- #lastHealthCheckAt = 0;
5046
- #reconnecting = false;
5047
- // event handlers to remove later
5048
- #onOnline = null;
5049
- #onVisibilityChange = null;
5050
- #onSigcont = null;
5051
- #onPeerConnected = null;
5052
- get isMonitoring() {
5053
- return this.#isMonitoring;
5054
- }
5055
- get connectedPeers() {
5056
- return Object.values(globalThis.peernet?.connections || {}).filter((peer) => peer.connected);
5057
- }
5058
- get compatiblePeers() {
5059
- return this.connectedPeers.filter((peer) => {
5060
- if (!peer.version || !this.#version) return false;
5061
- const [peerMajor, peerMinor] = peer.version.split(".");
5062
- const [localMajor, localMinor] = this.#version.split(".");
5063
- return peerMajor === localMajor && peerMinor === localMinor;
5064
- });
5065
- }
5066
- get disconnectedPeers() {
5067
- return Object.values(globalThis.peernet?.connections || {}).filter((peer) => !peer.connected);
5068
- }
5069
- start(version) {
5070
- this.#version = version;
5071
- console.log(`\u{1F517} Connection Monitor initialized for version: ${this.#version}`);
5072
- if (this.#isMonitoring) return;
5073
- this.#isMonitoring = true;
5074
- console.log("\u{1F504} Starting connection monitor...");
5075
- if (typeof window !== "undefined" && typeof document !== "undefined") {
5076
- this.#onOnline = () => {
5077
- console.log("\u{1F310} Network online \u2014 attempting restore");
5078
- void this.#restoreNetwork();
5079
- };
5080
- window.addEventListener("online", this.#onOnline);
5081
- this.#onVisibilityChange = () => {
5082
- if (document.visibilityState === "visible") {
5083
- console.log("\u{1F4A1} Visibility regained");
5084
- if (this.connectedPeers.length === 0) {
5085
- console.log("\u{1F4A1} Visibility regained \u2014 attempting restore");
5086
- void this.#restoreNetwork();
5087
- }
5088
- }
5089
- };
5090
- document.addEventListener("visibilitychange", this.#onVisibilityChange);
5091
- }
5092
- if (typeof process !== "undefined" && typeof process.on === "function") {
5093
- this.#onSigcont = () => {
5094
- console.log("\u{1F514} Process resumed (SIGCONT) \u2014 attempting restore");
5095
- void this.#restoreNetwork();
5096
- };
5097
- try {
5098
- process.on("SIGCONT", this.#onSigcont);
5099
- } catch (e) {
5100
- }
5101
- }
5102
- this.#lastHealthCheckAt = Date.now();
5103
- this.#checkInterval = setInterval(() => {
5104
- this.#healthCheck();
5105
- }, this.#healthCheckInterval);
5106
- this.#onPeerConnected = () => {
5107
- if (this.#reconnectTimer) {
5108
- clearTimeout(this.#reconnectTimer);
5109
- this.#reconnectTimer = null;
5110
- }
5111
- this.#reconnecting = false;
5112
- this.#reconnectDelay = 5e3;
5113
- };
5114
- globalThis.pubsub?.subscribe("peer:connected", this.#onPeerConnected);
5115
- }
5116
- stop() {
5117
- if (!this.#isMonitoring) return;
5118
- this.#isMonitoring = false;
5119
- if (this.#checkInterval) {
5120
- clearInterval(this.#checkInterval);
5121
- this.#checkInterval = null;
5122
- }
5123
- if (typeof window !== "undefined") {
5124
- if (this.#onOnline) {
5125
- window.removeEventListener("online", this.#onOnline);
5126
- this.#onOnline = null;
5127
- }
5128
- if (this.#onVisibilityChange) {
5129
- document.removeEventListener("visibilitychange", this.#onVisibilityChange);
5130
- this.#onVisibilityChange = null;
5131
- }
5132
- }
5133
- if (typeof process !== "undefined" && typeof process.removeListener === "function" && this.#onSigcont) {
5134
- try {
5135
- process.removeListener("SIGCONT", this.#onSigcont);
5136
- } catch (e) {
5137
- }
5138
- this.#onSigcont = null;
5139
- }
5140
- if (this.#onPeerConnected) {
5141
- globalThis.pubsub?.unsubscribe("peer:connected", this.#onPeerConnected);
5142
- this.#onPeerConnected = null;
5143
- }
5144
- if (this.#reconnectTimer) {
5145
- clearTimeout(this.#reconnectTimer);
5146
- this.#reconnectTimer = null;
5147
- }
5148
- console.log("\u23F9\uFE0F Connection monitor stopped");
5149
- }
5150
- async #healthCheck() {
5151
- const now = Date.now();
5152
- const expectedNext = this.#lastHealthCheckAt + this.#healthCheckInterval;
5153
- const drift = now - expectedNext;
5154
- this.#lastHealthCheckAt = now;
5155
- if (drift > 5e3) {
5156
- console.log(`\u23F0 Detected timer drift of ${drift}ms (likely system sleep) \u2014 attempting restore`);
5157
- void this.#restoreNetwork();
5158
- }
5159
- const connectedPeers = this.connectedPeers;
5160
- const compatiblePeers = this.compatiblePeers;
5161
- const disconnectedPeers = this.disconnectedPeers;
5162
- console.log(
5163
- `\u{1F50D} Health check: ${connectedPeers.length} connected, ${compatiblePeers.length} compatible, ${disconnectedPeers.length} negotiating`
5164
- );
5165
- if (connectedPeers.length === 0 && disconnectedPeers.length === 0) {
5166
- console.warn("\u26A0\uFE0F No peer connections detected \u2014 attempting reconnection");
5167
- await this.#attemptReconnection();
5168
- } else if (compatiblePeers.length === 0 && connectedPeers.length > 0) {
5169
- console.warn("\u26A0\uFE0F No compatible peers found \u2014 attempting reconnection");
5170
- await this.#attemptReconnection();
5171
- }
5172
- globalThis.pubsub?.publish("connection-status", {
5173
- connected: connectedPeers.length,
5174
- compatible: compatiblePeers.length,
5175
- healthy: compatiblePeers.length > 0
5176
- });
5177
- }
5178
- // lightweight TCP probe to detect internet connectivity in Node.js
5179
- async #isOnLine(timeout = 1500) {
5180
- if (navigator?.onLine !== void 0) {
5181
- return navigator.onLine;
5182
- }
5183
- return new Promise(async (resolve) => {
5184
- try {
5185
- const net = await import('net');
5186
- const socket = new net.Socket();
5187
- let finished = false;
5188
- const finish = (val) => {
5189
- if (finished) return;
5190
- finished = true;
5191
- try {
5192
- socket.destroy();
5193
- } catch (e) {
5194
- }
5195
- resolve(val);
5196
- };
5197
- socket.setTimeout(timeout);
5198
- socket.once("connect", () => finish(true));
5199
- socket.once("error", () => finish(false));
5200
- socket.once("timeout", () => finish(false));
5201
- socket.connect(53, "1.1.1.1");
5202
- } catch (e) {
5203
- resolve(false);
5204
- }
5205
- });
5206
- }
5207
- // Called on visibility/online/resume events
5208
- async #restoreNetwork() {
5209
- if (this.#reconnecting) {
5210
- console.log("\u{1F501} Reconnection already in progress, skipping");
5211
- return;
5212
- }
5213
- this.#reconnecting = true;
5214
- if (this.connectedPeers.length > 0) {
5215
- console.log("\u2705 Already connected to peers, skipping restoration");
5216
- this.#reconnecting = false;
5217
- return;
5218
- }
5219
- console.log("\u{1F501} Restoring network");
5220
- try {
5221
- const online = await this.#isOnLine(1500);
5222
- if (!online) {
5223
- console.warn("\u26A0\uFE0F No internet detected, skipping restore");
5224
- this.#reconnecting = false;
5225
- return;
5226
- }
5227
- } catch (e) {
5228
- console.warn("\u26A0\uFE0F Online probe failed, proceeding with restore", e?.message || e);
5229
- }
5230
- try {
5231
- console.log("\u{1F504} Attempting network restoration...");
5232
- if (globalThis.peernet?.client?.reinit) {
5233
- console.log(" \u2192 Trying client.reinit()");
5234
- try {
5235
- await globalThis.peernet.client.reinit();
5236
- console.log(" \u2705 client.reinit() succeeded");
5237
- } catch (e) {
5238
- console.warn(" \u26A0\uFE0F client.reinit() failed:", e?.message || e);
5239
- }
5240
- }
5241
- if (globalThis.peernet?.start) {
5242
- console.log(" \u2192 Trying peernet.start()");
5243
- try {
5244
- await globalThis.peernet.start();
5245
- console.log(" \u2705 peernet.start() succeeded");
5246
- } catch (e) {
5247
- console.warn(" \u26A0\uFE0F peernet.start() failed:", e?.message || e);
5248
- }
5249
- }
5250
- try {
5251
- const networkName = globalThis.peernet?.network;
5252
- if (networkName && typeof networkName === "string") {
5253
- const { default: networks } = await import('./constants-Cv0p224A.js').then(function (n) { return n.n; });
5254
- const [mainKey, subKey] = networkName.split(":");
5255
- const networkConfig = networks?.[mainKey]?.[subKey];
5256
- if (networkConfig?.stars && Array.isArray(networkConfig.stars)) {
5257
- console.log(" \u2192 Attempting to dial star servers:", networkConfig.stars.join(", "));
5258
- for (const star of networkConfig.stars) {
5259
- try {
5260
- if (globalThis.peernet?.client && "dial" in globalThis.peernet.client) {
5261
- await globalThis.peernet.client.dial(star);
5262
- console.log(` \u2705 Connected to star server: ${star}`);
5263
- }
5264
- } catch (e) {
5265
- console.warn(` \u26A0\uFE0F Failed to dial ${star}:`, e?.message || e);
5266
- }
5267
- }
5268
- }
5269
- }
5270
- } catch (e) {
5271
- console.warn(" \u26A0\uFE0F Could not load or dial star servers:", e?.message || e);
5272
- }
5273
- await new Promise((resolve) => setTimeout(resolve, 2e3));
5274
- const connectedAfter = this.connectedPeers.length;
5275
- console.log(`\u{1F504} Restoration complete. Connected peers: ${connectedAfter}`);
5276
- } catch (error) {
5277
- console.error("\u274C Network restoration failed:", error?.message || error);
5278
- } finally {
5279
- this.#reconnecting = false;
5280
- }
5281
- }
5282
- async waitForPeers(timeoutMs = 3e4) {
5283
- return new Promise((resolve) => {
5284
- const startTime = Date.now();
5285
- const checkPeers = () => {
5286
- if (this.compatiblePeers.length > 0) {
5287
- resolve(true);
5288
- return;
5289
- }
5290
- if (Date.now() - startTime >= timeoutMs) {
5291
- resolve(false);
5292
- return;
5293
- }
5294
- setTimeout(checkPeers, 1e3);
5295
- };
5296
- checkPeers();
5297
- });
5298
- }
5299
- async #attemptReconnection() {
5300
- try {
5301
- await this.#restoreNetwork();
5302
- const hasConnections = this.connectedPeers.length > 0 || this.disconnectedPeers.length > 0;
5303
- if (hasConnections) {
5304
- console.log("\u2705 Reconnection successful, resetting backoff delay");
5305
- this.#reconnectDelay = 5e3;
5306
- } else {
5307
- console.warn("\u26A0\uFE0F Reconnection attempt completed but no peers connected");
5308
- if (this.#reconnectDelay >= 3e4) {
5309
- console.warn("\u26A0\uFE0F Reconnection delay reached maximum, resetting to 5 seconds");
5310
- this.#reconnectDelay = 5e3;
5311
- } else {
5312
- this.#reconnectDelay = Math.min(this.#reconnectDelay * 1.5, 3e4);
5313
- console.warn(`\u26A0\uFE0F Increasing reconnection delay to ${this.#reconnectDelay} ms`);
5314
- }
5315
- this.#reconnectTimer = setTimeout(() => this.#attemptReconnection(), this.#reconnectDelay);
5316
- }
5317
- } catch (error) {
5318
- console.error("\u274C Reconnection failed:", error?.message || error);
5319
- if (this.#reconnectDelay >= 3e4) {
5320
- this.#reconnectDelay = 5e3;
5321
- } else {
5322
- this.#reconnectDelay = Math.min(this.#reconnectDelay * 1.5, 3e4);
5323
- }
5324
- this.#reconnectTimer = setTimeout(() => this.#attemptReconnection(), this.#reconnectDelay);
5325
- }
5326
- }
5327
- }
5328
-
5329
5052
  const validateChainLink = (localTip, incoming) => {
5330
5053
  const localHash = localTip?.hash || "0x0";
5331
5054
  const localIndex = Number(localTip?.index ?? -1);
@@ -6361,7 +6084,6 @@ class Chain extends VersionControl {
6361
6084
  seed: hash,
6362
6085
  timestamp: Number(executionTimestamp)
6363
6086
  });
6364
- globalThis.pubsub.publish(`transaction.completed.${hash}`, { status: "fulfilled", hash });
6365
6087
  return result || "no state change";
6366
6088
  } catch (error) {
6367
6089
  await transactionPoolStore.delete(hash);
@@ -6483,6 +6205,25 @@ class Chain extends VersionControl {
6483
6205
  async participate(address) {
6484
6206
  try {
6485
6207
  if (!await this.staticCall(addresses.validators, "has", [address])) {
6208
+ const minimumBalance = BigInt(await this.staticCall(addresses.validators, "minimumBalance"));
6209
+ const allowance = BigInt(
6210
+ await this.staticCall(addresses.nativeToken, "allowance", [address, addresses.validators]) || 0n
6211
+ );
6212
+ if (allowance < minimumBalance) {
6213
+ const approval = await signTransaction(
6214
+ {
6215
+ from: address,
6216
+ to: addresses.nativeToken,
6217
+ method: "approve",
6218
+ params: [addresses.validators, minimumBalance],
6219
+ nonce: await this.getNonce(address) + 1,
6220
+ timestamp: Date.now()
6221
+ },
6222
+ globalThis.peernet.identity
6223
+ );
6224
+ const pendingApproval = await this.sendTransaction(approval);
6225
+ await pendingApproval.wait;
6226
+ }
6486
6227
  const rawTransaction = {
6487
6228
  from: address,
6488
6229
  to: addresses.validators,
@@ -6759,7 +6500,8 @@ class Chain extends VersionControl {
6759
6500
  return this.call(addresses.nativeToken, "mint", [to, amount]);
6760
6501
  }
6761
6502
  transfer(from, to, amount) {
6762
- return this.call(addresses.nativeToken, "transfer", [from, to, amount]);
6503
+ if (from !== globalThis.peernet.selectedAccount) throw new Error("transfer sender must be the selected account");
6504
+ return this.call(addresses.nativeToken, "transfer", [to, amount]);
6763
6505
  }
6764
6506
  balanceOf(address) {
6765
6507
  return this.staticCall(addresses.nativeToken, "balanceOf", [address]);
@@ -1,8 +1,8 @@
1
- import { i as inflate_1, c as createDebugger, d as deflate_1, L as LittlePubSub } from './node-browser-xlqSBOaN.js';
2
- import 'crypto';
3
- import './constants-Cv0p224A.js';
4
- import './proposal.proto-BcUgd885.js';
1
+ import { i as inflate_1, c as createDebugger, d as deflate_1, L as LittlePubSub } from './node-browser-CQugE1WZ.js';
2
+ import './browser-crypto-CTP3Yk4M.js';
3
+ import './connection-monitor-pdopeM1I.js';
5
4
  import './index-CvKt4UDE.js';
5
+ import './sha2-piimb6xL.js';
6
6
 
7
7
  class Api {
8
8
  _pubsub;
@@ -233,7 +233,7 @@ class SocketRequestClient {
233
233
  const init = async () => {
234
234
  // @ts-ignore
235
235
  if (!globalThis.WebSocket && !this.#experimentalWebsocket)
236
- globalThis.WebSocket = (await import('./browser-DvU1xNFS-sdlKNCJc.js').then(function (n) { return n.b; })).default.w3cwebsocket;
236
+ globalThis.WebSocket = (await import('./browser-DvU1xNFS-BJCQsckZ.js').then(function (n) { return n.b; })).default.w3cwebsocket;
237
237
  const client = new WebSocket(this.#url, this.#protocol);
238
238
  if (this.#experimentalWebsocket) {
239
239
  client.addEventListener('error', this.onerror);
@@ -1155,6 +1155,7 @@ class Client {
1155
1155
  #connectEvent = 'peer:connected';
1156
1156
  #supportedTransports = new Set(['webrtc']);
1157
1157
  #preferredTransportKind = 'webrtc';
1158
+ #wrtcBackend = 'vandeurenglenn';
1158
1159
  #fallbackTransportOrder = [];
1159
1160
  #enableCircuitFallback = true;
1160
1161
  #transportConnectTimeoutMs = 10_000;
@@ -1212,6 +1213,13 @@ class Client {
1212
1213
  ? 'webrtc'
1213
1214
  : 'webtransport';
1214
1215
  this.#webTransportUrlTemplate = options.transport?.webtransport?.urlTemplate;
1216
+ const wrtcBackend = options.transport?.webrtc?.backend ||
1217
+ globalThis.process?.env?.NETPEER_SWARM_WRTC_BACKEND ||
1218
+ 'vandeurenglenn';
1219
+ if (wrtcBackend !== 'vandeurenglenn' && wrtcBackend !== 'koush') {
1220
+ throw new Error(`Unsupported WebRTC backend: ${wrtcBackend}`);
1221
+ }
1222
+ this.#wrtcBackend = wrtcBackend;
1215
1223
  this.#enableCircuitFallback = options.transport?.fallback?.enabled ?? true;
1216
1224
  if (typeof options.transport?.fallback?.connectTimeoutMs === 'number' &&
1217
1225
  options.transport.fallback.connectTimeoutMs > 0) {
@@ -1297,7 +1305,8 @@ class Client {
1297
1305
  throw lastErr;
1298
1306
  }
1299
1307
  async _init() {
1300
- if (!globalThis.RTCPeerConnection &&
1308
+ if (this.#supportedTransports.has('webrtc') &&
1309
+ !globalThis.RTCPeerConnection &&
1301
1310
  !globalThis.wrtc) {
1302
1311
  const { backend, implementation } = await this.#loadNodeWebrtcImplementation();
1303
1312
  globalThis.wrtc = implementation;
@@ -1325,13 +1334,28 @@ class Client {
1325
1334
  }
1326
1335
  }
1327
1336
  async #loadNodeWebrtcImplementation() {
1328
- const koushWrtcModule = await import('./browser-CWeoyGUw-BabtHowB.js').then(function (n) { return n.b; });
1329
- const koushWrtc = koushWrtcModule.default;
1330
- if (!isWrtcImplementation(koushWrtc)) {
1331
- throw new Error('@koush/wrtc does not match required wrtc contract');
1337
+ let wrtcModule;
1338
+ if (this.#wrtcBackend === 'koush') {
1339
+ try {
1340
+ wrtcModule = await import('@koush/wrtc');
1341
+ }
1342
+ catch (error) {
1343
+ throw new Error('The koush WebRTC backend is opt-in; install @koush/wrtc to use it', { cause: error });
1344
+ }
1332
1345
  }
1333
- debug('using @koush/wrtc as wrtc implementation');
1334
- return { backend: 'koush', implementation: koushWrtc };
1346
+ else {
1347
+ wrtcModule = await import('@vandeurenglenn/wrtc');
1348
+ }
1349
+ const moduleCandidate = wrtcModule;
1350
+ const implementation = isWrtcImplementation(moduleCandidate.default)
1351
+ ? moduleCandidate.default
1352
+ : wrtcModule;
1353
+ if (!isWrtcImplementation(implementation)) {
1354
+ const packageName = this.#wrtcBackend === 'koush' ? '@koush/wrtc' : '@vandeurenglenn/wrtc';
1355
+ throw new Error(`${packageName} does not match required wrtc contract`);
1356
+ }
1357
+ debug(`using ${this.#wrtcBackend} as wrtc implementation`);
1358
+ return { backend: this.#wrtcBackend, implementation };
1335
1359
  }
1336
1360
  setupStarListeners(starConnection, starId) {
1337
1361
  // create stable references to handlers so we can unsubscribe later