Harden control-plane smoke for low-balance tx states
Some checks are pending
check / contracts (push) Waiting to run
Some checks are pending
check / contracts (push) Waiting to run
This commit is contained in:
parent
60d7cbc5e1
commit
048482b05f
@ -88,6 +88,23 @@ function summarizeSkip(reasonCode, httpStatus, detail) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isInsufficientFundsError(err) {
|
||||||
|
const text = String(err?.message || err || "").toLowerCase();
|
||||||
|
return text.includes("insufficient funds");
|
||||||
|
}
|
||||||
|
|
||||||
|
function isTxPendingResponse(result) {
|
||||||
|
if (!result || result.ok) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const code = String(result.data?.code || "").toLowerCase();
|
||||||
|
const detail = String(result.data?.error || "").toLowerCase();
|
||||||
|
if (result.status === 409 && code.includes("verification") && detail.includes("pending")) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
required("DEPLOYER_PRIVATE_KEY", PRIVATE_KEY);
|
required("DEPLOYER_PRIVATE_KEY", PRIVATE_KEY);
|
||||||
required("BASE_SEPOLIA_RPC_URL", RPC_URL);
|
required("BASE_SEPOLIA_RPC_URL", RPC_URL);
|
||||||
@ -161,7 +178,25 @@ async function main() {
|
|||||||
chain_id: CHAIN_ID,
|
chain_id: CHAIN_ID,
|
||||||
});
|
});
|
||||||
|
|
||||||
const membershipTxHash = await submitTransaction(signer, quote.tx || {});
|
let membershipTxHash;
|
||||||
|
try {
|
||||||
|
membershipTxHash = await submitTransaction(signer, quote.tx || {});
|
||||||
|
} catch (err) {
|
||||||
|
if (isInsufficientFundsError(err)) {
|
||||||
|
result.stages.membership_activation = summarizeSkip(
|
||||||
|
"insufficient_funds",
|
||||||
|
0,
|
||||||
|
String(err?.message || err)
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!membershipTxHash) {
|
||||||
|
console.log(JSON.stringify(result, null, 2));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const confirmPayload = {
|
const confirmPayload = {
|
||||||
designation_code: intent.designation_code,
|
designation_code: intent.designation_code,
|
||||||
quote_id: quote.quote_id,
|
quote_id: quote.quote_id,
|
||||||
@ -179,12 +214,26 @@ async function main() {
|
|||||||
confirmPayload.identity_attestation_id = IDENTITY_ATTESTATION_ID;
|
confirmPayload.identity_attestation_id = IDENTITY_ATTESTATION_ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
const confirm = await expectOK("POST", "/secret/membership/confirm", confirmPayload);
|
const confirmRes = await requestJSON("POST", "/secret/membership/confirm", confirmPayload);
|
||||||
|
if (!confirmRes.ok) {
|
||||||
|
if (isTxPendingResponse(confirmRes)) {
|
||||||
|
result.stages.membership_activation = summarizeSkip(
|
||||||
|
"tx_pending",
|
||||||
|
confirmRes.status,
|
||||||
|
confirmRes.data?.error || JSON.stringify(confirmRes.data || {})
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
throw new Error(
|
||||||
|
`POST /secret/membership/confirm failed (${confirmRes.status}): ${JSON.stringify(confirmRes.data)}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
result.stages.membership_activation = {
|
result.stages.membership_activation = {
|
||||||
status: confirm.status,
|
status: confirmRes.data.status,
|
||||||
tx_hash: membershipTxHash,
|
tx_hash: membershipTxHash,
|
||||||
identity_assurance_level: confirm.identity_assurance_level || null,
|
identity_assurance_level: confirmRes.data.identity_assurance_level || null,
|
||||||
};
|
};
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
result.stages.membership_activation = {
|
result.stages.membership_activation = {
|
||||||
status: "skipped_already_active",
|
status: "skipped_already_active",
|
||||||
@ -236,8 +285,26 @@ async function main() {
|
|||||||
"checkout quote returned empty calldata"
|
"checkout quote returned empty calldata"
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
const checkoutTxHash = await submitTransaction(signer, checkoutQuote.tx || {});
|
let checkoutTxHash;
|
||||||
const checkoutConfirm = await expectOK(
|
try {
|
||||||
|
checkoutTxHash = await submitTransaction(signer, checkoutQuote.tx || {});
|
||||||
|
} catch (err) {
|
||||||
|
if (isInsufficientFundsError(err)) {
|
||||||
|
result.stages.marketplace_checkout = summarizeSkip(
|
||||||
|
"insufficient_funds",
|
||||||
|
0,
|
||||||
|
String(err?.message || err)
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!checkoutTxHash) {
|
||||||
|
console.log(JSON.stringify(result, null, 2));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const checkoutConfirmRes = await requestJSON(
|
||||||
"POST",
|
"POST",
|
||||||
"/marketplace/checkout/confirm",
|
"/marketplace/checkout/confirm",
|
||||||
{
|
{
|
||||||
@ -253,6 +320,19 @@ async function main() {
|
|||||||
},
|
},
|
||||||
sessionToken
|
sessionToken
|
||||||
);
|
);
|
||||||
|
if (!checkoutConfirmRes.ok) {
|
||||||
|
if (isTxPendingResponse(checkoutConfirmRes)) {
|
||||||
|
result.stages.marketplace_checkout = summarizeSkip(
|
||||||
|
"tx_pending",
|
||||||
|
checkoutConfirmRes.status,
|
||||||
|
checkoutConfirmRes.data?.error || JSON.stringify(checkoutConfirmRes.data || {})
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
throw new Error(
|
||||||
|
`POST /marketplace/checkout/confirm failed (${checkoutConfirmRes.status}): ${JSON.stringify(checkoutConfirmRes.data)}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
const entitlements = await expectOK(
|
const entitlements = await expectOK(
|
||||||
"GET",
|
"GET",
|
||||||
`/marketplace/entitlements?wallet=${encodeURIComponent(wallet)}`,
|
`/marketplace/entitlements?wallet=${encodeURIComponent(wallet)}`,
|
||||||
@ -260,8 +340,8 @@ async function main() {
|
|||||||
sessionToken
|
sessionToken
|
||||||
);
|
);
|
||||||
result.stages.marketplace_checkout = {
|
result.stages.marketplace_checkout = {
|
||||||
status: checkoutConfirm.status,
|
status: checkoutConfirmRes.data.status,
|
||||||
entitlement_id: checkoutConfirm.entitlement_id,
|
entitlement_id: checkoutConfirmRes.data.entitlement_id,
|
||||||
tx_hash: checkoutTxHash,
|
tx_hash: checkoutTxHash,
|
||||||
entitlement_count: Array.isArray(entitlements.entitlements)
|
entitlement_count: Array.isArray(entitlements.entitlements)
|
||||||
? entitlements.entitlements.length
|
? entitlements.entitlements.length
|
||||||
@ -269,6 +349,7 @@ async function main() {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const installTokenRes = await requestJSON(
|
const installTokenRes = await requestJSON(
|
||||||
"POST",
|
"POST",
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user