--- /dev/null
+(define-module (infiniteadaptability services bitcoin-core)
+ #:use-module (gnu)
+ #:use-module (gnu packages finance)
+ #:use-module (gnu services)
+ #:use-module (gnu services shepherd)
+ #:use-module (guix gexp)
+ #:use-module (guix records)
+ #:export (bitcoin-core-configuration bitcoin-core-service-type))
+
+(define-record-type* <bitcoin-core-configuration> bitcoin-core-configuration
+ make-bitcoin-core-configuration
+ bitcoin-core-configuration?
+
+ (user bitcoin-core-configuration-user ;string
+ (default "bitcoin"))
+
+ (bitcoin bitcoin-core-configuration-bitcoin ;file-like
+ (default bitcoin-core))
+
+ (datadir bitcoin-core-configuration-datadir ;string
+ (default "/home/bitcoin/.bitcoin"))
+
+ (extra-content bitcoin-core-configuration-extra-content ;string
+ (default "")))
+
+(define (bitcoin-core-config-file config)
+ "Return the bitcoin-core configureation file corresponding to CONFIG."
+ (computed-file "bitcoin.conf"
+ #~(begin
+ (call-with-output-file #$output
+ (lambda (port)
+ (format port "datadir=~a\n"
+ #$(bitcoin-core-configuration-datadir config))
+ (format port "~a\n"
+ #$(bitcoin-core-configuration-extra-content
+ config)))))))
+
+(define (bitcoin-core-accounts config)
+ "Return the accounts needed for service for CONFIG."
+ (define %username
+ (bitcoin-core-configuration-user config))
+
+ (list (user-group
+ (name %username))
+ (user-account
+ (name %username)
+ (group %username)
+ (home-directory (string-append "/home/" %username)))))
+
+(define (bitcoin-core-activation config)
+ "Return the activation GEXP for CONFIG."
+ (with-imported-modules '((guix build utils))
+ #~(begin
+ (use-modules (guix build utils))
+ (define %user
+ (getpw #$(bitcoin-core-configuration-user
+ config)))
+
+ (let* ((homedir (passwd:dir %user))
+ (datadir #$(bitcoin-core-configuration-datadir
+ config)))
+
+ ;; This is important if the datadir is inside the user's directory
+ (mkdir-p homedir)
+ (chown homedir
+ (passwd:uid %user)
+ (passwd:gid %user))
+
+ (mkdir-p datadir)
+ (chown datadir
+ (passwd:uid %user)
+ (passwd:gid %user))))))
+
+(define (bitcoin-core-service config)
+ "Return a <bitcoin-core-service> for bitcoin with CONFIG."
+
+ (define pid-file
+ (string-append (bitcoin-core-configuration-datadir config) "/bitcoind.pid"))
+
+ (define config-file
+ (bitcoin-core-config-file config))
+
+ (define bitcoind-command
+ #~(list (string-append #$(bitcoin-core-configuration-bitcoin config)
+ "/bin/bitcoind")
+ (string-append "-conf="
+ #$config-file)
+ (string-append "-pid="
+ #$pid-file) "-daemon"))
+
+ (list (shepherd-service (documentation "bitcoin core service")
+ (provision '(bitcoin-core))
+ (requirement '(user-processes networking))
+ (start #~(make-forkexec-constructor #$bitcoind-command
+ #:pid-file #$pid-file
+ #:user "bitcoin"
+ #:group
+ "bitcoin"
+ #:directory
+ "/home/bitcoin"))
+
+ (stop #~(make-kill-destructor SIGINT
+ #:grace-period 600)))))
+
+(define bitcoin-core-service-type
+ (service-type (name 'bitcoin-core)
+ (description "Bitcoin Core Daemon")
+ (default-value (bitcoin-core-configuration))
+ (extensions (list (service-extension
+ shepherd-root-service-type
+ bitcoin-core-service)
+ (service-extension activation-service-type
+ bitcoin-core-activation)
+ (service-extension account-service-type
+ bitcoin-core-accounts)))))