@bounded-sh/core 0.0.118 → 0.0.119

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 (36) hide show
  1. package/dist/client/operations.d.ts +19 -1
  2. package/dist/client/solana-operations.d.ts +6 -0
  3. package/dist/{index-l9LI3y1q.js → index-D7-5ecyu.js} +279 -217
  4. package/dist/index-D7-5ecyu.js.map +1 -0
  5. package/dist/{index-BXfRRAUZ.mjs → index-D93TEYGf.mjs} +279 -218
  6. package/dist/index-D93TEYGf.mjs.map +1 -0
  7. package/dist/index.d.ts +1 -1
  8. package/dist/index.js +2 -1
  9. package/dist/index.js.map +1 -1
  10. package/dist/index.mjs +1 -1
  11. package/dist/{mirror-sync-DoH9ewTo.mjs → mirror-sync-DPMtQC3A.mjs} +2 -2
  12. package/dist/{mirror-sync-DoH9ewTo.mjs.map → mirror-sync-DPMtQC3A.mjs.map} +1 -1
  13. package/dist/{mirror-sync-DJVm0KKu.js → mirror-sync-DzbDh6G_.js} +2 -2
  14. package/dist/{mirror-sync-DJVm0KKu.js.map → mirror-sync-DzbDh6G_.js.map} +1 -1
  15. package/dist/{realtime-store-kZMPgwVB.js → realtime-store-C2Jz8YM0.js} +2 -2
  16. package/dist/{realtime-store-kZMPgwVB.js.map → realtime-store-C2Jz8YM0.js.map} +1 -1
  17. package/dist/{realtime-store-BreUReSo.mjs → realtime-store-FObAdw-J.mjs} +2 -2
  18. package/dist/{realtime-store-BreUReSo.mjs.map → realtime-store-FObAdw-J.mjs.map} +1 -1
  19. package/dist/{solana-message-HkOoUz8z.js → solana-message-CPotom18.js} +2 -2
  20. package/dist/{solana-message-HkOoUz8z.js.map → solana-message-CPotom18.js.map} +1 -1
  21. package/dist/{solana-message-CjI0h27k.mjs → solana-message-DqKp-y53.mjs} +2 -2
  22. package/dist/{solana-message-CjI0h27k.mjs.map → solana-message-DqKp-y53.mjs.map} +1 -1
  23. package/dist/{solana-operations-DFohVGz6.js → solana-operations-DsT1303T.js} +26 -13
  24. package/dist/solana-operations-DsT1303T.js.map +1 -0
  25. package/dist/{solana-operations-CD6pks4-.mjs → solana-operations-cwcuTNyk.mjs} +26 -14
  26. package/dist/solana-operations-cwcuTNyk.mjs.map +1 -0
  27. package/dist/{solana-v1-operations-ewIzFDeY.mjs → solana-v1-operations-Jzg3uAot.mjs} +3 -3
  28. package/dist/{solana-v1-operations-ewIzFDeY.mjs.map → solana-v1-operations-Jzg3uAot.mjs.map} +1 -1
  29. package/dist/{solana-v1-operations-bhDjo-5U.js → solana-v1-operations-qj0WA2tF.js} +3 -3
  30. package/dist/{solana-v1-operations-bhDjo-5U.js.map → solana-v1-operations-qj0WA2tF.js.map} +1 -1
  31. package/dist/types.d.ts +14 -0
  32. package/package.json +1 -1
  33. package/dist/index-BXfRRAUZ.mjs.map +0 -1
  34. package/dist/index-l9LI3y1q.js.map +0 -1
  35. package/dist/solana-operations-CD6pks4-.mjs.map +0 -1
  36. package/dist/solana-operations-DFohVGz6.js.map +0 -1
@@ -4305,7 +4305,7 @@ class ServerSessionManager {
4305
4305
  const sessionConfig = (_a = this.sessionConfig) !== null && _a !== void 0 ? _a : undefined;
4306
4306
  /* fetch nonce from auth API (bound to the snapshotted app+issuer) */
4307
4307
  const nonce = await genAuthNonce(sessionConfig);
4308
- const { genSolanaMessage } = await import('./solana-message-CjI0h27k.mjs');
4308
+ const { genSolanaMessage } = await import('./solana-message-DqKp-y53.mjs');
4309
4309
  const message = await genSolanaMessage(address, nonce, sessionConfig === null || sessionConfig === void 0 ? void 0 : sessionConfig.appId);
4310
4310
  /* sign the message */
4311
4311
  const sigBytes = nacl.sign.detached(new TextEncoder().encode(message), kp.secretKey);
@@ -7677,7 +7677,7 @@ async function doReconnectWithNewAuth() {
7677
7677
  console.warn('[WS v2] Failed to clear HTTP read cache on auth change:', error);
7678
7678
  }
7679
7679
  try {
7680
- const { reconnectRealtimeStoreWithNewAuth } = await import('./realtime-store-BreUReSo.mjs');
7680
+ const { reconnectRealtimeStoreWithNewAuth } = await import('./realtime-store-FObAdw-J.mjs');
7681
7681
  await reconnectRealtimeStoreWithNewAuth();
7682
7682
  }
7683
7683
  catch (error) {
@@ -8896,7 +8896,7 @@ function buildRequestedDocuments(documents) {
8896
8896
  /** Best-effort readback, including a failure to load its lazy implementation. */
8897
8897
  async function attemptMirrorSync(paths, options, transactionSignature) {
8898
8898
  try {
8899
- const mirror = await import('./mirror-sync-DoH9ewTo.mjs');
8899
+ const mirror = await import('./mirror-sync-DPMtQC3A.mjs');
8900
8900
  return await mirror.attemptMirrorSync(paths, options, transactionSignature);
8901
8901
  }
8902
8902
  catch (error) {
@@ -8994,237 +8994,280 @@ async function set(path, document, options) {
8994
8994
  * state appears only under `observation`/`mirrorSync` once actually observed.
8995
8995
  */
8996
8996
  async function setMany(many, options) {
8997
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
8998
- // Returns the data that was set, or undefined if the document was already set.
8999
- try {
9000
- // A server WalletClient threads its immutable config snapshot; the default
9001
- // path reads the mutable process-global init() config. This keeps the app-id
9002
- // bound into an on-chain 202 write (Solana/offchain) on the wallet
9003
- // client's original app after a later global init() (CTA-05).
9004
- 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();
9005
- 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;
9006
- if (!authProvider) {
9007
- throw new Error('Auth provider not initialized');
9008
- }
9009
- let documents = [];
9010
- const pathsToInvalidate = new Set();
9011
- for (const { path, document: documentWithReservedFields } of many) {
9012
- // for setting, we should remove any pieces of the document that start with '_' as they are internal and shouldn't be updated. The API would block it if it is one of the reserved ones
9013
- let document = documentWithReservedFields;
9014
- if (documentWithReservedFields) {
9015
- document = Object.fromEntries(Object.entries(documentWithReservedFields).filter(([key]) => !key.startsWith('_')));
9016
- }
9017
- const normalizedPath = path.startsWith("/") ? path.slice(1) : path;
9018
- pathsToInvalidate.add(normalizedPath);
9019
- const pathIsDocument = normalizedPath.split("/").length % 2 === 0;
9020
- let curItemId = "";
9021
- if (pathIsDocument) {
9022
- curItemId = normalizedPath.split("/").pop() ? normalizedPath.split("/").pop() : "";
9023
- }
9024
- else {
9025
- curItemId = Math.random().toString(36).slice(2).substring(0, 12);
9026
- }
9027
- // if the path is a document, we need to append the document id to the path
9028
- const collectionPath = pathIsDocument ? normalizedPath.split("/").slice(0, -1).join("/") : normalizedPath;
9029
- pathsToInvalidate.add(collectionPath);
9030
- let destinationPath = collectionPath;
9031
- if (curItemId && curItemId.length > 0) {
9032
- destinationPath = `${destinationPath}/${curItemId}`;
9033
- }
9034
- documents.push({ destinationPath, document });
9035
- }
9036
- let setResponse;
8997
+ var _a, _b, _c, _d, _e, _f;
8998
+ // A server WalletClient threads its immutable config snapshot; the default
8999
+ // path reads the mutable process-global init() config. This keeps the app-id
9000
+ // bound into an on-chain 202 write (Solana/offchain) on the wallet
9001
+ // client's original app after a later global init() (CTA-05).
9002
+ 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();
9003
+ 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;
9004
+ if (!authProvider) {
9005
+ throw new Error('Auth provider not initialized');
9006
+ }
9007
+ const { documents, pathsToInvalidate } = normalizeWriteBatch(many);
9008
+ // A grant lane's credential is single-use, so its write is built exactly once, and its signer
9009
+ // is prepared the way it always was: inside the approval.
9010
+ const grantLane = (_e = options === null || options === void 0 ? void 0 : options._overrides) === null || _e === void 0 ? void 0 : _e._grantLane;
9011
+ if ((options === null || options === void 0 ? void 0 : options.onchain) && !grantLane) {
9012
+ // The caller knows the wallet will sign: the signer is prepared before the first build, so a
9013
+ // first-time emailed code never runs inside a transaction's lifetime and no build is wasted.
9037
9014
  try {
9038
- // SIMD-0385: tell the worker which Solana transaction formats this client
9039
- // can sign, so it builds v1 only for a client that can complete it.
9040
- const clientTransactionVersions = await resolveClientTransactionVersions(authProvider);
9041
- setResponse = await makeApiRequest('PUT', `items`, { documents, clientTransactionVersions }, options === null || options === void 0 ? void 0 : options._overrides);
9015
+ await ((_f = authProvider.prepareToSign) === null || _f === void 0 ? void 0 : _f.call(authProvider));
9042
9016
  }
9043
9017
  catch (error) {
9044
- if ((error === null || error === void 0 ? void 0 : error.statusCode) === 402 && (error === null || error === void 0 ? void 0 : error.error) === 'INSUFFICIENT_BALANCE') {
9045
- const deficitLamports = Number((_e = error.deficitLamports) !== null && _e !== void 0 ? _e : 0);
9046
- const deficitSol = Number((_f = error.deficitSol) !== null && _f !== void 0 ? _f : deficitLamports / 1000000000);
9047
- throw markWriteNotApplied(new InsufficientBalanceError(String((_g = error.address) !== null && _g !== void 0 ? _g : ''), Number((_h = error.balanceLamports) !== null && _h !== void 0 ? _h : 0), Number((_j = error.estimatedCostLamports) !== null && _j !== void 0 ? _j : 0), deficitLamports, deficitSol), 'before_broadcast');
9048
- }
9049
- // The server answered and refused the write (a rule or invariant denial, a bad request, no
9050
- // session, a rate limit): nothing was built, signed or committed. A network failure, a 5xx,
9051
- // a 408 or a 499 may follow a commit the response never reported, so those stay untagged.
9052
- if (DEFINITIVE_WRITE_REFUSAL_STATUSES.has(Number(error === null || error === void 0 ? void 0 : error.statusCode))) {
9053
- throw markWriteNotApplied(error, 'before_broadcast');
9054
- }
9055
- throw error;
9018
+ throw markWriteNotApplied(error, 'before_broadcast');
9056
9019
  }
9020
+ }
9021
+ // Each reason to build again is spent once: the wallet's own ceremony (the build it ran beside is
9022
+ // dying), and a send refused because the blockhash expired (a long pause on the approve card).
9023
+ const rebuilds = { ceremony: !grantLane, expiry: !grantLane };
9024
+ for (;;) {
9025
+ const setResponse = await requestWrite(documents, authProvider, options);
9057
9026
  // Invalidate caches and pending requests for affected paths
9058
9027
  pathsToInvalidate.forEach(path => {
9059
9028
  clearCacheByPrefix(path);
9060
9029
  });
9061
- if (setResponse.status === 202) {
9062
- // This means that the document needs to be set on-chain (or signed for offchain),
9063
- // the API did nothing and gave us the required info to run this transaction.
9064
- // Until something is sent, every failure below is definitively not applied.
9065
- let sending = false;
9030
+ if (setResponse.status === 200)
9031
+ return directCommitResult(setResponse, documents);
9032
+ if (setResponse.status !== 202)
9033
+ throw new Error(`Failed to set document: ${setResponse}`);
9034
+ const outcome = await completePreparedWrite(setResponse, documents, config, authProvider, options, rebuilds);
9035
+ if (!isRebuild(outcome))
9036
+ return outcome;
9037
+ rebuilds[outcome.rebuild] = false;
9038
+ }
9039
+ }
9040
+ /** The caller's batch as the worker takes it, plus every read-cache prefix the write touches. */
9041
+ function normalizeWriteBatch(many) {
9042
+ const documents = [];
9043
+ const pathsToInvalidate = new Set();
9044
+ for (const { path, document: documentWithReservedFields } of many) {
9045
+ // for setting, we should remove any pieces of the document that start with '_' as they are internal and shouldn't be updated. The API would block it if it is one of the reserved ones
9046
+ let document = documentWithReservedFields;
9047
+ if (documentWithReservedFields) {
9048
+ document = Object.fromEntries(Object.entries(documentWithReservedFields).filter(([key]) => !key.startsWith('_')));
9049
+ }
9050
+ const normalizedPath = path.startsWith("/") ? path.slice(1) : path;
9051
+ pathsToInvalidate.add(normalizedPath);
9052
+ const pathIsDocument = normalizedPath.split("/").length % 2 === 0;
9053
+ let curItemId = "";
9054
+ if (pathIsDocument) {
9055
+ curItemId = normalizedPath.split("/").pop() ? normalizedPath.split("/").pop() : "";
9056
+ }
9057
+ else {
9058
+ curItemId = Math.random().toString(36).slice(2).substring(0, 12);
9059
+ }
9060
+ // if the path is a document, we need to append the document id to the path
9061
+ const collectionPath = pathIsDocument ? normalizedPath.split("/").slice(0, -1).join("/") : normalizedPath;
9062
+ pathsToInvalidate.add(collectionPath);
9063
+ let destinationPath = collectionPath;
9064
+ if (curItemId && curItemId.length > 0) {
9065
+ destinationPath = `${destinationPath}/${curItemId}`;
9066
+ }
9067
+ documents.push({ destinationPath, document });
9068
+ }
9069
+ return { documents, pathsToInvalidate };
9070
+ }
9071
+ /** The write PUT: a direct commit (200), a transaction to sign (202), or a definitive refusal. */
9072
+ async function requestWrite(documents, authProvider, options) {
9073
+ var _a, _b, _c, _d, _e;
9074
+ try {
9075
+ // SIMD-0385: tell the worker which Solana transaction formats this client
9076
+ // can sign, so it builds v1 only for a client that can complete it.
9077
+ const clientTransactionVersions = await resolveClientTransactionVersions(authProvider);
9078
+ return await makeApiRequest('PUT', `items`, { documents, clientTransactionVersions }, options === null || options === void 0 ? void 0 : options._overrides);
9079
+ }
9080
+ catch (error) {
9081
+ if ((error === null || error === void 0 ? void 0 : error.statusCode) === 402 && (error === null || error === void 0 ? void 0 : error.error) === 'INSUFFICIENT_BALANCE') {
9082
+ const deficitLamports = Number((_a = error.deficitLamports) !== null && _a !== void 0 ? _a : 0);
9083
+ const deficitSol = Number((_b = error.deficitSol) !== null && _b !== void 0 ? _b : deficitLamports / 1000000000);
9084
+ throw markWriteNotApplied(new InsufficientBalanceError(String((_c = error.address) !== null && _c !== void 0 ? _c : ''), Number((_d = error.balanceLamports) !== null && _d !== void 0 ? _d : 0), Number((_e = error.estimatedCostLamports) !== null && _e !== void 0 ? _e : 0), deficitLamports, deficitSol), 'before_broadcast');
9085
+ }
9086
+ // The server answered and refused the write (a rule or invariant denial, a bad request, no
9087
+ // session, a rate limit): nothing was built, signed or committed. A network failure, a 5xx,
9088
+ // a 408 or a 499 may follow a commit the response never reported, so those stay untagged.
9089
+ if (DEFINITIVE_WRITE_REFUSAL_STATUSES.has(Number(error === null || error === void 0 ? void 0 : error.statusCode))) {
9090
+ throw markWriteNotApplied(error, 'before_broadcast');
9091
+ }
9092
+ throw error;
9093
+ }
9094
+ }
9095
+ function isRebuild(outcome) {
9096
+ return 'rebuild' in outcome;
9097
+ }
9098
+ /**
9099
+ * Finish a 202: the worker built the transaction (or the poofnet approval) and did nothing
9100
+ * else; the wallet signs it here and, on a real chain, it is broadcast. Until something is
9101
+ * sent, every failure is definitively not applied. `rebuilds` says which reasons to build
9102
+ * again are still open.
9103
+ */
9104
+ async function completePreparedWrite(setResponse, documents, config, authProvider, options, rebuilds) {
9105
+ var _a, _b, _c;
9106
+ let sending = false;
9107
+ try {
9108
+ const { transactions, offchainTransaction } = setResponse.data;
9109
+ // Handle offchain transaction flow (for 'offchain' protocol apps)
9110
+ if (offchainTransaction && Array.isArray(transactions) && transactions.length > 0) {
9111
+ throw new Error('Ambiguous write response mixes offchain and onchain transaction targets');
9112
+ }
9113
+ if (offchainTransaction) {
9114
+ // Offchain signing is retired: no server mints this envelope any more
9115
+ // (the realtime worker commits poofnet writes directly). Fail loudly
9116
+ // rather than silently ignoring a payload the caller was asked to sign.
9117
+ throw new Error('Unsupported 202 transaction shape: offchain signing is retired');
9118
+ }
9119
+ // Handle Solana on-chain transaction flow
9120
+ if (!Array.isArray(transactions) || transactions.length !== 1) {
9121
+ throw new Error(`Expected exactly one on-chain transaction, received ${Array.isArray(transactions) ? transactions.length : 0}`);
9122
+ }
9123
+ const curTx = transactions[0];
9124
+ // The EVM onchain data plane is retired: no worker mints an EVM 202 any
9125
+ // more. A payload that still carries one is an unexpected response and
9126
+ // fails loudly BEFORE anything is signed - never silently ignored.
9127
+ if ((curTx === null || curTx === void 0 ? void 0 : curTx.evmTransaction) != null) {
9128
+ throw new Error('Unsupported 202 transaction shape: the write response carried an evmTransaction, ' +
9129
+ 'but EVM onchain writes are no longer supported. Nothing was signed or submitted.');
9130
+ }
9131
+ const hasSerializedSolanaTarget = (curTx === null || curTx === void 0 ? void 0 : curTx.serializedTransaction) != null;
9132
+ const hasBuiltSolanaTarget = (curTx === null || curTx === void 0 ? void 0 : curTx.transactionArgs) != null || (curTx === null || curTx === void 0 ? void 0 : curTx.remainingAccounts) != null ||
9133
+ (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;
9134
+ if (hasSerializedSolanaTarget && hasBuiltSolanaTarget) {
9135
+ throw new Error('Ambiguous on-chain write response mixes Solana transaction target formats');
9136
+ }
9137
+ // All requested paths (writes AND deletes), in request order. Used for the
9138
+ // post-confirm mirror read-back, which correlates every requested path.
9139
+ // The pre-sign validation derives its own full expected intent from
9140
+ // `documents` (see below) and needs nothing from this list.
9141
+ const requestedPaths = documents.map(d => d.destinationPath);
9142
+ const requestedDocuments = buildRequestedDocuments(documents);
9143
+ const appId = config.appId;
9144
+ // The lane comes verbatim from the worker, and is read BEFORE anything is
9145
+ // signed or submitted: a missing tag fails closed while nothing has been
9146
+ // broadcast, instead of stranding a landed transaction with no receipt.
9147
+ const workerChain = readWorkerChainTag((_a = setResponse.data) === null || _a === void 0 ? void 0 : _a.receipt, setResponse.data, curTx);
9148
+ if (!workerChain) {
9149
+ throw new Error('The write response carried no execution-chain tag, so this receipt could not state where the write ran. ' +
9150
+ 'Nothing was signed or submitted.');
9151
+ }
9152
+ const grantLane = (_b = options === null || options === void 0 ? void 0 : options._overrides) === null || _b === void 0 ? void 0 : _b._grantLane;
9153
+ grantLane === null || grantLane === void 0 ? void 0 : grantLane.assertLane(workerChain);
9154
+ // The wallet's own ceremony runs now, before it sees a transaction: a hosted embedded
9155
+ // wallet whose 24-hour signing session has lapsed collects its emailed code here, and that
9156
+ // outlives the blockhash the worker just minted. A ceremony that ran means this build is
9157
+ // already dying, so the write is built again and the wallet signs the fresh one in one click.
9158
+ // (A caller that passed `onchain` prepared the signer before the build, so this normally
9159
+ // answers 'ready' at once. It runs the ceremony here only when that preparation could not
9160
+ // reach the signer; the build it then replaces is left to expire unsigned.)
9161
+ if (rebuilds.ceremony && await ((_c = authProvider.prepareToSign) === null || _c === void 0 ? void 0 : _c.call(authProvider)) === 'established')
9162
+ return { rebuild: 'ceremony' };
9163
+ if (workerChain === 'realtime_offchain') {
9164
+ // Poofnet: the wallet signs the worker's unsendable approval message and
9165
+ // the worker verifies and commits it. Nothing is submitted to any chain.
9166
+ if (typeof curTx.serializedTransaction !== 'string' || typeof curTx.poofnetIntentId !== 'string') {
9167
+ throw new Error('Unsupported 202 transaction shape: a poofnet write needs serializedTransaction and poofnetIntentId');
9168
+ }
9169
+ const { signPoofnetTransaction, buildExpectedWriteIntent } = await import('./solana-operations-cwcuTNyk.mjs');
9170
+ const signedTransaction = await signPoofnetTransaction(curTx.serializedTransaction, authProvider, options, buildExpectedWriteIntent(documents));
9171
+ // Signing-only, exactly as on a real chain: signed and NOT committed.
9172
+ if ((options === null || options === void 0 ? void 0 : options.shouldSubmitTx) === false) {
9173
+ return {
9174
+ status: 'signed', appId, requestedDocuments: buildRequestedDocuments(documents),
9175
+ chain: 'realtime_offchain', transactionId: null, signedTransaction,
9176
+ poofnetIntentId: curTx.poofnetIntentId,
9177
+ };
9178
+ }
9179
+ // A grant lane's first credential is spent by the PUT that built this approval, so the
9180
+ // commit's is minted now, before `sending`: failing to mint sends nothing.
9181
+ const commitHeaders = await (grantLane === null || grantLane === void 0 ? void 0 : grantLane.commitHeaders());
9182
+ // The commit PUT is the one ambiguous step of this lane: a lost response may follow a
9183
+ // commit, so a transport failure or a 5xx stays untagged (read the path back). A 4xx is
9184
+ // realtime stating it committed nothing (the intent expired or was taken, the signer did
9185
+ // not match, a rule refused it), as for the first PUT. 408 and 499 are a proxy's words,
9186
+ // not realtime's, and may follow a commit, so they stay ambiguous too.
9187
+ sending = true;
9188
+ let commitResponse;
9066
9189
  try {
9067
- const { transactions, offchainTransaction } = setResponse.data;
9068
- // Handle offchain transaction flow (for 'offchain' protocol apps)
9069
- if (offchainTransaction && Array.isArray(transactions) && transactions.length > 0) {
9070
- throw new Error('Ambiguous write response mixes offchain and onchain transaction targets');
9071
- }
9072
- if (offchainTransaction) {
9073
- // Offchain signing is retired: no server mints this envelope any more
9074
- // (the realtime worker commits poofnet writes directly). Fail loudly
9075
- // rather than silently ignoring a payload the caller was asked to sign.
9076
- throw new Error('Unsupported 202 transaction shape: offchain signing is retired');
9077
- }
9078
- // Handle Solana on-chain transaction flow
9079
- if (!Array.isArray(transactions) || transactions.length !== 1) {
9080
- throw new Error(`Expected exactly one on-chain transaction, received ${Array.isArray(transactions) ? transactions.length : 0}`);
9081
- }
9082
- const curTx = transactions[0];
9083
- // The EVM onchain data plane is retired: no worker mints an EVM 202 any
9084
- // more. A payload that still carries one is an unexpected response and
9085
- // fails loudly BEFORE anything is signed - never silently ignored.
9086
- if ((curTx === null || curTx === void 0 ? void 0 : curTx.evmTransaction) != null) {
9087
- throw new Error('Unsupported 202 transaction shape: the write response carried an evmTransaction, ' +
9088
- 'but EVM onchain writes are no longer supported. Nothing was signed or submitted.');
9089
- }
9090
- const hasSerializedSolanaTarget = (curTx === null || curTx === void 0 ? void 0 : curTx.serializedTransaction) != null;
9091
- const hasBuiltSolanaTarget = (curTx === null || curTx === void 0 ? void 0 : curTx.transactionArgs) != null || (curTx === null || curTx === void 0 ? void 0 : curTx.remainingAccounts) != null ||
9092
- (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;
9093
- if (hasSerializedSolanaTarget && hasBuiltSolanaTarget) {
9094
- throw new Error('Ambiguous on-chain write response mixes Solana transaction target formats');
9095
- }
9096
- // All requested paths (writes AND deletes), in request order. Used for the
9097
- // post-confirm mirror read-back, which correlates every requested path.
9098
- // The pre-sign validation derives its own full expected intent from
9099
- // `documents` (see below) and needs nothing from this list.
9100
- const requestedPaths = documents.map(d => d.destinationPath);
9101
- const requestedDocuments = buildRequestedDocuments(documents);
9102
- const appId = config.appId;
9103
- // The lane comes verbatim from the worker, and is read BEFORE anything is
9104
- // signed or submitted: a missing tag fails closed while nothing has been
9105
- // broadcast, instead of stranding a landed transaction with no receipt.
9106
- const workerChain = readWorkerChainTag((_k = setResponse.data) === null || _k === void 0 ? void 0 : _k.receipt, setResponse.data, curTx);
9107
- if (!workerChain) {
9108
- throw new Error('The write response carried no execution-chain tag, so this receipt could not state where the write ran. ' +
9109
- 'Nothing was signed or submitted.');
9110
- }
9111
- const grantLane = (_l = options === null || options === void 0 ? void 0 : options._overrides) === null || _l === void 0 ? void 0 : _l._grantLane;
9112
- grantLane === null || grantLane === void 0 ? void 0 : grantLane.assertLane(workerChain);
9113
- if (workerChain === 'realtime_offchain') {
9114
- // Poofnet: the wallet signs the worker's unsendable approval message and
9115
- // the worker verifies and commits it. Nothing is submitted to any chain.
9116
- if (typeof curTx.serializedTransaction !== 'string' || typeof curTx.poofnetIntentId !== 'string') {
9117
- throw new Error('Unsupported 202 transaction shape: a poofnet write needs serializedTransaction and poofnetIntentId');
9118
- }
9119
- const { signPoofnetTransaction, buildExpectedWriteIntent } = await import('./solana-operations-CD6pks4-.mjs');
9120
- const signedTransaction = await signPoofnetTransaction(curTx.serializedTransaction, authProvider, options, buildExpectedWriteIntent(documents));
9121
- // Signing-only, exactly as on a real chain: signed and NOT committed.
9122
- if ((options === null || options === void 0 ? void 0 : options.shouldSubmitTx) === false) {
9123
- return {
9124
- status: 'signed', appId, requestedDocuments: buildRequestedDocuments(documents),
9125
- chain: 'realtime_offchain', transactionId: null, signedTransaction,
9126
- poofnetIntentId: curTx.poofnetIntentId,
9127
- };
9128
- }
9129
- // A grant lane's first credential is spent by the PUT that built this approval, so the
9130
- // commit's is minted now, before `sending`: failing to mint sends nothing.
9131
- const commitHeaders = await (grantLane === null || grantLane === void 0 ? void 0 : grantLane.commitHeaders());
9132
- // The commit PUT is the one ambiguous step of this lane: a lost response may follow a
9133
- // commit, so a transport failure or a 5xx stays untagged (read the path back). A 4xx is
9134
- // realtime stating it committed nothing (the intent expired or was taken, the signer did
9135
- // not match, a rule refused it), as for the first PUT. 408 and 499 are a proxy's words,
9136
- // not realtime's, and may follow a commit, so they stay ambiguous too.
9137
- sending = true;
9138
- let commitResponse;
9139
- try {
9140
- commitResponse = await makeApiRequest('PUT', 'items/signed', { intentId: curTx.poofnetIntentId, signedTransaction }, commitHeaders ? Object.assign(Object.assign({}, options === null || options === void 0 ? void 0 : options._overrides), { _getAuthHeaders: async () => commitHeaders }) : options === null || options === void 0 ? void 0 : options._overrides);
9141
- if (commitResponse.status !== 200) {
9142
- throw Object.assign(new Error(`Poofnet signed write was not committed (status ${commitResponse.status})`), { statusCode: commitResponse.status });
9143
- }
9144
- }
9145
- catch (error) {
9146
- const status = Number(error === null || error === void 0 ? void 0 : error.statusCode);
9147
- throw status >= 400 && status < 500 && status !== 408 && status !== 499 ? markWriteNotApplied(error, 'broadcast_rejected') : error;
9148
- }
9149
- return directCommitResult(commitResponse, documents);
9150
- }
9151
- if (curTx.serializedTransaction) {
9152
- if (!SOLANA_CHAIN_TAGS.has(workerChain)) {
9153
- throw new Error(`The write response reported execution chain "${workerChain}" for a Solana transaction. ` +
9154
- 'Nothing was signed or submitted.');
9155
- }
9156
- const solanaChain = workerChain;
9157
- const { handlePreBuiltTransaction, buildExpectedWriteIntent } = await import('./solana-operations-CD6pks4-.mjs');
9158
- // OA-0001: derive the expected intent from OUR OWN request (the one
9159
- // ground truth a tampered builder response cannot change) so the
9160
- // validator can reject any transaction whose operation semantics
9161
- // diverge from it BEFORE the wallet is asked to sign.
9162
- const expectedIntent = buildExpectedWriteIntent(documents);
9163
- const onBroadcast = options === null || options === void 0 ? void 0 : options.onBroadcast;
9164
- const solanaOutcome = await handlePreBuiltTransaction(curTx, authProvider, options, expectedIntent, onBroadcast && (async (signed) => {
9165
- await onBroadcast({
9166
- status: 'submitted', appId, requestedDocuments, chain: solanaChain,
9167
- transactionId: signed.transactionSignature,
9168
- signedTransaction: signed.signedTransaction,
9169
- fence: signed.fence,
9170
- confirmation: { state: 'unknown', reason: 'about to broadcast' },
9171
- });
9172
- }));
9173
- // Past this point the bytes may be on the network: nothing is tagged here.
9174
- sending = true;
9175
- // `shouldSubmitTx: false` signed WITHOUT sending — no signature exists,
9176
- // and there is nothing to mirror, so no synchronization is attempted.
9177
- if (solanaOutcome.outcome === 'signed') {
9178
- return {
9179
- status: 'signed', appId, requestedDocuments, chain: solanaChain,
9180
- transactionId: null,
9181
- signedTransaction: solanaOutcome.signedTransaction,
9182
- fence: solanaOutcome.fence,
9183
- };
9184
- }
9185
- if (solanaOutcome.outcome === 'submitted') {
9186
- return {
9187
- status: 'submitted', appId, requestedDocuments, chain: solanaChain,
9188
- transactionId: solanaOutcome.transactionSignature,
9189
- signedTransaction: solanaOutcome.signedTransaction,
9190
- fence: solanaOutcome.fence,
9191
- confirmation: { state: 'unknown', reason: solanaOutcome.reason },
9192
- };
9193
- }
9194
- // Confirmed: the receipt is already complete, so the mirror read is a
9195
- // best-effort enrichment reported in `mirrorSync`, never a rejection.
9196
- const mirrorSync = grantLane
9197
- ? { observed: false, reason: 'not attempted: a venue grant authorizes only the write' }
9198
- : await attemptMirrorSync(requestedPaths, Object.assign(Object.assign({}, options), { _overrides: Object.assign(Object.assign({}, options === null || options === void 0 ? void 0 : options._overrides), { _config: config }) }), solanaOutcome.transactionSignature);
9199
- return {
9200
- status: 'confirmed', appId, requestedDocuments, chain: solanaChain,
9201
- transactionId: solanaOutcome.transactionSignature,
9202
- signedTransaction: solanaOutcome.signedTransaction,
9203
- fence: solanaOutcome.fence,
9204
- confirmationContextSlot: solanaOutcome.confirmationContextSlot,
9205
- mirrorSync,
9206
- };
9207
- }
9208
- else {
9209
- throw new Error('Unsupported 202 transaction shape: expected serializedTransaction');
9190
+ commitResponse = await makeApiRequest('PUT', 'items/signed', { intentId: curTx.poofnetIntentId, signedTransaction }, commitHeaders ? Object.assign(Object.assign({}, options === null || options === void 0 ? void 0 : options._overrides), { _getAuthHeaders: async () => commitHeaders }) : options === null || options === void 0 ? void 0 : options._overrides);
9191
+ if (commitResponse.status !== 200) {
9192
+ throw Object.assign(new Error(`Poofnet signed write was not committed (status ${commitResponse.status})`), { statusCode: commitResponse.status });
9210
9193
  }
9211
9194
  }
9212
9195
  catch (error) {
9213
- // The Solana lane tags its own broadcast and on-chain failures; anything
9214
- // untagged from it, and every poofnet step before the commit PUT, failed
9215
- // before a single byte was sent.
9216
- throw sending ? error : markWriteNotApplied(error, 'before_broadcast');
9196
+ const status = Number(error === null || error === void 0 ? void 0 : error.statusCode);
9197
+ throw status >= 400 && status < 500 && status !== 408 && status !== 499 ? markWriteNotApplied(error, 'broadcast_rejected') : error;
9217
9198
  }
9199
+ return directCommitResult(commitResponse, documents);
9218
9200
  }
9219
- else if (setResponse.status === 200) {
9220
- return directCommitResult(setResponse, documents);
9201
+ if (curTx.serializedTransaction) {
9202
+ if (!SOLANA_CHAIN_TAGS.has(workerChain)) {
9203
+ throw new Error(`The write response reported execution chain "${workerChain}" for a Solana transaction. ` +
9204
+ 'Nothing was signed or submitted.');
9205
+ }
9206
+ const solanaChain = workerChain;
9207
+ const { handlePreBuiltTransaction, buildExpectedWriteIntent } = await import('./solana-operations-cwcuTNyk.mjs');
9208
+ // OA-0001: derive the expected intent from OUR OWN request (the one
9209
+ // ground truth a tampered builder response cannot change) so the
9210
+ // validator can reject any transaction whose operation semantics
9211
+ // diverge from it BEFORE the wallet is asked to sign.
9212
+ const expectedIntent = buildExpectedWriteIntent(documents);
9213
+ const onBroadcast = options === null || options === void 0 ? void 0 : options.onBroadcast;
9214
+ const solanaOutcome = await handlePreBuiltTransaction(curTx, authProvider, options, expectedIntent, onBroadcast && (async (signed) => {
9215
+ await onBroadcast({
9216
+ status: 'submitted', appId, requestedDocuments, chain: solanaChain,
9217
+ transactionId: signed.transactionSignature,
9218
+ signedTransaction: signed.signedTransaction,
9219
+ fence: signed.fence,
9220
+ confirmation: { state: 'unknown', reason: 'about to broadcast' },
9221
+ });
9222
+ }));
9223
+ // Past this point the bytes may be on the network: nothing is tagged here.
9224
+ sending = true;
9225
+ // `shouldSubmitTx: false` signed WITHOUT sending — no signature exists,
9226
+ // and there is nothing to mirror, so no synchronization is attempted.
9227
+ if (solanaOutcome.outcome === 'signed') {
9228
+ return {
9229
+ status: 'signed', appId, requestedDocuments, chain: solanaChain,
9230
+ transactionId: null,
9231
+ signedTransaction: solanaOutcome.signedTransaction,
9232
+ fence: solanaOutcome.fence,
9233
+ };
9234
+ }
9235
+ if (solanaOutcome.outcome === 'submitted') {
9236
+ return {
9237
+ status: 'submitted', appId, requestedDocuments, chain: solanaChain,
9238
+ transactionId: solanaOutcome.transactionSignature,
9239
+ signedTransaction: solanaOutcome.signedTransaction,
9240
+ fence: solanaOutcome.fence,
9241
+ confirmation: { state: 'unknown', reason: solanaOutcome.reason },
9242
+ };
9243
+ }
9244
+ // Confirmed: the receipt is already complete, so the mirror read is a
9245
+ // best-effort enrichment reported in `mirrorSync`, never a rejection.
9246
+ const mirrorSync = grantLane
9247
+ ? { observed: false, reason: 'not attempted: a venue grant authorizes only the write' }
9248
+ : await attemptMirrorSync(requestedPaths, Object.assign(Object.assign({}, options), { _overrides: Object.assign(Object.assign({}, options === null || options === void 0 ? void 0 : options._overrides), { _config: config }) }), solanaOutcome.transactionSignature);
9249
+ return {
9250
+ status: 'confirmed', appId, requestedDocuments, chain: solanaChain,
9251
+ transactionId: solanaOutcome.transactionSignature,
9252
+ signedTransaction: solanaOutcome.signedTransaction,
9253
+ fence: solanaOutcome.fence,
9254
+ confirmationContextSlot: solanaOutcome.confirmationContextSlot,
9255
+ mirrorSync,
9256
+ };
9221
9257
  }
9222
9258
  else {
9223
- throw new Error(`Failed to set document: ${setResponse}`);
9259
+ throw new Error('Unsupported 202 transaction shape: expected serializedTransaction');
9224
9260
  }
9225
9261
  }
9226
9262
  catch (error) {
9227
- throw error;
9263
+ // The blockhash died before the send: the RPC refused the bytes in preflight, so nothing
9264
+ // entered the network. The worker builds a fresh one and the wallet signs it again.
9265
+ if (rebuilds.expiry && (await import('./solana-operations-cwcuTNyk.mjs')).isExpiredBlockhashRejection(error))
9266
+ return { rebuild: 'expiry' };
9267
+ // The Solana lane tags its own broadcast and on-chain failures; anything
9268
+ // untagged from it, and every poofnet step before the commit PUT, failed
9269
+ // before a single byte was sent.
9270
+ throw sending ? error : markWriteNotApplied(error, 'before_broadcast');
9228
9271
  }
9229
9272
  }
9230
9273
  /**
@@ -9460,6 +9503,23 @@ async function signTransaction(transaction) {
9460
9503
  }
9461
9504
  return config.authProvider.signTransaction(transaction);
9462
9505
  }
9506
+ /**
9507
+ * Make the signed-in wallet ready to sign without delay, BEFORE the transaction it will sign
9508
+ * exists. A hosted embedded wallet whose 24-hour signing session has lapsed collects its emailed
9509
+ * code here; a transaction built before that code is dead by the time it is signed, because a
9510
+ * blockhash lives about 33 seconds on mainnet (late 2026) and the code takes longer. `set` and
9511
+ * `setMany` do this themselves before a wallet signature; call it directly before a flow that
9512
+ * builds and signs outside them, such as a permit approval. Resolves `'established'` when a
9513
+ * ceremony ran, else `'ready'`; a wallet that holds its own key always answers `'ready'`.
9514
+ */
9515
+ async function prepareToSign() {
9516
+ var _a, _b, _c;
9517
+ const config = await getConfig();
9518
+ if (!config.authProvider) {
9519
+ throw new Error('Auth provider not initialized. Please call init() first.');
9520
+ }
9521
+ return (_c = (await ((_b = (_a = config.authProvider).prepareToSign) === null || _b === void 0 ? void 0 : _b.call(_a)))) !== null && _c !== void 0 ? _c : 'ready';
9522
+ }
9463
9523
  async function signAndSubmitTransaction(transaction, feePayer) {
9464
9524
  const config = await getConfig();
9465
9525
  if (!config.authProvider) {
@@ -9480,6 +9540,7 @@ var operations = /*#__PURE__*/Object.freeze({
9480
9540
  getFiles: getFiles,
9481
9541
  getMany: getMany,
9482
9542
  onReadCacheAuthChange: onReadCacheAuthChange,
9543
+ prepareToSign: prepareToSign,
9483
9544
  queryAggregate: queryAggregate,
9484
9545
  runExpression: runExpression,
9485
9546
  runExpressionMany: runExpressionMany,
@@ -11042,7 +11103,7 @@ function toMillis(seconds) {
11042
11103
 
11043
11104
  /** SIWS message creation is async already, so its onchain module can be lazy. */
11044
11105
  async function genSolanaMessage(address, nonce) {
11045
- const implementation = await import('./solana-message-CjI0h27k.mjs');
11106
+ const implementation = await import('./solana-message-DqKp-y53.mjs');
11046
11107
  return implementation.genSolanaMessage(address, nonce);
11047
11108
  }
11048
11109
 
@@ -11591,5 +11652,5 @@ function defineLiveModule(mod) {
11591
11652
  return mod;
11592
11653
  }
11593
11654
 
11594
- export { DECLINE_EVENT_NAME as $, reconcileSetResult as A, waitForSetResult as B, isWriteNotApplied as C, writeNotAppliedPhase as D, subscribe as E, closeAllSubscriptions as F, clearCache as G, getCachedData as H, InsufficientBalanceError as I, reconnectWithNewAuth as J, createClient as K, exchangeAppToken as L, clearAppTokenCache as M, createAppTokenAuthHeaders as N, AppTokenExchangeError as O, setWithVenueGrant as P, resolveVenueRpcUrl as Q, subscribeQuery as R, ScopedClientReadOnlyError as S, closeAllQuerySubscriptions as T, canonicalizeArgs as U, canonicalizeResult as V, DEFAULT_QUERY_POLL_INTERVAL_MS as W, MIN_QUERY_POLL_INTERVAL_MS as X, BoundedDeclineError as Y, deriveDecline as Z, dispatchDeclineEvent as _, markWriteNotApplied as a, dispatchRateLimitEvent as a0, RATE_LIMIT_EVENT_NAME as a1, hasActiveConnection as a2, increment as a3, serverTimestamp as a4, now as a5, toSeconds as a6, toMillis as a7, getIdToken as a8, deriveUserIdentityFromIdToken as a9, SOLANA_SIGN_IN_STATEMENT as aA, genSiweMessage as aB, normalizeEvmAddress as aC, toLowerEvmAddress as aD, functions as aE, invoke as aF, FunctionInvokeError as aG, live as aH, intent as aI, status as aJ, subscribeView as aK, LiveIntentError as aL, withEffects as aM, isEffectResult as aN, defineLiveModule as aO, EFFECT_INTENT_ADDRESS as aP, getSessionGeneration as aa, WebSessionManager as ab, ReactNativeSessionManager as ac, getActiveSessionManager as ad, onSessionCleared as ae, announceSessionChange as af, onSessionChange as ag, SESSION_SIGNAL_CHANNEL as ah, SessionEnvironmentError as ai, UNSUPPORTED_ENVIRONMENT_CODE as aj, AUTH_CHANGED_CODE as ak, AUTH_EXPIRED_CODE as al, isAuthExpiredError as am, getFreshAuthToken as an, ServerSessionManager as ao, createSessionWithSignature as ap, refreshSession as aq, revokeSession as ar, signSessionCreateMessage as as, genAuthNonce as at, genSolanaMessage as au, createSolanaSignInRequest as av, createSolanaSignInMessageText as aw, genSolanaSignInRequest as ax, genSolanaSignInMessage as ay, browserSignInDomain as az, bufferExports as b, confirmSignature as c, getWebhookKeysUrl as d, getConfiguredAppId as e, get as f, getConfig as g, getMany as h, init as i, docId as j, setMany as k, setFile as l, makeApiRequest as m, getFiles as n, search as o, runQueryMany as p, queryAggregate as q, runQuery as r, set as s, runExpression as t, runExpressionMany as u, signMessage as v, signTransaction as w, signAndSubmitTransaction as x, count as y, aggregate as z };
11595
- //# sourceMappingURL=index-BXfRRAUZ.mjs.map
11655
+ export { dispatchDeclineEvent as $, aggregate as A, reconcileSetResult as B, waitForSetResult as C, isWriteNotApplied as D, writeNotAppliedPhase as E, subscribe as F, closeAllSubscriptions as G, clearCache as H, InsufficientBalanceError as I, getCachedData as J, reconnectWithNewAuth as K, createClient as L, exchangeAppToken as M, clearAppTokenCache as N, createAppTokenAuthHeaders as O, AppTokenExchangeError as P, setWithVenueGrant as Q, resolveVenueRpcUrl as R, ScopedClientReadOnlyError as S, subscribeQuery as T, closeAllQuerySubscriptions as U, canonicalizeArgs as V, canonicalizeResult as W, DEFAULT_QUERY_POLL_INTERVAL_MS as X, MIN_QUERY_POLL_INTERVAL_MS as Y, BoundedDeclineError as Z, deriveDecline as _, markWriteNotApplied as a, DECLINE_EVENT_NAME as a0, dispatchRateLimitEvent as a1, RATE_LIMIT_EVENT_NAME as a2, hasActiveConnection as a3, increment as a4, serverTimestamp as a5, now as a6, toSeconds as a7, toMillis as a8, getIdToken as a9, browserSignInDomain as aA, SOLANA_SIGN_IN_STATEMENT as aB, genSiweMessage as aC, normalizeEvmAddress as aD, toLowerEvmAddress as aE, functions as aF, invoke as aG, FunctionInvokeError as aH, live as aI, intent as aJ, status as aK, subscribeView as aL, LiveIntentError as aM, withEffects as aN, isEffectResult as aO, defineLiveModule as aP, EFFECT_INTENT_ADDRESS as aQ, deriveUserIdentityFromIdToken as aa, getSessionGeneration as ab, WebSessionManager as ac, ReactNativeSessionManager as ad, getActiveSessionManager as ae, onSessionCleared as af, announceSessionChange as ag, onSessionChange as ah, SESSION_SIGNAL_CHANNEL as ai, SessionEnvironmentError as aj, UNSUPPORTED_ENVIRONMENT_CODE as ak, AUTH_CHANGED_CODE as al, AUTH_EXPIRED_CODE as am, isAuthExpiredError as an, getFreshAuthToken as ao, ServerSessionManager as ap, createSessionWithSignature as aq, refreshSession as ar, revokeSession as as, signSessionCreateMessage as at, genAuthNonce as au, genSolanaMessage as av, createSolanaSignInRequest as aw, createSolanaSignInMessageText as ax, genSolanaSignInRequest as ay, genSolanaSignInMessage as az, bufferExports as b, confirmSignature as c, getWebhookKeysUrl as d, getConfiguredAppId as e, get as f, getConfig as g, getMany as h, init as i, docId as j, setMany as k, setFile as l, makeApiRequest as m, getFiles as n, search as o, runQueryMany as p, queryAggregate as q, runQuery as r, set as s, runExpression as t, runExpressionMany as u, signMessage as v, signTransaction as w, signAndSubmitTransaction as x, prepareToSign as y, count as z };
11656
+ //# sourceMappingURL=index-D93TEYGf.mjs.map