Function bodies 1,118 total
run method · go · L218-L235 (18 LOC)cmd/volume-gen/worker.go
func (w *Worker) run() {
defer close(w.done)
// Run generation immediately on start
w.generateTransactions()
ticker := time.NewTicker(w.config.Interval)
defer ticker.Stop()
for {
select {
case <-ticker.C:
w.generateTransactions()
case <-w.stopChan:
return
}
}
}generateTransactions method · go · L238-L269 (32 LOC)cmd/volume-gen/worker.go
func (w *Worker) generateTransactions() {
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
defer cancel()
// Query all chains with virtual_active status
pagination := types.Pagination{
Page: 1,
Limit: 100, // Get up to 100 chains per tick
}
chains, _, err := w.chainRepo.ListByStatus(ctx, models.ChainStatusVirtualActive, pagination)
if err != nil {
log.Printf("[FakeVolume Worker] Error querying chains: %v", err)
return
}
if len(chains) == 0 {
log.Printf("[FakeVolume Worker] No active chains found")
return
}
log.Printf("[FakeVolume Worker] Generating transactions for %d active chain(s)", len(chains))
// Generate 1-3 transactions per chain per interval
for i := range chains {
numTransactions := randomInt(1, 3)
for j := 0; j < numTransactions; j++ {
if err := w.generateSingleTransaction(ctx, &chains[i]); err != nil {
log.Printf("[FakeVolume Worker] Error generating transaction for chain %s: %v", chains[i].ChainName, err)
}
generateSingleTransaction method · go · L272-L274 (3 LOC)cmd/volume-gen/worker.go
func (w *Worker) generateSingleTransaction(ctx context.Context, chain *models.Chain) error {
return w.generateSingleTransactionWithTime(ctx, chain, time.Now())
}generateSingleTransactionWithTime method · go · L277-L322 (46 LOC)cmd/volume-gen/worker.go
func (w *Worker) generateSingleTransactionWithTime(ctx context.Context, chain *models.Chain, timestamp time.Time) error {
// Get the virtual pool for this chain
pool, err := w.poolRepo.GetPoolByChainID(ctx, chain.ID)
if err != nil {
return fmt.Errorf("failed to get virtual pool: %w", err)
}
// Get or create chain state
state, err := w.getOrCreateChainState(ctx, chain)
if err != nil {
return fmt.Errorf("failed to get chain state: %w", err)
}
// Update state with current price
if err := w.updateChainState(ctx, chain, pool); err != nil {
return fmt.Errorf("failed to update chain state: %w", err)
}
// Select a user for trading
profile, user, err := w.selectUserForTrade(state)
if err != nil {
// Fallback to old method if archetype selection fails
user, err = w.getOrCreateRandomUser(ctx)
if err != nil {
return fmt.Errorf("failed to get random user: %w", err)
}
// Use simple 80/20 split as fallback
isBuy := randomInt(1, 100) <= 80
if isBuy {
return wexecuteBuyWithAmount method · go · L325-L345 (21 LOC)cmd/volume-gen/worker.go
func (w *Worker) executeBuyWithAmount(ctx context.Context, chain *models.Chain, pool *models.VirtualPool, user *models.User, timestamp time.Time, cnpyAmount float64) error {
// Ensure minimum CNPY amount (must be at least 1 when converted to uint64)
if cnpyAmount < 1.0 {
cnpyAmount = randomFloat(1.0, 10.0) // Fallback to small random amount
}
// Construct a SellOrder for the buy (user selling CNPY for tokens)
order := &lib.SellOrder{
AmountForSale: uint64(cnpyAmount),
RequestedAmount: 1, // Must be > 0 to indicate buy
BuyerReceiveAddress: []byte(user.ID.String()),
}
// Process the order through OrderProcessor with backdated timestamp
err := w.orderProcessor.ProcessOrder(ctx, order, chain.ID, ×tamp)
if err != nil {
return fmt.Errorf("order processing failed: %w", err)
}
return nil
}executeBuy method · go · L348-L385 (38 LOC)cmd/volume-gen/worker.go
func (w *Worker) executeBuy(ctx context.Context, chain *models.Chain, pool *models.VirtualPool, user *models.User, timestamp time.Time) error {
// Random CNPY amount between 0.1 and 100.0 CNPY
cnpyAmount := randomFloat(1, 100.0)
// Construct a SellOrder for the buy (user selling CNPY for tokens)
order := &lib.SellOrder{
AmountForSale: uint64(cnpyAmount),
RequestedAmount: 1, // Must be > 0 to indicate buy
BuyerReceiveAddress: []byte(user.ID.String()),
}
// Process the order through OrderProcessor with backdated timestamp
err := w.orderProcessor.ProcessOrder(ctx, order, chain.ID, ×tamp)
if err != nil {
return fmt.Errorf("order processing failed: %w", err)
}
log.Printf("[FakeVolume Worker] BUY: Chain=%s, CNPY=%.4f", chain.ChainName, cnpyAmount)
// Refresh pool state after the buy to get updated reserve
updatedPool, err := w.poolRepo.GetPoolByChainID(ctx, chain.ID)
if err != nil {
log.Printf("[FakeVolume Worker] Failed to get updated pool for chainexecuteSell method · go · L388-L439 (52 LOC)cmd/volume-gen/worker.go
func (w *Worker) executeSell(ctx context.Context, chain *models.Chain, pool *models.VirtualPool, user *models.User, timestamp time.Time) error {
// Get user position (create if doesn't exist with some tokens)
position, err := w.poolRepo.GetUserPosition(ctx, user.ID, chain.ID)
if err != nil {
return fmt.Errorf("failed to get user position: %w", err)
}
// If user has no position or insufficient tokens, give them some tokens first
if position == nil || position.TokenBalance < 1000 {
// Give user tokens by doing a buy first
log.Printf("[FakeVolume Worker] SELL->BUY conversion: User %s has insufficient balance (%d tokens), executing buy instead", user.ID, func() int64 {
if position == nil {
return 0
}
return position.TokenBalance
}())
return w.executeBuy(ctx, chain, pool, user, timestamp)
}
// Fetch fresh position data immediately before calculating sell amount
// This prevents using stale data when multiple trades happen in quick succession
position, err Repobility · severity-and-effort ranking · https://repobility.com
initializeFakeUsers method · go · L442-L480 (39 LOC)cmd/volume-gen/worker.go
func (w *Worker) initializeFakeUsers() error {
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
numUsers := len(w.fakeUserProfiles)
log.Printf("[FakeVolume Worker] Initializing pool of %d fake users...", numUsers)
// Create/get users and map to profiles
for i, profile := range w.fakeUserProfiles {
walletAddress := profile.Address
// Try to get existing user first
user, err := w.userRepo.GetByWalletAddress(ctx, walletAddress)
if err == nil && user != nil {
w.userIDMap[user.ID] = i
log.Printf("[FakeVolume Worker] Found existing user %s (archetype: %s)", walletAddress, profile.Archetype)
continue
}
// Create new fake user
newUser := &models.User{
WalletAddress: walletAddress,
Username: nil,
IsVerified: false,
VerificationTier: "basic",
}
user, err = w.userRepo.Create(ctx, newUser)
if err != nil {
return fmt.Errorf("failed to create fake user %d: %w", i, err)
}
w.userIDMap[usgetOrCreateRandomUser method · go · L483-L507 (25 LOC)cmd/volume-gen/worker.go
func (w *Worker) getOrCreateRandomUser(ctx context.Context) (*models.User, error) {
if len(w.userIDMap) == 0 {
return nil, fmt.Errorf("fake user pool is empty")
}
// Pick a random user ID from the map
var userID uuid.UUID
randomIndex := w.rng.Intn(len(w.userIDMap))
i := 0
for uid := range w.userIDMap {
if i == randomIndex {
userID = uid
break
}
i++
}
// Get the user from database
user, err := w.userRepo.GetByID(ctx, userID)
if err != nil {
return nil, fmt.Errorf("failed to get fake user: %w", err)
}
return user, nil
}checkAndFillHistoricalData method · go · L512-L582 (71 LOC)cmd/volume-gen/worker.go
func (w *Worker) checkAndFillHistoricalData() error {
ctx, cancel := context.WithTimeout(context.Background(), 60*time.Minute)
defer cancel()
const minTradeCount = 100
// Get virtual_active chains
pagination := types.Pagination{
Page: 1,
Limit: 100,
}
activeChains, _, err := w.chainRepo.ListByStatus(ctx, models.ChainStatusVirtualActive, pagination)
if err != nil {
return fmt.Errorf("failed to query virtual_active chains: %w", err)
}
// Get graduated chains
graduatedChains, _, err := w.chainRepo.ListByStatus(ctx, models.ChainStatusGraduated, pagination)
if err != nil {
return fmt.Errorf("failed to query graduated chains: %w", err)
}
// Combine both lists
allChains := append(activeChains, graduatedChains...)
if len(allChains) == 0 {
log.Println("[FakeVolume Worker] No eligible chains found (virtual_active or graduated), skipping historical data check")
return nil
}
log.Printf("[FakeVolume Worker] Checking %d chains (%d active, %d graduated) for historgenerateHistoricalData method · go · L587-L636 (50 LOC)cmd/volume-gen/worker.go
func (w *Worker) generateHistoricalData() error {
ctx, cancel := context.WithTimeout(context.Background(), 60*time.Minute)
defer cancel()
// Get virtual_active chains
pagination := types.Pagination{
Page: 1,
Limit: 100,
}
activeChains, _, err := w.chainRepo.ListByStatus(ctx, models.ChainStatusVirtualActive, pagination)
if err != nil {
return fmt.Errorf("failed to query virtual_active chains: %w", err)
}
// Get graduated chains
graduatedChains, _, err := w.chainRepo.ListByStatus(ctx, models.ChainStatusGraduated, pagination)
if err != nil {
return fmt.Errorf("failed to query graduated chains: %w", err)
}
// Combine both lists
chains := append(activeChains, graduatedChains...)
if len(chains) == 0 {
log.Println("[FakeVolume Worker] No eligible chains found (virtual_active or graduated), skipping historical generation")
return nil
}
log.Printf("[FakeVolume Worker] Generating one year of historical data for %d chains (%d active, %d graduated)...",
len(chagenerateHistoricalDataForChain method · go · L641-L717 (77 LOC)cmd/volume-gen/worker.go
func (w *Worker) generateHistoricalDataForChain(ctx context.Context, chain *models.Chain, numTrades int) error {
// Explicitly skip draft, pending_launch, and failed chains
if chain.Status == models.ChainStatusDraft ||
chain.Status == models.ChainStatusPendingLaunch ||
chain.Status == models.ChainStatusFailed {
log.Printf("[FakeVolume Worker] Skipping historical generation for chain %s (status: %s) - ineligible status",
chain.ChainName, chain.Status)
return nil
}
// Get the virtual pool for this chain
pool, err := w.poolRepo.GetPoolByChainID(ctx, chain.ID)
if err != nil {
return fmt.Errorf("failed to get virtual pool: %w", err)
}
startTime := time.Now()
log.Printf("[FakeVolume Worker] Generating %d trades for chain %s (status: %s, backdated over 6 months)...",
numTrades, chain.ChainName, chain.Status)
successCount := 0
errorCount := 0
// Calculate time intervals for backdating
// Spread trades evenly over the past 6 months (180 days)
now := time.Now()
randomInt function · go · L722-L731 (10 LOC)cmd/volume-gen/worker.go
func randomInt(min, max int) int {
if min >= max {
return min
}
n, err := rand.Int(rand.Reader, big.NewInt(int64(max-min+1)))
if err != nil {
return min
}
return int(n.Int64()) + min
}randomFloat function · go · L734-L748 (15 LOC)cmd/volume-gen/worker.go
func randomFloat(min, max float64) float64 {
// Generate random bytes
var b [8]byte
rand.Read(b[:])
// Convert to uint64
n := uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 |
uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56
// Normalize to [0, 1)
f := float64(n) / float64(1<<64)
// Scale to [min, max)
return min + f*(max-min)
}generateRandomAddress function · go · L751-L755 (5 LOC)cmd/volume-gen/worker.go
func generateRandomAddress() string {
b := make([]byte, 20)
rand.Read(b)
return "0x" + hex.EncodeToString(b)
}Provenance: Repobility (https://repobility.com) — every score reproducible from /scan/
getOrCreateChainState method · go · L758-L830 (73 LOC)cmd/volume-gen/worker.go
func (w *Worker) getOrCreateChainState(ctx context.Context, chain *models.Chain) (*ChainMarketState, error) {
w.chainStatesMux.RLock()
state, exists := w.chainStates[chain.ID]
w.chainStatesMux.RUnlock()
if exists {
return state, nil
}
// Create new chain state
w.chainStatesMux.Lock()
defer w.chainStatesMux.Unlock()
// Double-check after acquiring write lock
if state, exists := w.chainStates[chain.ID]; exists {
return state, nil
}
// Deterministically assign strategy based on chain ID
strategy := DeterministicStrategyAssignment(chain.ID)
strategyConfig := GetStrategyConfig(strategy)
// Apply strategy to create chain-specific config
chainConfig := ApplyStrategyToConfig(w.config, strategy)
log.Printf("[FakeVolume Worker] Chain %s (ID: %d) assigned strategy: %s - %s",
chain.ChainName, chain.ID, strategy, strategyConfig.Description)
// Initialize price history
priceHistory := NewPriceHistory(chain.ID, 100) // Keep last 100 prices
// Get current pool to initupdateChainState method · go · L833-L855 (23 LOC)cmd/volume-gen/worker.go
func (w *Worker) updateChainState(ctx context.Context, chain *models.Chain, pool *models.VirtualPool) error {
state, err := w.getOrCreateChainState(ctx, chain)
if err != nil {
return err
}
// Update price history
if pool.CurrentPriceCNPY > 0 {
state.PriceHistory.AddPrice(pool.CurrentPriceCNPY, time.Now())
}
// Check for market phase transition
if state.MarketCycleManager != nil && state.MarketCycleManager.ShouldTransitionPhase() {
oldPhase := state.MarketCycleManager.GetCurrentPhase()
state.MarketCycleManager.TransitionToNextPhase()
newPhase := state.MarketCycleManager.GetCurrentPhase()
log.Printf("[FakeVolume Worker] Chain %s: Market phase transition %s -> %s",
chain.ChainName, oldPhase, newPhase)
}
state.LastUpdateTime = time.Now()
return nil
}selectUserForTrade method · go · L858-L886 (29 LOC)cmd/volume-gen/worker.go
func (w *Worker) selectUserForTrade(state *ChainMarketState) (*UserProfile, *models.User, error) {
// Select random user profile
profileIdx := w.rng.Intn(len(w.fakeUserProfiles))
profile := &w.fakeUserProfiles[profileIdx]
// Find corresponding user in database
var userID uuid.UUID
for uid, idx := range w.userIDMap {
if idx == profileIdx {
userID = uid
break
}
}
if userID == uuid.Nil {
return nil, nil, fmt.Errorf("user ID not found for profile %d", profileIdx)
}
// Get user from database
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
user, err := w.userRepo.GetByID(ctx, userID)
if err != nil {
return nil, nil, fmt.Errorf("failed to get user: %w", err)
}
return profile, user, nil
}determineTradeDirection method · go · L889-L918 (30 LOC)cmd/volume-gen/worker.go
func (w *Worker) determineTradeDirection(
profile *UserProfile,
state *ChainMarketState,
pool *models.VirtualPool,
) bool {
currentPrice := pool.CurrentPriceCNPY
sma := state.PriceHistory.GetSMA(20)
// Base buy probability from user profile
baseBuyProb := profile.BuyProbability * 100
// Apply market phase adjustment
if state.MarketCycleManager != nil {
baseBuyProb = state.MarketCycleManager.AdjustBuyProbability(baseBuyProb/100) * 100
}
// Apply mean reversion bias
if state.MeanReversionCalc != nil && sma > 0 {
bias := state.MeanReversionCalc.CalculateBuyBias(currentPrice, sma)
baseBuyProb += bias
}
// User archetype decides based on their personality
var marketPhase MarketPhase
if state.MarketCycleManager != nil {
marketPhase = state.MarketCycleManager.GetCurrentPhase()
}
return profile.DecideBuyOrSell(currentPrice, sma, marketPhase, w.rng)
}calculateTradeSize method · go · L921-L941 (21 LOC)cmd/volume-gen/worker.go
func (w *Worker) calculateTradeSize(
profile *UserProfile,
state *ChainMarketState,
) float64 {
// Base size from archetype
intensityMultiplier := 1.0
// Apply market phase volume multiplier
if state.MarketCycleManager != nil {
volumeMult := state.MarketCycleManager.GetVolumeMultiplier()
intensityMultiplier *= volumeMult
}
// Apply trade size bias from market phase
if state.MarketCycleManager != nil {
sizeBias := state.MarketCycleManager.GetTradeSizeBias()
intensityMultiplier *= sizeBias
}
return profile.GetTradeSize(intensityMultiplier, w.rng)
}Load function · go · L56-L58 (3 LOC)internal/config/config.go
func Load() (*Config, error) {
return LoadConfig(), nil
}LoadConfig function · go · L62-L88 (27 LOC)internal/config/config.go
func LoadConfig() *Config {
cfg := &Config{
Port: getEnv("PORT", "3001"),
Environment: getEnv("ENVIRONMENT", "development"),
DatabaseURL: getEnv("DATABASE_URL", ""),
JWTSecret: getEnv("JWT_SECRET", ""),
JWTExpirationHours: getEnvInt("JWT_EXPIRATION_HOURS", 24),
GithubClientID: getEnv("GITHUB_CLIENT_ID", ""),
GithubClientSecret: getEnv("GITHUB_CLIENT_SECRET", ""),
MaxFileUploadSize: getEnvInt64("MAX_FILE_UPLOAD_SIZE", 10*1024*1024), // 10MB
RequestTimeout: time.Duration(getEnvInt("REQUEST_TIMEOUT_SECONDS", 60)) * time.Second,
DefaultPageSize: getEnvInt("DEFAULT_PAGE_SIZE", 20),
MaxPageSize: getEnvInt("MAX_PAGE_SIZE", 100),
ClickhouseAddr: getEnv("CLICKHOUSE_ADDR", "clickhouse://65.21.56.89:9000?sslmode=disable"),
RootChainURL: getEnv("ROOT_CHAIN_URL", "ws://localhost:8081"),
RootChainID: uint64(getEnvInt("ROOT_CHAIN_ID", 1)),
RootChainRPCURL: getEnv("ROOT_CHAIN_RPC_URL", "http://lovalidate method · go · L90-L104 (15 LOC)internal/config/config.go
func (c *Config) validate() error {
if c.DatabaseURL == "" {
return fmt.Errorf("DATABASE_URL is required")
}
if c.JWTSecret == "" {
return fmt.Errorf("JWT_SECRET is required")
}
if len(c.JWTSecret) < 32 {
return fmt.Errorf("JWT_SECRET must be at least 32 characters long")
}
return nil
}Repobility (the analyzer behind this table) · https://repobility.com
IsDevelopment method · go · L106-L108 (3 LOC)internal/config/config.go
func (c *Config) IsDevelopment() bool {
return c.Environment == "development"
}IsProduction method · go · L110-L112 (3 LOC)internal/config/config.go
func (c *Config) IsProduction() bool {
return c.Environment == "production"
}getEnv function · go · L114-L119 (6 LOC)internal/config/config.go
func getEnv(key, defaultValue string) string {
if value := os.Getenv(key); value != "" {
return value
}
return defaultValue
}getEnvInt function · go · L121-L128 (8 LOC)internal/config/config.go
func getEnvInt(key string, defaultValue int) int {
if value := os.Getenv(key); value != "" {
if intValue, err := strconv.Atoi(value); err == nil {
return intValue
}
}
return defaultValue
}getEnvInt64 function · go · L130-L137 (8 LOC)internal/config/config.go
func getEnvInt64(key string, defaultValue int64) int64 {
if value := os.Getenv(key); value != "" {
if intValue, err := strconv.ParseInt(value, 10, 64); err == nil {
return intValue
}
}
return defaultValue
}getEnvBool function · go · L139-L146 (8 LOC)internal/config/config.go
func getEnvBool(key string, defaultValue bool) bool {
if value := os.Getenv(key); value != "" {
if boolValue, err := strconv.ParseBool(value); err == nil {
return boolValue
}
}
return defaultValue
}NewGenesisGenerator function · go · L43-L47 (5 LOC)internal/graduator/genesis_generator.go
func NewGenesisGenerator(templatePath string) *GenesisGenerator {
return &GenesisGenerator{
renderer: NewTemplateRenderer(templatePath),
}
}Generate method · go · L50-L99 (50 LOC)internal/graduator/genesis_generator.go
func (g *GenesisGenerator) Generate(
ctx context.Context,
chain *models.Chain,
pool *models.VirtualPool,
positions []types.UserPositionWithAddress,
) (string, error) {
// Convert CNPY reserve to micro units (1 CNPY = 1,000,000 uCNPY)
// CNPYReserve is stored as float64 in CNPY units, must be converted to uint64 in micro units
cnpyAmountInMicroCNPY := uint64(pool.CNPYReserve * 1_000_000)
// Convert to genesis accounts and pool points
accounts := make([]GenesisAccount, len(positions))
poolPoints := make([]*GenesisPoolPoint, len(positions))
for i, pos := range positions {
accounts[i] = GenesisAccount{
Address: pos.WalletAddress,
Amount: pos.TokenBalance,
}
// Create pool points - use token balance as points
points := uint64(pos.TokenBalance)
poolPoints[i] = &GenesisPoolPoint{
Address: pos.WalletAddress,
Points: points,
}
}
// Calculate TotalPoolPoints per specification: genesis_supply - virtual_pool_token_reserve
totalPoolPoints := uint64(chain.Powered by Repobility — scan your code at https://repobility.com
New function · go · L23-L37 (15 LOC)internal/graduator/graduator.go
func New(
chainGraduator ChainGraduator,
poolGraduator VirtualPoolGraduator,
notifier GraduationNotifier,
templatePath string,
rpcEndpoint string,
) *Graduator {
return &Graduator{
chainGraduator: chainGraduator,
poolGraduator: poolGraduator,
genesisGen: NewGenesisGenerator(templatePath),
rpcClient: NewGraduationRPCClient(rpcEndpoint),
notifier: notifier,
}
}CheckAndGraduate method · go · L40-L137 (98 LOC)internal/graduator/graduator.go
func (g *Graduator) CheckAndGraduate(ctx context.Context, chainID uint64) error {
// Get the chain with relationships
chain, err := g.chainGraduator.GetByID(ctx, chainID, []string{"creator", "repository"})
if err != nil {
return fmt.Errorf("failed to get chain: %w", err)
}
// Check if already graduated
if chain.IsGraduated {
return ErrAlreadyGraduated
}
// Get virtual pool
pool, err := g.poolGraduator.GetPoolByChainID(ctx, chainID)
if err != nil {
return fmt.Errorf("failed to get virtual pool: %w", err)
}
// Check if pool value meets graduation threshold
if pool.CNPYReserve < chain.GraduationThreshold {
return fmt.Errorf("%w: current %v, required %v", ErrThresholdNotMet, pool.CNPYReserve, chain.GraduationThreshold)
}
// Get positions for genesis generation
positions, err := g.poolGraduator.GetPositionsWithUsersByChainID(ctx, chainID)
if err != nil {
return fmt.Errorf("failed to get positions: %w", err)
}
// Generate genesis file
genesisFile, err := g.NewGraduationRPCClient function · go · L35-L42 (8 LOC)internal/graduator/rpc_client.go
func NewGraduationRPCClient(endpoint string) *GraduationRPCClient {
return &GraduationRPCClient{
endpoint: endpoint,
httpClient: &http.Client{
Timeout: 30 * time.Second,
},
}
}Graduate method · go · L45-L119 (75 LOC)internal/graduator/rpc_client.go
func (c *GraduationRPCClient) Graduate(ctx context.Context, chain *models.Chain, genesisFile string) error {
// Validate required relationships are loaded
if chain.Creator == nil {
return ErrCreatorNotLoaded
}
// Validate BlockTimeSeconds is set
if chain.BlockTimeSeconds == nil {
return ErrBlockTimeNotSet
}
// Handle missing repository - log warning but continue with placeholder
githubRepo := ""
if chain.Repository == nil {
log.Printf("[WARNING] Chain %s (ID: %d) graduating without repository configuration", chain.ChainName, chain.ID)
githubRepo = "pending-configuration"
} else {
githubRepo = chain.Repository.GithubURL
}
// Prepare tokenomics data
tokenomics := map[string]interface{}{
"token_name": chain.TokenName,
"token_symbol": chain.TokenSymbol,
"token_total_supply": chain.GenesisSupply,
"block_reward_amount": chain.BlockRewardAmount,
}
// Prepare RPC payload
payload := GraduationRPCPayload{
Username: getStringValue(cgetStringValue function · go · L122-L127 (6 LOC)internal/graduator/rpc_client.go
func getStringValue(s *string) string {
if s == nil {
return ""
}
return *s
}NewTemplateRenderer function · go · L15-L19 (5 LOC)internal/graduator/template_renderer.go
func NewTemplateRenderer(templatePath string) *TemplateRenderer {
return &TemplateRenderer{
templatePath: templatePath,
}
}Render method · go · L22-L36 (15 LOC)internal/graduator/template_renderer.go
func (r *TemplateRenderer) Render(data interface{}) (string, error) {
// Parse template file
tmpl, err := template.ParseFiles(r.templatePath)
if err != nil {
return "", fmt.Errorf("failed to parse template: %w", err)
}
// Execute template to buffer
var buf bytes.Buffer
if err := tmpl.Execute(&buf, data); err != nil {
return "", fmt.Errorf("failed to execute template: %w", err)
}
return buf.String(), nil
}NewAddressBookHandler function · go · L24-L30 (7 LOC)internal/handlers/address_book.go
func NewAddressBookHandler(addressBookService *addressbook.Service, validator *validators.Validator, logger *zap.Logger) *AddressBookHandler {
return &AddressBookHandler{
addressBookService: addressBookService,
validator: validator,
logger: logger,
}
}Repobility · severity-and-effort ranking · https://repobility.com
CreateEntry method · go · L33-L79 (47 LOC)internal/handlers/address_book.go
func (h *AddressBookHandler) CreateEntry(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
// Get authenticated user ID from context
userIDStr, ok := ctx.Value("userID").(string)
if !ok {
response.Unauthorized(w, "Authentication required")
return
}
userID, err := uuid.Parse(userIDStr)
if err != nil {
response.BadRequest(w, "Invalid user ID", err.Error())
return
}
var req models.CreateAddressBookEntryRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
response.BadRequest(w, "Invalid JSON payload", err.Error())
return
}
// Validate request
if err := h.validator.Validate(&req); err != nil {
validationErrors := h.validator.FormatErrors(err)
response.ValidationError(w, validationErrors)
return
}
// Create address book entry
entry, err := h.addressBookService.CreateEntry(ctx, userID, &req)
if err != nil {
if err == addressbook.ErrDuplicateAddressEntry {
response.Conflict(w, "Address already exists in address book", "")
GetEntry method · go · L82-L123 (42 LOC)internal/handlers/address_book.go
func (h *AddressBookHandler) GetEntry(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
// Get authenticated user ID from context
userIDStr, ok := ctx.Value("userID").(string)
if !ok {
response.Unauthorized(w, "Authentication required")
return
}
userID, err := uuid.Parse(userIDStr)
if err != nil {
response.BadRequest(w, "Invalid user ID", err.Error())
return
}
// Parse entry ID from URL
entryIDStr := chi.URLParam(r, "id")
entryID, err := uuid.Parse(entryIDStr)
if err != nil {
response.BadRequest(w, "Invalid entry ID", err.Error())
return
}
// Get entry
entry, err := h.addressBookService.GetEntry(ctx, userID, entryID)
if err != nil {
if err == addressbook.ErrAddressBookEntryNotFound {
response.NotFound(w, "Address book entry not found")
return
}
middleware.GetLogger(ctx).Error("failed to get address book entry",
zap.Error(err),
zap.String("user_id", userID.String()),
zap.String("entry_id", entryID.String()),
)
response.ListEntries method · go · L126-L205 (80 LOC)internal/handlers/address_book.go
func (h *AddressBookHandler) ListEntries(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
// Get authenticated user ID from context
userIDStr, ok := ctx.Value("userID").(string)
if !ok {
response.Unauthorized(w, "Authentication required")
return
}
userID, err := uuid.Parse(userIDStr)
if err != nil {
response.BadRequest(w, "Invalid user ID", err.Error())
return
}
// Parse query parameters
queryParams := r.URL.Query()
// Pagination
page := 1
if pageStr := queryParams.Get("page"); pageStr != "" {
if p, err := strconv.Atoi(pageStr); err == nil && p > 0 {
page = p
}
}
limit := 20
if limitStr := queryParams.Get("limit"); limitStr != "" {
if l, err := strconv.Atoi(limitStr); err == nil && l > 0 && l <= 100 {
limit = l
}
}
// Build filters
filters := models.AddressBookFilters{}
if chainID := queryParams.Get("chain_id"); chainID != "" {
filters.ChainID = &chainID
}
if contactLabel := queryParams.Get("contact_label"); contactLabelUpdateEntry method · go · L208-L262 (55 LOC)internal/handlers/address_book.go
func (h *AddressBookHandler) UpdateEntry(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
// Get authenticated user ID from context
userIDStr, ok := ctx.Value("userID").(string)
if !ok {
response.Unauthorized(w, "Authentication required")
return
}
userID, err := uuid.Parse(userIDStr)
if err != nil {
response.BadRequest(w, "Invalid user ID", err.Error())
return
}
// Parse entry ID from URL
entryIDStr := chi.URLParam(r, "id")
entryID, err := uuid.Parse(entryIDStr)
if err != nil {
response.BadRequest(w, "Invalid entry ID", err.Error())
return
}
var req models.UpdateAddressBookEntryRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
response.BadRequest(w, "Invalid JSON payload", err.Error())
return
}
// Validate request
if err := h.validator.Validate(&req); err != nil {
validationErrors := h.validator.FormatErrors(err)
response.ValidationError(w, validationErrors)
return
}
// Update entry
entry, err := h.addressBDeleteEntry method · go · L265-L306 (42 LOC)internal/handlers/address_book.go
func (h *AddressBookHandler) DeleteEntry(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
// Get authenticated user ID from context
userIDStr, ok := ctx.Value("userID").(string)
if !ok {
response.Unauthorized(w, "Authentication required")
return
}
userID, err := uuid.Parse(userIDStr)
if err != nil {
response.BadRequest(w, "Invalid user ID", err.Error())
return
}
// Parse entry ID from URL
entryIDStr := chi.URLParam(r, "id")
entryID, err := uuid.Parse(entryIDStr)
if err != nil {
response.BadRequest(w, "Invalid entry ID", err.Error())
return
}
// Delete entry
err = h.addressBookService.DeleteEntry(ctx, userID, entryID)
if err != nil {
if err == addressbook.ErrAddressBookEntryNotFound {
response.NotFound(w, "Address book entry not found")
return
}
middleware.GetLogger(ctx).Error("failed to delete address book entry",
zap.Error(err),
zap.String("user_id", userID.String()),
zap.String("entry_id", entryID.String()),
)
respoGetFavorites method · go · L309-L354 (46 LOC)internal/handlers/address_book.go
func (h *AddressBookHandler) GetFavorites(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
// Get authenticated user ID from context
userIDStr, ok := ctx.Value("userID").(string)
if !ok {
response.Unauthorized(w, "Authentication required")
return
}
userID, err := uuid.Parse(userIDStr)
if err != nil {
response.BadRequest(w, "Invalid user ID", err.Error())
return
}
// Parse query parameters
queryParams := r.URL.Query()
page := 1
if pageStr := queryParams.Get("page"); pageStr != "" {
if p, err := strconv.Atoi(pageStr); err == nil && p > 0 {
page = p
}
}
limit := 20
if limitStr := queryParams.Get("limit"); limitStr != "" {
if l, err := strconv.Atoi(limitStr); err == nil && l > 0 && l <= 100 {
limit = l
}
}
// Get favorites
result, err := h.addressBookService.GetFavorites(ctx, userID, page, limit)
if err != nil {
middleware.GetLogger(ctx).Error("failed to get favorites",
zap.Error(err),
zap.String("user_id", userID.String())SearchEntries method · go · L357-L409 (53 LOC)internal/handlers/address_book.go
func (h *AddressBookHandler) SearchEntries(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
// Get authenticated user ID from context
userIDStr, ok := ctx.Value("userID").(string)
if !ok {
response.Unauthorized(w, "Authentication required")
return
}
userID, err := uuid.Parse(userIDStr)
if err != nil {
response.BadRequest(w, "Invalid user ID", err.Error())
return
}
// Parse query parameters
queryParams := r.URL.Query()
query := queryParams.Get("q")
if query == "" {
response.BadRequest(w, "Search query is required", "")
return
}
page := 1
if pageStr := queryParams.Get("page"); pageStr != "" {
if p, err := strconv.Atoi(pageStr); err == nil && p > 0 {
page = p
}
}
limit := 20
if limitStr := queryParams.Get("limit"); limitStr != "" {
if l, err := strconv.Atoi(limitStr); err == nil && l > 0 && l <= 100 {
limit = l
}
}
// Search entries
result, err := h.addressBookService.SearchEntries(ctx, userID, query, page, limit)
if err !NewAMMHandler function · go · L23-L29 (7 LOC)internal/handlers/amm.go
func NewAMMHandler(ammService *amm.Service, validator *validators.Validator, logger *zap.Logger) *AMMHandler {
return &AMMHandler{
ammService: ammService,
validator: validator,
logger: logger,
}
}Provenance: Repobility (https://repobility.com) — every score reproducible from /scan/
DepositLiquidity method · go · L32-L59 (28 LOC)internal/handlers/amm.go
func (h *AMMHandler) DepositLiquidity(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
var req models.DepositLiquidityRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
response.BadRequest(w, "Invalid JSON payload", err.Error())
return
}
// Validate request
if err := h.validator.Validate(&req); err != nil {
validationErrors := h.validator.FormatErrors(err)
response.ValidationError(w, validationErrors)
return
}
// Deposit liquidity
depositResponse, err := h.ammService.DepositLiquidity(ctx, &req)
if err != nil {
middleware.GetLogger(ctx).Error("failed to deposit liquidity",
zap.Error(err),
)
response.InternalServerError(w, "Failed to deposit liquidity")
return
}
response.Success(w, http.StatusOK, depositResponse)
}WithdrawLiquidity method · go · L62-L89 (28 LOC)internal/handlers/amm.go
func (h *AMMHandler) WithdrawLiquidity(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
var req models.WithdrawLiquidityRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
response.BadRequest(w, "Invalid JSON payload", err.Error())
return
}
// Validate request
if err := h.validator.Validate(&req); err != nil {
validationErrors := h.validator.FormatErrors(err)
response.ValidationError(w, validationErrors)
return
}
// Withdraw liquidity
withdrawResponse, err := h.ammService.WithdrawLiquidity(ctx, &req)
if err != nil {
middleware.GetLogger(ctx).Error("failed to withdraw liquidity",
zap.Error(err),
)
response.InternalServerError(w, "Failed to withdraw liquidity")
return
}
response.Success(w, http.StatusOK, withdrawResponse)
}PlaceLimitOrder method · go · L92-L119 (28 LOC)internal/handlers/amm.go
func (h *AMMHandler) PlaceLimitOrder(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
var req models.LimitOrderRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
response.BadRequest(w, "Invalid JSON payload", err.Error())
return
}
// Validate request
if err := h.validator.Validate(&req); err != nil {
validationErrors := h.validator.FormatErrors(err)
response.ValidationError(w, validationErrors)
return
}
// Place limit order
orderResponse, err := h.ammService.PlaceLimitOrder(ctx, &req)
if err != nil {
middleware.GetLogger(ctx).Error("failed to place limit order",
zap.Error(err),
)
response.InternalServerError(w, "Failed to place limit order")
return
}
response.Success(w, http.StatusOK, orderResponse)
}