@bounded-sh/core 0.0.68 → 0.0.70

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 (32) hide show
  1. package/README.md +0 -1
  2. package/dist/client/config.d.ts +4 -8
  3. package/dist/client/operations.d.ts +0 -3
  4. package/dist/client/reconcile.d.ts +7 -16
  5. package/dist/{index-C9w7qQpj.js → index-CqTl6vHg.js} +76 -632
  6. package/dist/index-CqTl6vHg.js.map +1 -0
  7. package/dist/{index-C9h-Bnjk.mjs → index-Csf_2uZF.mjs} +77 -629
  8. package/dist/index-Csf_2uZF.mjs.map +1 -0
  9. package/dist/index.d.ts +0 -2
  10. package/dist/index.js +1 -5
  11. package/dist/index.js.map +1 -1
  12. package/dist/index.mjs +1 -1
  13. package/dist/{realtime-store-B_Szs6F3.mjs → realtime-store-ByP5wYsa.mjs} +2 -2
  14. package/dist/{realtime-store-B_Szs6F3.mjs.map → realtime-store-ByP5wYsa.mjs.map} +1 -1
  15. package/dist/{realtime-store-CQiij3zc.js → realtime-store-DfeKV55-.js} +2 -2
  16. package/dist/{realtime-store-CQiij3zc.js.map → realtime-store-DfeKV55-.js.map} +1 -1
  17. package/dist/{solana-message-ngQQt80s.mjs → solana-message-BFqre_Oi.mjs} +2 -2
  18. package/dist/{solana-message-ngQQt80s.mjs.map → solana-message-BFqre_Oi.mjs.map} +1 -1
  19. package/dist/{solana-message-DibkzgkZ.js → solana-message-BecAT47y.js} +2 -2
  20. package/dist/{solana-message-DibkzgkZ.js.map → solana-message-BecAT47y.js.map} +1 -1
  21. package/dist/{solana-operations-B0Q9UOHR.mjs → solana-operations-ByMDnjog.mjs} +127 -8
  22. package/dist/solana-operations-ByMDnjog.mjs.map +1 -0
  23. package/dist/{solana-operations-XjBhPOnu.js → solana-operations-uN89eqO2.js} +127 -8
  24. package/dist/solana-operations-uN89eqO2.js.map +1 -0
  25. package/dist/types.d.ts +14 -182
  26. package/dist/utils/session-events.d.ts +2 -2
  27. package/package.json +2 -2
  28. package/dist/index-C9h-Bnjk.mjs.map +0 -1
  29. package/dist/index-C9w7qQpj.js.map +0 -1
  30. package/dist/solana-operations-B0Q9UOHR.mjs.map +0 -1
  31. package/dist/solana-operations-XjBhPOnu.js.map +0 -1
  32. package/dist/utils/evm/evm-transaction-validation.d.ts +0 -46
@@ -687,8 +687,8 @@ function refreshedTokenMayReplaceStored(newIdToken, storedAddress, decodeBase64U
687
687
  * event bus, so a session dying inside a session manager used to be invisible to
688
688
  * the SDK: `setCurrentUser(null)` was only ever called by `logout()` and `init()`.
689
689
  * The result was a UI that kept showing a connected wallet long after the session
690
- * it was showing had been wiped, which is exactly what let the Solana lab freeze a
691
- * review against a wallet the server no longer knew about.
690
+ * it was showing had been wiped, which is exactly what let a wallet-review UI
691
+ * freeze a review against a wallet the server no longer knew about.
692
692
  *
693
693
  * `js-sdk` registers a handler at init; core fires it ONLY when storage was
694
694
  * actually cleared, never on a failed-but-preserved refresh. Firing on a
@@ -4045,7 +4045,7 @@ class ServerSessionManager {
4045
4045
  const sessionConfig = (_a = this.sessionConfig) !== null && _a !== void 0 ? _a : undefined;
4046
4046
  /* fetch nonce from auth API (bound to the snapshotted app+issuer) */
4047
4047
  const nonce = await genAuthNonce(sessionConfig);
4048
- const { genSolanaMessage } = await Promise.resolve().then(function () { return require('./solana-message-DibkzgkZ.js'); });
4048
+ const { genSolanaMessage } = await Promise.resolve().then(function () { return require('./solana-message-BecAT47y.js'); });
4049
4049
  const message = await genSolanaMessage(address, nonce, sessionConfig === null || sessionConfig === void 0 ? void 0 : sessionConfig.appId);
4050
4050
  /* sign the message */
4051
4051
  const sigBytes = nacl.sign.detached(new TextEncoder().encode(message), kp.secretKey);
@@ -5406,6 +5406,35 @@ async function getWsAuthToken(isServer) {
5406
5406
  throw rememberAmbientAuthFailure(normalizeAuthExpiredError(error, 'Authentication expired and refresh failed'));
5407
5407
  }
5408
5408
  }
5409
+ /**
5410
+ * The server refused the token sent on the auth frame: its error frame arrives
5411
+ * while the auth ack is still pending, just before the 1008 close. Local expiry
5412
+ * had vouched for that exact token (unexpired but invalid - e.g. a rotated
5413
+ * issuer key), so re-sending it would only be refused again. Force a genuinely
5414
+ * new one: a definitive issuer rejection clears the session inside the shared
5415
+ * helper (firing notifySessionCleared, which signs the UI out), a successful
5416
+ * refresh commits a new token - and the ordinary reconnect loop picks up either
5417
+ * outcome on its own. Fresh token: authenticates. No token: connects
5418
+ * anonymously and public reads replay instead of erroring forever.
5419
+ */
5420
+ async function recoverFromServerAuthRejection(connection) {
5421
+ const rejected = connection.pendingAuthToken;
5422
+ if (!rejected)
5423
+ return;
5424
+ // One forced refresh per distinct rejected token value: a transiently
5425
+ // unreachable issuer must not turn the reconnect loop into a refresh storm.
5426
+ if (connection.serverRejectedAuthToken === rejected)
5427
+ return;
5428
+ connection.serverRejectedAuthToken = rejected;
5429
+ try {
5430
+ await getFreshAuthToken(connection.isServer, { force: true });
5431
+ }
5432
+ catch (_a) {
5433
+ // Every failure mode is already handled inside the helper: a dead
5434
+ // session was cleared (auth listeners notified), a transient refresh
5435
+ // failure keeps the session and the latch above stops the storm.
5436
+ }
5437
+ }
5409
5438
  async function getConnectionAuthToken(isServer, authTokenProvider, anonymous) {
5410
5439
  // A read-only scoped instance connects anonymously: no auth frame, and it
5411
5440
  // must never read (or refresh) the ambient global session - that session
@@ -5729,6 +5758,8 @@ async function getOrCreateConnectionOnce(appId, isServer, routePath, authTokenPr
5729
5758
  authFailure: null,
5730
5759
  source,
5731
5760
  anonymous,
5761
+ isServer,
5762
+ serverRejectedAuthToken: null,
5732
5763
  };
5733
5764
  connections.set(connKey, connection);
5734
5765
  // URL provider for reconnection with fresh tokens
@@ -5994,6 +6025,16 @@ function handleServerMessage(connection, message) {
5994
6025
  }
5995
6026
  case 'error': {
5996
6027
  console.error('[WS v2] Server error:', message.code, message.message);
6028
+ // The auth frame was just refused: while the auth ack is pending the
6029
+ // server sends no other error frame, and this one is immediately
6030
+ // followed by its 1008 close. Kick the forced-refresh recovery - the
6031
+ // ordinary reconnect loop then re-auths with a fresh token or, once a
6032
+ // definitively dead session is cleared, connects anonymously so
6033
+ // public reads still replay. Ambient connections only: wallet-scoped
6034
+ // connections refresh through their own provider.
6035
+ if (connection.isAuthenticating && connection.pendingAuthToken && !connection.authTokenProvider && !connection.anonymous) {
6036
+ void recoverFromServerAuthRejection(connection);
6037
+ }
5997
6038
  // Build an Error that ALSO carries the stable `code` as a structured
5998
6039
  // field (not just string-interpolated into the message) so callers can
5999
6040
  // branch on it — e.g. `catch (e) { if (e.code === 'invariant_violation') }`
@@ -6777,7 +6818,7 @@ async function doReconnectWithNewAuth() {
6777
6818
  console.warn('[WS v2] Failed to clear HTTP read cache on auth change:', error);
6778
6819
  }
6779
6820
  try {
6780
- const { reconnectRealtimeStoreWithNewAuth } = await Promise.resolve().then(function () { return require('./realtime-store-CQiij3zc.js'); });
6821
+ const { reconnectRealtimeStoreWithNewAuth } = await Promise.resolve().then(function () { return require('./realtime-store-DfeKV55-.js'); });
6781
6822
  await reconnectRealtimeStoreWithNewAuth();
6782
6823
  }
6783
6824
  catch (error) {
@@ -6888,7 +6929,7 @@ async function runNamedQueriesOverSocket(appId, queries, isServer) {
6888
6929
  return null; // timeout / disconnect / server error frame -> HTTP re-runs authoritatively
6889
6930
  }
6890
6931
  if ((data === null || data === void 0 ? void 0 : data.useHttp) === true)
6891
- return null; // server deferred (onchain/EVM, cross-room, malformed)
6932
+ return null; // server deferred (onchain, cross-room, malformed)
6892
6933
  if (Array.isArray(data === null || data === void 0 ? void 0 : data.queries))
6893
6934
  return data.queries;
6894
6935
  return null; // unexpected shape -> HTTP
@@ -7001,456 +7042,6 @@ async function wsIntentReliable(appId, roomRoutePath, intent, isServer) {
7001
7042
  });
7002
7043
  }
7003
7044
 
7004
- /**
7005
- * Selectors derived from the canonical BoundedRuntime signatures (BoundedTypes.sol):
7006
- *
7007
- * cast sig 'setDocuments(string,(string[],bool,(string,uint8,uint8,bytes)[])[])'
7008
- * => 0x0827b094
7009
- * cast sig 'setDocumentsAttested(string,(string[],bool,(string,uint8,uint8,bytes)[])[],(bytes32,uint256,uint256,uint8,bytes32,bytes32))'
7010
- * => 0x87b111c4
7011
- *
7012
- * Keep the signatures beside the constants: changing either Solidity tuple is an
7013
- * ABI break and must deliberately update these values and the Foundry goldens.
7014
- */
7015
- const BOUNDED_RUNTIME_SET_DOCUMENTS_SELECTOR = '0x0827b094';
7016
- const BOUNDED_RUNTIME_SET_DOCUMENTS_ATTESTED_SELECTOR = '0x87b111c4';
7017
- const SET_DOCUMENTS_SELECTOR = BOUNDED_RUNTIME_SET_DOCUMENTS_SELECTOR.slice(2);
7018
- const SET_DOCUMENTS_ATTESTED_SELECTOR = BOUNDED_RUNTIME_SET_DOCUMENTS_ATTESTED_SELECTOR.slice(2);
7019
- const MAX_CALLDATA_BYTES = 1024 * 1024;
7020
- const MAX_ARRAY_ITEMS = 2048;
7021
- const BIGINT_ZERO = BigInt(0);
7022
- const BIGINT_ONE = BigInt(1);
7023
- const BIGINT_EIGHT = BigInt(8);
7024
- const SECP256K1_N = BigInt('0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141');
7025
- const SECP256K1_HALF_N = BigInt('0x7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0');
7026
- function hexBytes(raw) {
7027
- if (typeof raw !== 'string' || !/^0x[0-9a-fA-F]*$/.test(raw) || raw.length % 2 !== 0) {
7028
- throw new Error('EVM transaction calldata must be even-length 0x hex');
7029
- }
7030
- const hex = raw.slice(2);
7031
- if (hex.length / 2 > MAX_CALLDATA_BYTES)
7032
- throw new Error('EVM transaction calldata exceeds the client safety limit');
7033
- const out = new Uint8Array(hex.length / 2);
7034
- for (let i = 0; i < out.length; i++)
7035
- out[i] = Number.parseInt(hex.slice(i * 2, i * 2 + 2), 16);
7036
- return out;
7037
- }
7038
- class AbiReader {
7039
- constructor(bytes) {
7040
- this.bytes = bytes;
7041
- this.maxRead = 0;
7042
- this.dynamicPayloadBytes = 0;
7043
- this.utf8 = new TextDecoder('utf-8', { fatal: true, ignoreBOM: false });
7044
- }
7045
- range(offset, length, label) {
7046
- if (!Number.isSafeInteger(offset) || !Number.isSafeInteger(length) || offset < 0 || length < 0 || offset + length > this.bytes.length) {
7047
- throw new Error(`Malformed EVM setDocuments calldata (${label})`);
7048
- }
7049
- this.maxRead = Math.max(this.maxRead, offset + length);
7050
- }
7051
- word(offset, label) {
7052
- this.range(offset, 32, label);
7053
- let value = BIGINT_ZERO;
7054
- for (let i = 0; i < 32; i++)
7055
- value = (value << BIGINT_EIGHT) | BigInt(this.bytes[offset + i]);
7056
- return value;
7057
- }
7058
- numberWord(offset, label, max = Number.MAX_SAFE_INTEGER) {
7059
- const value = this.word(offset, label);
7060
- if (value > BigInt(max))
7061
- throw new Error(`Malformed EVM setDocuments calldata (${label} too large)`);
7062
- return Number(value);
7063
- }
7064
- offset(base, wordOffset, min, label) {
7065
- const relative = this.numberWord(wordOffset, `${label} offset`, this.bytes.length);
7066
- if (relative < min || relative % 32 !== 0)
7067
- throw new Error(`Malformed EVM setDocuments calldata (${label} offset)`);
7068
- const absolute = base + relative;
7069
- this.range(absolute, 0, label);
7070
- return absolute;
7071
- }
7072
- dynamicBytes(at, label) {
7073
- const length = this.numberWord(at, `${label} length`, MAX_CALLDATA_BYTES);
7074
- this.dynamicPayloadBytes += length;
7075
- // ABI offsets may alias. Cap the cumulative decoded payload so a malicious
7076
- // 1 MB tail referenced by thousands of fields cannot amplify into a
7077
- // multi-gigabyte allocation/UTF-8 decode in the wallet process.
7078
- if (this.dynamicPayloadBytes > MAX_CALLDATA_BYTES) {
7079
- throw new Error('Malformed EVM setDocuments calldata (dynamic payload amplification)');
7080
- }
7081
- const start = at + 32;
7082
- const padded = Math.ceil(length / 32) * 32;
7083
- this.range(start, padded, label);
7084
- for (let i = start + length; i < start + padded; i++) {
7085
- if (this.bytes[i] !== 0)
7086
- throw new Error(`Malformed EVM setDocuments calldata (${label} padding)`);
7087
- }
7088
- return this.bytes.slice(start, start + length);
7089
- }
7090
- dynamicEnd(at, label) {
7091
- const length = this.numberWord(at, `${label} length`, MAX_CALLDATA_BYTES);
7092
- const end = at + 32 + Math.ceil(length / 32) * 32;
7093
- this.range(at + 32, Math.ceil(length / 32) * 32, label);
7094
- return end;
7095
- }
7096
- string(at, label) {
7097
- try {
7098
- return this.utf8.decode(this.dynamicBytes(at, label));
7099
- }
7100
- catch (_a) {
7101
- throw new Error(`Malformed EVM setDocuments calldata (${label} utf8)`);
7102
- }
7103
- }
7104
- finish() {
7105
- if (this.maxRead !== this.bytes.length)
7106
- throw new Error('Malformed EVM setDocuments calldata (unreferenced trailing bytes)');
7107
- }
7108
- }
7109
- function assertCanonicalOffset(actual, expected, label) {
7110
- if (actual !== expected)
7111
- throw new Error(`Malformed EVM setDocuments calldata (${label} non-canonical offset)`);
7112
- }
7113
- function decodeStringArray(reader, at, label) {
7114
- const count = reader.numberWord(at, `${label} count`, MAX_ARRAY_ITEMS);
7115
- const head = at + 32;
7116
- const min = count * 32;
7117
- const out = [];
7118
- let expectedTail = head + min;
7119
- for (let i = 0; i < count; i++) {
7120
- const itemAt = reader.offset(head, head + i * 32, min, `${label}[${i}]`);
7121
- assertCanonicalOffset(itemAt, expectedTail, `${label}[${i}]`);
7122
- out.push(reader.string(itemAt, `${label}[${i}]`));
7123
- expectedTail = reader.dynamicEnd(itemAt, `${label}[${i}]`);
7124
- }
7125
- return { value: out, end: expectedTail };
7126
- }
7127
- function decodeFields(reader, at) {
7128
- const count = reader.numberWord(at, 'fields count', MAX_ARRAY_ITEMS);
7129
- const head = at + 32;
7130
- const min = count * 32;
7131
- const out = [];
7132
- let expectedTail = head + min;
7133
- for (let i = 0; i < count; i++) {
7134
- const tuple = reader.offset(head, head + i * 32, min, `field[${i}]`);
7135
- assertCanonicalOffset(tuple, expectedTail, `field[${i}]`);
7136
- const nameAt = reader.offset(tuple, tuple, 128, `field[${i}].name`);
7137
- assertCanonicalOffset(nameAt, tuple + 128, `field[${i}].name`);
7138
- const name = reader.string(nameAt, `field[${i}].name`);
7139
- const nameEnd = reader.dynamicEnd(nameAt, `field[${i}].name`);
7140
- const ftype = reader.numberWord(tuple + 32, `field[${i}].ftype`, 255);
7141
- const op = reader.numberWord(tuple + 64, `field[${i}].op`, 255);
7142
- const valueAt = reader.offset(tuple, tuple + 96, 128, `field[${i}].value`);
7143
- assertCanonicalOffset(valueAt, nameEnd, `field[${i}].value`);
7144
- const value = reader.dynamicBytes(valueAt, `field[${i}].value`);
7145
- expectedTail = reader.dynamicEnd(valueAt, `field[${i}].value`);
7146
- out.push({ name, ftype, op, value });
7147
- }
7148
- return { value: out, end: expectedTail };
7149
- }
7150
- function decodeRuntimeWrite(rawData) {
7151
- const bytes = hexBytes(rawData);
7152
- if (bytes.length < 68)
7153
- throw new Error('Malformed EVM setDocuments calldata');
7154
- const selector = Array.from(bytes.slice(0, 4)).map((b) => b.toString(16).padStart(2, '0')).join('');
7155
- const kind = selector === SET_DOCUMENTS_SELECTOR
7156
- ? 'setDocuments'
7157
- : selector === SET_DOCUMENTS_ATTESTED_SELECTOR
7158
- ? 'setDocumentsAttested'
7159
- : null;
7160
- if (!kind)
7161
- throw new Error('EVM transaction is not a supported BoundedRuntime document write');
7162
- const reader = new AbiReader(bytes);
7163
- reader.maxRead = 4;
7164
- const args = 4;
7165
- // ExternalCallAttestation is a fully-static six-word tuple and is therefore
7166
- // expanded inline into the top-level head: 2 dynamic offsets + 6 words.
7167
- const headBytes = kind === 'setDocumentsAttested' ? 256 : 64;
7168
- const appAt = reader.offset(args, args, headBytes, 'appId');
7169
- assertCanonicalOffset(appAt, args + headBytes, 'appId');
7170
- const opsAt = reader.offset(args, args + 32, headBytes, 'ops');
7171
- const appId = reader.string(appAt, 'appId');
7172
- const appEnd = reader.dynamicEnd(appAt, 'appId');
7173
- assertCanonicalOffset(opsAt, appEnd, 'ops');
7174
- const count = reader.numberWord(opsAt, 'ops count', MAX_ARRAY_ITEMS);
7175
- const head = opsAt + 32;
7176
- const min = count * 32;
7177
- const ops = [];
7178
- let expectedTail = head + min;
7179
- for (let i = 0; i < count; i++) {
7180
- const tuple = reader.offset(head, head + i * 32, min, `op[${i}]`);
7181
- assertCanonicalOffset(tuple, expectedTail, `op[${i}]`);
7182
- const pathAt = reader.offset(tuple, tuple, 96, `op[${i}].path`);
7183
- assertCanonicalOffset(pathAt, tuple + 96, `op[${i}].path`);
7184
- const deleteWord = reader.numberWord(tuple + 32, `op[${i}].isDelete`, 1);
7185
- const fieldsAt = reader.offset(tuple, tuple + 64, 96, `op[${i}].fields`);
7186
- const path = decodeStringArray(reader, pathAt, `op[${i}].path`);
7187
- assertCanonicalOffset(fieldsAt, path.end, `op[${i}].fields`);
7188
- const fields = decodeFields(reader, fieldsAt);
7189
- expectedTail = fields.end;
7190
- ops.push({
7191
- pathSegments: path.value,
7192
- isDelete: deleteWord === 1,
7193
- fields: fields.value,
7194
- });
7195
- }
7196
- let attestation;
7197
- if (kind === 'setDocumentsAttested') {
7198
- const callsHash = reader.word(args + 64, 'attestation.callsHash');
7199
- const nonce = reader.word(args + 96, 'attestation.nonce');
7200
- const deadline = reader.word(args + 128, 'attestation.deadline');
7201
- const v = reader.numberWord(args + 160, 'attestation.v', 255);
7202
- const r = reader.word(args + 192, 'attestation.r');
7203
- const s = reader.word(args + 224, 'attestation.s');
7204
- if (v !== 27 && v !== 28)
7205
- throw new Error('Malformed EVM setDocuments calldata (attestation.v must be 27 or 28)');
7206
- if (r === BIGINT_ZERO || r >= SECP256K1_N)
7207
- throw new Error('Malformed EVM setDocuments calldata (attestation.r is not canonical)');
7208
- if (s === BIGINT_ZERO || s > SECP256K1_HALF_N)
7209
- throw new Error('Malformed EVM setDocuments calldata (attestation.s is not canonical low-s)');
7210
- attestation = { callsHash, nonce, deadline, v, r, s };
7211
- }
7212
- if (expectedTail !== bytes.length)
7213
- throw new Error('Malformed EVM setDocuments calldata (unreferenced trailing bytes)');
7214
- reader.finish();
7215
- return Object.assign({ kind, appId, ops }, (attestation ? { attestation } : {}));
7216
- }
7217
- /**
7218
- * Fail closed unless calldata is a byte-for-byte canonical ABI encoding of one
7219
- * supported BoundedRuntime write. This is the defense used by direct signer
7220
- * surfaces; the higher-level write validator below additionally binds app/ops.
7221
- */
7222
- function assertCanonicalBoundedRuntimeWriteCalldata(rawData) {
7223
- decodeRuntimeWrite(rawData);
7224
- }
7225
- const MAX_EVM_DOCUMENT_PATH_UTF8_BYTES = 1024;
7226
- function canonicalUtf8ByteLength(value) {
7227
- let bytes = 0;
7228
- for (let i = 0; i < value.length; i++) {
7229
- const unit = value.charCodeAt(i);
7230
- if (unit <= 0x7f)
7231
- bytes += 1;
7232
- else if (unit <= 0x7ff)
7233
- bytes += 2;
7234
- else if (unit >= 0xd800 && unit <= 0xdbff) {
7235
- const low = value.charCodeAt(++i);
7236
- if (!(low >= 0xdc00 && low <= 0xdfff))
7237
- throw new Error(`Invalid EVM write path: ${value}`);
7238
- bytes += 4;
7239
- }
7240
- else if (unit >= 0xdc00 && unit <= 0xdfff) {
7241
- throw new Error(`Invalid EVM write path: ${value}`);
7242
- }
7243
- else
7244
- bytes += 3;
7245
- }
7246
- return bytes;
7247
- }
7248
- function normalizedPathSegments(path) {
7249
- if (typeof path !== 'string' || path.length === 0 ||
7250
- canonicalUtf8ByteLength(path) > MAX_EVM_DOCUMENT_PATH_UTF8_BYTES) {
7251
- throw new Error(`Invalid EVM write path: ${path}`);
7252
- }
7253
- const segments = path.split('/');
7254
- if (segments.length < 2 || segments.length % 2 !== 0 ||
7255
- segments[0].startsWith('__') ||
7256
- segments.some((s) => !s || s === '.' || s === '..' || /[\\\u0000-\u001f\u007f]/.test(s))) {
7257
- throw new Error(`Invalid EVM write path: ${path}`);
7258
- }
7259
- return segments;
7260
- }
7261
- function bytesBigInt(bytes, signed) {
7262
- if (bytes.length !== 32)
7263
- throw new Error('EVM field value is not one ABI word');
7264
- let value = BIGINT_ZERO;
7265
- for (const b of bytes)
7266
- value = (value << BIGINT_EIGHT) | BigInt(b);
7267
- if (signed && (value & (BIGINT_ONE << BigInt(255))) !== BIGINT_ZERO)
7268
- value -= BIGINT_ONE << BigInt(256);
7269
- return value;
7270
- }
7271
- function decodedAbiString(bytes) {
7272
- const reader = new AbiReader(bytes);
7273
- const at = reader.offset(0, 0, 32, 'field string');
7274
- const value = reader.string(at, 'field string');
7275
- reader.finish();
7276
- return value;
7277
- }
7278
- function assertSetValue(field, expected) {
7279
- if (field.op !== 0)
7280
- throw new Error(`EVM field ${field.name} changes the requested SET action`);
7281
- if (typeof expected === 'boolean') {
7282
- if (field.ftype !== 3 || bytesBigInt(field.value, false) !== (expected ? BIGINT_ONE : BIGINT_ZERO))
7283
- throw new Error(`EVM field ${field.name} value mismatch`);
7284
- return;
7285
- }
7286
- if (typeof expected === 'number') {
7287
- if (!Number.isFinite(expected))
7288
- throw new Error(`EVM field ${field.name} is not finite`);
7289
- if (Number.isInteger(expected)) {
7290
- if (!Number.isSafeInteger(expected)) {
7291
- throw new Error(`EVM field ${field.name} integer must be a safe number or canonical decimal string`);
7292
- }
7293
- const actual = field.ftype === 1 ? bytesBigInt(field.value, false) : field.ftype === 2 ? bytesBigInt(field.value, true) : null;
7294
- if (actual === null || actual !== BigInt(expected))
7295
- throw new Error(`EVM field ${field.name} value mismatch`);
7296
- return;
7297
- }
7298
- if (field.ftype !== 4 || decodedAbiString(field.value) !== expected.toString())
7299
- throw new Error(`EVM field ${field.name} value mismatch`);
7300
- return;
7301
- }
7302
- if (typeof expected === 'bigint') {
7303
- const actual = field.ftype === 1 ? bytesBigInt(field.value, false) : field.ftype === 2 ? bytesBigInt(field.value, true) : null;
7304
- if (actual === null || actual !== expected)
7305
- throw new Error(`EVM field ${field.name} value mismatch`);
7306
- return;
7307
- }
7308
- if (typeof expected === 'string') {
7309
- if (field.ftype === 4 && decodedAbiString(field.value) === expected)
7310
- return;
7311
- if ((field.ftype === 1 || field.ftype === 2) && expected.length <= 20 && /^-?(?:0|[1-9][0-9]*)$/.test(expected)) {
7312
- const exact = BigInt(expected);
7313
- if (exact >= BigInt(Number.MIN_SAFE_INTEGER) && exact <= BigInt(Number.MAX_SAFE_INTEGER)) {
7314
- throw new Error(`EVM field ${field.name} safe integer must be supplied as a number`);
7315
- }
7316
- const inRange = field.ftype === 1
7317
- ? exact >= BIGINT_ZERO && exact <= ((BIGINT_ONE << BigInt(64)) - BIGINT_ONE)
7318
- : exact >= -(BIGINT_ONE << BigInt(63)) && exact <= ((BIGINT_ONE << BigInt(63)) - BIGINT_ONE);
7319
- const actual = bytesBigInt(field.value, field.ftype === 2);
7320
- if (inRange && actual === exact)
7321
- return;
7322
- throw new Error(`EVM field ${field.name} value mismatch`);
7323
- }
7324
- if (field.ftype === 5 && normalizeEvmAddress(expected)) {
7325
- const word = field.value;
7326
- if (word.length === 32 && word.slice(0, 12).every((b) => b === 0)) {
7327
- const actual = `0x${Array.from(word.slice(12)).map((b) => b.toString(16).padStart(2, '0')).join('')}`;
7328
- if (actual === normalizeEvmAddress(expected))
7329
- return;
7330
- }
7331
- }
7332
- throw new Error(`EVM field ${field.name} value mismatch`);
7333
- }
7334
- if (expected === undefined || expected === null) {
7335
- throw new Error(`EVM field ${field.name} cannot be represented safely on EVM; use a document delete or omit the field`);
7336
- }
7337
- const json = JSON.stringify(expected);
7338
- if (typeof json !== 'string' || field.ftype !== 4 || decodedAbiString(field.value) !== json) {
7339
- throw new Error(`EVM field ${field.name} value mismatch`);
7340
- }
7341
- }
7342
- function assertField(field, expected) {
7343
- if (expected === null) {
7344
- if (field.op !== 2 || field.ftype < 1 || field.ftype > 5 || field.value.length !== 0) {
7345
- throw new Error(`EVM field ${field.name} deletion mismatch`);
7346
- }
7347
- return;
7348
- }
7349
- if (expected && typeof expected === 'object' && !Array.isArray(expected)) {
7350
- const operation = expected.operation;
7351
- if (operation === 'increment') {
7352
- const delta = expected.value;
7353
- const actual = field.ftype === 1 || field.ftype === 2
7354
- ? bytesBigInt(field.value, true)
7355
- : null;
7356
- if (!Number.isSafeInteger(delta) || field.op !== 3 || actual === null || actual !== BigInt(delta)) {
7357
- throw new Error(`EVM field ${field.name} increment mismatch`);
7358
- }
7359
- return;
7360
- }
7361
- if (operation === 'time' && expected.value === 'now') {
7362
- if (field.op !== 4 || (field.ftype !== 1 && field.ftype !== 2) || field.value.length !== 0) {
7363
- throw new Error(`EVM field ${field.name} timestamp mismatch`);
7364
- }
7365
- return;
7366
- }
7367
- }
7368
- assertSetValue(field, expected);
7369
- }
7370
- function assertOp(decoded, path, document) {
7371
- const expectedSegments = normalizedPathSegments(path);
7372
- if (decoded.pathSegments.length !== expectedSegments.length || decoded.pathSegments.some((s, i) => s !== expectedSegments[i])) {
7373
- throw new Error(`EVM transaction path does not match requested write: ${path}`);
7374
- }
7375
- if (decoded.isDelete !== (document === null))
7376
- throw new Error(`EVM transaction action does not match requested write: ${path}`);
7377
- if (document === null) {
7378
- if (decoded.fields.length !== 0)
7379
- throw new Error(`EVM delete unexpectedly carries fields: ${path}`);
7380
- return;
7381
- }
7382
- if (!document || typeof document !== 'object' || Array.isArray(document))
7383
- throw new Error(`EVM document must be a plain object or null: ${path}`);
7384
- const expectedEntries = Object.entries(document);
7385
- if (expectedEntries.some(([name]) => name.startsWith('_')))
7386
- throw new Error(`Reserved EVM field reached transaction validation: ${path}`);
7387
- const expected = new Map(expectedEntries);
7388
- const seen = new Set();
7389
- for (const field of decoded.fields) {
7390
- if (!field.name || seen.has(field.name) || !expected.has(field.name))
7391
- throw new Error(`EVM transaction contains unexpected or duplicate field ${field.name}`);
7392
- seen.add(field.name);
7393
- assertField(field, expected.get(field.name));
7394
- }
7395
- const missing = [...expected.keys()].filter((name) => !seen.has(name));
7396
- if (missing.length > 0)
7397
- throw new Error(`EVM transaction omits requested fields: ${missing.join(', ')}`);
7398
- }
7399
- function zeroWei(raw) {
7400
- if (raw === undefined || raw === null || raw === '')
7401
- return true;
7402
- if (typeof raw !== 'string' && typeof raw !== 'number')
7403
- return false;
7404
- try {
7405
- return BigInt(raw) === BIGINT_ZERO;
7406
- }
7407
- catch (_a) {
7408
- return false;
7409
- }
7410
- }
7411
- /** Verify the untrusted 202 payload is exactly the governed write the app asked for. */
7412
- function assertEvmTransactionMatchesWrite(transaction, context) {
7413
- var _a, _b;
7414
- if (!transaction || !Number.isSafeInteger(transaction.chainId) || transaction.chainId <= 0) {
7415
- throw new Error('EVM transaction chainId is required');
7416
- }
7417
- const chainId = transaction.chainId;
7418
- const policy = context.policy;
7419
- if (!policy)
7420
- throw new Error('EVM transaction signing requires an explicit runtime/chain policy');
7421
- if (policy.chainId !== undefined && policy.chainId !== chainId)
7422
- throw new Error(`EVM transaction chain ${chainId} does not match configured chain ${policy.chainId}`);
7423
- const expectedRuntime = (_b = (_a = policy.runtimeAddresses) === null || _a === void 0 ? void 0 : _a[String(chainId)]) !== null && _b !== void 0 ? _b : (policy.chainId === chainId ? policy.runtimeAddress : undefined);
7424
- const normalizedRuntime = normalizeEvmAddress(expectedRuntime);
7425
- if (!normalizedRuntime)
7426
- throw new Error(`No trusted BoundedRuntime address configured for EVM chain ${chainId}`);
7427
- if (normalizeEvmAddress(transaction.to) !== normalizedRuntime)
7428
- throw new Error('EVM transaction target is not the configured BoundedRuntime');
7429
- if (!zeroWei(transaction.value))
7430
- throw new Error('BoundedRuntime.setDocuments must not transfer native value');
7431
- if (transaction.nonce !== undefined)
7432
- throw new Error('Server-supplied EVM nonce is not accepted');
7433
- const decoded = decodeRuntimeWrite(transaction.data);
7434
- if (decoded.appId !== context.appId)
7435
- throw new Error('EVM transaction appId does not match configured appId');
7436
- if (decoded.ops.length !== context.documents.length)
7437
- throw new Error('EVM transaction operation count does not match requested writes');
7438
- // The worker's contract ABI groups upserts first and document deletes second.
7439
- const expectedOps = [
7440
- ...context.documents.filter((entry) => entry.document !== null),
7441
- ...context.documents.filter((entry) => entry.document === null),
7442
- ];
7443
- const paths = new Set();
7444
- for (let i = 0; i < expectedOps.length; i++) {
7445
- const expected = expectedOps[i];
7446
- const canonicalPath = normalizedPathSegments(expected.destinationPath).join('/');
7447
- if (paths.has(canonicalPath))
7448
- throw new Error(`Duplicate EVM write path is not allowed: ${canonicalPath}`);
7449
- paths.add(canonicalPath);
7450
- assertOp(decoded.ops[i], canonicalPath, expected.document);
7451
- }
7452
- }
7453
-
7454
7045
  /**
7455
7046
  * Thrown when a user's wallet doesn't have enough SOL to cover the transaction.
7456
7047
  * Apps can catch this to trigger an onramp/funding flow.
@@ -8566,12 +8157,12 @@ async function set(path, document, options) {
8566
8157
  * state appears only under `observation`/`mirrorSync` once actually observed.
8567
8158
  */
8568
8159
  async function setMany(many, options) {
8569
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
8160
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
8570
8161
  // Returns the data that was set, or undefined if the document was already set.
8571
8162
  try {
8572
8163
  // A server WalletClient threads its immutable config snapshot; the default
8573
8164
  // path reads the mutable process-global init() config. This keeps the app-id
8574
- // bound into an on-chain 202 write (EVM/Solana/offchain) on the wallet
8165
+ // bound into an on-chain 202 write (Solana/offchain) on the wallet
8575
8166
  // client's original app after a later global init() (CTA-05).
8576
8167
  const config = (_b = (_a = options === null || options === void 0 ? void 0 : options._overrides) === null || _a === void 0 ? void 0 : _a._config) !== null && _b !== void 0 ? _b : await getConfig();
8577
8168
  const authProvider = (_d = (_c = options === null || options === void 0 ? void 0 : options._overrides) === null || _c === void 0 ? void 0 : _c.authProvider) !== null && _d !== void 0 ? _d : config.authProvider;
@@ -8640,13 +8231,18 @@ async function setMany(many, options) {
8640
8231
  throw new Error(`Expected exactly one on-chain transaction, received ${Array.isArray(transactions) ? transactions.length : 0}`);
8641
8232
  }
8642
8233
  const curTx = transactions[0];
8643
- const hasEvmTarget = (curTx === null || curTx === void 0 ? void 0 : curTx.evmTransaction) != null;
8234
+ // The EVM onchain data plane is retired: no worker mints an EVM 202 any
8235
+ // more. A payload that still carries one is an unexpected response and
8236
+ // fails loudly BEFORE anything is signed - never silently ignored.
8237
+ if ((curTx === null || curTx === void 0 ? void 0 : curTx.evmTransaction) != null) {
8238
+ throw new Error('Unsupported 202 transaction shape: the write response carried an evmTransaction, ' +
8239
+ 'but EVM onchain writes are no longer supported. Nothing was signed or submitted.');
8240
+ }
8644
8241
  const hasSerializedSolanaTarget = (curTx === null || curTx === void 0 ? void 0 : curTx.serializedTransaction) != null;
8645
8242
  const hasBuiltSolanaTarget = (curTx === null || curTx === void 0 ? void 0 : curTx.transactionArgs) != null || (curTx === null || curTx === void 0 ? void 0 : curTx.remainingAccounts) != null ||
8646
8243
  (curTx === null || curTx === void 0 ? void 0 : curTx.idl) != null || (curTx === null || curTx === void 0 ? void 0 : curTx.txData) != null || (curTx === null || curTx === void 0 ? void 0 : curTx.preInstructions) != null;
8647
- if ((hasEvmTarget && (hasSerializedSolanaTarget || hasBuiltSolanaTarget)) ||
8648
- (hasSerializedSolanaTarget && hasBuiltSolanaTarget)) {
8649
- throw new Error('Ambiguous on-chain write response mixes EVM and/or Solana transaction target formats');
8244
+ if (hasSerializedSolanaTarget && hasBuiltSolanaTarget) {
8245
+ throw new Error('Ambiguous on-chain write response mixes Solana transaction target formats');
8650
8246
  }
8651
8247
  const expectedWritePaths = documents.map(d => d.destinationPath);
8652
8248
  const requestedDocuments = buildRequestedDocuments(documents);
@@ -8659,67 +8255,13 @@ async function setMany(many, options) {
8659
8255
  throw new Error('The write response carried no execution-chain tag, so this receipt could not state where the write ran. ' +
8660
8256
  'Nothing was signed or submitted.');
8661
8257
  }
8662
- // EVM onchain write: the worker returns a PRE-BUILT EIP-1559 tx on
8663
- // `transactions[0].evmTransaction` (the EVM twin of Solana's pre-built
8664
- // `serializedTransaction`). WORKER 202 CONTRACT (field name + shape the
8665
- // worker side must emit to match):
8666
- // { transactions: [ { evmTransaction: {
8667
- // to, data, value?, chainId, gas?, maxFeePerGas?, maxPriorityFeePerGas?, nonce?
8668
- // } } ] }
8669
- // We hand it to the EVM auth provider's runTransaction(evmTx, undefined, options)
8670
- // (eth_sendTransaction — the wallet signs + submits). syncItems below is
8671
- // identical to the Solana path.
8672
- if (curTx.evmTransaction) {
8673
- assertEvmTransactionMatchesWrite(curTx.evmTransaction, {
8674
- appId: config.appId,
8675
- documents,
8676
- policy: (_o = (_m = (_l = options === null || options === void 0 ? void 0 : options._overrides) === null || _l === void 0 ? void 0 : _l._evmTransactionPolicy) !== null && _m !== void 0 ? _m : config.evmWalletConfig) !== null && _o !== void 0 ? _o : null,
8677
- });
8678
- const evmChain = workerChain;
8679
- const evmOutcome = await handleEvmTransaction(curTx.evmTransaction, authProvider, options);
8680
- // CAPTURE THE RECEIPT FIRST. Mirror synchronization comes after, and its
8681
- // failure can never turn a landed transaction into a thrown error that
8682
- // invites the caller to submit the same write twice.
8683
- if (evmOutcome.outcome === 'confirmed') {
8684
- const mirrorSync = await attemptMirrorSync(expectedWritePaths, options);
8685
- return {
8686
- status: 'confirmed', appId, requestedDocuments, chain: evmChain,
8687
- transactionId: evmOutcome.transactionSignature,
8688
- blockNumber: evmOutcome.blockNumber,
8689
- mirrorSync,
8690
- };
8691
- }
8692
- // An unknown confirmation outcome is NOT a mirror question: nothing is
8693
- // known to have landed, so no synchronization is attempted.
8694
- if (evmOutcome.transactionSignature === null) {
8695
- return {
8696
- status: 'submitted', appId, requestedDocuments, chain: evmChain,
8697
- transactionId: null,
8698
- confirmation: { state: 'unknown', reason: evmOutcome.reason, reconcilable: false },
8699
- };
8700
- }
8701
- if ('fence' in evmOutcome && evmOutcome.fence) {
8702
- return {
8703
- status: 'submitted', appId, requestedDocuments, chain: evmChain,
8704
- transactionId: evmOutcome.transactionSignature,
8705
- fence: evmOutcome.fence,
8706
- confirmation: { state: 'unknown', reason: evmOutcome.reason },
8707
- };
8708
- }
8709
- return {
8710
- status: 'submitted', appId, requestedDocuments, chain: evmChain,
8711
- transactionId: evmOutcome.transactionSignature,
8712
- rebroadcastable: false,
8713
- confirmation: { state: 'unknown', reason: evmOutcome.reason },
8714
- };
8715
- }
8716
- else if (curTx.serializedTransaction) {
8258
+ if (curTx.serializedTransaction) {
8717
8259
  if (!SOLANA_CHAIN_TAGS.has(workerChain)) {
8718
8260
  throw new Error(`The write response reported execution chain "${workerChain}" for a Solana transaction. ` +
8719
8261
  'Nothing was signed or submitted.');
8720
8262
  }
8721
8263
  const solanaChain = workerChain;
8722
- const { handlePreBuiltTransaction } = await Promise.resolve().then(function () { return require('./solana-operations-XjBhPOnu.js'); });
8264
+ const { handlePreBuiltTransaction } = await Promise.resolve().then(function () { return require('./solana-operations-uN89eqO2.js'); });
8723
8265
  const solanaOutcome = await handlePreBuiltTransaction(curTx, authProvider, options, expectedWritePaths);
8724
8266
  // `shouldSubmitTx: false` signed WITHOUT sending — no signature exists,
8725
8267
  // and there is nothing to mirror, so no synchronization is attempted.
@@ -8753,7 +8295,7 @@ async function setMany(many, options) {
8753
8295
  };
8754
8296
  }
8755
8297
  else {
8756
- throw new Error('Unsupported 202 transaction shape: expected serializedTransaction or evmTransaction');
8298
+ throw new Error('Unsupported 202 transaction shape: expected serializedTransaction');
8757
8299
  }
8758
8300
  }
8759
8301
  else if (setResponse.status === 200) {
@@ -8774,7 +8316,7 @@ async function setMany(many, options) {
8774
8316
  observation: observationFromDirectCommit(documents.map(d => d.destinationPath), receipt === null || receipt === void 0 ? void 0 : receipt.observation),
8775
8317
  // A worker predating the batch receipt reports no lane. Say so rather
8776
8318
  // than inventing one — and never discard a committed write's receipt.
8777
- chain: ((_p = readWorkerChainTag(receipt)) !== null && _p !== void 0 ? _p : 'unknown'),
8319
+ chain: ((_l = readWorkerChainTag(receipt)) !== null && _l !== void 0 ? _l : 'unknown'),
8778
8320
  transactionId: typeof rawTransactionId === 'string' && rawTransactionId.length > 0 ? rawTransactionId : null,
8779
8321
  };
8780
8322
  }
@@ -8785,18 +8327,6 @@ async function setMany(many, options) {
8785
8327
  catch (error) {
8786
8328
  throw error;
8787
8329
  }
8788
- // EVM onchain write: hand the worker's pre-built EIP-1559 tx to the EVM auth
8789
- // provider, which eth_sendTransaction-s it (the wallet signs + submits in one
8790
- // step). Mirrors handlePreBuiltTransaction's shape but routes through the EVM
8791
- // slot of runTransaction (Solana slot undefined). shouldSubmitTx is honored by
8792
- // the provider itself.
8793
- async function handleEvmTransaction(evmTransaction, authProvider, options) {
8794
- const result = await authProvider.runTransaction(evmTransaction, undefined, options);
8795
- if ((result === null || result === void 0 ? void 0 : result.lane) !== 'evm') {
8796
- throw new Error('The EVM auth provider returned a non-EVM transaction outcome');
8797
- }
8798
- return result;
8799
- }
8800
8330
  }
8801
8331
  /**
8802
8332
  * Extract the document/collection path from a cache key. Keys are
@@ -9050,7 +8580,6 @@ var operations = /*#__PURE__*/Object.freeze({
9050
8580
  const DEFAULT_TIMEOUT_MS = 60000;
9051
8581
  const DEFAULT_MAX_ATTEMPTS = 20;
9052
8582
  const DEFAULT_POLL_INTERVAL_MS = 3000;
9053
- const DEFAULT_MIN_REBROADCAST_INTERVAL_MS = 15000;
9054
8583
  /** Mirror read after a late confirmation. No settle delay: the tx already landed. */
9055
8584
  const RECONCILE_MIRROR_SETTLE_MS = 0;
9056
8585
  function errorText(error) {
@@ -9060,12 +8589,6 @@ function errorText(error) {
9060
8589
  function isSolanaSubmitted(receipt) {
9061
8590
  return receipt.status === 'submitted' && 'signedTransaction' in receipt;
9062
8591
  }
9063
- function isEvmFencedSubmitted(receipt) {
9064
- return receipt.status === 'submitted' && 'fence' in receipt && !('signedTransaction' in receipt);
9065
- }
9066
- function isEvmHashKnownSubmitted(receipt) {
9067
- return receipt.status === 'submitted' && receipt.rebroadcastable === false;
9068
- }
9069
8592
  /**
9070
8593
  * The Solana execution lane a client config REQUIRES, or `null` when the config
9071
8594
  * carries no constraint. Only a positive contradiction rejects a receipt — an
@@ -9090,7 +8613,6 @@ function requiredSolanaChain(config) {
9090
8613
  * a global re-`init()` could otherwise poll the wrong app's endpoints entirely.
9091
8614
  */
9092
8615
  function assertReceiptMatchesContext(receipt, config) {
9093
- var _a;
9094
8616
  if (!receipt.appId || typeof receipt.appId !== 'string') {
9095
8617
  throw new Error('This write receipt carries no appId and cannot be reconciled.');
9096
8618
  }
@@ -9103,22 +8625,6 @@ function assertReceiptMatchesContext(receipt, config) {
9103
8625
  if (required && required !== receipt.chain) {
9104
8626
  throw new Error(`This write receipt ran on "${receipt.chain}" but the bound client targets "${required}".`);
9105
8627
  }
9106
- return;
9107
- }
9108
- const fence = receipt.fence;
9109
- if (fence && typeof fence.chainId === 'number') {
9110
- const evm = config.evmWalletConfig;
9111
- const configured = new Set();
9112
- if (evm && typeof evm.chainId === 'number')
9113
- configured.add(evm.chainId);
9114
- for (const id of Object.keys((_a = evm === null || evm === void 0 ? void 0 : evm.runtimeAddresses) !== null && _a !== void 0 ? _a : {})) {
9115
- const parsed = Number(id);
9116
- if (Number.isSafeInteger(parsed))
9117
- configured.add(parsed);
9118
- }
9119
- if (configured.size > 0 && !configured.has(fence.chainId)) {
9120
- throw new Error(`This write receipt ran on EVM chain ${fence.chainId}, which the bound client does not configure.`);
9121
- }
9122
8628
  }
9123
8629
  }
9124
8630
  function stillSubmitted(receipt, reason) {
@@ -9235,67 +8741,18 @@ async function reconcileSolana(receipt, config, options) {
9235
8741
  };
9236
8742
  }
9237
8743
  /**
9238
- * EVM reconciliation runs through the provider's own transport, so a wallet
9239
- * client reconciles with its own identity and RPC. There is deliberately NO
9240
- * EVM retry-safe terminal state: nonce advancement is not proof the write did
9241
- * not execute, and plain JSON-RPC offers no transaction-by-sender-and-nonce
9242
- * lookup, so a `submitted` EVM receipt either confirms or stays `submitted`.
9243
- */
9244
- async function reconcileEvm(receipt, provider, options) {
9245
- if (!provider || typeof provider.reconcileEvmTransaction !== 'function') {
9246
- return stillSubmitted(receipt, 'no EVM reconciliation transport is available on the bound auth provider');
9247
- }
9248
- const fenced = isEvmFencedSubmitted(receipt) ? receipt.fence : undefined;
9249
- const allowRebroadcast = Boolean(fenced) && (options === null || options === void 0 ? void 0 : options.allowRebroadcast) !== false;
9250
- let outcome;
9251
- try {
9252
- outcome = await provider.reconcileEvmTransaction({
9253
- transactionHash: receipt.transactionId,
9254
- fence: fenced,
9255
- allowRebroadcast,
9256
- });
9257
- }
9258
- catch (error) {
9259
- return stillSubmitted(receipt, `EVM reconciliation failed: ${errorText(error)}`);
9260
- }
9261
- if (outcome.state === 'failed') {
9262
- // Landed and reverted: a genuine failure, never `submitted`.
9263
- throw new Error(outcome.reason);
9264
- }
9265
- if (outcome.state === 'confirmed') {
9266
- if (typeof outcome.blockNumber !== 'number') {
9267
- return stillSubmitted(receipt, 'the EVM receipt reported success without a block number, so confirmation could not be stated');
9268
- }
9269
- const confirmed = {
9270
- status: 'confirmed',
9271
- appId: receipt.appId,
9272
- requestedDocuments: receipt.requestedDocuments,
9273
- chain: receipt.chain,
9274
- transactionId: receipt.transactionId,
9275
- blockNumber: outcome.blockNumber,
9276
- mirrorSync: await mirrorFor(receipt, options),
9277
- };
9278
- return confirmed;
9279
- }
9280
- if (outcome.state === 'absent_after_expiry') {
9281
- // Defensive: no EVM lane may report a retry-safe terminal state.
9282
- return stillSubmitted(receipt, 'the EVM transport reported absence, which is not proof an EVM write did not execute');
9283
- }
9284
- return stillSubmitted(receipt, outcome.reason);
9285
- }
9286
- /**
9287
- * Poll the SAME signature/hash a `submitted` receipt carries and return the
8744
+ * Poll the SAME signature a `submitted` receipt carries and return the
9288
8745
  * resulting `SetResult`.
9289
8746
  *
9290
8747
  * - Terminal receipts (`committed`, `confirmed`, `expired_not_landed`,
9291
8748
  * `signed`) are returned unchanged; nothing was left open.
9292
- * - An irreconcilable injected-wallet receipt (`transactionId: null`) is
9293
- * rejected immediately: no identifier exists to poll.
8749
+ * - A `submitted` receipt with no transaction identifier (`transactionId:
8750
+ * null`) is rejected immediately: no identifier exists to poll.
9294
8751
  * - A transaction that landed and FAILED throws, exactly as it would have on
9295
8752
  * the original write.
9296
8753
  */
9297
8754
  async function reconcileSetResult(receipt, options) {
9298
- var _a, _b, _c, _d, _e;
8755
+ var _a, _b;
9299
8756
  if (!receipt || typeof receipt !== 'object' || typeof receipt.status !== 'string') {
9300
8757
  throw new Error('reconcileSetResult requires a write receipt returned by set/setMany.');
9301
8758
  }
@@ -9311,23 +8768,21 @@ async function reconcileSetResult(receipt, options) {
9311
8768
  if (isSolanaSubmitted(receipt)) {
9312
8769
  return reconcileSolana(receipt, config, options);
9313
8770
  }
9314
- const provider = (_e = (_d = (_c = options === null || options === void 0 ? void 0 : options._overrides) === null || _c === void 0 ? void 0 : _c.authProvider) !== null && _d !== void 0 ? _d : config.authProvider) !== null && _e !== void 0 ? _e : null;
9315
- if (isEvmFencedSubmitted(receipt) || isEvmHashKnownSubmitted(receipt)) {
9316
- return reconcileEvm(receipt, provider, options);
9317
- }
8771
+ // Anything else (e.g. a legacy serialized receipt from a retired lane) has no
8772
+ // reconciliation transport any more; say so rather than guessing.
9318
8773
  return stillSubmitted(receipt, 'this receipt shape has no reconciliation lane');
9319
8774
  }
9320
8775
  /**
9321
8776
  * Reconcile repeatedly until the receipt leaves `submitted` or the bound is hit.
9322
8777
  *
9323
8778
  * The bound is mandatory, because some states are permanently non-terminal by
9324
- * design: an unidentified nonce consumer or a permanently underpriced EVM
9325
- * transaction never resolves. On exhaustion (or abort) this returns the LATEST
9326
- * `submitted` receipt with its identifier intact rather than hanging or
9327
- * throwing the identifier away.
8779
+ * design: an RPC that can never observe the signature or the expiry never
8780
+ * resolves. On exhaustion (or abort) this returns the LATEST `submitted`
8781
+ * receipt with its identifier intact rather than hanging or throwing the
8782
+ * identifier away.
9328
8783
  */
9329
8784
  async function waitForSetResult(receipt, options) {
9330
- var _a, _b, _c, _d, _e;
8785
+ var _a, _b, _c, _d;
9331
8786
  if (receipt && typeof receipt === 'object' && receipt.status === 'submitted' && receipt.transactionId === null) {
9332
8787
  // Rejected immediately rather than polled: there is nothing to poll.
9333
8788
  return reconcileSetResult(receipt, options);
@@ -9335,21 +8790,14 @@ async function waitForSetResult(receipt, options) {
9335
8790
  const timeoutMs = (_a = options === null || options === void 0 ? void 0 : options.timeoutMs) !== null && _a !== void 0 ? _a : DEFAULT_TIMEOUT_MS;
9336
8791
  const maxAttempts = (_b = options === null || options === void 0 ? void 0 : options.maxAttempts) !== null && _b !== void 0 ? _b : DEFAULT_MAX_ATTEMPTS;
9337
8792
  const pollIntervalMs = (_c = options === null || options === void 0 ? void 0 : options.pollIntervalMs) !== null && _c !== void 0 ? _c : DEFAULT_POLL_INTERVAL_MS;
9338
- const minRebroadcastIntervalMs = (_d = options === null || options === void 0 ? void 0 : options.minRebroadcastIntervalMs) !== null && _d !== void 0 ? _d : DEFAULT_MIN_REBROADCAST_INTERVAL_MS;
9339
- const rebroadcastPermitted = (options === null || options === void 0 ? void 0 : options.allowRebroadcast) !== false;
9340
8793
  const startedAt = Date.now();
9341
8794
  let current = receipt;
9342
8795
  let attempts = 0;
9343
- let lastRebroadcastAt = -Infinity;
9344
8796
  while (attempts < maxAttempts && Date.now() - startedAt < timeoutMs) {
9345
- if ((_e = options === null || options === void 0 ? void 0 : options.signal) === null || _e === void 0 ? void 0 : _e.aborted)
8797
+ if ((_d = options === null || options === void 0 ? void 0 : options.signal) === null || _d === void 0 ? void 0 : _d.aborted)
9346
8798
  return current;
9347
- const now = Date.now();
9348
- const allowRebroadcast = rebroadcastPermitted && (now - lastRebroadcastAt >= minRebroadcastIntervalMs);
9349
- if (allowRebroadcast)
9350
- lastRebroadcastAt = now;
9351
8799
  attempts++;
9352
- current = await reconcileSetResult(current, Object.assign(Object.assign({}, options), { allowRebroadcast }));
8800
+ current = await reconcileSetResult(current, options);
9353
8801
  if (current.status !== 'submitted')
9354
8802
  return current;
9355
8803
  if (attempts >= maxAttempts)
@@ -10254,7 +9702,7 @@ function toMillis(seconds) {
10254
9702
 
10255
9703
  /** SIWS message creation is async already, so its onchain module can be lazy. */
10256
9704
  async function genSolanaMessage(address, nonce) {
10257
- const implementation = await Promise.resolve().then(function () { return require('./solana-message-DibkzgkZ.js'); });
9705
+ const implementation = await Promise.resolve().then(function () { return require('./solana-message-BecAT47y.js'); });
10258
9706
  return implementation.genSolanaMessage(address, nonce);
10259
9707
  }
10260
9708
 
@@ -10731,8 +10179,6 @@ function defineLiveModule(mod) {
10731
10179
 
10732
10180
  exports.AUTH_CHANGED_CODE = AUTH_CHANGED_CODE;
10733
10181
  exports.AUTH_EXPIRED_CODE = AUTH_EXPIRED_CODE;
10734
- exports.BOUNDED_RUNTIME_SET_DOCUMENTS_ATTESTED_SELECTOR = BOUNDED_RUNTIME_SET_DOCUMENTS_ATTESTED_SELECTOR;
10735
- exports.BOUNDED_RUNTIME_SET_DOCUMENTS_SELECTOR = BOUNDED_RUNTIME_SET_DOCUMENTS_SELECTOR;
10736
10182
  exports.BoundedDeclineError = BoundedDeclineError;
10737
10183
  exports.DECLINE_EVENT_NAME = DECLINE_EVENT_NAME;
10738
10184
  exports.DEFAULT_QUERY_POLL_INTERVAL_MS = DEFAULT_QUERY_POLL_INTERVAL_MS;
@@ -10749,8 +10195,6 @@ exports.SessionEnvironmentError = SessionEnvironmentError;
10749
10195
  exports.UNSUPPORTED_ENVIRONMENT_CODE = UNSUPPORTED_ENVIRONMENT_CODE;
10750
10196
  exports.WebSessionManager = WebSessionManager;
10751
10197
  exports.aggregate = aggregate;
10752
- exports.assertCanonicalBoundedRuntimeWriteCalldata = assertCanonicalBoundedRuntimeWriteCalldata;
10753
- exports.assertEvmTransactionMatchesWrite = assertEvmTransactionMatchesWrite;
10754
10198
  exports.bufferExports = bufferExports;
10755
10199
  exports.canonicalizeArgs = canonicalizeArgs;
10756
10200
  exports.canonicalizeResult = canonicalizeResult;
@@ -10819,4 +10263,4 @@ exports.toMillis = toMillis;
10819
10263
  exports.toSeconds = toSeconds;
10820
10264
  exports.waitForSetResult = waitForSetResult;
10821
10265
  exports.withEffects = withEffects;
10822
- //# sourceMappingURL=index-C9w7qQpj.js.map
10266
+ //# sourceMappingURL=index-CqTl6vHg.js.map