package main import ( "context" "encoding/json" "errors" "fmt" "math/big" "net/http" "sort" "strconv" "strings" "time" ) const ( marketplaceMembershipActivationAtomic = "100000000" // 100.00 USDC (6 decimals) marketplaceStandardOfferAtomic = "1000000000" // 1000.00 USDC (6 decimals) offerIDSoloCore = "edut.solo.core" offerIDWorkspaceCore = "edut.workspace.core" offerIDWorkspaceAI = "edut.workspace.ai" offerIDWorkspaceLane24 = "edut.workspace.lane24" offerIDWorkspaceSovereign = "edut.workspace.sovereign" ) func (a *app) marketplaceOffers() []marketplaceOffer { offers := []marketplaceOffer{ { OfferID: offerIDSoloCore, IssuerID: "edut.firstparty", Title: "EDUT Solo Core", Summary: "Single-principal governance runtime for personal operations.", Status: "active", Pricing: marketplaceOfferPrice{ Currency: "USDC", AmountAtomic: marketplaceStandardOfferAtomic, Decimals: 6, ChainID: a.cfg.ChainID, }, Policies: marketplaceOfferPolicy{ MemberOnly: true, WorkspaceBound: true, Transferable: false, InternalUseOnly: true, MultiTenant: false, EntitlementClass: "solo_core", }, SortOrder: 10, }, { OfferID: offerIDWorkspaceCore, IssuerID: "edut.firstparty", Title: "EDUT Workspace Core", Summary: "Org-bound deterministic governance runtime for team operations.", Status: "active", Pricing: marketplaceOfferPrice{ Currency: "USDC", AmountAtomic: marketplaceStandardOfferAtomic, Decimals: 6, ChainID: a.cfg.ChainID, }, Policies: marketplaceOfferPolicy{ MemberOnly: true, WorkspaceBound: true, Transferable: false, InternalUseOnly: true, MultiTenant: false, EntitlementClass: "workspace_core", }, SortOrder: 20, }, { OfferID: offerIDWorkspaceAI, IssuerID: "edut.firstparty", Title: "EDUT Workspace AI Layer", Summary: "AI reasoning layer for governed workspace operations.", Status: "active", Pricing: marketplaceOfferPrice{ Currency: "USDC", AmountAtomic: marketplaceStandardOfferAtomic, Decimals: 6, ChainID: a.cfg.ChainID, }, Policies: marketplaceOfferPolicy{ MemberOnly: true, WorkspaceBound: true, Transferable: false, InternalUseOnly: true, MultiTenant: false, EntitlementClass: "workspace_ai", RequiresOffers: []string{offerIDWorkspaceCore}, }, SortOrder: 30, }, { OfferID: offerIDWorkspaceLane24, IssuerID: "edut.firstparty", Title: "EDUT Workspace 24h Lane", Summary: "Autonomous execution lane capacity for workspace queue throughput.", Status: "active", Pricing: marketplaceOfferPrice{ Currency: "USDC", AmountAtomic: marketplaceStandardOfferAtomic, Decimals: 6, ChainID: a.cfg.ChainID, }, Policies: marketplaceOfferPolicy{ MemberOnly: true, WorkspaceBound: true, Transferable: false, InternalUseOnly: true, MultiTenant: false, EntitlementClass: "workspace_lane24", RequiresOffers: []string{offerIDWorkspaceCore}, }, SortOrder: 40, }, { OfferID: offerIDWorkspaceSovereign, IssuerID: "edut.firstparty", Title: "EDUT Workspace Sovereign Continuity", Summary: "Workspace continuity profile for stronger local/offline operation.", Status: "active", Pricing: marketplaceOfferPrice{ Currency: "USDC", AmountAtomic: marketplaceStandardOfferAtomic, Decimals: 6, ChainID: a.cfg.ChainID, }, Policies: marketplaceOfferPolicy{ MemberOnly: true, WorkspaceBound: true, Transferable: false, InternalUseOnly: true, MultiTenant: false, EntitlementClass: "workspace_sovereign", RequiresOffers: []string{offerIDWorkspaceCore}, }, SortOrder: 50, }, } sort.SliceStable(offers, func(i, j int) bool { return offers[i].SortOrder < offers[j].SortOrder }) return offers } func (a *app) marketplaceOfferByID(offerID string) (marketplaceOffer, error) { target := strings.TrimSpace(strings.ToLower(offerID)) for _, offer := range a.marketplaceOffers() { if strings.EqualFold(strings.TrimSpace(offer.OfferID), target) { return offer, nil } } return marketplaceOffer{}, errNotFound } func isSoloOffer(offerID string) bool { return strings.EqualFold(strings.TrimSpace(offerID), offerIDSoloCore) } func isWorkspaceOffer(offerID string) bool { switch strings.ToLower(strings.TrimSpace(offerID)) { case offerIDWorkspaceCore, offerIDWorkspaceAI, offerIDWorkspaceLane24, offerIDWorkspaceSovereign: return true default: return false } } func shouldBindPrincipalOnOffer(offerID string) bool { switch strings.ToLower(strings.TrimSpace(offerID)) { case offerIDSoloCore, offerIDWorkspaceCore: return true default: return false } } func defaultSoloOrgRootID(wallet string) string { return "solo:" + strings.ToLower(strings.TrimSpace(wallet)) } func (a *app) handleMarketplaceOffers(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodGet { writeError(w, http.StatusMethodNotAllowed, "method not allowed") return } writeJSON(w, http.StatusOK, marketplaceOffersResponse{Offers: a.marketplaceOffers()}) } func (a *app) handleMarketplaceOfferByID(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodGet { writeError(w, http.StatusMethodNotAllowed, "method not allowed") return } const prefix = "/marketplace/offers/" offerID := strings.TrimSpace(strings.TrimPrefix(r.URL.Path, prefix)) if offerID == "" || strings.Contains(offerID, "/") { writeErrorCode(w, http.StatusNotFound, "offer_not_found", "offer not found") return } offer, err := a.marketplaceOfferByID(offerID) if err != nil { writeErrorCode(w, http.StatusNotFound, "offer_not_found", "offer not found") return } writeJSON(w, http.StatusOK, offer) } func (a *app) handleMarketplaceCheckoutQuote(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { writeError(w, http.StatusMethodNotAllowed, "method not allowed") return } var req marketplaceCheckoutQuoteRequest if err := json.NewDecoder(r.Body).Decode(&req); err != nil { writeErrorCode(w, http.StatusBadRequest, "invalid_request", "invalid request body") return } wallet, err := normalizeAddress(req.Wallet) if err != nil { writeErrorCode(w, http.StatusBadRequest, "invalid_wallet", err.Error()) return } if !a.enforceWalletSession(w, r, wallet) { return } offer, err := a.marketplaceOfferByID(req.OfferID) if err != nil { writeErrorCode(w, http.StatusNotFound, "offer_not_found", "offer not found") return } payerWallet := wallet if strings.TrimSpace(req.PayerWallet) != "" { payerWallet, err = normalizeAddress(req.PayerWallet) if err != nil { writeErrorCode(w, http.StatusBadRequest, "invalid_payer_wallet", err.Error()) return } } if !strings.EqualFold(wallet, payerWallet) { if !isLikelyHexSignature(req.OwnershipProof) { writeErrorCode(w, http.StatusForbidden, "ownership_proof_required", "distinct payer requires ownership proof") return } } orgRootID := strings.TrimSpace(req.OrgRootID) principalID := strings.TrimSpace(req.PrincipalID) if principalID == "" { principalID = wallet } principalRole := strings.ToLower(strings.TrimSpace(req.PrincipalRole)) if principalRole == "" { principalRole = "org_root_owner" } workspaceID := strings.TrimSpace(req.WorkspaceID) if isSoloOffer(offer.OfferID) { expectedSoloRoot := defaultSoloOrgRootID(wallet) if orgRootID == "" { orgRootID = expectedSoloRoot } if !strings.EqualFold(orgRootID, expectedSoloRoot) { writeErrorCode(w, http.StatusBadRequest, "invalid_scope", "solo core must use wallet-scoped solo org root") return } if principalRole != "org_root_owner" { writeErrorCode(w, http.StatusForbidden, "role_insufficient", "solo core checkout requires org_root_owner role") return } if workspaceID != "" { writeErrorCode(w, http.StatusBadRequest, "invalid_scope", "solo core does not bind workspace_id") return } } if isWorkspaceOffer(offer.OfferID) { if orgRootID == "" { writeErrorCode(w, http.StatusBadRequest, "invalid_scope", "workspace offer requires org_root_id") return } if principalRole != "org_root_owner" { writeErrorCode(w, http.StatusForbidden, "role_insufficient", "workspace checkout requires org_root_owner role") return } } for _, requiredOfferID := range offer.Policies.RequiresOffers { hasRequired, err := a.store.hasActiveEntitlement(r.Context(), wallet, requiredOfferID, orgRootID) if err != nil { writeErrorCode(w, http.StatusInternalServerError, "store_error", "failed to resolve prerequisite entitlements") return } if !hasRequired { writeErrorCode(w, http.StatusForbidden, "prerequisite_required", fmt.Sprintf("active entitlement required: %s", requiredOfferID)) return } } includeMembership := true if req.IncludeMembershipIfMissing != nil { includeMembership = *req.IncludeMembershipIfMissing } membershipStatus, statusErr := a.resolveMembershipStatusForWallet(r, wallet) if statusErr != nil { writeErrorCode(w, http.StatusInternalServerError, "store_error", "failed to resolve membership status") return } membershipIncluded := false switch membershipStatus { case "active": // no-op case "none", "unknown", "": if includeMembership { membershipIncluded = true } else { writeErrorCode(w, http.StatusForbidden, "membership_required", "active membership is required for checkout") return } case "suspended", "revoked": writeErrorCode(w, http.StatusForbidden, "membership_required", "active membership is required for checkout") return default: if includeMembership { membershipIncluded = true } else { writeErrorCode(w, http.StatusForbidden, "membership_required", "active membership is required for checkout") return } } licenseAmount := offer.Pricing.AmountAtomic totalAmount := new(big.Int) if _, ok := totalAmount.SetString(licenseAmount, 10); !ok { writeErrorCode(w, http.StatusInternalServerError, "pricing_invalid", "offer pricing is invalid") return } lineItems := []marketplaceQuoteLineItem{ { Kind: "license", Label: offer.Title, Amount: formatAtomicAmount(licenseAmount, offer.Pricing.Decimals), AmountAtomic: licenseAmount, Decimals: offer.Pricing.Decimals, Currency: offer.Pricing.Currency, }, } if membershipIncluded { membershipAmount := new(big.Int) if _, ok := membershipAmount.SetString(marketplaceMembershipActivationAtomic, 10); !ok { writeErrorCode(w, http.StatusInternalServerError, "pricing_invalid", "membership pricing is invalid") return } totalAmount = new(big.Int).Add(totalAmount, membershipAmount) lineItems = append(lineItems, marketplaceQuoteLineItem{ Kind: "membership", Label: "EDUT Membership Activation", Amount: formatAtomicAmount(marketplaceMembershipActivationAtomic, offer.Pricing.Decimals), AmountAtomic: marketplaceMembershipActivationAtomic, Decimals: offer.Pricing.Decimals, Currency: offer.Pricing.Currency, }) } lineItemsJSON, err := json.Marshal(lineItems) if err != nil { writeErrorCode(w, http.StatusInternalServerError, "encoding_failed", "failed to encode quote line items") return } quoteIDRaw, err := randomHex(16) if err != nil { writeErrorCode(w, http.StatusInternalServerError, "quote_generation_failed", "failed to generate quote id") return } txTo := strings.ToLower(strings.TrimSpace(a.cfg.MembershipContract)) txData := "0x" txValueHex := "0x0" if entitlementContract := strings.ToLower(strings.TrimSpace(a.cfg.EntitlementContract)); entitlementContract != "" && !strings.EqualFold(entitlementContract, "0x0000000000000000000000000000000000000000") { entitlementCalldata, calldataErr := encodePurchaseEntitlementCalldata(offer.OfferID, wallet, orgRootID, workspaceID) if calldataErr != nil { writeErrorCode(w, http.StatusInternalServerError, "quote_generation_failed", "failed to encode checkout transaction") return } txTo = entitlementContract txData = entitlementCalldata } now := time.Now().UTC() expiresAt := now.Add(a.cfg.QuoteTTL) accessClass := "connected" if strings.EqualFold(strings.TrimSpace(offer.OfferID), offerIDWorkspaceSovereign) { accessClass = "sovereign" } quote := marketplaceQuoteRecord{ QuoteID: "cq_" + quoteIDRaw, Wallet: wallet, PayerWallet: payerWallet, OfferID: offer.OfferID, OrgRootID: orgRootID, PrincipalID: principalID, PrincipalRole: principalRole, WorkspaceID: workspaceID, Currency: offer.Pricing.Currency, AmountAtomic: licenseAmount, TotalAmountAtomic: totalAmount.String(), Decimals: offer.Pricing.Decimals, MembershipIncluded: membershipIncluded, LineItemsJSON: string(lineItemsJSON), PolicyHash: a.cfg.GovernancePolicyHash, AccessClass: accessClass, AvailabilityState: "active", ExpectedTxTo: txTo, ExpectedTxData: txData, ExpectedTxValueHex: txValueHex, CreatedAt: now, ExpiresAt: expiresAt, } if err := a.store.putMarketplaceQuote(r.Context(), quote); err != nil { writeErrorCode(w, http.StatusInternalServerError, "store_error", "failed to persist quote") return } writeJSON(w, http.StatusOK, marketplaceCheckoutQuoteResponse{ QuoteID: quote.QuoteID, Wallet: quote.Wallet, PayerWallet: quote.PayerWallet, OfferID: quote.OfferID, OrgRootID: quote.OrgRootID, PrincipalID: quote.PrincipalID, PrincipalRole: quote.PrincipalRole, Currency: quote.Currency, Amount: formatAtomicAmount(quote.AmountAtomic, quote.Decimals), AmountAtomic: quote.AmountAtomic, TotalAmount: formatAtomicAmount(quote.TotalAmountAtomic, quote.Decimals), TotalAmountAtomic: quote.TotalAmountAtomic, Decimals: quote.Decimals, MembershipActivationIncluded: quote.MembershipIncluded, LineItems: lineItems, PolicyHash: quote.PolicyHash, ExpiresAt: quote.ExpiresAt.Format(time.RFC3339Nano), Tx: map[string]any{ "from": quote.PayerWallet, "to": quote.ExpectedTxTo, "value": quote.ExpectedTxValueHex, "data": quote.ExpectedTxData, }, AccessClass: quote.AccessClass, AvailabilityState: quote.AvailabilityState, }) } func (a *app) handleMarketplaceCheckoutConfirm(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { writeError(w, http.StatusMethodNotAllowed, "method not allowed") return } var req marketplaceCheckoutConfirmRequest if err := json.NewDecoder(r.Body).Decode(&req); err != nil { writeErrorCode(w, http.StatusBadRequest, "invalid_request", "invalid request body") return } wallet, err := normalizeAddress(req.Wallet) if err != nil { writeErrorCode(w, http.StatusBadRequest, "invalid_wallet", err.Error()) return } if !a.enforceWalletSession(w, r, wallet) { return } payerWallet := "" if strings.TrimSpace(req.PayerWallet) != "" { payerWallet, err = normalizeAddress(req.PayerWallet) if err != nil { writeErrorCode(w, http.StatusBadRequest, "invalid_payer_wallet", err.Error()) return } } if req.ChainID != a.cfg.ChainID { writeErrorCode(w, http.StatusBadRequest, "unsupported_chain_id", fmt.Sprintf("unsupported chain_id: %d", req.ChainID)) return } if !isTxHash(req.TxHash) { writeErrorCode(w, http.StatusBadRequest, "invalid_tx_hash", "invalid tx hash") return } quote, err := a.store.getMarketplaceQuote(r.Context(), strings.TrimSpace(req.QuoteID)) if err != nil { if errors.Is(err, errNotFound) { writeErrorCode(w, http.StatusNotFound, "quote_not_found", "quote not found") return } writeErrorCode(w, http.StatusInternalServerError, "store_error", "failed to load quote") return } if time.Now().UTC().After(quote.ExpiresAt) { writeErrorCode(w, http.StatusConflict, "quote_expired", "quote expired") return } if !strings.EqualFold(quote.Wallet, wallet) || !strings.EqualFold(strings.TrimSpace(quote.OfferID), strings.TrimSpace(req.OfferID)) { writeErrorCode(w, http.StatusBadRequest, "context_mismatch", "quote context mismatch") return } if strings.TrimSpace(req.OrgRootID) != "" && !strings.EqualFold(strings.TrimSpace(req.OrgRootID), quote.OrgRootID) { writeErrorCode(w, http.StatusBadRequest, "context_mismatch", "org_root_id mismatch") return } if strings.TrimSpace(req.PrincipalID) != "" && !strings.EqualFold(strings.TrimSpace(req.PrincipalID), quote.PrincipalID) { writeErrorCode(w, http.StatusBadRequest, "context_mismatch", "principal_id mismatch") return } if strings.TrimSpace(req.PrincipalRole) != "" && !strings.EqualFold(strings.TrimSpace(req.PrincipalRole), quote.PrincipalRole) { writeErrorCode(w, http.StatusBadRequest, "context_mismatch", "principal_role mismatch") return } if strings.TrimSpace(req.WorkspaceID) != "" && !strings.EqualFold(strings.TrimSpace(req.WorkspaceID), quote.WorkspaceID) { writeErrorCode(w, http.StatusBadRequest, "context_mismatch", "workspace_id mismatch") return } if payerWallet != "" && !strings.EqualFold(payerWallet, quote.PayerWallet) { writeErrorCode(w, http.StatusBadRequest, "context_mismatch", "payer_wallet mismatch") return } if quote.ConfirmedAt != nil { if existing, existingErr := a.store.getMarketplaceEntitlementByQuote(r.Context(), quote.QuoteID); existingErr == nil { writeJSON(w, http.StatusOK, marketplaceCheckoutConfirmResponse{ Status: "entitlement_active", EntitlementID: existing.EntitlementID, OfferID: existing.OfferID, OrgRootID: existing.OrgRootID, PrincipalID: existing.PrincipalID, PrincipalRole: existing.PrincipalRole, Wallet: existing.Wallet, TxHash: existing.TxHash, PolicyHash: existing.PolicyHash, ActivatedAt: existing.IssuedAt.Format(time.RFC3339Nano), AccessClass: existing.AccessClass, AvailabilityState: existing.AvailabilityState, }) return } writeErrorCode(w, http.StatusConflict, "quote_already_confirmed", "quote already confirmed") return } if a.cfg.RequireOnchainTxVerify && strings.TrimSpace(a.cfg.ChainRPCURL) == "" { writeErrorCode(w, http.StatusServiceUnavailable, "chain_verification_unavailable", "chain rpc required for checkout confirmation") return } expectedPayer := strings.TrimSpace(quote.PayerWallet) if expectedPayer == "" { expectedPayer = wallet } if err := verifyTransactionCallOnChain( r.Context(), a.cfg, req.TxHash, expectedPayer, quote.ExpectedTxTo, quote.ExpectedTxData, quote.ExpectedTxValueHex, ); err != nil { writeErrorCode(w, http.StatusConflict, "tx_verification_failed", fmt.Sprintf("tx verification pending/failed: %v", err)) return } if quote.MembershipIncluded { if err := verifyMintedOnChain(r.Context(), a.cfg, req.TxHash, wallet); err != nil { writeErrorCode(w, http.StatusConflict, "membership_verification_failed", fmt.Sprintf("membership verification pending/failed: %v", err)) return } } now := time.Now().UTC() quote.ConfirmedAt = &now quote.ConfirmedTxHash = strings.ToLower(strings.TrimSpace(req.TxHash)) if err := a.store.putMarketplaceQuote(r.Context(), quote); err != nil { writeErrorCode(w, http.StatusInternalServerError, "store_error", "failed to persist quote confirmation") return } if quote.MembershipIncluded { assurance := assuranceCryptoDirect if strings.TrimSpace(quote.PayerWallet) != "" && !strings.EqualFold(strings.TrimSpace(quote.PayerWallet), wallet) { assurance = assuranceSponsoredUnattested } if err := a.ensureMembershipActiveForWallet(r.Context(), wallet, quote.ConfirmedTxHash, assurance); err != nil { writeErrorCode(w, http.StatusInternalServerError, "store_error", "failed to activate membership") return } } entitlementID := buildEntitlementID(a.cfg.ChainID, wallet) ent := marketplaceEntitlementRecord{ EntitlementID: entitlementID, QuoteID: quote.QuoteID, OfferID: quote.OfferID, Wallet: wallet, PayerWallet: quote.PayerWallet, OrgRootID: quote.OrgRootID, PrincipalID: quote.PrincipalID, PrincipalRole: quote.PrincipalRole, WorkspaceID: quote.WorkspaceID, State: "active", AccessClass: quote.AccessClass, AvailabilityState: quote.AvailabilityState, PolicyHash: quote.PolicyHash, IssuedAt: now, TxHash: quote.ConfirmedTxHash, } if err := a.store.putMarketplaceEntitlement(r.Context(), ent); err != nil { writeErrorCode(w, http.StatusInternalServerError, "store_error", "failed to persist entitlement") return } if shouldBindPrincipalOnOffer(quote.OfferID) { principal, principalErr := a.resolveOrCreatePrincipal(r.Context(), wallet, quote.OrgRootID, quote.PrincipalID, quote.PrincipalRole) if principalErr == nil { principal.EntitlementID = ent.EntitlementID principal.EntitlementStatus = "active" principal.AccessClass = quote.AccessClass principal.AvailabilityState = quote.AvailabilityState principal.UpdatedAt = now _ = a.store.putGovernancePrincipal(r.Context(), principal) } } writeJSON(w, http.StatusOK, marketplaceCheckoutConfirmResponse{ Status: "entitlement_active", EntitlementID: ent.EntitlementID, OfferID: ent.OfferID, OrgRootID: ent.OrgRootID, PrincipalID: ent.PrincipalID, PrincipalRole: ent.PrincipalRole, Wallet: ent.Wallet, TxHash: ent.TxHash, PolicyHash: ent.PolicyHash, ActivatedAt: ent.IssuedAt.Format(time.RFC3339Nano), AccessClass: ent.AccessClass, AvailabilityState: ent.AvailabilityState, }) } func (a *app) handleMarketplaceEntitlements(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodGet { writeError(w, http.StatusMethodNotAllowed, "method not allowed") return } wallet, err := normalizeAddress(strings.TrimSpace(r.URL.Query().Get("wallet"))) if err != nil { writeErrorCode(w, http.StatusBadRequest, "invalid_wallet", err.Error()) return } if !a.enforceWalletSession(w, r, wallet) { return } records, err := a.store.listMarketplaceEntitlementsByWallet(r.Context(), wallet) if err != nil { writeErrorCode(w, http.StatusInternalServerError, "store_error", "failed to list entitlements") return } out := make([]marketplaceEntitlement, 0, len(records)) for _, rec := range records { out = append(out, marketplaceEntitlement{ EntitlementID: rec.EntitlementID, OfferID: rec.OfferID, WalletAddress: rec.Wallet, WorkspaceID: rec.WorkspaceID, OrgRootID: rec.OrgRootID, State: rec.State, AccessClass: rec.AccessClass, AvailabilityState: rec.AvailabilityState, PolicyHash: rec.PolicyHash, IssuedAt: rec.IssuedAt.Format(time.RFC3339Nano), }) } writeJSON(w, http.StatusOK, marketplaceEntitlementsResponse{Entitlements: out}) } func (a *app) resolveMembershipStatusForWallet(r *http.Request, wallet string) (string, error) { rec, err := a.store.getDesignationByAddress(r.Context(), wallet) if err != nil { if errors.Is(err, errNotFound) { return "none", nil } return "unknown", err } status := strings.ToLower(strings.TrimSpace(rec.MembershipStatus)) if status == "" { status = "none" } return status, nil } func (a *app) ensureMembershipActiveForWallet(ctx context.Context, wallet, txHash, assurance string) error { rec, err := a.store.getDesignationByAddress(ctx, wallet) if err != nil { if !errors.Is(err, errNotFound) { return err } now := time.Now().UTC() intentID, err := randomHex(16) if err != nil { return err } nonce, err := randomHex(16) if err != nil { return err } code, displayToken, err := newDesignationCode() if err != nil { return err } rec = designationRecord{ Code: code, DisplayToken: displayToken, IntentID: intentID, Nonce: nonce, Origin: "edut-launcher", Locale: "en", Address: wallet, ChainID: a.cfg.ChainID, IssuedAt: now, ExpiresAt: now.Add(a.cfg.IntentTTL), VerifiedAt: &now, MembershipStatus: "none", IdentityAssurance: assuranceNone, } } now := time.Now().UTC() rec.MembershipStatus = "active" rec.MembershipTxHash = strings.ToLower(strings.TrimSpace(txHash)) rec.ActivatedAt = &now rec.IdentityAssurance = normalizeAssuranceLevel(assurance) return a.store.putDesignation(ctx, rec) } func buildEntitlementID(chainID int64, wallet string) string { token, _ := randomHex(4) return fmt.Sprintf("ent:%d:%s:%s", chainID, wallet, token) } func formatAtomicAmount(amountAtomic string, decimals int) string { amountAtomic = strings.TrimSpace(amountAtomic) if amountAtomic == "" { return "0" } n := new(big.Int) if _, ok := n.SetString(amountAtomic, 10); !ok { return "0" } sign := "" if n.Sign() < 0 { sign = "-" n.Abs(n) } raw := n.String() if decimals <= 0 { return sign + raw } if len(raw) <= decimals { raw = strings.Repeat("0", decimals-len(raw)+1) + raw } whole := raw[:len(raw)-decimals] fraction := strings.TrimRight(raw[len(raw)-decimals:], "0") if fraction == "" { return sign + whole } return sign + whole + "." + fraction } func isLikelyHexSignature(value string) bool { value = strings.TrimSpace(strings.ToLower(value)) if !strings.HasPrefix(value, "0x") || len(value) < 132 { return false } _, err := strconv.ParseUint(value[2:18], 16, 64) return err == nil }