cic-custodial/cmd/service/custodial.go

75 lines
3.2 KiB
Go

package main
import (
"context"
"math/big"
"time"
eth_crypto "github.com/celo-org/celo-blockchain/crypto"
"github.com/go-redis/redis/v8"
"github.com/grassrootseconomics/cic-custodial/internal/custodial"
"github.com/grassrootseconomics/cic-custodial/internal/nonce"
"github.com/grassrootseconomics/w3-celo-patch"
)
// Define common smart contrcat ABI's that can be injected into the system container.
// Any relevant function signature that will be used by the custodial system can be defined here.
func initAbis() map[string]*w3.Func {
return map[string]*w3.Func{
// Keccak hash -> 0x449a52f8
"mintTo": w3.MustNewFunc("mintTo(address, uint256)", "bool"),
// Keccak hash -> 0xa9059cbb
"transfer": w3.MustNewFunc("transfer(address,uint256)", "bool"),
// Keccak hash -> 0x23b872dd
"transferFrom": w3.MustNewFunc("transferFrom(address, address, uint256)", "bool"),
// Add to account index
"add": w3.MustNewFunc("add(address)", "bool"),
// giveTo gas refill
"giveTo": w3.MustNewFunc("giveTo(address)", "uint256"),
}
}
// Bootstrap the internal custodial system configs and system signer key.
// This container is passed down to individual tasker and API handlers.
func initSystemContainer(ctx context.Context, noncestore nonce.Noncestore) *custodial.SystemContainer {
ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
defer cancel()
// Some custodial system defaults loaded from the config file.
systemContainer := &custodial.SystemContainer{
Abis: initAbis(),
AccountIndexContract: w3.A(ko.MustString("system.account_index_address")),
GasFaucetContract: w3.A(ko.MustString("system.gas_faucet_address")),
GasRefillThreshold: big.NewInt(ko.MustInt64("system.gas_refill_threshold")),
GasRefillValue: big.NewInt(ko.MustInt64("system.gas_refill_value")),
GiftableGasValue: big.NewInt(ko.MustInt64("system.giftable_gas_value")),
GiftableToken: w3.A(ko.MustString("system.giftable_token_address")),
GiftableTokenValue: big.NewInt(ko.MustInt64("system.giftable_token_value")),
LockPrefix: ko.MustString("system.lock_prefix"),
LockTimeout: 1 * time.Second,
PublicKey: ko.MustString("system.public_key"),
TokenDecimals: ko.MustInt("system.token_decimals"),
TokenTransferGasLimit: uint64(ko.MustInt64("system.token_transfer_gas_limit")),
}
// Check if system signer account nonce is present.
// If not (first boot), we bootstrap it from the network.
currentSystemNonce, err := noncestore.Peek(ctx, ko.MustString("system.public_key"))
lo.Info("custodial: loaded system nonce from noncestore", "nonce", currentSystemNonce)
if err == redis.Nil {
nonce, err := noncestore.SyncNetworkNonce(ctx, ko.MustString("system.public_key"))
lo.Info("custodial: syncing system nonce from network", "nonce", nonce)
if err != nil {
lo.Fatal("custodial: critical error bootstrapping system container", "error", err)
}
}
loadedPrivateKey, err := eth_crypto.HexToECDSA(ko.MustString("system.private_key"))
if err != nil {
lo.Fatal("custodial: critical error bootstrapping system container", "error", err)
}
systemContainer.PrivateKey = loadedPrivateKey
return systemContainer
}