Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,9 @@
- Exposed `StateGetNetworkParams` in the Lotus Gateway API ([filecoin-project/lotus#12881](https://github.com/filecoin-project/lotus/pull/12881))
- **BREAKING**: Removed `SupportedProofTypes` from `StateGetNetworkParams` response as it was unreliable and didn't match FVM's actual supported proofs ([filecoin-project/lotus#12881](https://github.com/filecoin-project/lotus/pull/12881))
- refactor(eth): attach ToFilecoinMessage converter to EthCall method for improved package/module import structure. This change also exports the converter as a public method, enhancing usability for developers utilizing Lotus as a library. ([filecoin-project/lotus#12844](https://github.com/filecoin-project/lotus/pull/12844))

- chore: switch to pure-go zstd decoder for snapshot imports. ([filecoin-project/lotus#12857](https://github.com/filecoin-project/lotus/pull/12857))

- feat: automatically detect if the genesis is zstd compressed. ([filecoin-project/lotus#12885](https://github.com/filecoin-project/lotus/pull/12885)
- `lotus send` now supports `--csv` option for sending multiple transactions. ([filecoin-project/lotus#12892](https://github.com/filecoin-project/lotus/pull/12892))

# UNRELEASED v.1.32.0

Expand Down
115 changes: 115 additions & 0 deletions cli/send.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@ package cli

import (
"bytes"
"encoding/csv"
"encoding/hex"
"fmt"
"os"
"strconv"
"strings"

"github.com/urfave/cli/v2"
Expand Down Expand Up @@ -69,8 +72,16 @@ var SendCmd = &cli.Command{
Name: "force",
Usage: "Deprecated: use global 'force-send'",
},
&cli.StringFlag{
Name: "csv",
Usage: "send multiple transactions from a CSV file (format: Recipient,FIL,Method,Params)",
},
},
Action: func(cctx *cli.Context) error {
if csvFile := cctx.String("csv"); csvFile != "" {
return handleCSVSend(cctx, csvFile)
}

if cctx.IsSet("force") {
fmt.Println("'force' flag is deprecated, use global flag 'force-send'")
}
Expand Down Expand Up @@ -244,3 +255,107 @@ var SendCmd = &cli.Command{
return nil
},
}

func handleCSVSend(cctx *cli.Context, csvFile string) error {
srv, err := GetFullNodeServices(cctx)
if err != nil {
return err
}
defer srv.Close() //nolint:errcheck

ctx := ReqContext(cctx)

// Add logic to handle --from address
Comment thread
rjan90 marked this conversation as resolved.
Outdated
var fromAddr address.Address
if from := cctx.String("from"); from != "" {
addr, err := address.NewFromString(from)
if err != nil {
return err
}
fromAddr = addr
} else {
defaddr, err := srv.FullNodeAPI().WalletDefaultAddress(ctx)
if err != nil {
return fmt.Errorf("failed to get default address: %w", err)
}
fromAddr = defaddr
}

// Print sending address
_, _ = fmt.Fprintf(cctx.App.Writer, "Sending messages from: %s\n", fromAddr.String())

fileReader, err := os.Open(csvFile)
if err != nil {
return xerrors.Errorf("read csv: %w", err)
}
defer func() {
if err := fileReader.Close(); err != nil {
log.Errorf("failed to close csv file: %v", err)
}
}()

r := csv.NewReader(fileReader)
records, err := r.ReadAll()
if err != nil {
return xerrors.Errorf("read csv: %w", err)
}

// Validate header
if len(records) == 0 ||
Comment thread
rjan90 marked this conversation as resolved.
strings.TrimSpace(records[0][0]) != "Recipient" ||
strings.TrimSpace(records[0][1]) != "FIL" ||
strings.TrimSpace(records[0][2]) != "Method" ||
strings.TrimSpace(records[0][3]) != "Params" {
return xerrors.Errorf("expected header row to be \"Recipient,FIL,Method,Params\"")
}

for i, e := range records[1:] {
var params SendParams
Comment thread
rjan90 marked this conversation as resolved.
Outdated

// Set the from address
params.From = fromAddr

// Parse recipient
params.To, err = address.NewFromString(e[0])
if err != nil {
return xerrors.Errorf("failed to parse address in row %d: %w", i, err)
}

// Parse value
val, err := types.ParseFIL(e[1])
if err != nil {
return xerrors.Errorf("failed to parse amount in row %d: %w", i, err)
}
params.Val = abi.TokenAmount(val)

// Parse method
method, err := strconv.Atoi(strings.TrimSpace(e[2]))
if err != nil {
return xerrors.Errorf("failed to parse method number in row %d: %w", i, err)
}
params.Method = abi.MethodNum(method)

// Parse params
if strings.TrimSpace(e[3]) != "nil" {
params.Params, err = hex.DecodeString(strings.TrimSpace(e[3]))
if err != nil {
return xerrors.Errorf("failed to parse hex params in row %d: %w", i, err)
}
}

// Use existing send logic
proto, err := srv.MessageForSend(ctx, params)
if err != nil {
return xerrors.Errorf("creating message prototype for row %d: %w", i, err)
}

sm, err := InteractiveSend(ctx, cctx, srv, proto)
if err != nil {
return xerrors.Errorf("sending message for row %d: %w", i, err)
}

fmt.Printf("Sent message %d: %s\n", i, sm.Cid())
}

return nil
}
1 change: 1 addition & 0 deletions documentation/en/cli-lotus.md
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ OPTIONS:
--params-json value specify invocation parameters in json
--params-hex value specify invocation parameters in hex
--force Deprecated: use global 'force-send' (default: false)
--csv value send multiple transactions from a CSV file (format: Recipient,FIL,Method,Params)
--help, -h show help
```

Expand Down