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",
|
"test": "hardhat test",
|
||||||
"check": "npm run build && npm run test",
|
"check": "npm run build && npm run test",
|
||||||
"deploy:sepolia": "hardhat run scripts/deploy-membership.cjs --network baseSepolia",
|
"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": {
|
"devDependencies": {
|
||||||
"@nomiclabs/hardhat-ethers": "^2.2.3",
|
"@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