github.com/diadata-org/diadata@v1.4.593/pkg/model/oracle.go (about) 1 package models 2 3 import ( 4 "context" 5 "database/sql" 6 "encoding/json" 7 "errors" 8 "fmt" 9 "strconv" 10 "strings" 11 "time" 12 13 "github.com/diadata-org/diadata/pkg/dia" 14 "github.com/ethereum/go-ethereum/common" 15 "github.com/jackc/pgx/v4" 16 ) 17 18 type Customer struct { 19 CustomerID int `json:"customer_id"` 20 Email string `json:"email"` 21 Name string `json:"name"` 22 AccountCreationDate time.Time `json:"account_creation_date"` 23 CustomerPlan int `json:"customer_plan"` 24 DeployedOracles int `json:"deployed_oracles"` 25 PaymentStatus string `json:"payment_status"` 26 // LastPayment time.Time `json:"last_payment"` 27 PaymentSource string `json:"payment_source"` 28 NumberOfDataFeeds int `json:"number_of_data_feeds"` 29 Active bool `json:"active"` 30 PublicKeys []PublicKey `json:"public_keys"` 31 PayerAddress string `json:"payer_address"` 32 } 33 34 type Plan struct { 35 PlanID int `json:"plan_id"` 36 Name string `json:"plan_name"` 37 Description string `json:"plan_description"` 38 Price int `json:"plan_price"` 39 TotalFeeds int `json:"total_feeds"` 40 TotalOracles int `json:"total_oracles"` 41 } 42 43 type PublicKey struct { 44 AccessLevel string `json:"access_level"` 45 PublicKey string `json:"public_key"` 46 UserName string `json:"username"` 47 CustomerId string `json:"customer_id"` 48 Invitor string `json:"invitor"` 49 } 50 51 func (rdb *RelDB) SetKeyPair(publickey string, privatekey string) error { 52 query := fmt.Sprintf(`INSERT INTO %s 53 (publickey,privatekey) VALUES ($1,$2) 54 on conflict(publickey) 55 do 56 update set publickey=EXCLUDED.publickey`, keypairTable) 57 exec, err := rdb.postgresClient.Exec(context.Background(), query, publickey, privatekey) 58 59 log.Infoln("exec", exec) 60 if err != nil { 61 return err 62 } 63 return nil 64 } 65 66 func (rdb *RelDB) GetKeyPairID(publicKey string) string { 67 query := fmt.Sprintf(`SELECT id from %s WHERE publickey=$1`, keypairTable) 68 rows := rdb.postgresClient.QueryRow(context.Background(), query, publicKey) 69 var keypairId string 70 71 err := rows.Scan(&keypairId) 72 if err != nil { 73 log.Error("Error getting results from db ", err) 74 } 75 76 return keypairId 77 } 78 79 func (rdb *RelDB) SetOracleConfig(ctx context.Context, customerId, address, feederID, owner, feederAddress, symbols, feedSelection, chainID, frequency, sleepseconds, deviationpermille, blockchainnode, mandatoryFrequency, name string, draft, billable bool) error { 80 currentTime := time.Now() 81 query := fmt.Sprintf(` 82 INSERT INTO %s ( address,feeder_id,owner,symbols,chainID, 83 frequency,sleepseconds,deviationpermille,blockchainnode, 84 mandatory_frequency,feeder_address,createddate,lastupdate,feedSelection, 85 name,draft,customer_id,billable) 86 VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18) 87 ON CONFLICT(feeder_id) 88 DO UPDATE SET symbols=$4,frequency=$6,sleepseconds=$7,deviationpermille=$8,blockchainnode=$9,mandatory_frequency=$10, 89 feeder_address=$11,lastupdate=$13,feedSelection=$14,name=$15,draft=$16,address=$1,billable=$18`, 90 oracleconfigTable, 91 ) 92 93 _, err := rdb.postgresClient.Exec(ctx, query, address, feederID, owner, symbols, chainID, frequency, sleepseconds, deviationpermille, blockchainnode, mandatoryFrequency, feederAddress, currentTime, currentTime, feedSelection, name, draft, customerId, billable) 94 if err != nil { 95 return err 96 } 97 return nil 98 } 99 100 func (rdb *RelDB) GetFeederID(address string) (feederId string) { 101 query := fmt.Sprintf(`SELECT id FROM %s WHERE owner=$1`, feederaccessTable) 102 log.Infoln("GetFeederID query", query) 103 log.Infoln("address", address) 104 var feederidint int 105 err := rdb.postgresClient.QueryRow(context.Background(), query, address).Scan(&feederidint) 106 if err != nil { 107 log.Error("Error getting results from db ", err) 108 } 109 feederId = strconv.Itoa(feederidint) 110 111 return 112 } 113 114 func (rdb *RelDB) SetFeederConfig(feederid, oracleconfigid string) error { 115 query := fmt.Sprintf(` 116 INSERT INTO %s (id, oracleconfig_id) 117 VALUES ($1,$2) 118 ON CONFLICT(id) 119 DO UPDATE SET oracleconfig_id=EXCLUDED.oracleconfig_id`, 120 feederconfigTable, 121 ) 122 _, err := rdb.postgresClient.Exec(context.Background(), query, feederid, oracleconfigid) 123 if err != nil { 124 return err 125 } 126 return nil 127 } 128 129 func (rdb *RelDB) GetFeederAccessByID(id string) (owner string) { 130 query := fmt.Sprintf(`SELECT owner FROM %s WHERE feeder_id=$1`, oracleconfigTable) 131 err := rdb.postgresClient.QueryRow(context.Background(), query, id).Scan(&owner) 132 if err != nil { 133 log.Error("Error getting results from db ", err) 134 } 135 return 136 } 137 138 func (rdb *RelDB) GetFeederByID(id string) (owner string) { 139 query := fmt.Sprintf(`SELECT owner from %s WHERE feeder_id=$1`, oracleconfigTable) 140 err := rdb.postgresClient.QueryRow(context.Background(), query, id).Scan(&owner) 141 if err != nil { 142 log.Error("Error getting results from db ", err) 143 } 144 return 145 } 146 func (rdb *RelDB) GetFeederLimit(owner string) (limit int) { 147 query := fmt.Sprintf(`SELECT total FROM %s WHERE owner=$1`, feederResourceTable) 148 err := rdb.postgresClient.QueryRow(context.Background(), query, owner).Scan(&limit) 149 if err != nil { 150 log.Error("Error getting results from db ", err) 151 } 152 return 153 } 154 155 func (rdb *RelDB) GetTotalOracles(customerId string) (total int) { 156 query := fmt.Sprintf(`SELECT count(*) FROM %s WHERE customer_id=$1 AND active=true`, oracleconfigTable) 157 err := rdb.postgresClient.QueryRow(context.Background(), query, customerId).Scan(&total) 158 if err != nil { 159 log.Error("Error getting results from db ", err) 160 } 161 return 162 } 163 164 func (rdb *RelDB) UpdateFeederAddressCheckSum(oracleaddress string) (err error) { 165 166 query := fmt.Sprintf(` 167 UPDATE %s 168 SET address=$1 169 WHERE address=$2`, oracleconfigTable) 170 171 _, err = rdb.postgresClient.Exec(context.Background(), query, common.HexToAddress(oracleaddress).Hex(), oracleaddress) 172 if err != nil { 173 return 174 } 175 176 return 177 } 178 179 func (rdb *RelDB) GetExpiredFeeders() (oracleconfigs []dia.OracleConfig, err error) { 180 181 var ( 182 rows pgx.Rows 183 deviationFloat float64 184 query string 185 ) 186 187 // AND t1.deleted = false 188 189 query = fmt.Sprintf(` 190 SELECT 191 t1.address, t1.feeder_id, t1.deleted, t1.owner, t1.symbols, t1.chainID, 192 t1.frequency, t1.sleepseconds, t1.deviationpermille, t1.blockchainnode, t1.active, 193 t1.mandatory_frequency, t1.feeder_address, t1.createddate, 194 COALESCE(t1.lastupdate, '0001-01-01 00:00:00'::timestamp) AS lastupdate, 195 t1.expired, t1.expired_time, 196 COALESCE(MAX(fu.update_time), '0001-01-01 00:00:00'::timestamp) AS max_update_time 197 FROM %s AS t1 198 LEFT JOIN %s AS fu 199 ON t1.address = fu.oracle_address 200 GROUP BY 201 t1.address, t1.feeder_id, t1.deleted, t1.owner, t1.symbols, t1.chainID, 202 t1.frequency, t1.sleepseconds, t1.deviationpermille, t1.blockchainnode, t1.active, 203 t1.mandatory_frequency, t1.feeder_address, t1.createddate, 204 t1.lastupdate, t1.expired, t1.expired_time 205 HAVING 206 EXTRACT(EPOCH FROM (NOW() - lastupdate)) / 86400 > 60 207 AND t1.expired = false 208 `, oracleconfigTable, feederupdatesTable) 209 210 rows, err = rdb.postgresClient.Query(context.Background(), query) 211 212 if err != nil { 213 fmt.Println(err) 214 215 return 216 } 217 defer rows.Close() 218 219 for rows.Next() { 220 var ( 221 oracleconfig dia.OracleConfig 222 symbols string 223 frequencynull sql.NullString 224 sleepsecondsnull sql.NullString 225 feedSelection sql.NullString 226 ) 227 err := rows.Scan(&oracleconfig.Address, &oracleconfig.FeederID, &oracleconfig.Deleted, &oracleconfig.Owner, &symbols, &oracleconfig.ChainID, 228 &frequencynull, &sleepsecondsnull, &oracleconfig.DeviationPermille, &oracleconfig.BlockchainNode, &oracleconfig.Active, 229 &oracleconfig.MandatoryFrequency, &oracleconfig.FeederAddress, &oracleconfig.CreatedDate, 230 &oracleconfig.LastUpdate, &oracleconfig.Expired, &oracleconfig.ExpiredDate, &oracleconfig.LastOracleUpdate) 231 if err != nil { 232 233 log.Error("GetExpiredFeeders scan", err, oracleconfig.FeederID) 234 } 235 236 if frequencynull.Valid { 237 oracleconfig.Frequency = frequencynull.String 238 239 } 240 241 if feedSelection.Valid { 242 oracleconfig.FeederSelection = feedSelection.String 243 } 244 245 if sleepsecondsnull.Valid { 246 oracleconfig.SleepSeconds = sleepsecondsnull.String 247 248 } 249 250 oracleconfig.Symbols = strings.Split(symbols, ",") 251 if oracleconfig.DeviationPermille != "" { 252 deviationFloat, err = strconv.ParseFloat(oracleconfig.DeviationPermille, 64) 253 if err != nil { 254 log.Error(err) 255 256 } 257 oracleconfig.DeviationPermille = fmt.Sprintf("%.2f", deviationFloat/10) 258 } 259 260 oracleconfigs = append(oracleconfigs, oracleconfig) 261 } 262 return 263 264 } 265 func (rdb *RelDB) GetFeeder(feederID string) (oracleconfig dia.OracleConfig, err error) { 266 var ( 267 row pgx.Row 268 deviationFloat float64 269 query string 270 ) 271 272 query = fmt.Sprintf(` 273 SELECT address, feeder_id, owner,symbols, chainID, frequency, sleepseconds, deviationpermille, blockchainnode, active,mandatory_frequency, feeder_address, name, createddate, COALESCE(lastupdate, '0001-01-01 00:00:00'::timestamp), 274 deleted,feedselection,expired,expired_time, draft,customer_id 275 FROM %s WHERE feeder_id=$1 276 `, oracleconfigTable) 277 row = rdb.postgresClient.QueryRow(context.Background(), query, feederID) 278 279 if err != nil { 280 return 281 } 282 283 var ( 284 symbols string 285 frequencynull sql.NullString 286 sleepsecondsnull sql.NullString 287 feedSelection sql.NullString 288 customerID int 289 ) 290 err = row.Scan(&oracleconfig.Address, &oracleconfig.FeederID, &oracleconfig.Owner, &symbols, &oracleconfig.ChainID, &frequencynull, &sleepsecondsnull, &oracleconfig.DeviationPermille, &oracleconfig.BlockchainNode, &oracleconfig.Active, &oracleconfig.MandatoryFrequency, &oracleconfig.FeederAddress, &oracleconfig.Name, &oracleconfig.CreatedDate, &oracleconfig.LastUpdate, &oracleconfig.Deleted, 291 &feedSelection, &oracleconfig.Expired, &oracleconfig.ExpiredDate, &oracleconfig.Draft, &customerID) 292 if err != nil { 293 294 log.Error("GetFeeder scan", err, oracleconfig.FeederID) 295 } 296 297 if frequencynull.Valid { 298 oracleconfig.Frequency = frequencynull.String 299 300 } 301 302 oracleconfig.CustomerID = strconv.Itoa(customerID) 303 304 if feedSelection.Valid { 305 oracleconfig.FeederSelection = feedSelection.String 306 } 307 308 if sleepsecondsnull.Valid { 309 oracleconfig.SleepSeconds = sleepsecondsnull.String 310 311 } 312 313 oracleconfig.Symbols = strings.Split(symbols, ",") 314 if oracleconfig.DeviationPermille != "" { 315 deviationFloat, err = strconv.ParseFloat(oracleconfig.DeviationPermille, 64) 316 if err != nil { 317 log.Error(err) 318 319 } 320 oracleconfig.DeviationPermille = fmt.Sprintf("%.2f", deviationFloat/10) 321 } 322 323 return 324 } 325 326 func (rdb *RelDB) GetAllFeeders(isDeleted bool, isExpired bool) (oracleconfigs []dia.OracleConfig, err error) { 327 var ( 328 rows pgx.Rows 329 deviationFloat float64 330 query string 331 ) 332 333 switch { 334 335 case isDeleted: 336 { 337 query = fmt.Sprintf(` 338 SELECT address, feeder_id, owner,symbols, chainID, frequency, sleepseconds, deviationpermille, blockchainnode, active,mandatory_frequency, feeder_address, createddate, COALESCE(lastupdate, '0001-01-01 00:00:00'::timestamp),deleted,feedselection,expired,expired_time 339 FROM %s WHERE mandatory_frequency IS NOT NULL and deleted=$1 340 `, oracleconfigTable) 341 rows, err = rdb.postgresClient.Query(context.Background(), query, isDeleted) 342 343 } 344 345 case isExpired: 346 { 347 query = fmt.Sprintf(` 348 SELECT address, feeder_id, owner,symbols, chainID, frequency, sleepseconds, deviationpermille, blockchainnode, active,mandatory_frequency, feeder_address, createddate, COALESCE(lastupdate, '0001-01-01 00:00:00'::timestamp),deleted,feedselection,expired,expired_time 349 FROM %s WHERE mandatory_frequency IS NOT NULL and expired=$1 350 `, oracleconfigTable) 351 rows, err = rdb.postgresClient.Query(context.Background(), query, isExpired) 352 } 353 354 case isExpired && isDeleted: 355 { 356 query = fmt.Sprintf(` 357 SELECT address, feeder_id, owner,symbols, chainID, frequency, sleepseconds, deviationpermille, blockchainnode, active,mandatory_frequency, feeder_address, createddate, COALESCE(lastupdate, '0001-01-01 00:00:00'::timestamp),deleted,feedselection,expired,expired_time 358 FROM %s WHERE mandatory_frequency IS NOT NULL and expired=$1 and deleted=$2 359 `, oracleconfigTable) 360 rows, err = rdb.postgresClient.Query(context.Background(), query, isExpired, isDeleted) 361 } 362 case !isExpired && !isDeleted: 363 { 364 query = fmt.Sprintf(` 365 SELECT address, feeder_id, owner,symbols, chainID, frequency, sleepseconds, deviationpermille, blockchainnode, active,mandatory_frequency, feeder_address, createddate, COALESCE(lastupdate, '0001-01-01 00:00:00'::timestamp),deleted,feedselection,expired,expired_time 366 FROM %s WHERE mandatory_frequency IS NOT NULL 367 `, oracleconfigTable) 368 rows, err = rdb.postgresClient.Query(context.Background(), query) 369 370 } 371 372 } 373 374 if err != nil { 375 return 376 } 377 defer rows.Close() 378 379 for rows.Next() { 380 var ( 381 oracleconfig dia.OracleConfig 382 symbols string 383 frequencynull sql.NullString 384 sleepsecondsnull sql.NullString 385 feedSelection sql.NullString 386 ) 387 err := rows.Scan(&oracleconfig.Address, &oracleconfig.FeederID, &oracleconfig.Owner, &symbols, &oracleconfig.ChainID, &frequencynull, &sleepsecondsnull, &oracleconfig.DeviationPermille, &oracleconfig.BlockchainNode, &oracleconfig.Active, &oracleconfig.MandatoryFrequency, &oracleconfig.FeederAddress, &oracleconfig.CreatedDate, &oracleconfig.LastUpdate, &oracleconfig.Deleted, &feedSelection, &oracleconfig.Expired, &oracleconfig.ExpiredDate) 388 if err != nil { 389 390 log.Error("GetAllFeeders scan", err, oracleconfig.FeederID) 391 } 392 393 if frequencynull.Valid { 394 oracleconfig.Frequency = frequencynull.String 395 396 } 397 398 if feedSelection.Valid { 399 oracleconfig.FeederSelection = feedSelection.String 400 } 401 402 if sleepsecondsnull.Valid { 403 oracleconfig.SleepSeconds = sleepsecondsnull.String 404 405 } 406 407 oracleconfig.Symbols = strings.Split(symbols, ",") 408 if oracleconfig.DeviationPermille != "" { 409 deviationFloat, err = strconv.ParseFloat(oracleconfig.DeviationPermille, 64) 410 if err != nil { 411 log.Error(err) 412 413 } 414 oracleconfig.DeviationPermille = fmt.Sprintf("%.2f", deviationFloat/10) 415 } 416 417 oracleconfigs = append(oracleconfigs, oracleconfig) 418 } 419 return 420 } 421 func (rdb *RelDB) GetFeederResources() (addresses []string, err error) { 422 var ( 423 rows pgx.Rows 424 ) 425 query := fmt.Sprintf(` 426 SELECT owner 427 FROM %s`, feederResourceTable) 428 rows, err = rdb.postgresClient.Query(context.Background(), query) 429 if err != nil { 430 return 431 } 432 defer rows.Close() 433 434 for rows.Next() { 435 var ( 436 address string 437 ) 438 err := rows.Scan(&address) 439 if err != nil { 440 log.Error(err) 441 } 442 addresses = append(addresses, address) 443 } 444 return 445 446 } 447 448 func (rdb *RelDB) GetOraclesByCustomer(customerId string) (oracleconfigs []dia.OracleConfig, err error) { 449 var ( 450 rows pgx.Rows 451 deviationFloat float64 452 ) 453 454 /* 455 `SELECT address, chainid, COALESCE(latest.scraped_block, 0) AS latest_scraped_block FROM oracleconfig 456 LEFT JOIN (SELECT oracle_address, chain_id, MAX(update_block) AS scraped_block FROM feederupdates GROUP BY oracle_address,chain_id) latest ON (oracleconfig.address = latest.oracle_address and oracleconfig.chainid = latest.chain_id) WHERE oracleconfig.chainid = '%s'` 457 458 459 */ 460 461 query := fmt.Sprintf(` 462 SELECT 463 t1.name,t1.address, t1.feeder_id,t1.deleted, t1.owner, t1.symbols, t1.chainID, 464 t1.frequency, t1.sleepseconds, t1.deviationpermille, t1.blockchainnode, t1.active, 465 t1.mandatory_frequency, t1.feeder_address, t1.createddate, t1.feedselection, 466 COALESCE(t1.lastupdate, '0001-01-01 00:00:00'::timestamp) AS lastupdate, 467 t1.expired, t1.expired_time, 468 COALESCE(MAX(fu.update_time), '0001-01-01 00:00:00'::timestamp) AS max_update_time, 469 t1.billable, 470 t1.draft, 471 t1.ecosystem 472 FROM %s AS t1 473 LEFT JOIN %s AS fu 474 ON t1.address = fu.oracle_address 475 AND t1.chainID = fu.chain_id 476 WHERE t1.customer_id = $1 477 GROUP BY 478 t1.name,t1.address, t1.feeder_id, t1.deleted, t1.owner, t1.symbols, t1.chainID, 479 t1.frequency, t1.sleepseconds, t1.deviationpermille, t1.blockchainnode, t1.active, 480 t1.mandatory_frequency, t1.feeder_address, t1.createddate, t1.feedselection, 481 t1.lastupdate, t1.expired,t1.expired_time,t1.billable,t1.draft,t1.ecosystem;`, oracleconfigTable, feederupdatesTable) 482 rows, err = rdb.postgresClient.Query(context.Background(), query, customerId) 483 if err != nil { 484 return 485 } 486 defer rows.Close() 487 488 for rows.Next() { 489 var ( 490 oracleconfig dia.OracleConfig 491 symbols string 492 feedSelection sql.NullString 493 name sql.NullString 494 ) 495 496 err := rows.Scan(&name, &oracleconfig.Address, &oracleconfig.FeederID, &oracleconfig.Deleted, &oracleconfig.Owner, &symbols, 497 &oracleconfig.ChainID, &oracleconfig.Frequency, &oracleconfig.SleepSeconds, &oracleconfig.DeviationPermille, 498 &oracleconfig.BlockchainNode, &oracleconfig.Active, &oracleconfig.MandatoryFrequency, &oracleconfig.FeederAddress, 499 &oracleconfig.CreatedDate, &feedSelection, &oracleconfig.LastUpdate, &oracleconfig.Expired, &oracleconfig.ExpiredDate, &oracleconfig.LastOracleUpdate, &oracleconfig.Billable, 500 &oracleconfig.Draft, 501 &oracleconfig.Ecosystem) 502 if err != nil { 503 log.Error(err) 504 } 505 if feedSelection.Valid { 506 oracleconfig.FeederSelection = feedSelection.String 507 } 508 509 oracleconfig.Symbols = strings.Split(symbols, ",") 510 511 if oracleconfig.DeviationPermille != "" { 512 deviationFloat, err = strconv.ParseFloat(oracleconfig.DeviationPermille, 64) 513 if err != nil { 514 log.Error(err) 515 516 } 517 oracleconfig.DeviationPermille = fmt.Sprintf("%.2f", deviationFloat/10) 518 } 519 520 if name.Valid { 521 oracleconfig.Name = name.String 522 } 523 524 lastupdate := oracleconfig.LastOracleUpdate 525 526 if oracleconfig.LastOracleUpdate.IsZero() { 527 lastupdate = oracleconfig.CreatedDate 528 } 529 oracleconfig.ExpiringDate = lastupdate.Add(time.Duration(60 * time.Hour * 24)) 530 if oracleconfig.ExpiringDate.Before(time.Now()) { 531 oracleconfig.Expired = true 532 } 533 534 oracleconfigs = append(oracleconfigs, oracleconfig) 535 } 536 return 537 } 538 539 func (rdb *RelDB) GetOraclesByOwner(owner string) (oracleconfigs []dia.OracleConfig, err error) { 540 var ( 541 rows pgx.Rows 542 deviationFloat float64 543 ) 544 545 /* 546 `SELECT address, chainid, COALESCE(latest.scraped_block, 0) AS latest_scraped_block FROM oracleconfig 547 LEFT JOIN (SELECT oracle_address, chain_id, MAX(update_block) AS scraped_block FROM feederupdates GROUP BY oracle_address,chain_id) latest ON (oracleconfig.address = latest.oracle_address and oracleconfig.chainid = latest.chain_id) WHERE oracleconfig.chainid = '%s'` 548 549 550 */ 551 552 query := fmt.Sprintf(` 553 SELECT 554 t1.address, t1.feeder_id,t1.deleted, t1.owner, t1.symbols, t1.chainID, 555 t1.frequency, t1.sleepseconds, t1.deviationpermille, t1.blockchainnode, t1.active, 556 t1.mandatory_frequency, t1.feeder_address, t1.createddate, t1.feedselection, 557 COALESCE(t1.lastupdate, '0001-01-01 00:00:00'::timestamp) AS lastupdate, 558 t1.expired, t1.expired_time, 559 COALESCE(MAX(fu.update_time), '0001-01-01 00:00:00'::timestamp) AS max_update_time 560 FROM %s AS t1 561 LEFT JOIN %s AS fu 562 ON t1.address = fu.oracle_address 563 AND t1.chainID = fu.chain_id 564 WHERE t1.owner = $1 565 GROUP BY 566 t1.address, t1.feeder_id, t1.deleted, t1.owner, t1.symbols, t1.chainID, 567 t1.frequency, t1.sleepseconds, t1.deviationpermille, t1.blockchainnode, t1.active, 568 t1.mandatory_frequency, t1.feeder_address, t1.createddate, t1.feedselection, 569 t1.lastupdate, t1.expired,t1.expired_time;`, oracleconfigTable, feederupdatesTable) 570 rows, err = rdb.postgresClient.Query(context.Background(), query, owner) 571 if err != nil { 572 return 573 } 574 defer rows.Close() 575 576 for rows.Next() { 577 var ( 578 oracleconfig dia.OracleConfig 579 symbols string 580 feedSelection sql.NullString 581 ) 582 583 err := rows.Scan(&oracleconfig.Address, &oracleconfig.FeederID, &oracleconfig.Deleted, &oracleconfig.Owner, &symbols, 584 &oracleconfig.ChainID, &oracleconfig.Frequency, &oracleconfig.SleepSeconds, &oracleconfig.DeviationPermille, 585 &oracleconfig.BlockchainNode, &oracleconfig.Active, &oracleconfig.MandatoryFrequency, &oracleconfig.FeederAddress, 586 &oracleconfig.CreatedDate, &feedSelection, &oracleconfig.LastUpdate, &oracleconfig.Expired, &oracleconfig.ExpiredDate, &oracleconfig.LastOracleUpdate) 587 if err != nil { 588 log.Error(err) 589 } 590 if feedSelection.Valid { 591 oracleconfig.FeederSelection = feedSelection.String 592 } 593 594 oracleconfig.Symbols = strings.Split(symbols, ",") 595 596 if oracleconfig.DeviationPermille != "" { 597 deviationFloat, err = strconv.ParseFloat(oracleconfig.DeviationPermille, 64) 598 if err != nil { 599 log.Error(err) 600 601 } 602 oracleconfig.DeviationPermille = fmt.Sprintf("%.2f", deviationFloat/10) 603 } 604 605 lastupdate := oracleconfig.LastOracleUpdate 606 607 if oracleconfig.LastOracleUpdate.IsZero() { 608 lastupdate = oracleconfig.CreatedDate 609 } 610 oracleconfig.ExpiringDate = lastupdate.Add(time.Duration(60 * time.Hour * 24)) 611 if oracleconfig.ExpiringDate.Before(time.Now()) { 612 oracleconfig.Expired = true 613 } 614 615 oracleconfigs = append(oracleconfigs, oracleconfig) 616 } 617 return 618 } 619 620 func (rdb *RelDB) GetOracleConfig(address, chainid string) (oracleconfig dia.OracleConfig, err error) { 621 var ( 622 symbols string 623 feedSelection sql.NullString 624 ) 625 query := fmt.Sprintf(` 626 SELECT address, feeder_id, owner,feeder_address,symbols, chainid, feedSelection,deviationpermille, sleepseconds,frequency, blockchainnode, mandatory_frequency, deleted, draft 627 FROM %s 628 WHERE address=$1 and chainid=$2`, oracleconfigTable) 629 fmt.Println(query) 630 err = rdb.postgresClient.QueryRow(context.Background(), query, address, chainid).Scan(&oracleconfig.Address, &oracleconfig.FeederID, &oracleconfig.Owner, &oracleconfig.FeederAddress, &symbols, &oracleconfig.ChainID, &feedSelection, &oracleconfig.DeviationPermille, &oracleconfig.SleepSeconds, &oracleconfig.Frequency, &oracleconfig.BlockchainNode, &oracleconfig.MandatoryFrequency, &oracleconfig.Deleted, &oracleconfig.Draft) 631 if err != nil { 632 return 633 } 634 635 if feedSelection.Valid { 636 oracleconfig.FeederSelection = feedSelection.String 637 } 638 639 oracleconfig.Symbols = strings.Split(symbols, " ") 640 641 return 642 } 643 644 func (rdb *RelDB) ChangeOracleState(feederID string, active bool) (err error) { 645 currentTime := time.Now() 646 647 query := fmt.Sprintf(` 648 UPDATE %s 649 SET active=$1, lastupdate=$3 650 WHERE feeder_id=$2`, oracleconfigTable) 651 _, err = rdb.postgresClient.Exec(context.Background(), query, active, feederID, currentTime) 652 if err != nil { 653 return 654 } 655 656 return 657 } 658 659 func (rdb *RelDB) ChangeEcosystemConfig(feederId string, enable bool) (err error) { 660 currentTime := time.Now() 661 662 query := fmt.Sprintf(` 663 UPDATE %s 664 SET ecosystem=$1, lastupdate=$3 665 WHERE feeder_id=$2`, oracleconfigTable) 666 _, err = rdb.postgresClient.Exec(context.Background(), query, enable, feederId, currentTime) 667 if err != nil { 668 return 669 } 670 671 return 672 } 673 674 func (rdb *RelDB) DeleteOracle(feederID string) (err error) { 675 currentTime := time.Now() 676 query := fmt.Sprintf(` 677 UPDATE %s 678 SET deleted=$1,lastupdate=$3 679 WHERE feeder_id=$2`, oracleconfigTable) 680 _, err = rdb.postgresClient.Exec(context.Background(), query, true, feederID, currentTime) 681 if err != nil { 682 return 683 } 684 685 return 686 } 687 688 func (rdb *RelDB) ExpireOracle(feederID string) (err error) { 689 currentTime := time.Now() 690 query := fmt.Sprintf(` 691 UPDATE %s 692 SET expired=$1, deleted=$2,lastupdate=$4 693 WHERE feeder_id=$3`, oracleconfigTable) 694 _, err = rdb.postgresClient.Exec(context.Background(), query, true, true, feederID, currentTime) 695 if err != nil { 696 return 697 } 698 699 return 700 } 701 702 func (rdb *RelDB) GetOracleUpdateCount(address, chainid, symbol string) (int64, error) { 703 query := fmt.Sprintf(` 704 SELECT count(*) from %s 705 WHERE oracle_address=$1 and chain_id=$2 706 AND ($3 = '' OR asset_key = $3) 707 708 `, feederupdatesTable) 709 710 var numUpdates sql.NullInt64 711 err := rdb.postgresClient.QueryRow(context.Background(), query, address, chainid, symbol).Scan(&numUpdates) 712 if numUpdates.Valid { 713 return numUpdates.Int64, nil 714 } 715 return 0, err 716 717 } 718 719 func (rdb *RelDB) GetOracleLastUpdate(address, chainid, symbol string) (time.Time, string, error) { 720 symbol = symbol + "/USD" 721 var ( 722 updateTime sql.NullTime 723 price string 724 ) 725 query := fmt.Sprintf(` 726 SELECT update_time,asset_price 727 FROM %s fu 728 WHERE oracle_address = $1 AND chain_id = $2 and asset_key=$3 order by update_block desc LIMIT 1 729 `, feederupdatesTable) 730 731 err := rdb.postgresClient.QueryRow(context.Background(), query, address, chainid, symbol).Scan(&updateTime, &price) 732 if err != nil { 733 return time.Time{}, "", err 734 } 735 736 return updateTime.Time, price, nil 737 } 738 func (rdb *RelDB) GetOracleUpdates(address string, chainid string, offset int) ([]dia.OracleUpdate, error) { 739 query := fmt.Sprintf(` 740 SELECT fu.oracle_address, 741 fu.transaction_hash, 742 fu.transaction_cost, 743 fu.asset_key, 744 fu.asset_price, 745 fu.update_block, 746 fu.update_from, 747 fu.from_balance, 748 fu.gas_cost, 749 fu.gas_used, 750 fu.chain_id, 751 fu.update_time, 752 oc.creation_block, 753 oc.creation_block_time 754 755 756 FROM %s fu 757 JOIN %s oc ON fu.oracle_address = oc.address AND fu.chain_id = oc.chainID 758 WHERE fu.oracle_address = $1 AND fu.chain_id = $2 order by fu.update_block desc LIMIT 20 OFFSET %d 759 `, feederupdatesTable, oracleconfigTable, offset) 760 761 rows, err := rdb.postgresClient.Query(context.Background(), query, address, chainid) 762 if err != nil { 763 return nil, err 764 } 765 defer rows.Close() 766 767 var ( 768 updates []dia.OracleUpdate 769 ) 770 771 for rows.Next() { 772 773 var ( 774 update dia.OracleUpdate 775 updateTime sql.NullTime 776 creationBlock sql.NullInt64 777 creationBlockTime sql.NullTime 778 ) 779 err := rows.Scan( 780 &update.OracleAddress, 781 &update.TransactionHash, 782 &update.TransactionCost, 783 &update.AssetKey, 784 &update.AssetPrice, 785 &update.UpdateBlock, 786 &update.UpdateFrom, 787 &update.FromBalance, 788 &update.GasCost, 789 &update.GasUsed, 790 &update.ChainID, 791 &updateTime, 792 &creationBlock, 793 &creationBlockTime, 794 ) 795 796 if updateTime.Valid { 797 update.UpdateTime = updateTime.Time 798 } 799 if creationBlockTime.Valid { 800 update.CreationBlockTime = creationBlockTime.Time 801 } 802 if creationBlock.Valid { 803 update.CreationBlock = uint64(creationBlock.Int64) 804 } 805 806 if err != nil { 807 return nil, err 808 } 809 810 updates = append(updates, update) 811 } 812 813 if err := rows.Err(); err != nil { 814 return nil, err 815 } 816 817 return updates, nil 818 } 819 func (rdb *RelDB) GetOracleUpdatesByTimeRange(address, chainid, symbol string, offset int, startTime, endTime time.Time) ([]dia.OracleUpdate, error) { 820 query := "" 821 if offset == -1 { 822 query = fmt.Sprintf(` 823 SELECT fu.oracle_address, 824 fu.transaction_hash, 825 fu.transaction_cost, 826 fu.asset_key, 827 fu.asset_price, 828 fu.update_block, 829 fu.update_from, 830 fu.from_balance, 831 fu.gas_cost, 832 fu.gas_used, 833 fu.chain_id, 834 fu.update_time, 835 oc.creation_block, 836 oc.creation_block_time 837 838 FROM %s fu 839 JOIN %s oc ON fu.oracle_address = oc.address AND fu.chain_id = oc.chainID 840 WHERE fu.oracle_address = $1 AND fu.chain_id = $2 841 AND ($3 = 0 OR $4 = 0 OR (fu.update_time < to_timestamp($3) AND fu.update_time > to_timestamp($4))) 842 AND ($5 = '' OR fu.asset_key = $5) 843 844 order by fu.update_block desc 845 `, feederupdatesTable, oracleconfigTable) 846 847 } else { 848 query = fmt.Sprintf(` 849 SELECT fu.oracle_address, 850 fu.transaction_hash, 851 fu.transaction_cost, 852 fu.asset_key, 853 fu.asset_price, 854 fu.update_block, 855 fu.update_from, 856 fu.from_balance, 857 fu.gas_cost, 858 fu.gas_used, 859 fu.chain_id, 860 fu.update_time, 861 oc.creation_block, 862 oc.creation_block_time 863 864 FROM %s fu 865 JOIN %s oc ON fu.oracle_address = oc.address AND fu.chain_id = oc.chainID 866 WHERE fu.oracle_address = $1 AND fu.chain_id = $2 867 AND ($3 = 0 OR $4 = 0 OR (fu.update_time < to_timestamp($3) AND fu.update_time > to_timestamp($4))) 868 AND ($5 = '' OR fu.asset_key = $5) 869 870 order by fu.update_block desc LIMIT 20 OFFSET %d 871 `, feederupdatesTable, oracleconfigTable, offset) 872 873 } 874 875 rows, err := rdb.postgresClient.Query(context.Background(), query, address, chainid, endTime.Unix(), startTime.Unix(), symbol) 876 if err != nil { 877 return nil, err 878 } 879 defer rows.Close() 880 881 var ( 882 updates []dia.OracleUpdate 883 ) 884 885 for rows.Next() { 886 887 var ( 888 update dia.OracleUpdate 889 updateTime sql.NullTime 890 creationBlock sql.NullInt64 891 creationBlockTime sql.NullTime 892 ) 893 err := rows.Scan( 894 &update.OracleAddress, 895 &update.TransactionHash, 896 &update.TransactionCost, 897 &update.AssetKey, 898 &update.AssetPrice, 899 &update.UpdateBlock, 900 &update.UpdateFrom, 901 &update.FromBalance, 902 &update.GasCost, 903 &update.GasUsed, 904 &update.ChainID, 905 &updateTime, 906 &creationBlock, 907 &creationBlockTime, 908 ) 909 910 if updateTime.Valid { 911 update.UpdateTime = updateTime.Time 912 } 913 if creationBlockTime.Valid { 914 update.CreationBlockTime = creationBlockTime.Time 915 } 916 if creationBlock.Valid { 917 update.CreationBlock = uint64(creationBlock.Int64) 918 } 919 920 if err != nil { 921 return nil, err 922 } 923 924 updates = append(updates, update) 925 } 926 927 if err := rows.Err(); err != nil { 928 return nil, err 929 } 930 931 return updates, nil 932 } 933 func (rdb *RelDB) GetLastOracleUpdate(address string, chainid string) ([]dia.OracleUpdate, error) { 934 query := fmt.Sprintf(` 935 SELECT fu.oracle_address, 936 fu.transaction_hash, 937 fu.transaction_cost, 938 fu.asset_key, 939 fu.asset_price, 940 fu.update_block, 941 fu.update_from, 942 fu.from_balance, 943 fu.gas_cost, 944 fu.gas_used, 945 fu.chain_id, 946 fu.update_time, 947 oc.creation_block, 948 oc.creation_block_time 949 950 951 FROM %s fu 952 JOIN %s oc ON fu.oracle_address = oc.address AND fu.chain_id = oc.chainID 953 WHERE fu.oracle_address = $1 AND fu.chain_id = $2 order by fu.update_time desc LIMIT 1 954 `, feederupdatesTable, oracleconfigTable) 955 956 rows, err := rdb.postgresClient.Query(context.Background(), query, address, chainid) 957 if err != nil { 958 return nil, err 959 } 960 defer rows.Close() 961 962 var ( 963 updates []dia.OracleUpdate 964 ) 965 966 for rows.Next() { 967 968 var ( 969 update dia.OracleUpdate 970 updateTime sql.NullTime 971 creationBlock sql.NullInt64 972 creationBlockTime sql.NullTime 973 ) 974 err := rows.Scan( 975 &update.OracleAddress, 976 &update.TransactionHash, 977 &update.TransactionCost, 978 &update.AssetKey, 979 &update.AssetPrice, 980 &update.UpdateBlock, 981 &update.UpdateFrom, 982 &update.FromBalance, 983 &update.GasCost, 984 &update.GasUsed, 985 &update.ChainID, 986 &updateTime, 987 &creationBlock, 988 &creationBlockTime, 989 ) 990 991 if updateTime.Valid { 992 update.UpdateTime = updateTime.Time 993 } 994 if creationBlockTime.Valid { 995 update.CreationBlockTime = creationBlockTime.Time 996 } 997 if creationBlock.Valid { 998 update.CreationBlock = uint64(creationBlock.Int64) 999 } 1000 1001 if err != nil { 1002 return nil, err 1003 } 1004 1005 updates = append(updates, update) 1006 } 1007 1008 if err := rows.Err(); err != nil { 1009 return nil, err 1010 } 1011 1012 return updates, nil 1013 } 1014 func (rdb *RelDB) GetTotalGasSpend(address string, chainid string) (float64, error) { 1015 query := fmt.Sprintf(` 1016 SELECT 1017 SUM(fu.gas_used) AS total_gas_used 1018 FROM %s fu 1019 WHERE fu.oracle_address = $1 AND fu.chain_id = $2 1020 `, feederupdatesTable) 1021 1022 rows, err := rdb.postgresClient.Query(context.Background(), query, address, chainid) 1023 if err != nil { 1024 fmt.Println("err", err) 1025 return 0.0, err 1026 } 1027 defer rows.Close() 1028 1029 var ( 1030 gasUsed sql.NullFloat64 1031 ) 1032 1033 for rows.Next() { 1034 1035 rows.Scan( 1036 1037 &gasUsed, 1038 ) 1039 1040 } 1041 1042 if gasUsed.Valid { 1043 return gasUsed.Float64, nil 1044 1045 } 1046 return 0.0, nil 1047 1048 } 1049 1050 func (rdb *RelDB) GetBalanceRemaining(address string, chainid string) (float64, error) { 1051 query := fmt.Sprintf(` 1052 SELECT 1053 from_balance, 1054 update_time 1055 FROM %s fu 1056 WHERE fu.oracle_address = $1 AND fu.chain_id = $2 ORDER BY update_time DESC LIMIT 1 1057 `, feederupdatesTable) 1058 1059 rows, err := rdb.postgresClient.Query(context.Background(), query, address, chainid) 1060 if err != nil { 1061 fmt.Println("err", err) 1062 return 0.0, err 1063 } 1064 defer rows.Close() 1065 1066 var ( 1067 gasRemaining sql.NullFloat64 1068 ) 1069 1070 for rows.Next() { 1071 1072 rows.Scan( 1073 &gasRemaining, 1074 nil, 1075 ) 1076 1077 } 1078 1079 if gasRemaining.Valid { 1080 return gasRemaining.Float64, nil 1081 1082 } 1083 return 0.0, nil 1084 1085 } 1086 1087 func (rdb *RelDB) GetDayWiseUpdates(address string, chainid string) ([]dia.FeedUpdates, float64, float64, error) { 1088 query := fmt.Sprintf(` 1089 WITH Dates AS ( 1090 SELECT generate_series(CURRENT_DATE - INTERVAL '29 days', CURRENT_DATE, INTERVAL '1 day')::DATE AS day 1091 ), 1092 DailyUpdates AS ( 1093 SELECT 1094 d.day, 1095 AVG(fu.gas_used) AS average_gas_used, 1096 SUM(fu.gas_used) AS total_gas_used, 1097 COUNT(fu.update_time) AS total_updates 1098 FROM Dates d 1099 LEFT JOIN %s fu ON DATE(fu.update_time) = d.day 1100 AND fu.oracle_address = $1 1101 AND fu.chain_id = $2 1102 GROUP BY d.day 1103 ) 1104 SELECT 1105 day, 1106 COALESCE(total_gas_used, 0) AS total_gas_used, 1107 COALESCE(total_updates, 0) AS total_updates, 1108 (SELECT AVG(total_updates::NUMERIC) FROM DailyUpdates) AS average_total_updates_per_day, 1109 (SELECT AVG(average_gas_used) FROM DailyUpdates) AS average_gas_used_per_day 1110 FROM DailyUpdates 1111 ORDER BY day DESC; 1112 `, feederupdatesTable) 1113 1114 rows, err := rdb.postgresClient.Query(context.Background(), query, address, chainid) 1115 if err != nil { 1116 fmt.Println("err", err) 1117 return nil, 0, 0, err 1118 } 1119 defer rows.Close() 1120 1121 var ( 1122 avgGasUsed sql.NullFloat64 1123 avgUpdateCount sql.NullFloat64 1124 stats []dia.FeedUpdates 1125 updateTime sql.NullTime 1126 ) 1127 1128 for rows.Next() { 1129 du := dia.FeedUpdates{} 1130 rows.Scan( 1131 &updateTime, 1132 &du.GasUsed, 1133 &du.UpdateCount, 1134 &avgUpdateCount, 1135 &avgGasUsed, 1136 ) 1137 if updateTime.Valid { 1138 du.Day = updateTime.Time 1139 } 1140 1141 stats = append(stats, du) 1142 1143 } 1144 1145 return stats, avgGasUsed.Float64, avgUpdateCount.Float64, nil 1146 1147 } 1148 1149 // dave oracleconfig in cache 1150 func (datastore *DB) SetOracleConfigCache(oc dia.OracleConfig) error { 1151 key := oc.Address + "-" + oc.ChainID 1152 1153 if datastore.redisClient == nil { 1154 return nil 1155 } 1156 1157 data, _ := json.Marshal(oc) 1158 1159 err := datastore.redisClient.Set(key, data, TimeOutRedis).Err() 1160 if err != nil { 1161 log.Printf("Error: %v on SetOracleConfigCache %v\n", err, oc) 1162 } 1163 1164 return err 1165 } 1166 1167 func (datastore *DB) GetOracleConfigCache(key string) (dia.OracleConfig, error) { 1168 // key := oc.Address + oc.ChainID 1169 var oc dia.OracleConfig 1170 if datastore.redisClient == nil { 1171 return oc, errors.New("no redisclient") 1172 } 1173 1174 err := datastore.redisClient.Get(key).Scan(&oc) 1175 if err != nil { 1176 log.Printf("Error: %v on GetOracle--ConfigCache %v\n", err, oc) 1177 return oc, errors.New("no redisclient") 1178 1179 } 1180 1181 return oc, err 1182 1183 } 1184 1185 func (reldb *RelDB) AddWalletKeys(owner, username, accessLevel string, publicKey []string, customerId string) error { 1186 var err error 1187 1188 // customerID, err := reldb.GetCustomerIDByWalletPublicKey(owner) 1189 // if err != nil { 1190 // return err 1191 // } 1192 1193 tx, err := reldb.postgresClient.BeginTx(context.Background(), pgx.TxOptions{}) 1194 if err != nil { 1195 return err 1196 1197 } 1198 defer tx.Rollback(context.Background()) 1199 1200 for _, publicKey := range publicKey { 1201 _, err = tx.Exec(context.Background(), ` 1202 INSERT INTO wallet_public_keys (customer_id, public_key, access_level,username) 1203 VALUES ($1, $2,$3,$4) 1204 `, customerId, publicKey, accessLevel, username) 1205 if err != nil { 1206 return err 1207 } 1208 } 1209 1210 err = tx.Commit(context.Background()) 1211 if err != nil { 1212 return err 1213 } 1214 1215 return nil 1216 } 1217 1218 func (reldb *RelDB) AddTempWalletKeys(owner, username, accessLevel string, publicKey []string) error { 1219 var err error 1220 1221 customerID, err := reldb.GetCustomerIDByWalletPublicKey(owner) 1222 if err != nil { 1223 return err 1224 } 1225 1226 tx, err := reldb.postgresClient.BeginTx(context.Background(), pgx.TxOptions{}) 1227 if err != nil { 1228 return err 1229 1230 } 1231 defer tx.Rollback(context.Background()) 1232 1233 for _, publicKey := range publicKey { 1234 _, err = tx.Exec(context.Background(), ` 1235 INSERT INTO wallet_public_keys_temp (customer_id, public_key, access_level,username,invitor) 1236 VALUES ($1, $2,$3,$4,$5) 1237 `, customerID, publicKey, accessLevel, username, owner) 1238 if err != nil { 1239 return err 1240 } 1241 } 1242 1243 err = tx.Commit(context.Background()) 1244 if err != nil { 1245 return err 1246 } 1247 1248 return nil 1249 1250 } 1251 1252 func (reldb *RelDB) DeleteTempWalletRequest(ctx context.Context, keyId string) (err error) { 1253 query := ` 1254 DELETE FROM wallet_public_keys_temp 1255 WHERE key_id = $1; 1256 ` 1257 1258 result, err := reldb.postgresClient.Exec(ctx, query, keyId) 1259 if err != nil { 1260 return fmt.Errorf("failed to execute delete query: %v", err) 1261 } 1262 1263 rowsAffected := result.RowsAffected() 1264 1265 if rowsAffected == 0 { 1266 return fmt.Errorf("no record found with key_id: %d", keyId) 1267 } 1268 1269 return nil 1270 } 1271 1272 func (reldb *RelDB) GetTempWalletRequest(ctx context.Context, publicKey, customerID string) (keyID int, accessLevel, username string, err error) { 1273 query := ` 1274 SELECT key_id, access_level, username 1275 FROM wallet_public_keys_temp 1276 WHERE public_key = $1 AND customer_id = $2; 1277 ` 1278 1279 err = reldb.postgresClient.QueryRow(ctx, query, publicKey, customerID).Scan( 1280 &keyID, 1281 &accessLevel, 1282 &username, 1283 ) 1284 1285 if err != nil { 1286 if err == sql.ErrNoRows { 1287 err = fmt.Errorf("no wallet public key found for public_key: %s and username: %s", publicKey, username) 1288 } 1289 } 1290 1291 return 1292 1293 } 1294 1295 func (reldb *RelDB) UpdateAccessLevel(username, accessLevel, publicKey string) error { 1296 // Start building the SQL query 1297 query := "UPDATE wallet_public_keys SET" 1298 var fields []string 1299 var args []interface{} 1300 argID := 1 1301 1302 if accessLevel != "" { 1303 fields = append(fields, fmt.Sprintf(" access_level = $%d", argID)) 1304 args = append(args, accessLevel) 1305 argID++ 1306 } 1307 1308 username = strings.TrimSpace(username) 1309 1310 // Conditionally add username if it's not nil or empty 1311 if username != "" { 1312 fields = append(fields, fmt.Sprintf(" username = $%d", argID)) 1313 args = append(args, username) 1314 argID++ 1315 } 1316 1317 // If no fields are provided to update, return an error 1318 if len(fields) == 0 { 1319 return fmt.Errorf("no fields provided to update") 1320 } 1321 1322 // Add the WHERE clause to target the correct public_key 1323 query += strings.Join(fields, ",") + fmt.Sprintf(" WHERE public_key = $%d", argID) 1324 args = append(args, publicKey) 1325 1326 tx, err := reldb.postgresClient.BeginTx(context.Background(), pgx.TxOptions{}) 1327 if err != nil { 1328 return err 1329 1330 } 1331 1332 _, err = tx.Exec(context.Background(), query, args...) 1333 if err != nil { 1334 return fmt.Errorf("failed to prepare statement: %w", err) 1335 } 1336 1337 err = tx.Commit(context.Background()) 1338 1339 if err != nil { 1340 return fmt.Errorf("failed to execute update: %w", err) 1341 } 1342 1343 return nil 1344 } 1345 1346 func (reldb *RelDB) RemoveWalletKeys(publicKey []string) error { 1347 var err error 1348 1349 tx, err := reldb.postgresClient.BeginTx(context.Background(), pgx.TxOptions{}) 1350 if err != nil { 1351 return err 1352 1353 } 1354 defer tx.Rollback(context.Background()) 1355 1356 for _, publicKey := range publicKey { 1357 _, err = tx.Exec(context.Background(), ` 1358 DELETE FROM wallet_public_keys 1359 WHERE public_key = $1 1360 `, publicKey) 1361 if err != nil { 1362 return err 1363 } 1364 } 1365 1366 err = tx.Commit(context.Background()) 1367 if err != nil { 1368 return err 1369 } 1370 1371 return nil 1372 } 1373 func (reldb *RelDB) GetCustomerIDByWalletPublicKey(publicKey string) (int, error) { 1374 var customerID int 1375 err := reldb.postgresClient.QueryRow(context.Background(), ` 1376 SELECT customer_id 1377 FROM wallet_public_keys 1378 WHERE public_key = $1 1379 `, publicKey).Scan(&customerID) 1380 if err != nil { 1381 return 0, err 1382 } 1383 return customerID, nil 1384 } 1385 1386 func (reldb *RelDB) CreateCustomer(email string, name string, customerPlan int, paymentStatus string, paymentSource string, numberOfDataFeeds int, walletPublicKeys []string) error { 1387 tx, err := reldb.postgresClient.Begin(context.Background()) 1388 if err != nil { 1389 return fmt.Errorf("unable to start a transaction: %v", err) 1390 } 1391 defer tx.Rollback(context.Background()) 1392 1393 // Insert the new customer 1394 var customerID int 1395 insertCustomerQuery := ` 1396 INSERT INTO customers (email, customer_plan, payment_status, payment_source, number_of_data_feeds,name) 1397 VALUES ($1, $2, $3, $4, $5,$6) 1398 RETURNING customer_id` 1399 1400 err = tx.QueryRow(context.Background(), insertCustomerQuery, email, customerPlan, paymentStatus, paymentSource, numberOfDataFeeds, name).Scan(&customerID) 1401 if err != nil { 1402 return fmt.Errorf("unable to insert customer: %v", err) 1403 } 1404 1405 err = addWalletPublicKeys(tx, customerID, walletPublicKeys) 1406 if err != nil { 1407 return err 1408 } 1409 1410 err = tx.Commit(context.Background()) 1411 if err != nil { 1412 return fmt.Errorf("unable to commit transaction: %v", err) 1413 } 1414 1415 return nil 1416 } 1417 1418 func (reldb *RelDB) UpdateCustomerPlan(ctx context.Context, customerID int, customerPlan int, paymentSource string, lastPayment string, payerAddress string) error { 1419 1420 ut, err := strconv.ParseInt(lastPayment, 10, 64) 1421 if err != nil { 1422 return err 1423 } 1424 lastPaymentts := time.Unix(ut, 0) 1425 1426 query := ` 1427 UPDATE customers 1428 SET customer_plan = $1, 1429 payment_source = $2, 1430 last_payment = $3, 1431 payer_address = $5 1432 WHERE customer_id = $4 1433 ` 1434 _, err = reldb.postgresClient.Exec(ctx, query, customerPlan, paymentSource, lastPaymentts, customerID, payerAddress) 1435 return err 1436 } 1437 1438 func addWalletPublicKeys(tx pgx.Tx, customerID int, walletPublicKeys []string) error { 1439 insertWalletKeyQuery := ` 1440 INSERT INTO wallet_public_keys (customer_id, public_key) 1441 VALUES ($1, $2)` 1442 1443 for _, publicKey := range walletPublicKeys { 1444 _, err := tx.Exec(context.Background(), insertWalletKeyQuery, customerID, publicKey) 1445 if err != nil { 1446 return fmt.Errorf("unable to insert wallet public key: %v", err) 1447 } 1448 } 1449 1450 return nil 1451 } 1452 1453 func (reldb *RelDB) GetPlan(ctx context.Context, planID int) (*Plan, error) { 1454 var plan Plan 1455 query := `SELECT plan_id, plan_name, plan_description, plan_price, total_feeds,total_oracles 1456 FROM plans 1457 WHERE plan_id = $1` 1458 err := reldb.postgresClient.QueryRow(ctx, query, planID).Scan( 1459 &plan.PlanID, 1460 &plan.Name, 1461 &plan.Description, 1462 &plan.Price, 1463 &plan.TotalFeeds, 1464 &plan.TotalOracles, 1465 ) 1466 if err != nil { 1467 return nil, err 1468 } 1469 return &plan, err 1470 1471 } 1472 1473 func (reldb *RelDB) GetPendingRequestByPublicKey(owner string) (pk []PublicKey, err error) { 1474 1475 query := ` 1476 SELECT customer_id, access_level,username 1477 FROM wallet_public_keys_temp 1478 WHERE public_key = $1 1479 ` 1480 rows, err := reldb.postgresClient.Query(context.Background(), query, owner) 1481 if err != nil { 1482 return nil, err 1483 } 1484 defer rows.Close() 1485 1486 var username sql.NullString 1487 1488 for rows.Next() { 1489 var publicKey PublicKey 1490 if err := rows.Scan(&publicKey.CustomerId, &publicKey.AccessLevel, &username); err != nil { 1491 return nil, err 1492 } 1493 if username.Valid { 1494 publicKey.UserName = username.String 1495 } 1496 pk = append(pk, publicKey) 1497 } 1498 return 1499 1500 } 1501 1502 func (reldb *RelDB) GetPendingInvites(ctx context.Context, publicKeyAddress string) (pk []PublicKey, err error) { 1503 1504 query := ` 1505 SELECT customer_id, access_level,username,invitor 1506 FROM wallet_public_keys_temp 1507 WHERE public_key = $1 1508 ` 1509 rows, err := reldb.postgresClient.Query(ctx, query, publicKeyAddress) 1510 if err != nil { 1511 return nil, err 1512 } 1513 defer rows.Close() 1514 1515 var username sql.NullString 1516 var invitor sql.NullString 1517 1518 var customerId int 1519 1520 for rows.Next() { 1521 var publicKey PublicKey 1522 if err := rows.Scan(&customerId, &publicKey.AccessLevel, &username, &invitor); err != nil { 1523 return nil, err 1524 } 1525 if invitor.Valid { 1526 publicKey.Invitor = invitor.String 1527 } 1528 if username.Valid { 1529 publicKey.UserName = username.String 1530 } 1531 publicKey.CustomerId = strconv.Itoa(customerId) 1532 publicKey.PublicKey = publicKeyAddress 1533 pk = append(pk, publicKey) 1534 } 1535 return 1536 1537 } 1538 1539 func (reldb *RelDB) GetPendingPublicKeyByCustomer(ctx context.Context, customerId string) (pk []PublicKey, err error) { 1540 1541 query := ` 1542 SELECT public_key, access_level,username 1543 FROM wallet_public_keys_temp 1544 WHERE customer_id = $1 1545 ` 1546 rows, err := reldb.postgresClient.Query(ctx, query, customerId) 1547 if err != nil { 1548 return nil, err 1549 } 1550 defer rows.Close() 1551 1552 var username sql.NullString 1553 1554 for rows.Next() { 1555 var publicKey PublicKey 1556 if err := rows.Scan(&publicKey.PublicKey, &publicKey.AccessLevel, &username); err != nil { 1557 return nil, err 1558 } 1559 if username.Valid { 1560 publicKey.UserName = username.String 1561 } 1562 pk = append(pk, publicKey) 1563 } 1564 return 1565 1566 } 1567 1568 func (reldb *RelDB) GetCustomerByPublicKey(publicKey string) (*Customer, error) { 1569 var customer Customer 1570 query := ` 1571 SELECT c.customer_id, c.email, c.account_creation_date, c.customer_plan, c.deployed_oracles, 1572 c.payment_status, c.payment_source, c.number_of_data_feeds, c.active,c.payer_address 1573 FROM customers c 1574 INNER JOIN wallet_public_keys wpk ON c.customer_id = wpk.customer_id 1575 WHERE wpk.public_key = $1 1576 ` 1577 var ( 1578 emailSql sql.NullString 1579 customerPlanSql sql.NullInt16 1580 paymentStatusSql sql.NullString 1581 paymentSourceSql sql.NullString 1582 payerAddress sql.NullString 1583 ) 1584 err := reldb.postgresClient.QueryRow(context.Background(), query, publicKey).Scan( 1585 &customer.CustomerID, 1586 &emailSql, 1587 &customer.AccountCreationDate, 1588 &customerPlanSql, 1589 &customer.DeployedOracles, 1590 &paymentStatusSql, 1591 // &customer.LastPayment, 1592 &paymentSourceSql, 1593 &customer.NumberOfDataFeeds, 1594 &customer.Active, 1595 &payerAddress, 1596 ) 1597 if err != nil { 1598 return nil, err 1599 } 1600 query = ` 1601 SELECT public_key, access_level,username 1602 FROM wallet_public_keys 1603 WHERE customer_id = $1 1604 ` 1605 rows, err := reldb.postgresClient.Query(context.Background(), query, customer.CustomerID) 1606 if err != nil { 1607 return nil, err 1608 } 1609 defer rows.Close() 1610 1611 var username sql.NullString 1612 1613 for rows.Next() { 1614 var publicKey PublicKey 1615 if err := rows.Scan(&publicKey.PublicKey, &publicKey.AccessLevel, &username); err != nil { 1616 return nil, err 1617 } 1618 if username.Valid { 1619 publicKey.UserName = username.String 1620 } 1621 customer.PublicKeys = append(customer.PublicKeys, publicKey) 1622 } 1623 1624 if emailSql.Valid { 1625 customer.Email = emailSql.String 1626 } 1627 if payerAddress.Valid { 1628 customer.PayerAddress = payerAddress.String 1629 } 1630 if paymentStatusSql.Valid { 1631 customer.PaymentStatus = paymentStatusSql.String 1632 } 1633 if customerPlanSql.Valid { 1634 customer.CustomerPlan = int(customerPlanSql.Int16) 1635 } 1636 if paymentSourceSql.Valid { 1637 customer.PaymentSource = paymentSourceSql.String 1638 } 1639 1640 if rows.Err() != nil { 1641 return nil, rows.Err() 1642 } 1643 return &customer, nil 1644 } 1645 1646 func (reldb *RelDB) GetAccessLevel(publicKey string) (string, error) { 1647 var accessLevel string 1648 err := reldb.postgresClient.QueryRow(context.Background(), ` 1649 SELECT access_level 1650 FROM wallet_public_keys 1651 WHERE public_key = $1 1652 `, publicKey).Scan(&accessLevel) 1653 1654 if err != nil { 1655 return "", err 1656 } 1657 return accessLevel, nil 1658 1659 }