diff --git a/CHANGELOG.md b/CHANGELOG.md index 460cfff502b..43b067b11ad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ - https://github.com/filecoin-project/lotus/pull/12279 Upgrade to go-f3 v0.0.5 - https://github.com/filecoin-project/lotus/pull/12295 Upgrade to go-f3 v0.0.6 - https://github.com/filecoin-project/lotus/pull/12292: feat: p2p: allow overriding bootstrap nodes with environmemnt variable +- https://github.com/filecoin-project/lotus/pull/12319: feat: `lotus send CLI`: allow sending to ETH addresses ## New features diff --git a/cli/send.go b/cli/send.go index a106e848037..c02e809b4e2 100644 --- a/cli/send.go +++ b/cli/send.go @@ -90,7 +90,20 @@ var SendCmd = &cli.Command{ params.To, err = address.NewFromString(cctx.Args().Get(0)) if err != nil { - return ShowHelp(cctx, fmt.Errorf("failed to parse target address: %w", err)) + // could be an ETH address + ea, err := ethtypes.ParseEthAddress(cctx.Args().Get(0)) + if err != nil { + return ShowHelp(cctx, fmt.Errorf("failed to parse target address; address must be a valid FIL address or an ETH address: %w", err)) + } + // this will be either "f410f..." or "f0..." + params.To, err = ea.ToFilecoinAddress() + if err != nil { + return ShowHelp(cctx, fmt.Errorf("failed to convert ETH address to FIL address: %w", err)) + } + // ideally, this should never happen + if !(params.To.Protocol() == address.ID || params.To.Protocol() == address.Delegated) { + return ShowHelp(cctx, fmt.Errorf("ETH addresses can only map to a FIL addresses starting with f410f or f0")) + } } val, err := types.ParseFIL(cctx.Args().Get(1)) @@ -118,6 +131,12 @@ var SendCmd = &cli.Command{ } fmt.Println("f4 addr: ", faddr) params.From = faddr + } else { + defaddr, err := srv.FullNodeAPI().WalletDefaultAddress(ctx) + if err != nil { + return fmt.Errorf("failed to get default address: %w", err) + } + params.From = defaddr } if cctx.IsSet("params-hex") { @@ -128,7 +147,7 @@ var SendCmd = &cli.Command{ params.Params = decparams } - if ethtypes.IsEthAddress(params.From) { + if ethtypes.IsEthAddress(params.From) || ethtypes.IsEthAddress(params.To) { // Method numbers don't make sense from eth accounts. if cctx.IsSet("method") { return xerrors.Errorf("messages from f410f addresses may not specify a method number") @@ -167,6 +186,8 @@ var SendCmd = &cli.Command{ params.Method = abi.MethodNum(cctx.Uint64("method")) } + _, _ = fmt.Fprintf(cctx.App.Writer, "Sending message from: %s\nSending message to: %s\nUsing Method: %d\n", params.From.String(), params.To.String(), params.Method) + if cctx.IsSet("gas-premium") { gp, err := types.BigFromString(cctx.String("gas-premium")) if err != nil { diff --git a/cli/send_test.go b/cli/send_test.go index 59b8942f44b..21a0f950223 100644 --- a/cli/send_test.go +++ b/cli/send_test.go @@ -59,16 +59,17 @@ func TestSendCLI(t *testing.T) { gomock.InOrder( mockSrvcs.EXPECT().MessageForSend(gomock.Any(), SendParams{ - To: mustAddr(address.NewIDAddress(1)), - Val: oneFil, + From: mustAddr(address.NewIDAddress(1)), + To: mustAddr(address.NewIDAddress(1)), + Val: oneFil, }).Return(arbtProto, nil), mockSrvcs.EXPECT().PublishMessage(gomock.Any(), arbtProto, false). Return(sigMsg, nil, nil), mockSrvcs.EXPECT().Close(), ) - err := app.Run([]string{"lotus", "send", "t01", "1"}) + err := app.Run([]string{"lotus", "send", "--from", "t01", "t01", "1"}) require.NoError(t, err) - require.EqualValues(t, sigMsg.Cid().String()+"\n", buf.String()) + require.Contains(t, buf.String(), sigMsg.Cid().String()+"\n") }) } @@ -112,6 +113,6 @@ func TestSendEthereum(t *testing.T) { ) err = app.Run([]string{"lotus", "send", "--from-eth-addr", testEthAddr.String(), "--params-hex", "01020304", "f01", "1"}) require.NoError(t, err) - require.EqualValues(t, sigMsg.Cid().String()+"\n", buf.String()) + require.Contains(t, buf.String(), sigMsg.Cid().String()+"\n") }) }