Add marketplace checkout harness controls to launcher
This commit is contained in:
parent
9b989bd735
commit
b1fb4706a8
@ -37,9 +37,10 @@ Advanced integration controls (collapsible):
|
|||||||
1. API/chain connection settings
|
1. API/chain connection settings
|
||||||
2. Wallet intent + verify primitives
|
2. Wallet intent + verify primitives
|
||||||
3. Membership quote + confirm primitives
|
3. Membership quote + confirm primitives
|
||||||
4. Member channel register/poll primitives
|
4. Marketplace offer list + checkout quote/confirm primitives
|
||||||
5. Governance install + lease primitives
|
5. Member channel register/poll primitives
|
||||||
6. Raw response log for deterministic troubleshooting
|
6. Governance install + lease primitives
|
||||||
|
7. Raw response log for deterministic troubleshooting
|
||||||
|
|
||||||
Wallet automation helpers remain available in advanced controls:
|
Wallet automation helpers remain available in advanced controls:
|
||||||
|
|
||||||
|
|||||||
67
app/app.js
67
app/app.js
@ -6,6 +6,7 @@ const state = {
|
|||||||
eventMap: new Map(),
|
eventMap: new Map(),
|
||||||
lastIntent: null,
|
lastIntent: null,
|
||||||
lastQuote: null,
|
lastQuote: null,
|
||||||
|
lastCheckoutQuote: null,
|
||||||
channelReady: false,
|
channelReady: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -584,6 +585,68 @@ async function onInstallStatus() {
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function onListOffers() {
|
||||||
|
const out = await request("GET", "/marketplace/offers");
|
||||||
|
logLine("marketplace offers", out);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function onCheckoutQuote() {
|
||||||
|
const payload = {
|
||||||
|
wallet: requireWallet(),
|
||||||
|
offer_id: $("checkoutOfferId").value.trim(),
|
||||||
|
org_root_id: orgRootID(),
|
||||||
|
principal_id: principalID(),
|
||||||
|
principal_role: principalRole(),
|
||||||
|
include_membership_if_missing: true,
|
||||||
|
};
|
||||||
|
const payerWallet = $("payerWallet").value.trim();
|
||||||
|
const payerProof = $("payerProof").value.trim();
|
||||||
|
if (payerWallet) {
|
||||||
|
payload.payer_wallet = payerWallet;
|
||||||
|
}
|
||||||
|
if (payerProof) {
|
||||||
|
payload.ownership_proof = payerProof;
|
||||||
|
}
|
||||||
|
const out = await request("POST", "/marketplace/checkout/quote", payload);
|
||||||
|
state.lastCheckoutQuote = out;
|
||||||
|
$("checkoutQuoteId").value = out.quote_id || "";
|
||||||
|
$("checkoutTotal").value = out.total_amount || "";
|
||||||
|
logLine("marketplace checkout quote", out);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function onCheckoutConfirm() {
|
||||||
|
const quoteID = $("checkoutQuoteId").value.trim();
|
||||||
|
if (!quoteID) {
|
||||||
|
throw new Error("checkout quote id is required");
|
||||||
|
}
|
||||||
|
const txHash = $("checkoutTxHash").value.trim();
|
||||||
|
if (!txHash) {
|
||||||
|
throw new Error("checkout tx hash is required");
|
||||||
|
}
|
||||||
|
const offerID = state.lastCheckoutQuote?.offer_id || $("checkoutOfferId").value.trim();
|
||||||
|
const out = await request("POST", "/marketplace/checkout/confirm", {
|
||||||
|
quote_id: quoteID,
|
||||||
|
wallet: requireWallet(),
|
||||||
|
offer_id: offerID,
|
||||||
|
org_root_id: orgRootID(),
|
||||||
|
principal_id: principalID(),
|
||||||
|
principal_role: principalRole(),
|
||||||
|
tx_hash: txHash,
|
||||||
|
chain_id: chainID(),
|
||||||
|
});
|
||||||
|
$("checkoutEntitlementId").value = out.entitlement_id || "";
|
||||||
|
logLine("marketplace checkout confirm", out);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function onListEntitlements() {
|
||||||
|
const out = await request("GET", `/marketplace/entitlements?wallet=${encodeURIComponent(requireWallet())}`);
|
||||||
|
logLine("marketplace entitlements", out);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
async function ensureChannelBinding() {
|
async function ensureChannelBinding() {
|
||||||
if (state.channelReady) {
|
if (state.channelReady) {
|
||||||
return;
|
return;
|
||||||
@ -690,6 +753,10 @@ bind("btnInstallConfirm", onInstallConfirm);
|
|||||||
bind("btnInstallStatus", onInstallStatus);
|
bind("btnInstallStatus", onInstallStatus);
|
||||||
bind("btnLeaseHeartbeat", onLeaseHeartbeat);
|
bind("btnLeaseHeartbeat", onLeaseHeartbeat);
|
||||||
bind("btnOfflineRenew", onOfflineRenew);
|
bind("btnOfflineRenew", onOfflineRenew);
|
||||||
|
bind("btnListOffers", onListOffers);
|
||||||
|
bind("btnCheckoutQuote", onCheckoutQuote);
|
||||||
|
bind("btnCheckoutConfirm", onCheckoutConfirm);
|
||||||
|
bind("btnListEntitlements", onListEntitlements);
|
||||||
|
|
||||||
logLine("launcher shell ready", {
|
logLine("launcher shell ready", {
|
||||||
api_base: baseURL(),
|
api_base: baseURL(),
|
||||||
|
|||||||
@ -167,6 +167,46 @@
|
|||||||
</label>
|
</label>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
<section class="subpanel">
|
||||||
|
<h2>Marketplace Checkout</h2>
|
||||||
|
<div class="actions">
|
||||||
|
<button id="btnListOffers">List offers</button>
|
||||||
|
<button id="btnCheckoutQuote">Checkout quote</button>
|
||||||
|
<button id="btnCheckoutConfirm">Checkout confirm</button>
|
||||||
|
<button id="btnListEntitlements">List entitlements</button>
|
||||||
|
</div>
|
||||||
|
<div class="grid three">
|
||||||
|
<label>
|
||||||
|
Offer ID
|
||||||
|
<select id="checkoutOfferId">
|
||||||
|
<option value="edut.solo.core">edut.solo.core</option>
|
||||||
|
<option value="edut.workspace.core">edut.workspace.core</option>
|
||||||
|
<option value="edut.workspace.ai">edut.workspace.ai</option>
|
||||||
|
<option value="edut.workspace.lane24">edut.workspace.lane24</option>
|
||||||
|
<option value="edut.workspace.sovereign">edut.workspace.sovereign</option>
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
|
<label>
|
||||||
|
Checkout quote ID
|
||||||
|
<input id="checkoutQuoteId" />
|
||||||
|
</label>
|
||||||
|
<label>
|
||||||
|
Checkout tx hash
|
||||||
|
<input id="checkoutTxHash" placeholder="0x..." />
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="grid two">
|
||||||
|
<label>
|
||||||
|
Checkout total
|
||||||
|
<input id="checkoutTotal" />
|
||||||
|
</label>
|
||||||
|
<label>
|
||||||
|
Checkout entitlement ID
|
||||||
|
<input id="checkoutEntitlementId" />
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
<section class="subpanel">
|
<section class="subpanel">
|
||||||
<h2>Member Channel</h2>
|
<h2>Member Channel</h2>
|
||||||
<div class="grid three">
|
<div class="grid three">
|
||||||
|
|||||||
@ -9,10 +9,14 @@ Launcher integrates with EDUT web/backend contracts as follows:
|
|||||||
3. `POST /secret/membership/quote`
|
3. `POST /secret/membership/quote`
|
||||||
4. `POST /secret/membership/confirm`
|
4. `POST /secret/membership/confirm`
|
||||||
5. `GET /secret/membership/status`
|
5. `GET /secret/membership/status`
|
||||||
6. `POST /governance/install/token`
|
6. `GET /marketplace/offers`
|
||||||
7. `POST /governance/install/confirm`
|
7. `POST /marketplace/checkout/quote`
|
||||||
8. `GET /governance/install/status`
|
8. `POST /marketplace/checkout/confirm`
|
||||||
9. `GET /member/channel/events`
|
9. `GET /marketplace/entitlements`
|
||||||
|
10. `POST /governance/install/token`
|
||||||
|
11. `POST /governance/install/confirm`
|
||||||
|
12. `GET /governance/install/status`
|
||||||
|
13. `GET /member/channel/events`
|
||||||
|
|
||||||
## Deterministic Requirements
|
## Deterministic Requirements
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user