@bounded-sh/core 0.0.118-openapps.0 → 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.
- package/dist/client/operations.d.ts +19 -1
- package/dist/client/reconcile.d.ts +2 -2
- package/dist/client/solana-confirm.d.ts +49 -0
- package/dist/client/solana-operations.d.ts +13 -1
- package/dist/{index-DQ0FXeI8.js → index-D7-5ecyu.js} +356 -237
- package/dist/index-D7-5ecyu.js.map +1 -0
- package/dist/{index-C6ZW5Gt2.mjs → index-D93TEYGf.mjs} +355 -238
- package/dist/index-D93TEYGf.mjs.map +1 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/{mirror-sync-kt9PzQen.mjs → mirror-sync-DPMtQC3A.mjs} +2 -2
- package/dist/{mirror-sync-kt9PzQen.mjs.map → mirror-sync-DPMtQC3A.mjs.map} +1 -1
- package/dist/{mirror-sync-ChzMq7bH.js → mirror-sync-DzbDh6G_.js} +2 -2
- package/dist/{mirror-sync-ChzMq7bH.js.map → mirror-sync-DzbDh6G_.js.map} +1 -1
- package/dist/{realtime-store-CURbZ68v.js → realtime-store-C2Jz8YM0.js} +2 -2
- package/dist/{realtime-store-CURbZ68v.js.map → realtime-store-C2Jz8YM0.js.map} +1 -1
- package/dist/{realtime-store-FUjGL_Z8.mjs → realtime-store-FObAdw-J.mjs} +2 -2
- package/dist/{realtime-store-FUjGL_Z8.mjs.map → realtime-store-FObAdw-J.mjs.map} +1 -1
- package/dist/{solana-message-F1e5wPKF.js → solana-message-CPotom18.js} +2 -2
- package/dist/{solana-message-F1e5wPKF.js.map → solana-message-CPotom18.js.map} +1 -1
- package/dist/{solana-message-CEjXjnaG.mjs → solana-message-DqKp-y53.mjs} +2 -2
- package/dist/{solana-message-CEjXjnaG.mjs.map → solana-message-DqKp-y53.mjs.map} +1 -1
- package/dist/{solana-operations-CI0sREvl.js → solana-operations-DsT1303T.js} +55 -39
- package/dist/solana-operations-DsT1303T.js.map +1 -0
- package/dist/{solana-operations-5WjFwhnt.mjs → solana-operations-cwcuTNyk.mjs} +54 -40
- package/dist/solana-operations-cwcuTNyk.mjs.map +1 -0
- package/dist/{solana-v1-operations-DB9pih7o.mjs → solana-v1-operations-Jzg3uAot.mjs} +10 -24
- package/dist/solana-v1-operations-Jzg3uAot.mjs.map +1 -0
- package/dist/{solana-v1-operations-oot2R63I.js → solana-v1-operations-qj0WA2tF.js} +10 -24
- package/dist/solana-v1-operations-qj0WA2tF.js.map +1 -0
- package/dist/types.d.ts +22 -15
- package/package.json +1 -1
- package/dist/index-C6ZW5Gt2.mjs.map +0 -1
- package/dist/index-DQ0FXeI8.js.map +0 -1
- package/dist/solana-operations-5WjFwhnt.mjs.map +0 -1
- package/dist/solana-operations-CI0sREvl.js.map +0 -1
- package/dist/solana-v1-operations-DB9pih7o.mjs.map +0 -1
- package/dist/solana-v1-operations-oot2R63I.js.map +0 -1
|
@@ -4307,7 +4307,7 @@ class ServerSessionManager {
|
|
|
4307
4307
|
const sessionConfig = (_a = this.sessionConfig) !== null && _a !== void 0 ? _a : undefined;
|
|
4308
4308
|
/* fetch nonce from auth API (bound to the snapshotted app+issuer) */
|
|
4309
4309
|
const nonce = await genAuthNonce(sessionConfig);
|
|
4310
|
-
const { genSolanaMessage } = await Promise.resolve().then(function () { return require('./solana-message-
|
|
4310
|
+
const { genSolanaMessage } = await Promise.resolve().then(function () { return require('./solana-message-CPotom18.js'); });
|
|
4311
4311
|
const message = await genSolanaMessage(address, nonce, sessionConfig === null || sessionConfig === void 0 ? void 0 : sessionConfig.appId);
|
|
4312
4312
|
/* sign the message */
|
|
4313
4313
|
const sigBytes = nacl.sign.detached(new TextEncoder().encode(message), kp.secretKey);
|
|
@@ -7679,7 +7679,7 @@ async function doReconnectWithNewAuth() {
|
|
|
7679
7679
|
console.warn('[WS v2] Failed to clear HTTP read cache on auth change:', error);
|
|
7680
7680
|
}
|
|
7681
7681
|
try {
|
|
7682
|
-
const { reconnectRealtimeStoreWithNewAuth } = await Promise.resolve().then(function () { return require('./realtime-store-
|
|
7682
|
+
const { reconnectRealtimeStoreWithNewAuth } = await Promise.resolve().then(function () { return require('./realtime-store-C2Jz8YM0.js'); });
|
|
7683
7683
|
await reconnectRealtimeStoreWithNewAuth();
|
|
7684
7684
|
}
|
|
7685
7685
|
catch (error) {
|
|
@@ -8898,7 +8898,7 @@ function buildRequestedDocuments(documents) {
|
|
|
8898
8898
|
/** Best-effort readback, including a failure to load its lazy implementation. */
|
|
8899
8899
|
async function attemptMirrorSync(paths, options, transactionSignature) {
|
|
8900
8900
|
try {
|
|
8901
|
-
const mirror = await Promise.resolve().then(function () { return require('./mirror-sync-
|
|
8901
|
+
const mirror = await Promise.resolve().then(function () { return require('./mirror-sync-DzbDh6G_.js'); });
|
|
8902
8902
|
return await mirror.attemptMirrorSync(paths, options, transactionSignature);
|
|
8903
8903
|
}
|
|
8904
8904
|
catch (error) {
|
|
@@ -8996,237 +8996,280 @@ async function set(path, document, options) {
|
|
|
8996
8996
|
* state appears only under `observation`/`mirrorSync` once actually observed.
|
|
8997
8997
|
*/
|
|
8998
8998
|
async function setMany(many, options) {
|
|
8999
|
-
var _a, _b, _c, _d, _e, _f
|
|
9000
|
-
//
|
|
9001
|
-
|
|
9002
|
-
|
|
9003
|
-
|
|
9004
|
-
|
|
9005
|
-
|
|
9006
|
-
|
|
9007
|
-
|
|
9008
|
-
|
|
9009
|
-
|
|
9010
|
-
|
|
9011
|
-
|
|
9012
|
-
|
|
9013
|
-
|
|
9014
|
-
|
|
9015
|
-
|
|
9016
|
-
if (documentWithReservedFields) {
|
|
9017
|
-
document = Object.fromEntries(Object.entries(documentWithReservedFields).filter(([key]) => !key.startsWith('_')));
|
|
9018
|
-
}
|
|
9019
|
-
const normalizedPath = path.startsWith("/") ? path.slice(1) : path;
|
|
9020
|
-
pathsToInvalidate.add(normalizedPath);
|
|
9021
|
-
const pathIsDocument = normalizedPath.split("/").length % 2 === 0;
|
|
9022
|
-
let curItemId = "";
|
|
9023
|
-
if (pathIsDocument) {
|
|
9024
|
-
curItemId = normalizedPath.split("/").pop() ? normalizedPath.split("/").pop() : "";
|
|
9025
|
-
}
|
|
9026
|
-
else {
|
|
9027
|
-
curItemId = Math.random().toString(36).slice(2).substring(0, 12);
|
|
9028
|
-
}
|
|
9029
|
-
// if the path is a document, we need to append the document id to the path
|
|
9030
|
-
const collectionPath = pathIsDocument ? normalizedPath.split("/").slice(0, -1).join("/") : normalizedPath;
|
|
9031
|
-
pathsToInvalidate.add(collectionPath);
|
|
9032
|
-
let destinationPath = collectionPath;
|
|
9033
|
-
if (curItemId && curItemId.length > 0) {
|
|
9034
|
-
destinationPath = `${destinationPath}/${curItemId}`;
|
|
9035
|
-
}
|
|
9036
|
-
documents.push({ destinationPath, document });
|
|
9037
|
-
}
|
|
9038
|
-
let setResponse;
|
|
8999
|
+
var _a, _b, _c, _d, _e, _f;
|
|
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
|
+
const { documents, pathsToInvalidate } = normalizeWriteBatch(many);
|
|
9010
|
+
// A grant lane's credential is single-use, so its write is built exactly once, and its signer
|
|
9011
|
+
// is prepared the way it always was: inside the approval.
|
|
9012
|
+
const grantLane = (_e = options === null || options === void 0 ? void 0 : options._overrides) === null || _e === void 0 ? void 0 : _e._grantLane;
|
|
9013
|
+
if ((options === null || options === void 0 ? void 0 : options.onchain) && !grantLane) {
|
|
9014
|
+
// The caller knows the wallet will sign: the signer is prepared before the first build, so a
|
|
9015
|
+
// first-time emailed code never runs inside a transaction's lifetime and no build is wasted.
|
|
9039
9016
|
try {
|
|
9040
|
-
|
|
9041
|
-
// can sign, so it builds v1 only for a client that can complete it.
|
|
9042
|
-
const clientTransactionVersions = await resolveClientTransactionVersions(authProvider);
|
|
9043
|
-
setResponse = await makeApiRequest('PUT', `items`, { documents, clientTransactionVersions }, options === null || options === void 0 ? void 0 : options._overrides);
|
|
9017
|
+
await ((_f = authProvider.prepareToSign) === null || _f === void 0 ? void 0 : _f.call(authProvider));
|
|
9044
9018
|
}
|
|
9045
9019
|
catch (error) {
|
|
9046
|
-
|
|
9047
|
-
const deficitLamports = Number((_e = error.deficitLamports) !== null && _e !== void 0 ? _e : 0);
|
|
9048
|
-
const deficitSol = Number((_f = error.deficitSol) !== null && _f !== void 0 ? _f : deficitLamports / 1000000000);
|
|
9049
|
-
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');
|
|
9050
|
-
}
|
|
9051
|
-
// The server answered and refused the write (a rule or invariant denial, a bad request, no
|
|
9052
|
-
// session, a rate limit): nothing was built, signed or committed. A network failure, a 5xx,
|
|
9053
|
-
// a 408 or a 499 may follow a commit the response never reported, so those stay untagged.
|
|
9054
|
-
if (DEFINITIVE_WRITE_REFUSAL_STATUSES.has(Number(error === null || error === void 0 ? void 0 : error.statusCode))) {
|
|
9055
|
-
throw markWriteNotApplied(error, 'before_broadcast');
|
|
9056
|
-
}
|
|
9057
|
-
throw error;
|
|
9020
|
+
throw markWriteNotApplied(error, 'before_broadcast');
|
|
9058
9021
|
}
|
|
9022
|
+
}
|
|
9023
|
+
// Each reason to build again is spent once: the wallet's own ceremony (the build it ran beside is
|
|
9024
|
+
// dying), and a send refused because the blockhash expired (a long pause on the approve card).
|
|
9025
|
+
const rebuilds = { ceremony: !grantLane, expiry: !grantLane };
|
|
9026
|
+
for (;;) {
|
|
9027
|
+
const setResponse = await requestWrite(documents, authProvider, options);
|
|
9059
9028
|
// Invalidate caches and pending requests for affected paths
|
|
9060
9029
|
pathsToInvalidate.forEach(path => {
|
|
9061
9030
|
clearCacheByPrefix(path);
|
|
9062
9031
|
});
|
|
9063
|
-
if (setResponse.status ===
|
|
9064
|
-
|
|
9065
|
-
|
|
9066
|
-
|
|
9067
|
-
|
|
9032
|
+
if (setResponse.status === 200)
|
|
9033
|
+
return directCommitResult(setResponse, documents);
|
|
9034
|
+
if (setResponse.status !== 202)
|
|
9035
|
+
throw new Error(`Failed to set document: ${setResponse}`);
|
|
9036
|
+
const outcome = await completePreparedWrite(setResponse, documents, config, authProvider, options, rebuilds);
|
|
9037
|
+
if (!isRebuild(outcome))
|
|
9038
|
+
return outcome;
|
|
9039
|
+
rebuilds[outcome.rebuild] = false;
|
|
9040
|
+
}
|
|
9041
|
+
}
|
|
9042
|
+
/** The caller's batch as the worker takes it, plus every read-cache prefix the write touches. */
|
|
9043
|
+
function normalizeWriteBatch(many) {
|
|
9044
|
+
const documents = [];
|
|
9045
|
+
const pathsToInvalidate = new Set();
|
|
9046
|
+
for (const { path, document: documentWithReservedFields } of many) {
|
|
9047
|
+
// 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
|
|
9048
|
+
let document = documentWithReservedFields;
|
|
9049
|
+
if (documentWithReservedFields) {
|
|
9050
|
+
document = Object.fromEntries(Object.entries(documentWithReservedFields).filter(([key]) => !key.startsWith('_')));
|
|
9051
|
+
}
|
|
9052
|
+
const normalizedPath = path.startsWith("/") ? path.slice(1) : path;
|
|
9053
|
+
pathsToInvalidate.add(normalizedPath);
|
|
9054
|
+
const pathIsDocument = normalizedPath.split("/").length % 2 === 0;
|
|
9055
|
+
let curItemId = "";
|
|
9056
|
+
if (pathIsDocument) {
|
|
9057
|
+
curItemId = normalizedPath.split("/").pop() ? normalizedPath.split("/").pop() : "";
|
|
9058
|
+
}
|
|
9059
|
+
else {
|
|
9060
|
+
curItemId = Math.random().toString(36).slice(2).substring(0, 12);
|
|
9061
|
+
}
|
|
9062
|
+
// if the path is a document, we need to append the document id to the path
|
|
9063
|
+
const collectionPath = pathIsDocument ? normalizedPath.split("/").slice(0, -1).join("/") : normalizedPath;
|
|
9064
|
+
pathsToInvalidate.add(collectionPath);
|
|
9065
|
+
let destinationPath = collectionPath;
|
|
9066
|
+
if (curItemId && curItemId.length > 0) {
|
|
9067
|
+
destinationPath = `${destinationPath}/${curItemId}`;
|
|
9068
|
+
}
|
|
9069
|
+
documents.push({ destinationPath, document });
|
|
9070
|
+
}
|
|
9071
|
+
return { documents, pathsToInvalidate };
|
|
9072
|
+
}
|
|
9073
|
+
/** The write PUT: a direct commit (200), a transaction to sign (202), or a definitive refusal. */
|
|
9074
|
+
async function requestWrite(documents, authProvider, options) {
|
|
9075
|
+
var _a, _b, _c, _d, _e;
|
|
9076
|
+
try {
|
|
9077
|
+
// SIMD-0385: tell the worker which Solana transaction formats this client
|
|
9078
|
+
// can sign, so it builds v1 only for a client that can complete it.
|
|
9079
|
+
const clientTransactionVersions = await resolveClientTransactionVersions(authProvider);
|
|
9080
|
+
return await makeApiRequest('PUT', `items`, { documents, clientTransactionVersions }, options === null || options === void 0 ? void 0 : options._overrides);
|
|
9081
|
+
}
|
|
9082
|
+
catch (error) {
|
|
9083
|
+
if ((error === null || error === void 0 ? void 0 : error.statusCode) === 402 && (error === null || error === void 0 ? void 0 : error.error) === 'INSUFFICIENT_BALANCE') {
|
|
9084
|
+
const deficitLamports = Number((_a = error.deficitLamports) !== null && _a !== void 0 ? _a : 0);
|
|
9085
|
+
const deficitSol = Number((_b = error.deficitSol) !== null && _b !== void 0 ? _b : deficitLamports / 1000000000);
|
|
9086
|
+
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');
|
|
9087
|
+
}
|
|
9088
|
+
// The server answered and refused the write (a rule or invariant denial, a bad request, no
|
|
9089
|
+
// session, a rate limit): nothing was built, signed or committed. A network failure, a 5xx,
|
|
9090
|
+
// a 408 or a 499 may follow a commit the response never reported, so those stay untagged.
|
|
9091
|
+
if (DEFINITIVE_WRITE_REFUSAL_STATUSES.has(Number(error === null || error === void 0 ? void 0 : error.statusCode))) {
|
|
9092
|
+
throw markWriteNotApplied(error, 'before_broadcast');
|
|
9093
|
+
}
|
|
9094
|
+
throw error;
|
|
9095
|
+
}
|
|
9096
|
+
}
|
|
9097
|
+
function isRebuild(outcome) {
|
|
9098
|
+
return 'rebuild' in outcome;
|
|
9099
|
+
}
|
|
9100
|
+
/**
|
|
9101
|
+
* Finish a 202: the worker built the transaction (or the poofnet approval) and did nothing
|
|
9102
|
+
* else; the wallet signs it here and, on a real chain, it is broadcast. Until something is
|
|
9103
|
+
* sent, every failure is definitively not applied. `rebuilds` says which reasons to build
|
|
9104
|
+
* again are still open.
|
|
9105
|
+
*/
|
|
9106
|
+
async function completePreparedWrite(setResponse, documents, config, authProvider, options, rebuilds) {
|
|
9107
|
+
var _a, _b, _c;
|
|
9108
|
+
let sending = false;
|
|
9109
|
+
try {
|
|
9110
|
+
const { transactions, offchainTransaction } = setResponse.data;
|
|
9111
|
+
// Handle offchain transaction flow (for 'offchain' protocol apps)
|
|
9112
|
+
if (offchainTransaction && Array.isArray(transactions) && transactions.length > 0) {
|
|
9113
|
+
throw new Error('Ambiguous write response mixes offchain and onchain transaction targets');
|
|
9114
|
+
}
|
|
9115
|
+
if (offchainTransaction) {
|
|
9116
|
+
// Offchain signing is retired: no server mints this envelope any more
|
|
9117
|
+
// (the realtime worker commits poofnet writes directly). Fail loudly
|
|
9118
|
+
// rather than silently ignoring a payload the caller was asked to sign.
|
|
9119
|
+
throw new Error('Unsupported 202 transaction shape: offchain signing is retired');
|
|
9120
|
+
}
|
|
9121
|
+
// Handle Solana on-chain transaction flow
|
|
9122
|
+
if (!Array.isArray(transactions) || transactions.length !== 1) {
|
|
9123
|
+
throw new Error(`Expected exactly one on-chain transaction, received ${Array.isArray(transactions) ? transactions.length : 0}`);
|
|
9124
|
+
}
|
|
9125
|
+
const curTx = transactions[0];
|
|
9126
|
+
// The EVM onchain data plane is retired: no worker mints an EVM 202 any
|
|
9127
|
+
// more. A payload that still carries one is an unexpected response and
|
|
9128
|
+
// fails loudly BEFORE anything is signed - never silently ignored.
|
|
9129
|
+
if ((curTx === null || curTx === void 0 ? void 0 : curTx.evmTransaction) != null) {
|
|
9130
|
+
throw new Error('Unsupported 202 transaction shape: the write response carried an evmTransaction, ' +
|
|
9131
|
+
'but EVM onchain writes are no longer supported. Nothing was signed or submitted.');
|
|
9132
|
+
}
|
|
9133
|
+
const hasSerializedSolanaTarget = (curTx === null || curTx === void 0 ? void 0 : curTx.serializedTransaction) != null;
|
|
9134
|
+
const hasBuiltSolanaTarget = (curTx === null || curTx === void 0 ? void 0 : curTx.transactionArgs) != null || (curTx === null || curTx === void 0 ? void 0 : curTx.remainingAccounts) != null ||
|
|
9135
|
+
(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;
|
|
9136
|
+
if (hasSerializedSolanaTarget && hasBuiltSolanaTarget) {
|
|
9137
|
+
throw new Error('Ambiguous on-chain write response mixes Solana transaction target formats');
|
|
9138
|
+
}
|
|
9139
|
+
// All requested paths (writes AND deletes), in request order. Used for the
|
|
9140
|
+
// post-confirm mirror read-back, which correlates every requested path.
|
|
9141
|
+
// The pre-sign validation derives its own full expected intent from
|
|
9142
|
+
// `documents` (see below) and needs nothing from this list.
|
|
9143
|
+
const requestedPaths = documents.map(d => d.destinationPath);
|
|
9144
|
+
const requestedDocuments = buildRequestedDocuments(documents);
|
|
9145
|
+
const appId = config.appId;
|
|
9146
|
+
// The lane comes verbatim from the worker, and is read BEFORE anything is
|
|
9147
|
+
// signed or submitted: a missing tag fails closed while nothing has been
|
|
9148
|
+
// broadcast, instead of stranding a landed transaction with no receipt.
|
|
9149
|
+
const workerChain = readWorkerChainTag((_a = setResponse.data) === null || _a === void 0 ? void 0 : _a.receipt, setResponse.data, curTx);
|
|
9150
|
+
if (!workerChain) {
|
|
9151
|
+
throw new Error('The write response carried no execution-chain tag, so this receipt could not state where the write ran. ' +
|
|
9152
|
+
'Nothing was signed or submitted.');
|
|
9153
|
+
}
|
|
9154
|
+
const grantLane = (_b = options === null || options === void 0 ? void 0 : options._overrides) === null || _b === void 0 ? void 0 : _b._grantLane;
|
|
9155
|
+
grantLane === null || grantLane === void 0 ? void 0 : grantLane.assertLane(workerChain);
|
|
9156
|
+
// The wallet's own ceremony runs now, before it sees a transaction: a hosted embedded
|
|
9157
|
+
// wallet whose 24-hour signing session has lapsed collects its emailed code here, and that
|
|
9158
|
+
// outlives the blockhash the worker just minted. A ceremony that ran means this build is
|
|
9159
|
+
// already dying, so the write is built again and the wallet signs the fresh one in one click.
|
|
9160
|
+
// (A caller that passed `onchain` prepared the signer before the build, so this normally
|
|
9161
|
+
// answers 'ready' at once. It runs the ceremony here only when that preparation could not
|
|
9162
|
+
// reach the signer; the build it then replaces is left to expire unsigned.)
|
|
9163
|
+
if (rebuilds.ceremony && await ((_c = authProvider.prepareToSign) === null || _c === void 0 ? void 0 : _c.call(authProvider)) === 'established')
|
|
9164
|
+
return { rebuild: 'ceremony' };
|
|
9165
|
+
if (workerChain === 'realtime_offchain') {
|
|
9166
|
+
// Poofnet: the wallet signs the worker's unsendable approval message and
|
|
9167
|
+
// the worker verifies and commits it. Nothing is submitted to any chain.
|
|
9168
|
+
if (typeof curTx.serializedTransaction !== 'string' || typeof curTx.poofnetIntentId !== 'string') {
|
|
9169
|
+
throw new Error('Unsupported 202 transaction shape: a poofnet write needs serializedTransaction and poofnetIntentId');
|
|
9170
|
+
}
|
|
9171
|
+
const { signPoofnetTransaction, buildExpectedWriteIntent } = await Promise.resolve().then(function () { return require('./solana-operations-DsT1303T.js'); });
|
|
9172
|
+
const signedTransaction = await signPoofnetTransaction(curTx.serializedTransaction, authProvider, options, buildExpectedWriteIntent(documents));
|
|
9173
|
+
// Signing-only, exactly as on a real chain: signed and NOT committed.
|
|
9174
|
+
if ((options === null || options === void 0 ? void 0 : options.shouldSubmitTx) === false) {
|
|
9175
|
+
return {
|
|
9176
|
+
status: 'signed', appId, requestedDocuments: buildRequestedDocuments(documents),
|
|
9177
|
+
chain: 'realtime_offchain', transactionId: null, signedTransaction,
|
|
9178
|
+
poofnetIntentId: curTx.poofnetIntentId,
|
|
9179
|
+
};
|
|
9180
|
+
}
|
|
9181
|
+
// A grant lane's first credential is spent by the PUT that built this approval, so the
|
|
9182
|
+
// commit's is minted now, before `sending`: failing to mint sends nothing.
|
|
9183
|
+
const commitHeaders = await (grantLane === null || grantLane === void 0 ? void 0 : grantLane.commitHeaders());
|
|
9184
|
+
// The commit PUT is the one ambiguous step of this lane: a lost response may follow a
|
|
9185
|
+
// commit, so a transport failure or a 5xx stays untagged (read the path back). A 4xx is
|
|
9186
|
+
// realtime stating it committed nothing (the intent expired or was taken, the signer did
|
|
9187
|
+
// not match, a rule refused it), as for the first PUT. 408 and 499 are a proxy's words,
|
|
9188
|
+
// not realtime's, and may follow a commit, so they stay ambiguous too.
|
|
9189
|
+
sending = true;
|
|
9190
|
+
let commitResponse;
|
|
9068
9191
|
try {
|
|
9069
|
-
|
|
9070
|
-
|
|
9071
|
-
|
|
9072
|
-
throw new Error('Ambiguous write response mixes offchain and onchain transaction targets');
|
|
9073
|
-
}
|
|
9074
|
-
if (offchainTransaction) {
|
|
9075
|
-
// Offchain signing is retired: no server mints this envelope any more
|
|
9076
|
-
// (the realtime worker commits poofnet writes directly). Fail loudly
|
|
9077
|
-
// rather than silently ignoring a payload the caller was asked to sign.
|
|
9078
|
-
throw new Error('Unsupported 202 transaction shape: offchain signing is retired');
|
|
9079
|
-
}
|
|
9080
|
-
// Handle Solana on-chain transaction flow
|
|
9081
|
-
if (!Array.isArray(transactions) || transactions.length !== 1) {
|
|
9082
|
-
throw new Error(`Expected exactly one on-chain transaction, received ${Array.isArray(transactions) ? transactions.length : 0}`);
|
|
9083
|
-
}
|
|
9084
|
-
const curTx = transactions[0];
|
|
9085
|
-
// The EVM onchain data plane is retired: no worker mints an EVM 202 any
|
|
9086
|
-
// more. A payload that still carries one is an unexpected response and
|
|
9087
|
-
// fails loudly BEFORE anything is signed - never silently ignored.
|
|
9088
|
-
if ((curTx === null || curTx === void 0 ? void 0 : curTx.evmTransaction) != null) {
|
|
9089
|
-
throw new Error('Unsupported 202 transaction shape: the write response carried an evmTransaction, ' +
|
|
9090
|
-
'but EVM onchain writes are no longer supported. Nothing was signed or submitted.');
|
|
9091
|
-
}
|
|
9092
|
-
const hasSerializedSolanaTarget = (curTx === null || curTx === void 0 ? void 0 : curTx.serializedTransaction) != null;
|
|
9093
|
-
const hasBuiltSolanaTarget = (curTx === null || curTx === void 0 ? void 0 : curTx.transactionArgs) != null || (curTx === null || curTx === void 0 ? void 0 : curTx.remainingAccounts) != null ||
|
|
9094
|
-
(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;
|
|
9095
|
-
if (hasSerializedSolanaTarget && hasBuiltSolanaTarget) {
|
|
9096
|
-
throw new Error('Ambiguous on-chain write response mixes Solana transaction target formats');
|
|
9097
|
-
}
|
|
9098
|
-
// All requested paths (writes AND deletes), in request order. Used for the
|
|
9099
|
-
// post-confirm mirror read-back, which correlates every requested path.
|
|
9100
|
-
// The pre-sign validation derives its own full expected intent from
|
|
9101
|
-
// `documents` (see below) and needs nothing from this list.
|
|
9102
|
-
const requestedPaths = documents.map(d => d.destinationPath);
|
|
9103
|
-
const requestedDocuments = buildRequestedDocuments(documents);
|
|
9104
|
-
const appId = config.appId;
|
|
9105
|
-
// The lane comes verbatim from the worker, and is read BEFORE anything is
|
|
9106
|
-
// signed or submitted: a missing tag fails closed while nothing has been
|
|
9107
|
-
// broadcast, instead of stranding a landed transaction with no receipt.
|
|
9108
|
-
const workerChain = readWorkerChainTag((_k = setResponse.data) === null || _k === void 0 ? void 0 : _k.receipt, setResponse.data, curTx);
|
|
9109
|
-
if (!workerChain) {
|
|
9110
|
-
throw new Error('The write response carried no execution-chain tag, so this receipt could not state where the write ran. ' +
|
|
9111
|
-
'Nothing was signed or submitted.');
|
|
9112
|
-
}
|
|
9113
|
-
const grantLane = (_l = options === null || options === void 0 ? void 0 : options._overrides) === null || _l === void 0 ? void 0 : _l._grantLane;
|
|
9114
|
-
grantLane === null || grantLane === void 0 ? void 0 : grantLane.assertLane(workerChain);
|
|
9115
|
-
if (workerChain === 'realtime_offchain') {
|
|
9116
|
-
// Poofnet: the wallet signs the worker's unsendable approval message and
|
|
9117
|
-
// the worker verifies and commits it. Nothing is submitted to any chain.
|
|
9118
|
-
if (typeof curTx.serializedTransaction !== 'string' || typeof curTx.poofnetIntentId !== 'string') {
|
|
9119
|
-
throw new Error('Unsupported 202 transaction shape: a poofnet write needs serializedTransaction and poofnetIntentId');
|
|
9120
|
-
}
|
|
9121
|
-
const { signPoofnetTransaction, buildExpectedWriteIntent } = await Promise.resolve().then(function () { return require('./solana-operations-CI0sREvl.js'); });
|
|
9122
|
-
const signedTransaction = await signPoofnetTransaction(curTx.serializedTransaction, authProvider, options, buildExpectedWriteIntent(documents));
|
|
9123
|
-
// Signing-only, exactly as on a real chain: signed and NOT committed.
|
|
9124
|
-
if ((options === null || options === void 0 ? void 0 : options.shouldSubmitTx) === false) {
|
|
9125
|
-
return {
|
|
9126
|
-
status: 'signed', appId, requestedDocuments: buildRequestedDocuments(documents),
|
|
9127
|
-
chain: 'realtime_offchain', transactionId: null, signedTransaction,
|
|
9128
|
-
poofnetIntentId: curTx.poofnetIntentId,
|
|
9129
|
-
};
|
|
9130
|
-
}
|
|
9131
|
-
// A grant lane's first credential is spent by the PUT that built this approval, so the
|
|
9132
|
-
// commit's is minted now, before `sending`: failing to mint sends nothing.
|
|
9133
|
-
const commitHeaders = await (grantLane === null || grantLane === void 0 ? void 0 : grantLane.commitHeaders());
|
|
9134
|
-
// The commit PUT is the one ambiguous step of this lane: a lost response may follow a
|
|
9135
|
-
// commit, so a transport failure or a 5xx stays untagged (read the path back). A 4xx is
|
|
9136
|
-
// realtime stating it committed nothing (the intent expired or was taken, the signer did
|
|
9137
|
-
// not match, a rule refused it), as for the first PUT. 408 and 499 are a proxy's words,
|
|
9138
|
-
// not realtime's, and may follow a commit, so they stay ambiguous too.
|
|
9139
|
-
sending = true;
|
|
9140
|
-
let commitResponse;
|
|
9141
|
-
try {
|
|
9142
|
-
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);
|
|
9143
|
-
if (commitResponse.status !== 200) {
|
|
9144
|
-
throw Object.assign(new Error(`Poofnet signed write was not committed (status ${commitResponse.status})`), { statusCode: commitResponse.status });
|
|
9145
|
-
}
|
|
9146
|
-
}
|
|
9147
|
-
catch (error) {
|
|
9148
|
-
const status = Number(error === null || error === void 0 ? void 0 : error.statusCode);
|
|
9149
|
-
throw status >= 400 && status < 500 && status !== 408 && status !== 499 ? markWriteNotApplied(error, 'broadcast_rejected') : error;
|
|
9150
|
-
}
|
|
9151
|
-
return directCommitResult(commitResponse, documents);
|
|
9152
|
-
}
|
|
9153
|
-
if (curTx.serializedTransaction) {
|
|
9154
|
-
if (!SOLANA_CHAIN_TAGS.has(workerChain)) {
|
|
9155
|
-
throw new Error(`The write response reported execution chain "${workerChain}" for a Solana transaction. ` +
|
|
9156
|
-
'Nothing was signed or submitted.');
|
|
9157
|
-
}
|
|
9158
|
-
const solanaChain = workerChain;
|
|
9159
|
-
const { handlePreBuiltTransaction, buildExpectedWriteIntent } = await Promise.resolve().then(function () { return require('./solana-operations-CI0sREvl.js'); });
|
|
9160
|
-
// OA-0001: derive the expected intent from OUR OWN request (the one
|
|
9161
|
-
// ground truth a tampered builder response cannot change) so the
|
|
9162
|
-
// validator can reject any transaction whose operation semantics
|
|
9163
|
-
// diverge from it BEFORE the wallet is asked to sign.
|
|
9164
|
-
const expectedIntent = buildExpectedWriteIntent(documents);
|
|
9165
|
-
const onBroadcast = options === null || options === void 0 ? void 0 : options.onBroadcast;
|
|
9166
|
-
const solanaOutcome = await handlePreBuiltTransaction(curTx, authProvider, options, expectedIntent, onBroadcast && (async (signed) => {
|
|
9167
|
-
await onBroadcast({
|
|
9168
|
-
status: 'submitted', appId, requestedDocuments, chain: solanaChain,
|
|
9169
|
-
transactionId: signed.transactionSignature,
|
|
9170
|
-
signedTransaction: signed.signedTransaction,
|
|
9171
|
-
fence: signed.fence,
|
|
9172
|
-
confirmation: { state: 'unknown', reason: 'about to broadcast' },
|
|
9173
|
-
});
|
|
9174
|
-
}));
|
|
9175
|
-
// Past this point the bytes may be on the network: nothing is tagged here.
|
|
9176
|
-
sending = true;
|
|
9177
|
-
// `shouldSubmitTx: false` signed WITHOUT sending — no signature exists,
|
|
9178
|
-
// and there is nothing to mirror, so no synchronization is attempted.
|
|
9179
|
-
if (solanaOutcome.outcome === 'signed') {
|
|
9180
|
-
return {
|
|
9181
|
-
status: 'signed', appId, requestedDocuments, chain: solanaChain,
|
|
9182
|
-
transactionId: null,
|
|
9183
|
-
signedTransaction: solanaOutcome.signedTransaction,
|
|
9184
|
-
fence: solanaOutcome.fence,
|
|
9185
|
-
};
|
|
9186
|
-
}
|
|
9187
|
-
if (solanaOutcome.outcome === 'submitted') {
|
|
9188
|
-
return {
|
|
9189
|
-
status: 'submitted', appId, requestedDocuments, chain: solanaChain,
|
|
9190
|
-
transactionId: solanaOutcome.transactionSignature,
|
|
9191
|
-
signedTransaction: solanaOutcome.signedTransaction,
|
|
9192
|
-
fence: solanaOutcome.fence,
|
|
9193
|
-
confirmation: { state: 'unknown', reason: solanaOutcome.reason },
|
|
9194
|
-
};
|
|
9195
|
-
}
|
|
9196
|
-
// Confirmed: the receipt is already complete, so the mirror read is a
|
|
9197
|
-
// best-effort enrichment reported in `mirrorSync`, never a rejection.
|
|
9198
|
-
const mirrorSync = grantLane
|
|
9199
|
-
? { observed: false, reason: 'not attempted: a venue grant authorizes only the write' }
|
|
9200
|
-
: 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);
|
|
9201
|
-
return {
|
|
9202
|
-
status: 'confirmed', appId, requestedDocuments, chain: solanaChain,
|
|
9203
|
-
transactionId: solanaOutcome.transactionSignature,
|
|
9204
|
-
signedTransaction: solanaOutcome.signedTransaction,
|
|
9205
|
-
fence: solanaOutcome.fence,
|
|
9206
|
-
confirmationContextSlot: solanaOutcome.confirmationContextSlot,
|
|
9207
|
-
mirrorSync,
|
|
9208
|
-
};
|
|
9209
|
-
}
|
|
9210
|
-
else {
|
|
9211
|
-
throw new Error('Unsupported 202 transaction shape: expected serializedTransaction');
|
|
9192
|
+
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);
|
|
9193
|
+
if (commitResponse.status !== 200) {
|
|
9194
|
+
throw Object.assign(new Error(`Poofnet signed write was not committed (status ${commitResponse.status})`), { statusCode: commitResponse.status });
|
|
9212
9195
|
}
|
|
9213
9196
|
}
|
|
9214
9197
|
catch (error) {
|
|
9215
|
-
|
|
9216
|
-
|
|
9217
|
-
// before a single byte was sent.
|
|
9218
|
-
throw sending ? error : markWriteNotApplied(error, 'before_broadcast');
|
|
9198
|
+
const status = Number(error === null || error === void 0 ? void 0 : error.statusCode);
|
|
9199
|
+
throw status >= 400 && status < 500 && status !== 408 && status !== 499 ? markWriteNotApplied(error, 'broadcast_rejected') : error;
|
|
9219
9200
|
}
|
|
9201
|
+
return directCommitResult(commitResponse, documents);
|
|
9220
9202
|
}
|
|
9221
|
-
|
|
9222
|
-
|
|
9203
|
+
if (curTx.serializedTransaction) {
|
|
9204
|
+
if (!SOLANA_CHAIN_TAGS.has(workerChain)) {
|
|
9205
|
+
throw new Error(`The write response reported execution chain "${workerChain}" for a Solana transaction. ` +
|
|
9206
|
+
'Nothing was signed or submitted.');
|
|
9207
|
+
}
|
|
9208
|
+
const solanaChain = workerChain;
|
|
9209
|
+
const { handlePreBuiltTransaction, buildExpectedWriteIntent } = await Promise.resolve().then(function () { return require('./solana-operations-DsT1303T.js'); });
|
|
9210
|
+
// OA-0001: derive the expected intent from OUR OWN request (the one
|
|
9211
|
+
// ground truth a tampered builder response cannot change) so the
|
|
9212
|
+
// validator can reject any transaction whose operation semantics
|
|
9213
|
+
// diverge from it BEFORE the wallet is asked to sign.
|
|
9214
|
+
const expectedIntent = buildExpectedWriteIntent(documents);
|
|
9215
|
+
const onBroadcast = options === null || options === void 0 ? void 0 : options.onBroadcast;
|
|
9216
|
+
const solanaOutcome = await handlePreBuiltTransaction(curTx, authProvider, options, expectedIntent, onBroadcast && (async (signed) => {
|
|
9217
|
+
await onBroadcast({
|
|
9218
|
+
status: 'submitted', appId, requestedDocuments, chain: solanaChain,
|
|
9219
|
+
transactionId: signed.transactionSignature,
|
|
9220
|
+
signedTransaction: signed.signedTransaction,
|
|
9221
|
+
fence: signed.fence,
|
|
9222
|
+
confirmation: { state: 'unknown', reason: 'about to broadcast' },
|
|
9223
|
+
});
|
|
9224
|
+
}));
|
|
9225
|
+
// Past this point the bytes may be on the network: nothing is tagged here.
|
|
9226
|
+
sending = true;
|
|
9227
|
+
// `shouldSubmitTx: false` signed WITHOUT sending — no signature exists,
|
|
9228
|
+
// and there is nothing to mirror, so no synchronization is attempted.
|
|
9229
|
+
if (solanaOutcome.outcome === 'signed') {
|
|
9230
|
+
return {
|
|
9231
|
+
status: 'signed', appId, requestedDocuments, chain: solanaChain,
|
|
9232
|
+
transactionId: null,
|
|
9233
|
+
signedTransaction: solanaOutcome.signedTransaction,
|
|
9234
|
+
fence: solanaOutcome.fence,
|
|
9235
|
+
};
|
|
9236
|
+
}
|
|
9237
|
+
if (solanaOutcome.outcome === 'submitted') {
|
|
9238
|
+
return {
|
|
9239
|
+
status: 'submitted', appId, requestedDocuments, chain: solanaChain,
|
|
9240
|
+
transactionId: solanaOutcome.transactionSignature,
|
|
9241
|
+
signedTransaction: solanaOutcome.signedTransaction,
|
|
9242
|
+
fence: solanaOutcome.fence,
|
|
9243
|
+
confirmation: { state: 'unknown', reason: solanaOutcome.reason },
|
|
9244
|
+
};
|
|
9245
|
+
}
|
|
9246
|
+
// Confirmed: the receipt is already complete, so the mirror read is a
|
|
9247
|
+
// best-effort enrichment reported in `mirrorSync`, never a rejection.
|
|
9248
|
+
const mirrorSync = grantLane
|
|
9249
|
+
? { observed: false, reason: 'not attempted: a venue grant authorizes only the write' }
|
|
9250
|
+
: 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);
|
|
9251
|
+
return {
|
|
9252
|
+
status: 'confirmed', appId, requestedDocuments, chain: solanaChain,
|
|
9253
|
+
transactionId: solanaOutcome.transactionSignature,
|
|
9254
|
+
signedTransaction: solanaOutcome.signedTransaction,
|
|
9255
|
+
fence: solanaOutcome.fence,
|
|
9256
|
+
confirmationContextSlot: solanaOutcome.confirmationContextSlot,
|
|
9257
|
+
mirrorSync,
|
|
9258
|
+
};
|
|
9223
9259
|
}
|
|
9224
9260
|
else {
|
|
9225
|
-
throw new Error(
|
|
9261
|
+
throw new Error('Unsupported 202 transaction shape: expected serializedTransaction');
|
|
9226
9262
|
}
|
|
9227
9263
|
}
|
|
9228
9264
|
catch (error) {
|
|
9229
|
-
|
|
9265
|
+
// The blockhash died before the send: the RPC refused the bytes in preflight, so nothing
|
|
9266
|
+
// entered the network. The worker builds a fresh one and the wallet signs it again.
|
|
9267
|
+
if (rebuilds.expiry && (await Promise.resolve().then(function () { return require('./solana-operations-DsT1303T.js'); })).isExpiredBlockhashRejection(error))
|
|
9268
|
+
return { rebuild: 'expiry' };
|
|
9269
|
+
// The Solana lane tags its own broadcast and on-chain failures; anything
|
|
9270
|
+
// untagged from it, and every poofnet step before the commit PUT, failed
|
|
9271
|
+
// before a single byte was sent.
|
|
9272
|
+
throw sending ? error : markWriteNotApplied(error, 'before_broadcast');
|
|
9230
9273
|
}
|
|
9231
9274
|
}
|
|
9232
9275
|
/**
|
|
@@ -9462,6 +9505,23 @@ async function signTransaction(transaction) {
|
|
|
9462
9505
|
}
|
|
9463
9506
|
return config.authProvider.signTransaction(transaction);
|
|
9464
9507
|
}
|
|
9508
|
+
/**
|
|
9509
|
+
* Make the signed-in wallet ready to sign without delay, BEFORE the transaction it will sign
|
|
9510
|
+
* exists. A hosted embedded wallet whose 24-hour signing session has lapsed collects its emailed
|
|
9511
|
+
* code here; a transaction built before that code is dead by the time it is signed, because a
|
|
9512
|
+
* blockhash lives about 33 seconds on mainnet (late 2026) and the code takes longer. `set` and
|
|
9513
|
+
* `setMany` do this themselves before a wallet signature; call it directly before a flow that
|
|
9514
|
+
* builds and signs outside them, such as a permit approval. Resolves `'established'` when a
|
|
9515
|
+
* ceremony ran, else `'ready'`; a wallet that holds its own key always answers `'ready'`.
|
|
9516
|
+
*/
|
|
9517
|
+
async function prepareToSign() {
|
|
9518
|
+
var _a, _b, _c;
|
|
9519
|
+
const config = await getConfig();
|
|
9520
|
+
if (!config.authProvider) {
|
|
9521
|
+
throw new Error('Auth provider not initialized. Please call init() first.');
|
|
9522
|
+
}
|
|
9523
|
+
return (_c = (await ((_b = (_a = config.authProvider).prepareToSign) === null || _b === void 0 ? void 0 : _b.call(_a)))) !== null && _c !== void 0 ? _c : 'ready';
|
|
9524
|
+
}
|
|
9465
9525
|
async function signAndSubmitTransaction(transaction, feePayer) {
|
|
9466
9526
|
const config = await getConfig();
|
|
9467
9527
|
if (!config.authProvider) {
|
|
@@ -9482,6 +9542,7 @@ var operations = /*#__PURE__*/Object.freeze({
|
|
|
9482
9542
|
getFiles: getFiles,
|
|
9483
9543
|
getMany: getMany,
|
|
9484
9544
|
onReadCacheAuthChange: onReadCacheAuthChange,
|
|
9545
|
+
prepareToSign: prepareToSign,
|
|
9485
9546
|
queryAggregate: queryAggregate,
|
|
9486
9547
|
runExpression: runExpression,
|
|
9487
9548
|
runExpressionMany: runExpressionMany,
|
|
@@ -9496,9 +9557,81 @@ var operations = /*#__PURE__*/Object.freeze({
|
|
|
9496
9557
|
signTransaction: signTransaction
|
|
9497
9558
|
});
|
|
9498
9559
|
|
|
9560
|
+
const DEFAULT_POLL_INTERVAL_MS$1 = 1000;
|
|
9561
|
+
const DEFAULT_MAX_WAIT_MS = 120000;
|
|
9562
|
+
/**
|
|
9563
|
+
* Whether a status is final enough to decide on. `processed` can still belong to a fork
|
|
9564
|
+
* that is dropped, so only `confirmed` or `finalized` settle a write; an RPC that omits
|
|
9565
|
+
* `confirmationStatus` reports a rooted transaction as `confirmations: null`.
|
|
9566
|
+
*/
|
|
9567
|
+
function settledSignatureStatus(status) {
|
|
9568
|
+
if (!status)
|
|
9569
|
+
return false;
|
|
9570
|
+
if (status.confirmationStatus === 'confirmed' || status.confirmationStatus === 'finalized')
|
|
9571
|
+
return true;
|
|
9572
|
+
return status.confirmationStatus == null && status.confirmations === null;
|
|
9573
|
+
}
|
|
9574
|
+
/**
|
|
9575
|
+
* Poll the SAME signature until it is seen at `confirmed` or the blockhash fence closes.
|
|
9576
|
+
* Never broadcasts. A `processed` status, even one carrying an error, is not a verdict and
|
|
9577
|
+
* keeps the loop going. Once the confirmed block height passes `lastValidBlockHeight`, one
|
|
9578
|
+
* history-searching read decides whether the transaction landed anyway; if not, the answer
|
|
9579
|
+
* is "not seen" or "seen only below confirmed", never "never landed": only a finalized
|
|
9580
|
+
* expiry proves that, which is `reconcileSetResult`'s job. Transient RPC failures retry the
|
|
9581
|
+
* same signature.
|
|
9582
|
+
*/
|
|
9583
|
+
async function confirmSignature(rpc, fence, options = {}) {
|
|
9584
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
9585
|
+
if (typeof rpc.getSignatureStatuses !== 'function' || typeof rpc.getBlockHeight !== 'function') {
|
|
9586
|
+
// An injected RPC that cannot answer is reported at once, not retried for two minutes.
|
|
9587
|
+
return { landed: false, reason: 'the configured Solana RPC cannot report signature statuses and block height' };
|
|
9588
|
+
}
|
|
9589
|
+
const pollIntervalMs = (_a = options.pollIntervalMs) !== null && _a !== void 0 ? _a : DEFAULT_POLL_INTERVAL_MS$1;
|
|
9590
|
+
const maxWaitMs = (_b = options.maxWaitMs) !== null && _b !== void 0 ? _b : DEFAULT_MAX_WAIT_MS;
|
|
9591
|
+
const startedAt = Date.now();
|
|
9592
|
+
let lastFailure = null;
|
|
9593
|
+
for (;;) {
|
|
9594
|
+
try {
|
|
9595
|
+
// Status first: a settled status decides on its own, and the height is read only
|
|
9596
|
+
// while the transaction is still unseen, so a failing height read never discards
|
|
9597
|
+
// a confirmation this tick already has.
|
|
9598
|
+
const statuses = await rpc.getSignatureStatuses([fence.signature]);
|
|
9599
|
+
const status = (_d = (_c = statuses === null || statuses === void 0 ? void 0 : statuses.value) === null || _c === void 0 ? void 0 : _c[0]) !== null && _d !== void 0 ? _d : null;
|
|
9600
|
+
if (settledSignatureStatus(status))
|
|
9601
|
+
return { landed: true, status, contextSlot: (_e = statuses === null || statuses === void 0 ? void 0 : statuses.context) === null || _e === void 0 ? void 0 : _e.slot };
|
|
9602
|
+
const blockHeight = await rpc.getBlockHeight('confirmed');
|
|
9603
|
+
if (blockHeight > fence.lastValidBlockHeight) {
|
|
9604
|
+
const history = await rpc.getSignatureStatuses([fence.signature], { searchTransactionHistory: true });
|
|
9605
|
+
const late = (_g = (_f = history === null || history === void 0 ? void 0 : history.value) === null || _f === void 0 ? void 0 : _f[0]) !== null && _g !== void 0 ? _g : null;
|
|
9606
|
+
if (settledSignatureStatus(late))
|
|
9607
|
+
return { landed: true, status: late, contextSlot: (_h = history === null || history === void 0 ? void 0 : history.context) === null || _h === void 0 ? void 0 : _h.slot };
|
|
9608
|
+
const seen = late ? `seen only at ${String((_j = late.confirmationStatus) !== null && _j !== void 0 ? _j : 'an unconfirmed')} commitment` : 'not seen at confirmed';
|
|
9609
|
+
return {
|
|
9610
|
+
landed: false,
|
|
9611
|
+
reason: `${seen} before the blockhash expired (block height ${blockHeight} is past ${fence.lastValidBlockHeight})`,
|
|
9612
|
+
};
|
|
9613
|
+
}
|
|
9614
|
+
lastFailure = null;
|
|
9615
|
+
}
|
|
9616
|
+
catch (error) {
|
|
9617
|
+
// Transient: keep polling the same signature. The ceiling below bounds a dead RPC.
|
|
9618
|
+
lastFailure = error instanceof Error ? error.message : String(error);
|
|
9619
|
+
}
|
|
9620
|
+
if (Date.now() - startedAt >= maxWaitMs) {
|
|
9621
|
+
return {
|
|
9622
|
+
landed: false,
|
|
9623
|
+
reason: lastFailure
|
|
9624
|
+
? `the RPC kept failing while the transaction was awaited: ${lastFailure}`
|
|
9625
|
+
: `not seen at confirmed within ${Math.round(maxWaitMs / 1000)}s and the block height never passed the blockhash fence`,
|
|
9626
|
+
};
|
|
9627
|
+
}
|
|
9628
|
+
await new Promise((resolve) => setTimeout(resolve, pollIntervalMs));
|
|
9629
|
+
}
|
|
9630
|
+
}
|
|
9631
|
+
|
|
9499
9632
|
const DEFAULT_TIMEOUT_MS = 60000;
|
|
9500
|
-
const DEFAULT_MAX_ATTEMPTS$1 =
|
|
9501
|
-
const DEFAULT_POLL_INTERVAL_MS =
|
|
9633
|
+
const DEFAULT_MAX_ATTEMPTS$1 = 60;
|
|
9634
|
+
const DEFAULT_POLL_INTERVAL_MS = 1000;
|
|
9502
9635
|
function errorText(error) {
|
|
9503
9636
|
const message = error === null || error === void 0 ? void 0 : error.message;
|
|
9504
9637
|
return typeof message === 'string' && message.length > 0 ? message : String(error);
|
|
@@ -9566,18 +9699,6 @@ async function resolveSolanaRpc(config, options) {
|
|
|
9566
9699
|
const { Connection } = await import('@solana/web3.js');
|
|
9567
9700
|
return new Connection(rpcUrl, 'confirmed');
|
|
9568
9701
|
}
|
|
9569
|
-
/**
|
|
9570
|
-
* Whether a signature status is final enough to decide on. `processed` can still belong to a fork
|
|
9571
|
-
* that is dropped, so only `confirmed` or `finalized` settle a write; an RPC that omits
|
|
9572
|
-
* `confirmationStatus` reports a rooted transaction as `confirmations: null`.
|
|
9573
|
-
*/
|
|
9574
|
-
function settledStatus(status) {
|
|
9575
|
-
if (!status)
|
|
9576
|
-
return false;
|
|
9577
|
-
if (status.confirmationStatus === 'confirmed' || status.confirmationStatus === 'finalized')
|
|
9578
|
-
return true;
|
|
9579
|
-
return status.confirmationStatus == null && status.confirmations === null;
|
|
9580
|
-
}
|
|
9581
9702
|
/**
|
|
9582
9703
|
* Solana reconciliation NEVER broadcasts. It settles on a `confirmed` or `finalized` status only,
|
|
9583
9704
|
* and reaches `expired_not_landed` only from the chain's own blockhash expiry: the FINALIZED block
|
|
@@ -9589,17 +9710,13 @@ function settledStatus(status) {
|
|
|
9589
9710
|
async function reconcileSolana(receipt, config, options) {
|
|
9590
9711
|
var _a, _b, _c, _d;
|
|
9591
9712
|
const rpc = await resolveSolanaRpc(config, options);
|
|
9592
|
-
if (typeof rpc.getSignatureStatuses !== 'function') {
|
|
9593
|
-
return stillSubmitted(receipt, 'the configured Solana RPC cannot report signature statuses');
|
|
9594
|
-
}
|
|
9595
9713
|
// Expiry is read BEFORE the status, so an absence observed afterwards is an absence after the
|
|
9596
9714
|
// fence closed for good. A finalized height past lastValidBlockHeight is final: the blockhash
|
|
9597
9715
|
// can never become valid again.
|
|
9598
9716
|
let finalizedHeight;
|
|
9599
9717
|
let finalizedSlot;
|
|
9600
9718
|
try {
|
|
9601
|
-
|
|
9602
|
-
finalizedHeight = await rpc.getBlockHeight('finalized');
|
|
9719
|
+
finalizedHeight = await rpc.getBlockHeight('finalized');
|
|
9603
9720
|
if (typeof rpc.getSlot === 'function')
|
|
9604
9721
|
finalizedSlot = await rpc.getSlot('finalized');
|
|
9605
9722
|
}
|
|
@@ -9618,7 +9735,7 @@ async function reconcileSolana(receipt, config, options) {
|
|
|
9618
9735
|
return stillSubmitted(receipt, `signature status lookup failed: ${errorText(error)}`);
|
|
9619
9736
|
}
|
|
9620
9737
|
if (statusValue) {
|
|
9621
|
-
if (!
|
|
9738
|
+
if (!settledSignatureStatus(statusValue)) {
|
|
9622
9739
|
return stillSubmitted(receipt, `seen at ${String((_d = statusValue.confirmationStatus) !== null && _d !== void 0 ? _d : 'an unconfirmed')} commitment; waiting for confirmed`);
|
|
9623
9740
|
}
|
|
9624
9741
|
// Landed. A landed-but-failed transaction is a genuine failure, not `submitted`.
|
|
@@ -10988,7 +11105,7 @@ function toMillis(seconds) {
|
|
|
10988
11105
|
|
|
10989
11106
|
/** SIWS message creation is async already, so its onchain module can be lazy. */
|
|
10990
11107
|
async function genSolanaMessage(address, nonce) {
|
|
10991
|
-
const implementation = await Promise.resolve().then(function () { return require('./solana-message-
|
|
11108
|
+
const implementation = await Promise.resolve().then(function () { return require('./solana-message-CPotom18.js'); });
|
|
10992
11109
|
return implementation.genSolanaMessage(address, nonce);
|
|
10993
11110
|
}
|
|
10994
11111
|
|
|
@@ -11567,6 +11684,7 @@ exports.clearAppTokenCache = clearAppTokenCache;
|
|
|
11567
11684
|
exports.clearCache = clearCache;
|
|
11568
11685
|
exports.closeAllQuerySubscriptions = closeAllQuerySubscriptions;
|
|
11569
11686
|
exports.closeAllSubscriptions = closeAllSubscriptions;
|
|
11687
|
+
exports.confirmSignature = confirmSignature;
|
|
11570
11688
|
exports.count = count;
|
|
11571
11689
|
exports.createAppTokenAuthHeaders = createAppTokenAuthHeaders;
|
|
11572
11690
|
exports.createClient = createClient;
|
|
@@ -11612,6 +11730,7 @@ exports.normalizeEvmAddress = normalizeEvmAddress;
|
|
|
11612
11730
|
exports.now = now;
|
|
11613
11731
|
exports.onSessionChange = onSessionChange;
|
|
11614
11732
|
exports.onSessionCleared = onSessionCleared;
|
|
11733
|
+
exports.prepareToSign = prepareToSign;
|
|
11615
11734
|
exports.queryAggregate = queryAggregate;
|
|
11616
11735
|
exports.reconcileSetResult = reconcileSetResult;
|
|
11617
11736
|
exports.reconnectWithNewAuth = reconnectWithNewAuth;
|
|
@@ -11642,4 +11761,4 @@ exports.toSeconds = toSeconds;
|
|
|
11642
11761
|
exports.waitForSetResult = waitForSetResult;
|
|
11643
11762
|
exports.withEffects = withEffects;
|
|
11644
11763
|
exports.writeNotAppliedPhase = writeNotAppliedPhase;
|
|
11645
|
-
//# sourceMappingURL=index-
|
|
11764
|
+
//# sourceMappingURL=index-D7-5ecyu.js.map
|