{"action":"created","comment":{"url":"https://api.github.com/repos/btcsuite/btcwallet/pulls/comments/55329288","id":55329288,"diff_hunk":"@@ -1,125 +1,87 @@\n-// Copyright (c) 2013-2015 The btcsuite developers\n+// Copyright (c) 2013-2016 The btcsuite developers\n // Use of this source code is governed by an ISC\n // license that can be found in the LICENSE file.\n \n package wallet\n \n import (\n-\t\"errors\"\n \t\"fmt\"\n-\tbadrand \"math/rand\"\n \t\"sort\"\n-\t\"time\"\n \n \t\"github.com/btcsuite/btcd/blockchain\"\n-\t\"github.com/btcsuite/btcd/chaincfg\"\n+\t\"github.com/btcsuite/btcd/btcec\"\n \t\"github.com/btcsuite/btcd/txscript\"\n \t\"github.com/btcsuite/btcd/wire\"\n \t\"github.com/btcsuite/btcutil\"\n \t\"github.com/btcsuite/btcwallet/waddrmgr\"\n+\t\"github.com/btcsuite/btcwallet/wallet/txauthor\"\n \t\"github.com/btcsuite/btcwallet/wtxmgr\"\n )\n \n-const (\n-\t// All transactions have 4 bytes for version, 4 bytes of locktime,\n-\t// and 2 varints for the number of inputs and outputs.\n-\ttxOverheadEstimate = 4 + 4 + 1 + 1\n+// byAmount defines the methods needed to satisify sort.Interface to\n+// sort credits by their output amount.\n+type byAmount []wtxmgr.Credit\n \n-\t// A best case signature script to redeem a P2PKH output for a\n-\t// compressed pubkey has 70 bytes of the smallest possible DER signature\n-\t// (with no leading 0 bytes for R and S), 33 bytes of serialized pubkey,\n-\t// and data push opcodes for both, plus one byte for the hash type flag\n-\t// appended to the end of the signature.\n-\tsigScriptEstimate = 1 + 70 + 1 + 33 + 1\n+func (s byAmount) Len() int           { return len(s) }\n+func (s byAmount) Less(i, j int) bool { return s[i].Amount < s[j].Amount }\n+func (s byAmount) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }\n \n-\t// A best case tx input serialization cost is 32 bytes of sha, 4 bytes\n-\t// of output index, 4 bytes of sequnce, and the estimated signature\n-\t// script size.\n-\ttxInEstimate = 32 + 4 + 4 + sigScriptEstimate\n+func makeInputSource(eligible []wtxmgr.Credit) txauthor.InputSource {\n+\t// Pick largest outputs first.  This is only done for compatibility with\n+\t// previous tx creation code, not because it's a good idea.\n+\tsort.Sort(sort.Reverse(byAmount(eligible)))\n \n-\t// A P2PKH pkScript contains the following bytes:\n-\t//  - OP_DUP\n-\t//  - OP_HASH160\n-\t//  - OP_DATA_20 + 20 bytes of pubkey hash\n-\t//  - OP_EQUALVERIFY\n-\t//  - OP_CHECKSIG\n-\tpkScriptEstimate = 1 + 1 + 1 + 20 + 1 + 1\n+\t// Current inputs and their total value.  These are closed over by the\n+\t// returned input source and reused across multiple calls.\n+\tcurrentTotal := btcutil.Amount(0)\n+\tcurrentInputs := make([]*wire.TxIn, 0, len(eligible))\n+\tcurrentScripts := make([][]byte, 0, len(eligible))\n \n-\t// A best case tx output serialization cost is 8 bytes of value, one\n-\t// byte of varint, and the pkScript size.\n-\ttxOutEstimate = 8 + 1 + pkScriptEstimate\n-)\n-\n-func estimateTxSize(numInputs, numOutputs int) int {\n-\treturn txOverheadEstimate + txInEstimate*numInputs + txOutEstimate*numOutputs\n-}\n-\n-func feeForSize(incr btcutil.Amount, sz int) btcutil.Amount {\n-\treturn btcutil.Amount(1+sz/1000) * incr\n+\treturn func(target btcutil.Amount) (btcutil.Amount, []*wire.TxIn, [][]byte, error) {\n+\t\tfor currentTotal < target && len(eligible) != 0 {\n+\t\t\tnextCredit := &eligible[0]\n+\t\t\teligible = eligible[1:]\n+\t\t\tnextInput := wire.NewTxIn(&nextCredit.OutPoint, nil)\n+\t\t\tcurrentTotal += nextCredit.Amount\n+\t\t\tcurrentInputs = append(currentInputs, nextInput)\n+\t\t\tcurrentScripts = append(currentScripts, nextCredit.PkScript)\n+\t\t}\n+\t\treturn currentTotal, currentInputs, currentScripts, nil\n+\t}\n }\n \n-// InsufficientFundsError represents an error where there are not enough\n-// funds from unspent tx outputs for a wallet to create a transaction.\n-// This may be caused by not enough inputs for all of the desired total\n-// transaction output amount, or due to\n-type InsufficientFundsError struct {\n-\tin, out, fee btcutil.Amount\n+// secretSource is an implementation of txauthor.SecretSource for the wallet's\n+// address manager.\n+type secretSource struct {\n+\t*waddrmgr.Manager\n }\n \n-// Error satisifies the builtin error interface.\n-func (e InsufficientFundsError) Error() string {\n-\ttotal := e.out + e.fee\n-\tif e.fee == 0 {\n-\t\treturn fmt.Sprintf(\"insufficient funds: transaction requires \"+\n-\t\t\t\"%s input but only %v spendable\", total, e.in)\n+func (s secretSource) GetKey(addr btcutil.Address) (*btcec.PrivateKey, bool, error) {\n+\tma, err := s.Address(addr)\n+\tif err != nil {\n+\t\treturn nil, false, err\n \t}\n-\treturn fmt.Sprintf(\"insufficient funds: transaction requires %s input \"+\n-\t\t\"(%v output + %v fee) but only %v spendable\", total, e.out,\n-\t\te.fee, e.in)\n+\tprivKey, err := ma.(waddrmgr.ManagedPubKeyAddress).PrivKey()\n+\tif err != nil {\n+\t\treturn nil, false, err\n+\t}\n+\treturn privKey, ma.Compressed(), nil\n }\n \n-// ErrUnsupportedTransactionType represents an error where a transaction\n-// cannot be signed as the API only supports spending P2PKH outputs.\n-var ErrUnsupportedTransactionType = errors.New(\"Only P2PKH transactions are supported\")\n-\n-// ErrNonPositiveAmount represents an error where a bitcoin amount is\n-// not positive (either negative, or zero).\n-var ErrNonPositiveAmount = errors.New(\"amount is not positive\")\n-\n-// ErrNegativeFee represents an error where a fee is erroneously\n-// negative.\n-var ErrNegativeFee = errors.New(\"fee is negative\")\n-\n-// defaultFeeIncrement is the default minimum transation fee (0.00001 BTC,\n-// measured in satoshis) added to transactions requiring a fee.\n-const defaultFeeIncrement = 1e3\n-\n-// CreatedTx holds the state of a newly-created transaction and the change\n-// output (if one was added).\n-type CreatedTx struct {\n-\tMsgTx       *wire.MsgTx\n-\tChangeAddr  btcutil.Address\n-\tChangeIndex int // negative if no change\n-\tFee         btcutil.Amount\n+func (s secretSource) GetScript(addr btcutil.Address) ([]byte, error) {\n+\tma, err := s.Address(addr)\n+\tif err != nil {\n+\t\treturn nil, err\n+\t}\n+\treturn ma.(waddrmgr.ManagedScriptAddress).Script()\n }\n \n-// ByAmount defines the methods needed to satisify sort.Interface to\n-// sort a slice of Utxos by their amount.\n-type ByAmount []wtxmgr.Credit\n-\n-func (u ByAmount) Len() int           { return len(u) }\n-func (u ByAmount) Less(i, j int) bool { return u[i].Amount < u[j].Amount }\n-func (u ByAmount) Swap(i, j int)      { u[i], u[j] = u[j], u[i] }\n-\n-// txToPairs creates a raw transaction sending the amounts for each\n-// address/amount pair and fee to each address and the miner.  minconf\n-// specifies the minimum number of confirmations required before an\n-// unspent output is eligible for spending. Leftover input funds not sent\n-// to addr or as a fee for the miner are sent to a newly generated\n-// address. InsufficientFundsError is returned if there are not enough\n-// eligible unspent outputs to create the transaction.\n-func (w *Wallet) txToPairs(pairs map[string]btcutil.Amount, account uint32, minconf int32) (*CreatedTx, error) {\n-\n+// txToOutputs creates a signed transaction which includes each output from\n+// outputs.  Previous outputs to reedeem are chosen from the passed account's\n+// UTXO set and minconf policy. An additional output may be added to return\n+// change to the wallet.  An appropiate fee is included based on the wallet's","path":"wallet/createtx.go","position":174,"original_position":174,"commit_id":"326c0935d5ccc14789c3afcb040fc45f89655705","original_commit_id":"326c0935d5ccc14789c3afcb040fc45f89655705","user":{"login":"davecgh","id":2115102,"avatar_url":"https://avatars.githubusercontent.com/u/2115102?v=3","gravatar_id":"","url":"https://api.github.com/users/davecgh","html_url":"https://github.com/davecgh","followers_url":"https://api.github.com/users/davecgh/followers","following_url":"https://api.github.com/users/davecgh/following{/other_user}","gists_url":"https://api.github.com/users/davecgh/gists{/gist_id}","starred_url":"https://api.github.com/users/davecgh/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/davecgh/subscriptions","organizations_url":"https://api.github.com/users/davecgh/orgs","repos_url":"https://api.github.com/users/davecgh/repos","events_url":"https://api.github.com/users/davecgh/events{/privacy}","received_events_url":"https://api.github.com/users/davecgh/received_events","type":"User","site_admin":false},"body":"appropiate -> appropriate","created_at":"2016-03-08T08:31:51Z","updated_at":"2016-03-08T08:31:51Z","html_url":"https://github.com/btcsuite/btcwallet/pull/377#discussion_r55329288","pull_request_url":"https://api.github.com/repos/btcsuite/btcwallet/pulls/377","_links":{"self":{"href":"https://api.github.com/repos/btcsuite/btcwallet/pulls/comments/55329288"},"html":{"href":"https://github.com/btcsuite/btcwallet/pull/377#discussion_r55329288"},"pull_request":{"href":"https://api.github.com/repos/btcsuite/btcwallet/pulls/377"}}},"pull_request":{"url":"https://api.github.com/repos/btcsuite/btcwallet/pulls/377","id":60978065,"html_url":"https://github.com/btcsuite/btcwallet/pull/377","diff_url":"https://github.com/btcsuite/btcwallet/pull/377.diff","patch_url":"https://github.com/btcsuite/btcwallet/pull/377.patch","issue_url":"https://api.github.com/repos/btcsuite/btcwallet/issues/377","number":377,"state":"open","locked":false,"title":"Refactor wallet transaction creation code.","user":{"login":"jrick","id":1420313,"avatar_url":"https://avatars.githubusercontent.com/u/1420313?v=3","gravatar_id":"","url":"https://api.github.com/users/jrick","html_url":"https://github.com/jrick","followers_url":"https://api.github.com/users/jrick/followers","following_url":"https://api.github.com/users/jrick/following{/other_user}","gists_url":"https://api.github.com/users/jrick/gists{/gist_id}","starred_url":"https://api.github.com/users/jrick/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jrick/subscriptions","organizations_url":"https://api.github.com/users/jrick/orgs","repos_url":"https://api.github.com/users/jrick/repos","events_url":"https://api.github.com/users/jrick/events{/privacy}","received_events_url":"https://api.github.com/users/jrick/received_events","type":"User","site_admin":false},"body":"This began as a change to improve the fee calculation code and evolved\r\ninto a much larger refactor which improves the readability and\r\nmodularity of all of the transaction creation code.\r\n\r\nTransaction fee calculations have been switched from full increments\r\nof the relay fee to a proportion based on the transaction size.  This\r\nmeans that for a relay fee of 1e3 satoshis/kB, a 500 byte transaction\r\nis only required to pay a 5e2 satoshi fee and a 1500 byte transaction\r\nonly need pay a 1.5e3 fee.  The previous code would end up estimating\r\nthese fees to be 1e3 and 2e3 respectively.\r\n\r\nBecause the previous code would add more fee than needed in almost\r\nevery case, the transaction size estimations were optimistic\r\n(best/smallest case) and signing was done in a loop where the fee was\r\nincremented by the relay fee again each time the actual size of the\r\nsigned transaction rendered the fee too low.  This has switched to\r\nusing worst case transaction size estimates rather than best case, and\r\nsigning is only performed once.\r\n\r\nTransaction input signature creation has switched from using\r\ntxscript.SignatureScript to txscript.SignTxOutput.  The new API is\r\nable to redeem outputs other than just P2PKH, so the previous\r\nrestrictions about P2SH outputs being unspendable (except through the\r\nsignrawtransaction RPC) no longer hold.\r\n\r\nSeveral new public packages have been added:\r\n\r\nwallet/txauthor - transaction authoring and signing\r\nwallet/txrules - simple consensus and mempool policy rule checks\r\n\r\nAlong with some internal packages:\r\n\r\nwallet/internal/txsizes - transaction size estimation\r\ninternal/helpers - context free convenience functions\r\n\r\nThe txsizes package is internal as the estimations it provides are\r\nspecific for the algorithms used by the txrules and txauthor packages.\r\n\r\n**PR Note**: The old transaction creation tests tested the internal APIs and will need to be rewritten or replaced for the new code.  This PR will fail the CI infrastructure tests until this is resolved.","created_at":"2016-02-28T04:37:36Z","updated_at":"2016-03-08T08:31:51Z","closed_at":null,"merged_at":null,"merge_commit_sha":"8a8f50604d2c63b1aeb977668bf9dc94d1c0c586","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/btcsuite/btcwallet/pulls/377/commits","review_comments_url":"https://api.github.com/repos/btcsuite/btcwallet/pulls/377/comments","review_comment_url":"https://api.github.com/repos/btcsuite/btcwallet/pulls/comments{/number}","comments_url":"https://api.github.com/repos/btcsuite/btcwallet/issues/377/comments","statuses_url":"https://api.github.com/repos/btcsuite/btcwallet/statuses/326c0935d5ccc14789c3afcb040fc45f89655705","head":{"label":"jrick:createtxrefactor","ref":"createtxrefactor","sha":"326c0935d5ccc14789c3afcb040fc45f89655705","user":{"login":"jrick","id":1420313,"avatar_url":"https://avatars.githubusercontent.com/u/1420313?v=3","gravatar_id":"","url":"https://api.github.com/users/jrick","html_url":"https://github.com/jrick","followers_url":"https://api.github.com/users/jrick/followers","following_url":"https://api.github.com/users/jrick/following{/other_user}","gists_url":"https://api.github.com/users/jrick/gists{/gist_id}","starred_url":"https://api.github.com/users/jrick/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jrick/subscriptions","organizations_url":"https://api.github.com/users/jrick/orgs","repos_url":"https://api.github.com/users/jrick/repos","events_url":"https://api.github.com/users/jrick/events{/privacy}","received_events_url":"https://api.github.com/users/jrick/received_events","type":"User","site_admin":false},"repo":{"id":22847276,"name":"btcwallet","full_name":"jrick/btcwallet","owner":{"login":"jrick","id":1420313,"avatar_url":"https://avatars.githubusercontent.com/u/1420313?v=3","gravatar_id":"","url":"https://api.github.com/users/jrick","html_url":"https://github.com/jrick","followers_url":"https://api.github.com/users/jrick/followers","following_url":"https://api.github.com/users/jrick/following{/other_user}","gists_url":"https://api.github.com/users/jrick/gists{/gist_id}","starred_url":"https://api.github.com/users/jrick/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jrick/subscriptions","organizations_url":"https://api.github.com/users/jrick/orgs","repos_url":"https://api.github.com/users/jrick/repos","events_url":"https://api.github.com/users/jrick/events{/privacy}","received_events_url":"https://api.github.com/users/jrick/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/jrick/btcwallet","description":"","fork":true,"url":"https://api.github.com/repos/jrick/btcwallet","forks_url":"https://api.github.com/repos/jrick/btcwallet/forks","keys_url":"https://api.github.com/repos/jrick/btcwallet/keys{/key_id}","collaborators_url":"https://api.github.com/repos/jrick/btcwallet/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/jrick/btcwallet/teams","hooks_url":"https://api.github.com/repos/jrick/btcwallet/hooks","issue_events_url":"https://api.github.com/repos/jrick/btcwallet/issues/events{/number}","events_url":"https://api.github.com/repos/jrick/btcwallet/events","assignees_url":"https://api.github.com/repos/jrick/btcwallet/assignees{/user}","branches_url":"https://api.github.com/repos/jrick/btcwallet/branches{/branch}","tags_url":"https://api.github.com/repos/jrick/btcwallet/tags","blobs_url":"https://api.github.com/repos/jrick/btcwallet/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/jrick/btcwallet/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/jrick/btcwallet/git/refs{/sha}","trees_url":"https://api.github.com/repos/jrick/btcwallet/git/trees{/sha}","statuses_url":"https://api.github.com/repos/jrick/btcwallet/statuses/{sha}","languages_url":"https://api.github.com/repos/jrick/btcwallet/languages","stargazers_url":"https://api.github.com/repos/jrick/btcwallet/stargazers","contributors_url":"https://api.github.com/repos/jrick/btcwallet/contributors","subscribers_url":"https://api.github.com/repos/jrick/btcwallet/subscribers","subscription_url":"https://api.github.com/repos/jrick/btcwallet/subscription","commits_url":"https://api.github.com/repos/jrick/btcwallet/commits{/sha}","git_commits_url":"https://api.github.com/repos/jrick/btcwallet/git/commits{/sha}","comments_url":"https://api.github.com/repos/jrick/btcwallet/comments{/number}","issue_comment_url":"https://api.github.com/repos/jrick/btcwallet/issues/comments{/number}","contents_url":"https://api.github.com/repos/jrick/btcwallet/contents/{+path}","compare_url":"https://api.github.com/repos/jrick/btcwallet/compare/{base}...{head}","merges_url":"https://api.github.com/repos/jrick/btcwallet/merges","archive_url":"https://api.github.com/repos/jrick/btcwallet/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/jrick/btcwallet/downloads","issues_url":"https://api.github.com/repos/jrick/btcwallet/issues{/number}","pulls_url":"https://api.github.com/repos/jrick/btcwallet/pulls{/number}","milestones_url":"https://api.github.com/repos/jrick/btcwallet/milestones{/number}","notifications_url":"https://api.github.com/repos/jrick/btcwallet/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/jrick/btcwallet/labels{/name}","releases_url":"https://api.github.com/repos/jrick/btcwallet/releases{/id}","deployments_url":"https://api.github.com/repos/jrick/btcwallet/deployments","created_at":"2014-08-11T17:07:34Z","updated_at":"2014-07-31T07:09:28Z","pushed_at":"2016-03-03T14:57:01Z","git_url":"git://github.com/jrick/btcwallet.git","ssh_url":"git@github.com:jrick/btcwallet.git","clone_url":"https://github.com/jrick/btcwallet.git","svn_url":"https://github.com/jrick/btcwallet","homepage":null,"size":3192,"stargazers_count":0,"watchers_count":0,"language":null,"has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"btcsuite:master","ref":"master","sha":"5140086f6ea752c34874c817858004c1c7d2d15d","user":{"login":"btcsuite","id":10235229,"avatar_url":"https://avatars.githubusercontent.com/u/10235229?v=3","gravatar_id":"","url":"https://api.github.com/users/btcsuite","html_url":"https://github.com/btcsuite","followers_url":"https://api.github.com/users/btcsuite/followers","following_url":"https://api.github.com/users/btcsuite/following{/other_user}","gists_url":"https://api.github.com/users/btcsuite/gists{/gist_id}","starred_url":"https://api.github.com/users/btcsuite/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/btcsuite/subscriptions","organizations_url":"https://api.github.com/users/btcsuite/orgs","repos_url":"https://api.github.com/users/btcsuite/repos","events_url":"https://api.github.com/users/btcsuite/events{/privacy}","received_events_url":"https://api.github.com/users/btcsuite/received_events","type":"Organization","site_admin":false},"repo":{"id":12136863,"name":"btcwallet","full_name":"btcsuite/btcwallet","owner":{"login":"btcsuite","id":10235229,"avatar_url":"https://avatars.githubusercontent.com/u/10235229?v=3","gravatar_id":"","url":"https://api.github.com/users/btcsuite","html_url":"https://github.com/btcsuite","followers_url":"https://api.github.com/users/btcsuite/followers","following_url":"https://api.github.com/users/btcsuite/following{/other_user}","gists_url":"https://api.github.com/users/btcsuite/gists{/gist_id}","starred_url":"https://api.github.com/users/btcsuite/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/btcsuite/subscriptions","organizations_url":"https://api.github.com/users/btcsuite/orgs","repos_url":"https://api.github.com/users/btcsuite/repos","events_url":"https://api.github.com/users/btcsuite/events{/privacy}","received_events_url":"https://api.github.com/users/btcsuite/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/btcsuite/btcwallet","description":"A secure bitcoin wallet daemon written in Go (golang)","fork":false,"url":"https://api.github.com/repos/btcsuite/btcwallet","forks_url":"https://api.github.com/repos/btcsuite/btcwallet/forks","keys_url":"https://api.github.com/repos/btcsuite/btcwallet/keys{/key_id}","collaborators_url":"https://api.github.com/repos/btcsuite/btcwallet/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/btcsuite/btcwallet/teams","hooks_url":"https://api.github.com/repos/btcsuite/btcwallet/hooks","issue_events_url":"https://api.github.com/repos/btcsuite/btcwallet/issues/events{/number}","events_url":"https://api.github.com/repos/btcsuite/btcwallet/events","assignees_url":"https://api.github.com/repos/btcsuite/btcwallet/assignees{/user}","branches_url":"https://api.github.com/repos/btcsuite/btcwallet/branches{/branch}","tags_url":"https://api.github.com/repos/btcsuite/btcwallet/tags","blobs_url":"https://api.github.com/repos/btcsuite/btcwallet/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/btcsuite/btcwallet/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/btcsuite/btcwallet/git/refs{/sha}","trees_url":"https://api.github.com/repos/btcsuite/btcwallet/git/trees{/sha}","statuses_url":"https://api.github.com/repos/btcsuite/btcwallet/statuses/{sha}","languages_url":"https://api.github.com/repos/btcsuite/btcwallet/languages","stargazers_url":"https://api.github.com/repos/btcsuite/btcwallet/stargazers","contributors_url":"https://api.github.com/repos/btcsuite/btcwallet/contributors","subscribers_url":"https://api.github.com/repos/btcsuite/btcwallet/subscribers","subscription_url":"https://api.github.com/repos/btcsuite/btcwallet/subscription","commits_url":"https://api.github.com/repos/btcsuite/btcwallet/commits{/sha}","git_commits_url":"https://api.github.com/repos/btcsuite/btcwallet/git/commits{/sha}","comments_url":"https://api.github.com/repos/btcsuite/btcwallet/comments{/number}","issue_comment_url":"https://api.github.com/repos/btcsuite/btcwallet/issues/comments{/number}","contents_url":"https://api.github.com/repos/btcsuite/btcwallet/contents/{+path}","compare_url":"https://api.github.com/repos/btcsuite/btcwallet/compare/{base}...{head}","merges_url":"https://api.github.com/repos/btcsuite/btcwallet/merges","archive_url":"https://api.github.com/repos/btcsuite/btcwallet/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/btcsuite/btcwallet/downloads","issues_url":"https://api.github.com/repos/btcsuite/btcwallet/issues{/number}","pulls_url":"https://api.github.com/repos/btcsuite/btcwallet/pulls{/number}","milestones_url":"https://api.github.com/repos/btcsuite/btcwallet/milestones{/number}","notifications_url":"https://api.github.com/repos/btcsuite/btcwallet/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/btcsuite/btcwallet/labels{/name}","releases_url":"https://api.github.com/repos/btcsuite/btcwallet/releases{/id}","deployments_url":"https://api.github.com/repos/btcsuite/btcwallet/deployments","created_at":"2013-08-15T14:53:57Z","updated_at":"2016-03-06T03:30:08Z","pushed_at":"2016-03-03T19:37:26Z","git_url":"git://github.com/btcsuite/btcwallet.git","ssh_url":"git@github.com:btcsuite/btcwallet.git","clone_url":"https://github.com/btcsuite/btcwallet.git","svn_url":"https://github.com/btcsuite/btcwallet","homepage":"","size":10698,"stargazers_count":104,"watchers_count":104,"language":"Go","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":65,"mirror_url":null,"open_issues_count":50,"forks":65,"open_issues":50,"watchers":104,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/btcsuite/btcwallet/pulls/377"},"html":{"href":"https://github.com/btcsuite/btcwallet/pull/377"},"issue":{"href":"https://api.github.com/repos/btcsuite/btcwallet/issues/377"},"comments":{"href":"https://api.github.com/repos/btcsuite/btcwallet/issues/377/comments"},"review_comments":{"href":"https://api.github.com/repos/btcsuite/btcwallet/pulls/377/comments"},"review_comment":{"href":"https://api.github.com/repos/btcsuite/btcwallet/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/btcsuite/btcwallet/pulls/377/commits"},"statuses":{"href":"https://api.github.com/repos/btcsuite/btcwallet/statuses/326c0935d5ccc14789c3afcb040fc45f89655705"}}}}