Skip to content

Commit

Permalink
wip GetOutputsForAmount
Browse files Browse the repository at this point in the history
  • Loading branch information
lunfardo314 committed Feb 3, 2025
1 parent 2c7da07 commit 69d8a69
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 4 deletions.
40 changes: 40 additions & 0 deletions api/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,46 @@ func (c *APIClient) GetSimpleSigLockedOutputs(addr ledger.AddressED25519, maxOut
return ret, &retLRBID, nil
}

func (c *APIClient) GetOutputsForAmount(addr ledger.AddressED25519, amount uint64) ([]*ledger.OutputWithID, *ledger.TransactionID, error) {
path := fmt.Sprintf(api.PathGetOutputsForAmount+"?addr=%s&amount=%d", addr.Source(), amount)
body, err := c.getBody(path)
if err != nil {
return nil, nil, err
}

var res api.OutputList
err = json.Unmarshal(body, &res)
if err != nil {
return nil, nil, err
}
if res.Error.Error != "" {
return nil, nil, fmt.Errorf("from server: %s", res.Error.Error)
}

retLRBID, err := ledger.TransactionIDFromHexString(res.LRBID)
if err != nil {
return nil, nil, fmt.Errorf("while parsing transaction ID: %s", res.Error.Error)
}

ret := make([]*ledger.OutputWithID, 0, len(res.Outputs))

for idStr, dataStr := range res.Outputs {
id, err := ledger.OutputIDFromHexString(idStr)
if err != nil {
return nil, nil, fmt.Errorf("wrong output ID data from server: %s: '%w'", idStr, err)
}
o, err := ledger.OutputFromHexString(dataStr)
if err != nil {
return nil, nil, fmt.Errorf("wrong output data from server: %s: '%w'", dataStr, err)
}
ret = append(ret, &ledger.OutputWithID{
ID: id,
Output: o,
})
}
return ret, &retLRBID, nil
}

// GetChainedOutputs fetches all outputs of the account. Optionally sorts them on the server
func (c *APIClient) GetChainedOutputs(accountable ledger.Accountable) ([]*ledger.OutputWithChainID, *ledger.TransactionID, error) {
path := fmt.Sprintf(api.PathGetChainedOutputs+"?accountable=%s", accountable.String())
Expand Down
39 changes: 35 additions & 4 deletions api/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ func (srv *server) registerHandlers() {
srv.addHandler(api.PathGetAccountOutputs, srv.getAccountOutputs)
// GET request format: '/api/v1/get_account_simple_siglocked?addr=<a(0x....)>'
srv.addHandler(api.PathGetAccountSimpleSiglockedOutputs, srv.getAccountSimpleSigLockedOutputs)
// GET request format: '/api/v1/get_outputs_for_amount?addr=<a(0x....)>&amount=<amount>'
srv.addHandler(api.PathGetOutputsForAmount, srv.getOutputsForAmount)
// GET request format: '/api/v1/get_chained_outputs?accountable=<EasyFL source form of the accountable lock constraint>'
srv.addHandler(api.PathGetChainedOutputs, srv.getChainedOutputs)
// GET request format: '/api/v1/get_chain_output?chainid=<hex-encoded chain ID>'
Expand Down Expand Up @@ -232,7 +234,7 @@ func (srv *server) getOutputsForAmount(w http.ResponseWriter, r *http.Request) {
writeErr(w, "wrong parameter 'addr' in request 'get_outputs_for_amount'")
return
}
addr, err := ledger.AddressED25519FromSource(lst[0])
targetAddr, err := ledger.AddressED25519FromSource(lst[0])
if err != nil {
writeErr(w, err.Error())
return
Expand All @@ -243,20 +245,49 @@ func (srv *server) getOutputsForAmount(w http.ResponseWriter, r *http.Request) {
writeErr(w, "wrong parameter 'amount' in request 'get_outputs_for_amount'")
return
}
amount, err := strconv.Atoi(lst[0])
if err != nil {
writeErr(w, err.Error())
return
}

resp := &api.OutputList{
Outputs: make(map[string]string),
}
err = srv.withLRB(func(rdr multistate.SugaredStateReader) (errRet error) {
sum := uint64(0)
err = srv.withLRB(func(rdr multistate.SugaredStateReader) error {
lrbid := rdr.GetStemOutput().ID.TransactionID()
resp.LRBID = lrbid.StringHex()
err1 := rdr.IterateOutputsForAccount(addr, func(oid ledger.OutputID, o *ledger.Output) bool {
return true
err1 := rdr.IterateOutputsForAccount(targetAddr, func(oid ledger.OutputID, o *ledger.Output) bool {
if o.Lock().Name() != ledger.AddressED25519Name {
return true
}
if !ledger.EqualAccountables(targetAddr, o.Lock().(ledger.AddressED25519)) {
return true
}
resp.Outputs[oid.StringHex()] = o.Hex()
sum += o.Amount()
return sum < uint64(amount)
})
if err1 != nil {
return err1
}
return nil
})

if sum < uint64(amount) {
writeErr(w, "not enough tokens")
return
}

respBin, err := json.MarshalIndent(resp, "", " ")
if err != nil {
writeErr(w, err.Error())
return
}
_, err = w.Write(respBin)
util.AssertNoError(err)

}

func (srv *server) getChainOutput(w http.ResponseWriter, r *http.Request) {
Expand Down

0 comments on commit 69d8a69

Please sign in to comment.