feat(scripts): add end-to-end membership flow smoke runner
This commit is contained in:
parent
014712eab8
commit
cfb4770e7e
@ -8,7 +8,8 @@
|
||||
"test": "hardhat test",
|
||||
"check": "npm run build && npm run test",
|
||||
"deploy:sepolia": "hardhat run scripts/deploy-membership.cjs --network baseSepolia",
|
||||
"deploy:mainnet": "hardhat run scripts/deploy-membership.cjs --network base"
|
||||
"deploy:mainnet": "hardhat run scripts/deploy-membership.cjs --network base",
|
||||
"smoke:e2e:sepolia": "node scripts/e2e-membership-flow.cjs"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nomiclabs/hardhat-ethers": "^2.2.3",
|
||||
|
||||
165
scripts/e2e-membership-flow.cjs
Normal file
165
scripts/e2e-membership-flow.cjs
Normal file
@ -0,0 +1,165 @@
|
||||
const { ethers } = require("ethers");
|
||||
|
||||
const API_BASE = (process.env.SECRET_API_BASE_URL || "https://api.edut.ai").trim();
|
||||
const ORIGIN = (process.env.SECRET_API_ORIGIN || "https://edut.ai").trim();
|
||||
const LOCALE = (process.env.SECRET_API_LOCALE || "en-US").trim();
|
||||
const CHAIN_ID = Number((process.env.SECRET_API_CHAIN_ID || "84532").trim());
|
||||
const PRIVATE_KEY = (process.env.DEPLOYER_PRIVATE_KEY || "").trim();
|
||||
const RPC_URL = (process.env.BASE_SEPOLIA_RPC_URL || "").trim();
|
||||
const GAS_PRICE_WEI = (process.env.E2E_GAS_PRICE_WEI || "").trim();
|
||||
|
||||
function required(name, value) {
|
||||
if (!value) {
|
||||
throw new Error(`Missing required env: ${name}`);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
async function postJSON(path, payload) {
|
||||
const res = await fetch(`${API_BASE}${path}`, {
|
||||
method: "POST",
|
||||
headers: { "content-type": "application/json" },
|
||||
body: JSON.stringify(payload),
|
||||
});
|
||||
const text = await res.text();
|
||||
let data;
|
||||
try {
|
||||
data = text ? JSON.parse(text) : {};
|
||||
} catch (err) {
|
||||
throw new Error(`${path} returned non-json response: ${text}`);
|
||||
}
|
||||
if (!res.ok) {
|
||||
throw new Error(`${path} failed (${res.status}): ${JSON.stringify(data)}`);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
async function getJSON(path) {
|
||||
const res = await fetch(`${API_BASE}${path}`);
|
||||
const text = await res.text();
|
||||
let data;
|
||||
try {
|
||||
data = text ? JSON.parse(text) : {};
|
||||
} catch (err) {
|
||||
throw new Error(`${path} returned non-json response: ${text}`);
|
||||
}
|
||||
if (!res.ok) {
|
||||
throw new Error(`${path} failed (${res.status}): ${JSON.stringify(data)}`);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
async function main() {
|
||||
required("DEPLOYER_PRIVATE_KEY", PRIVATE_KEY);
|
||||
required("BASE_SEPOLIA_RPC_URL", RPC_URL);
|
||||
|
||||
const provider = new ethers.providers.JsonRpcProvider(RPC_URL);
|
||||
const signer = new ethers.Wallet(PRIVATE_KEY, provider);
|
||||
const address = await signer.getAddress();
|
||||
console.log("wallet:", address);
|
||||
console.log("chain_id:", CHAIN_ID);
|
||||
console.log("api_base:", API_BASE);
|
||||
|
||||
const intent = await postJSON("/secret/wallet/intent", {
|
||||
address,
|
||||
origin: ORIGIN,
|
||||
locale: LOCALE,
|
||||
chain_id: CHAIN_ID,
|
||||
});
|
||||
console.log("intent_id:", intent.intent_id);
|
||||
console.log("designation_code:", intent.designation_code);
|
||||
console.log("display_token:", intent.display_token);
|
||||
|
||||
const domain = {
|
||||
name: intent.domain_name,
|
||||
version: "1",
|
||||
chainId: intent.chain_id,
|
||||
verifyingContract: intent.verifying_contract,
|
||||
};
|
||||
const types = {
|
||||
DesignationIntent: [
|
||||
{ name: "designationCode", type: "string" },
|
||||
{ name: "designationToken", type: "string" },
|
||||
{ name: "nonce", type: "string" },
|
||||
{ name: "issuedAt", type: "string" },
|
||||
{ name: "origin", type: "string" },
|
||||
],
|
||||
};
|
||||
const message = {
|
||||
designationCode: intent.designation_code,
|
||||
designationToken: intent.display_token,
|
||||
nonce: intent.nonce,
|
||||
issuedAt: intent.issued_at,
|
||||
origin: ORIGIN,
|
||||
};
|
||||
const signature = await signer._signTypedData(domain, types, message);
|
||||
|
||||
const verify = await postJSON("/secret/wallet/verify", {
|
||||
intent_id: intent.intent_id,
|
||||
address,
|
||||
chain_id: CHAIN_ID,
|
||||
signature,
|
||||
});
|
||||
console.log("verify_status:", verify.status);
|
||||
|
||||
const quote = await postJSON("/secret/membership/quote", {
|
||||
designation_code: intent.designation_code,
|
||||
address,
|
||||
chain_id: CHAIN_ID,
|
||||
});
|
||||
console.log("quote_id:", quote.quote_id);
|
||||
console.log("contract:", quote.contract_address);
|
||||
console.log("value:", quote.value);
|
||||
|
||||
const txReq = quote.tx || {
|
||||
to: quote.contract_address,
|
||||
data: quote.calldata,
|
||||
value: quote.value,
|
||||
};
|
||||
const txRequest = {
|
||||
to: txReq.to,
|
||||
data: txReq.data,
|
||||
value: txReq.value,
|
||||
};
|
||||
if (GAS_PRICE_WEI) {
|
||||
txRequest.gasPrice = ethers.BigNumber.from(GAS_PRICE_WEI);
|
||||
}
|
||||
const tx = await signer.sendTransaction(txRequest);
|
||||
console.log("submitted_tx:", tx.hash);
|
||||
await tx.wait(1);
|
||||
console.log("mined_tx:", tx.hash);
|
||||
|
||||
const confirm = await postJSON("/secret/membership/confirm", {
|
||||
designation_code: intent.designation_code,
|
||||
quote_id: quote.quote_id,
|
||||
tx_hash: tx.hash,
|
||||
address,
|
||||
chain_id: CHAIN_ID,
|
||||
});
|
||||
console.log("confirm_status:", confirm.status);
|
||||
|
||||
const status = await getJSON(
|
||||
`/secret/membership/status?wallet=${encodeURIComponent(address)}`
|
||||
);
|
||||
console.log("membership_status:", status.status);
|
||||
|
||||
console.log(
|
||||
JSON.stringify(
|
||||
{
|
||||
wallet: address,
|
||||
designation_code: intent.designation_code,
|
||||
quote_id: quote.quote_id,
|
||||
tx_hash: tx.hash,
|
||||
confirm_status: confirm.status,
|
||||
membership_status: status.status,
|
||||
},
|
||||
null,
|
||||
2
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
main().catch((err) => {
|
||||
console.error(err.message || err);
|
||||
process.exit(1);
|
||||
});
|
||||
Loading…
Reference in New Issue
Block a user