Skip to content

Commit f4d456d

Browse files
authored
multi: Add apis for ledger transactions. (#28)
* addresses: Add address from extended key. * addresses: Add create extended key. * transactions: Change create sign tx to create tx. * transactions: Add decode tx. * transactions: Add get txn. * addresses: Add validate address. * transactions: Add add sig.
1 parent e7003db commit f4d456d

7 files changed

Lines changed: 856 additions & 29 deletions

File tree

‎cgo/addresses.go‎

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
dcrwallet "decred.org/dcrwallet/v4/wallet"
1010
"decred.org/dcrwallet/v4/wallet/udb"
1111
"github.com/decred/dcrd/txscript/v4/stdaddr"
12+
"github.com/decred/libwallet/dcr"
1213
)
1314

1415
//export currentReceiveAddress
@@ -187,3 +188,49 @@ func defaultPubkey(cName *C.char) *C.char {
187188

188189
return successCResponse("%s", pubkey)
189190
}
191+
192+
//export addrFromExtendedKey
193+
func addrFromExtendedKey(cAddrFromExtKeyJSON *C.char) *C.char {
194+
fromExtJSON := goString(cAddrFromExtKeyJSON)
195+
var fromExt AddrFromExtKey
196+
if err := json.Unmarshal([]byte(fromExtJSON), &fromExt); err != nil {
197+
return errCResponse("malformed create addr json: %v", err)
198+
}
199+
addr, err := dcr.AddrFromExtendedKey(fromExt.Key, fromExt.Path, fromExt.AddrType, fromExt.UseChildBIP32Std)
200+
if err != nil {
201+
return errCResponse("unable to create address: %v", err)
202+
}
203+
return successCResponse("%s", addr)
204+
}
205+
206+
//export createExtendedKey
207+
func createExtendedKey(cCreateExtendedKeyJSON *C.char) *C.char {
208+
createExtJSON := goString(cCreateExtendedKeyJSON)
209+
var createExt CreateExtendedKey
210+
if err := json.Unmarshal([]byte(createExtJSON), &createExt); err != nil {
211+
return errCResponse("malformed ceate extended key json: %v", err)
212+
}
213+
extKey, err := dcr.CreateExtendedKey(createExt.Key, createExt.ParentKey, createExt.ChainCode,
214+
createExt.Network, createExt.Depth, createExt.ChildN, createExt.IsPrivate)
215+
if err != nil {
216+
return errCResponse("unable to create key: %v", err)
217+
}
218+
return successCResponse("%s", extKey)
219+
}
220+
221+
//export validateAddr
222+
func validateAddr(cName, cAddr *C.char) *C.char {
223+
w, exists := loadedWallet(cName)
224+
if !exists {
225+
return errCResponse("wallet with name %q does not exist", goString(cName))
226+
}
227+
validated, err := w.ValidateAddr(w.ctx, goString(cAddr))
228+
if err != nil {
229+
return errCResponse("unable to validate address: %v", err)
230+
}
231+
b, err := json.Marshal(validated)
232+
if err != nil {
233+
return errCResponse("unable to marshal validate address: %v", err)
234+
}
235+
return successCResponse("%s", b)
236+
}

‎cgo/transactions.go‎

Lines changed: 78 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,21 @@ import (
88
"strconv"
99

1010
dcrwallet "decred.org/dcrwallet/v4/wallet"
11+
"github.com/decred/dcrd/chaincfg/chainhash"
1112
"github.com/decred/dcrd/txscript/v4/stdaddr"
1213
"github.com/decred/libwallet/dcr"
1314
)
1415

1516
const defaultAccount = "default"
1617

17-
//export createSignedTransaction
18-
func createSignedTransaction(cName, cCreateSignedTxJSONReq *C.char) *C.char {
18+
//export createTransaction
19+
func createTransaction(cName, cCreateTxJSONReq *C.char) *C.char {
1920
w, exists := loadedWallet(cName)
2021
if !exists {
2122
return errCResponse("wallet with name %q does not exist", goString(cName))
2223
}
23-
signSendJSONReq := goString(cCreateSignedTxJSONReq)
24-
var req CreateSignedTxReq
24+
signSendJSONReq := goString(cCreateTxJSONReq)
25+
var req CreateTxReq
2526
if err := json.Unmarshal([]byte(signSendJSONReq), &req); err != nil {
2627
return errCResponse("malformed sign send request: %v", err)
2728
}
@@ -53,19 +54,21 @@ func createSignedTransaction(cName, cCreateSignedTxJSONReq *C.char) *C.char {
5354
ignoreInputs[i] = o
5455
}
5556

56-
if err := w.MainWallet().Unlock(w.ctx, []byte(req.Password), nil); err != nil {
57-
return errCResponse("cannot unlock wallet: %v", err)
57+
if req.Sign {
58+
if err := w.MainWallet().Unlock(w.ctx, []byte(req.Password), nil); err != nil {
59+
return errCResponse("cannot unlock wallet: %v", err)
60+
}
61+
defer w.MainWallet().Lock()
5862
}
59-
defer w.MainWallet().Lock()
6063

61-
txBytes, txhash, fee, err := w.CreateSignedTransaction(w.ctx, outputs, inputs, ignoreInputs, uint64(req.FeeRate), req.SendAll)
64+
txBytes, txhash, fee, err := w.CreateTransaction(w.ctx, outputs, inputs, ignoreInputs, uint64(req.FeeRate), req.SendAll, req.Sign)
6265
if err != nil {
6366
return errCResponse("unable to sign send transaction: %v", err)
6467
}
65-
res := &CreateSignedTxRes{
66-
SignedHex: hex.EncodeToString(txBytes),
67-
Txid: txhash.String(),
68-
Fee: int(fee),
68+
res := &CreateTxRes{
69+
Hex: hex.EncodeToString(txBytes),
70+
Txid: txhash.String(),
71+
Fee: int(fee),
6972
}
7073

7174
b, err := json.Marshal(res)
@@ -214,3 +217,66 @@ func bestBlock(cName *C.char) *C.char {
214217
}
215218
return successCResponse("%s", b)
216219
}
220+
221+
//export decodeTx
222+
func decodeTx(cName, cTxHex *C.char) *C.char {
223+
w, exists := loadedWallet(cName)
224+
if !exists {
225+
return errCResponse("wallet with name %q does not exist", goString(cName))
226+
}
227+
decoded, err := w.DecodeTx(goString(cTxHex))
228+
if err != nil {
229+
return errCResponse("unable to decode tx: %v", err)
230+
}
231+
b, err := json.Marshal(decoded)
232+
if err != nil {
233+
return errCResponse("unable to marshal decoded tx: %v", err)
234+
}
235+
return successCResponse("%s", b)
236+
}
237+
238+
//export getTxn
239+
func getTxn(cName, cHashes *C.char) *C.char {
240+
w, exists := loadedWallet(cName)
241+
if !exists {
242+
return errCResponse("wallet with name %q does not exist", goString(cName))
243+
}
244+
var txIDs []string
245+
if err := json.Unmarshal([]byte(goString(cHashes)), &txIDs); err != nil {
246+
return errCResponse("unable to unmarshal hashes: %v", err)
247+
}
248+
txHashes := make([]*chainhash.Hash, len(txIDs))
249+
for i, txID := range txIDs {
250+
txHash, err := chainhash.NewHashFromStr(txID)
251+
if err != nil {
252+
return errCResponse("unable to create tx hash: %v", err)
253+
}
254+
txHashes[i] = txHash
255+
}
256+
hexes, err := w.GetTxn(w.ctx, txHashes)
257+
if err != nil {
258+
return errCResponse("unable to get txn: %v", err)
259+
}
260+
b, err := json.Marshal(hexes)
261+
if err != nil {
262+
return errCResponse("unable to marshal txn: %v", err)
263+
}
264+
return successCResponse("%s", b)
265+
}
266+
267+
//export addSigs
268+
func addSigs(cName, cTxHex, cSigScripts *C.char) *C.char {
269+
w, exists := loadedWallet(cName)
270+
if !exists {
271+
return errCResponse("wallet with name %q does not exist", goString(cName))
272+
}
273+
var sigScripts []string
274+
if err := json.Unmarshal([]byte(goString(cSigScripts)), &sigScripts); err != nil {
275+
return errCResponse("unable to unmarshal sig scripts: %v", err)
276+
}
277+
signedHex, err := w.AddSigs(goString(cTxHex), sigScripts)
278+
if err != nil {
279+
return errCResponse("unable sign tx: %v", err)
280+
}
281+
return successCResponse("%s", signedHex)
282+
}

‎cgo/types.go‎

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -104,19 +104,20 @@ type Output struct {
104104
Amount int `json:"amount"`
105105
}
106106

107-
type CreateSignedTxReq struct {
107+
type CreateTxReq struct {
108108
Outputs []Output `json:"outputs"`
109109
Inputs []Input `json:"inputs"`
110110
IgnoreInputs []Input `json:"ignoreinputs"`
111111
FeeRate int `json:"feerate"`
112112
SendAll bool `json:"sendall"`
113113
Password string `json:"password"`
114+
Sign bool `json:"sign"`
114115
}
115116

116-
type CreateSignedTxRes struct {
117-
SignedHex string `json:"signedhex"`
118-
Txid string `json:"txid"`
119-
Fee int `json:"fee"`
117+
type CreateTxRes struct {
118+
Hex string `json:"hex"`
119+
Txid string `json:"txid"`
120+
Fee int `json:"fee"`
120121
}
121122

122123
type ListUnspentRes struct {
@@ -171,3 +172,21 @@ type Config struct {
171172
// Only needed during watching only creation.
172173
PubKey string `json:"pubkey"`
173174
}
175+
176+
type AddrFromExtKey struct {
177+
Key string `json:"key"`
178+
Path string `json:"path"`
179+
// Currently support types: P2PKH
180+
AddrType string `json:"addrtype"`
181+
UseChildBIP32Std bool `json:"usechildbip32std"`
182+
}
183+
184+
type CreateExtendedKey struct {
185+
Key string `json:"key"`
186+
ParentKey string `json:"parentkey"`
187+
ChainCode string `json:"chaincode"`
188+
Network string `json:"network"`
189+
Depth uint8 `json:"depth"`
190+
ChildN uint32 `json:"childn"`
191+
IsPrivate bool `json:"isprivate"`
192+
}

0 commit comments

Comments
 (0)