Merge pull request #4290 from filecoin-project/feat/ledger-integration
adding in ledger support
This commit is contained in:
commit
65883cbb6b
@ -229,7 +229,9 @@ type FullNode interface {
|
||||
// MethodGroup: Wallet
|
||||
|
||||
// WalletNew creates a new address in the wallet with the given sigType.
|
||||
WalletNew(context.Context, crypto.SigType) (address.Address, error)
|
||||
// Available key types: bls, secp256k1, secp256k1-ledger
|
||||
// Support for numerical types: 1 - secp256k1, 2 - BLS is deprecated
|
||||
WalletNew(context.Context, types.KeyType) (address.Address, error)
|
||||
// WalletHas indicates whether the given address is in the wallet.
|
||||
WalletHas(context.Context, address.Address) (bool, error)
|
||||
// WalletList lists all the addresses in the wallet.
|
||||
|
@ -35,7 +35,7 @@ type MsgMeta struct {
|
||||
}
|
||||
|
||||
type WalletAPI interface {
|
||||
WalletNew(context.Context, crypto.SigType) (address.Address, error)
|
||||
WalletNew(context.Context, types.KeyType) (address.Address, error)
|
||||
WalletHas(context.Context, address.Address) (bool, error)
|
||||
WalletList(context.Context) ([]address.Address, error)
|
||||
|
||||
|
@ -133,7 +133,7 @@ type FullNodeStruct struct {
|
||||
MinerGetBaseInfo func(context.Context, address.Address, abi.ChainEpoch, types.TipSetKey) (*api.MiningBaseInfo, error) `perm:"read"`
|
||||
MinerCreateBlock func(context.Context, *api.BlockTemplate) (*types.BlockMsg, error) `perm:"write"`
|
||||
|
||||
WalletNew func(context.Context, crypto.SigType) (address.Address, error) `perm:"write"`
|
||||
WalletNew func(context.Context, types.KeyType) (address.Address, error) `perm:"write"`
|
||||
WalletHas func(context.Context, address.Address) (bool, error) `perm:"write"`
|
||||
WalletList func(context.Context) ([]address.Address, error) `perm:"write"`
|
||||
WalletBalance func(context.Context, address.Address) (types.BigInt, error) `perm:"read"`
|
||||
@ -384,7 +384,7 @@ type GatewayStruct struct {
|
||||
|
||||
type WalletStruct struct {
|
||||
Internal struct {
|
||||
WalletNew func(context.Context, crypto.SigType) (address.Address, error) `perm:"write"`
|
||||
WalletNew func(context.Context, types.KeyType) (address.Address, error) `perm:"write"`
|
||||
WalletHas func(context.Context, address.Address) (bool, error) `perm:"write"`
|
||||
WalletList func(context.Context) ([]address.Address, error) `perm:"write"`
|
||||
WalletSign func(context.Context, address.Address, []byte, api.MsgMeta) (*crypto.Signature, error) `perm:"sign"`
|
||||
@ -631,7 +631,7 @@ func (c *FullNodeStruct) ChainGetTipSetByHeight(ctx context.Context, h abi.Chain
|
||||
return c.Internal.ChainGetTipSetByHeight(ctx, h, tsk)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) WalletNew(ctx context.Context, typ crypto.SigType) (address.Address, error) {
|
||||
func (c *FullNodeStruct) WalletNew(ctx context.Context, typ types.KeyType) (address.Address, error) {
|
||||
return c.Internal.WalletNew(ctx, typ)
|
||||
}
|
||||
|
||||
@ -1465,7 +1465,7 @@ func (g GatewayStruct) StateWaitMsg(ctx context.Context, msg cid.Cid, confidence
|
||||
return g.Internal.StateWaitMsg(ctx, msg, confidence)
|
||||
}
|
||||
|
||||
func (c *WalletStruct) WalletNew(ctx context.Context, typ crypto.SigType) (address.Address, error) {
|
||||
func (c *WalletStruct) WalletNew(ctx context.Context, typ types.KeyType) (address.Address, error) {
|
||||
return c.Internal.WalletNew(ctx, typ)
|
||||
}
|
||||
|
||||
|
@ -87,6 +87,7 @@ func init() {
|
||||
addExample(abi.RegisteredPoStProof_StackedDrgWindow32GiBV1)
|
||||
addExample(abi.ChainEpoch(10101))
|
||||
addExample(crypto.SigTypeBLS)
|
||||
addExample(types.KTBLS)
|
||||
addExample(int64(9))
|
||||
addExample(12.3)
|
||||
addExample(123)
|
||||
|
@ -26,7 +26,6 @@ import (
|
||||
"github.com/filecoin-project/lotus/chain/events"
|
||||
"github.com/filecoin-project/lotus/chain/events/state"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/chain/wallet"
|
||||
)
|
||||
|
||||
func TestPaymentChannels(t *testing.T, b APIBuilder, blocktime time.Duration) {
|
||||
@ -58,7 +57,7 @@ func TestPaymentChannels(t *testing.T, b APIBuilder, blocktime time.Duration) {
|
||||
bm.MineBlocks()
|
||||
|
||||
// send some funds to register the receiver
|
||||
receiverAddr, err := paymentReceiver.WalletNew(ctx, wallet.ActSigType("secp256k1"))
|
||||
receiverAddr, err := paymentReceiver.WalletNew(ctx, types.KTSecp256k1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -155,14 +155,14 @@ func NewGeneratorWithSectors(numSectors int) (*ChainGen, error) {
|
||||
return nil, xerrors.Errorf("creating memrepo wallet failed: %w", err)
|
||||
}
|
||||
|
||||
banker, err := w.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
|
||||
banker, err := w.WalletNew(context.Background(), types.KTSecp256k1)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed to generate banker key: %w", err)
|
||||
}
|
||||
|
||||
receievers := make([]address.Address, msgsPerBlock)
|
||||
for r := range receievers {
|
||||
receievers[r], err = w.WalletNew(context.Background(), crypto.SigTypeBLS)
|
||||
receievers[r], err = w.WalletNew(context.Background(), types.KTBLS)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed to generate receiver key: %w", err)
|
||||
}
|
||||
|
@ -8,7 +8,6 @@ import (
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/crypto"
|
||||
"github.com/filecoin-project/lotus/chain/messagepool/gasguess"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/chain/types/mock"
|
||||
@ -232,7 +231,7 @@ func TestMessagePool(t *testing.T) {
|
||||
|
||||
a := tma.nextBlock()
|
||||
|
||||
sender, err := w.WalletNew(context.Background(), crypto.SigTypeBLS)
|
||||
sender, err := w.WalletNew(context.Background(), types.KTSecp256k1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -273,7 +272,7 @@ func TestMessagePoolMessagesInEachBlock(t *testing.T) {
|
||||
|
||||
a := tma.nextBlock()
|
||||
|
||||
sender, err := w.WalletNew(context.Background(), crypto.SigTypeBLS)
|
||||
sender, err := w.WalletNew(context.Background(), types.KTBLS)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -323,7 +322,7 @@ func TestRevertMessages(t *testing.T) {
|
||||
a := tma.nextBlock()
|
||||
b := tma.nextBlock()
|
||||
|
||||
sender, err := w.WalletNew(context.Background(), crypto.SigTypeBLS)
|
||||
sender, err := w.WalletNew(context.Background(), types.KTBLS)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -386,7 +385,7 @@ func TestPruningSimple(t *testing.T) {
|
||||
a := tma.nextBlock()
|
||||
tma.applyBlock(t, a)
|
||||
|
||||
sender, err := w.WalletNew(context.Background(), crypto.SigTypeBLS)
|
||||
sender, err := w.WalletNew(context.Background(), types.KTBLS)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -433,7 +432,7 @@ func TestLoadLocal(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
a1, err := w1.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
|
||||
a1, err := w1.WalletNew(context.Background(), types.KTSecp256k1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -443,7 +442,7 @@ func TestLoadLocal(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
a2, err := w2.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
|
||||
a2, err := w2.WalletNew(context.Background(), types.KTSecp256k1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -505,7 +504,7 @@ func TestClearAll(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
a1, err := w1.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
|
||||
a1, err := w1.WalletNew(context.Background(), types.KTSecp256k1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -515,7 +514,7 @@ func TestClearAll(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
a2, err := w2.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
|
||||
a2, err := w2.WalletNew(context.Background(), types.KTSecp256k1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -559,7 +558,7 @@ func TestClearNonLocal(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
a1, err := w1.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
|
||||
a1, err := w1.WalletNew(context.Background(), types.KTSecp256k1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -569,7 +568,7 @@ func TestClearNonLocal(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
a2, err := w2.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
|
||||
a2, err := w2.WalletNew(context.Background(), types.KTSecp256k1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -620,7 +619,7 @@ func TestUpdates(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
a1, err := w1.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
|
||||
a1, err := w1.WalletNew(context.Background(), types.KTSecp256k1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -630,7 +629,7 @@ func TestUpdates(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
a2, err := w2.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
|
||||
a2, err := w2.WalletNew(context.Background(), types.KTSecp256k1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -5,8 +5,8 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/crypto"
|
||||
"github.com/filecoin-project/lotus/chain/messagepool/gasguess"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/chain/wallet"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
"github.com/ipfs/go-datastore"
|
||||
@ -33,7 +33,7 @@ func TestRepubMessages(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
a1, err := w1.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
|
||||
a1, err := w1.WalletNew(context.Background(), types.KTSecp256k1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -43,7 +43,7 @@ func TestRepubMessages(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
a2, err := w2.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
|
||||
a2, err := w2.WalletNew(context.Background(), types.KTSecp256k1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -18,7 +18,6 @@ import (
|
||||
logging "github.com/ipfs/go-log"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/crypto"
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/chain/messagepool/gasguess"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
@ -77,7 +76,7 @@ func TestMessageChains(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
a1, err := w1.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
|
||||
a1, err := w1.WalletNew(context.Background(), types.KTSecp256k1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -87,7 +86,7 @@ func TestMessageChains(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
a2, err := w2.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
|
||||
a2, err := w2.WalletNew(context.Background(), types.KTSecp256k1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -315,7 +314,7 @@ func TestMessageChainSkipping(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
a1, err := w1.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
|
||||
a1, err := w1.WalletNew(context.Background(), types.KTSecp256k1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -325,7 +324,7 @@ func TestMessageChainSkipping(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
a2, err := w2.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
|
||||
a2, err := w2.WalletNew(context.Background(), types.KTSecp256k1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -391,7 +390,7 @@ func TestBasicMessageSelection(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
a1, err := w1.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
|
||||
a1, err := w1.WalletNew(context.Background(), types.KTSecp256k1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -401,7 +400,7 @@ func TestBasicMessageSelection(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
a2, err := w2.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
|
||||
a2, err := w2.WalletNew(context.Background(), types.KTSecp256k1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -535,7 +534,7 @@ func TestMessageSelectionTrimming(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
a1, err := w1.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
|
||||
a1, err := w1.WalletNew(context.Background(), types.KTSecp256k1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -545,7 +544,7 @@ func TestMessageSelectionTrimming(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
a2, err := w2.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
|
||||
a2, err := w2.WalletNew(context.Background(), types.KTSecp256k1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -598,7 +597,7 @@ func TestPriorityMessageSelection(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
a1, err := w1.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
|
||||
a1, err := w1.WalletNew(context.Background(), types.KTSecp256k1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -608,7 +607,7 @@ func TestPriorityMessageSelection(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
a2, err := w2.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
|
||||
a2, err := w2.WalletNew(context.Background(), types.KTSecp256k1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -677,7 +676,7 @@ func TestPriorityMessageSelection2(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
a1, err := w1.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
|
||||
a1, err := w1.WalletNew(context.Background(), types.KTSecp256k1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -687,7 +686,7 @@ func TestPriorityMessageSelection2(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
a2, err := w2.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
|
||||
a2, err := w2.WalletNew(context.Background(), types.KTSecp256k1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -746,7 +745,7 @@ func TestPriorityMessageSelection3(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
a1, err := w1.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
|
||||
a1, err := w1.WalletNew(context.Background(), types.KTSecp256k1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -756,7 +755,7 @@ func TestPriorityMessageSelection3(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
a2, err := w2.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
|
||||
a2, err := w2.WalletNew(context.Background(), types.KTSecp256k1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -843,7 +842,7 @@ func TestOptimalMessageSelection1(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
a1, err := w1.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
|
||||
a1, err := w1.WalletNew(context.Background(), types.KTSecp256k1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -853,7 +852,7 @@ func TestOptimalMessageSelection1(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
a2, err := w2.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
|
||||
a2, err := w2.WalletNew(context.Background(), types.KTSecp256k1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -910,7 +909,7 @@ func TestOptimalMessageSelection2(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
a1, err := w1.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
|
||||
a1, err := w1.WalletNew(context.Background(), types.KTSecp256k1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -920,7 +919,7 @@ func TestOptimalMessageSelection2(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
a2, err := w2.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
|
||||
a2, err := w2.WalletNew(context.Background(), types.KTSecp256k1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -994,7 +993,7 @@ func TestOptimalMessageSelection3(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
a, err := w.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
|
||||
a, err := w.WalletNew(context.Background(), types.KTSecp256k1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -1074,7 +1073,7 @@ func testCompetitiveMessageSelection(t *testing.T, rng *rand.Rand, getPremium fu
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
a, err := w.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
|
||||
a, err := w.WalletNew(context.Background(), types.KTSecp256k1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -1344,7 +1343,7 @@ readLoop:
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
a, err := w.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
|
||||
a, err := w.WalletNew(context.Background(), types.KTSecp256k1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -9,7 +9,6 @@ import (
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/wallet"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/crypto"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
ds_sync "github.com/ipfs/go-datastore/sync"
|
||||
@ -47,13 +46,13 @@ func TestMessageSignerSignMessage(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
w, _ := wallet.NewWallet(wallet.NewMemKeyStore())
|
||||
from1, err := w.WalletNew(ctx, crypto.SigTypeSecp256k1)
|
||||
from1, err := w.WalletNew(ctx, types.KTSecp256k1)
|
||||
require.NoError(t, err)
|
||||
from2, err := w.WalletNew(ctx, crypto.SigTypeSecp256k1)
|
||||
from2, err := w.WalletNew(ctx, types.KTSecp256k1)
|
||||
require.NoError(t, err)
|
||||
to1, err := w.WalletNew(ctx, crypto.SigTypeSecp256k1)
|
||||
to1, err := w.WalletNew(ctx, types.KTSecp256k1)
|
||||
require.NoError(t, err)
|
||||
to2, err := w.WalletNew(ctx, crypto.SigTypeSecp256k1)
|
||||
to2, err := w.WalletNew(ctx, types.KTSecp256k1)
|
||||
require.NoError(t, err)
|
||||
|
||||
type msgSpec struct {
|
||||
|
@ -1,7 +1,10 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/crypto"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -9,9 +12,50 @@ var (
|
||||
ErrKeyExists = fmt.Errorf("key already exists")
|
||||
)
|
||||
|
||||
// KeyType defines a type of a key
|
||||
type KeyType string
|
||||
|
||||
func (kt *KeyType) UnmarshalJSON(bb []byte) error {
|
||||
{
|
||||
// first option, try unmarshaling as string
|
||||
var s string
|
||||
err := json.Unmarshal(bb, &s)
|
||||
if err == nil {
|
||||
*kt = KeyType(s)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
var b byte
|
||||
err := json.Unmarshal(bb, &b)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not unmarshal KeyType either as string nor integer: %w", err)
|
||||
}
|
||||
bst := crypto.SigType(b)
|
||||
|
||||
switch bst {
|
||||
case crypto.SigTypeBLS:
|
||||
*kt = KTBLS
|
||||
case crypto.SigTypeSecp256k1:
|
||||
*kt = KTSecp256k1
|
||||
default:
|
||||
return fmt.Errorf("unknown sigtype: %d", bst)
|
||||
}
|
||||
log.Warnf("deprecation: integer style 'KeyType' is deprecated, switch to string style")
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
const (
|
||||
KTBLS KeyType = "bls"
|
||||
KTSecp256k1 KeyType = "secp256k1"
|
||||
KTSecp256k1Ledger KeyType = "secp256k1-ledger"
|
||||
)
|
||||
|
||||
// KeyInfo is used for storing keys in KeyStore
|
||||
type KeyInfo struct {
|
||||
Type string
|
||||
Type KeyType
|
||||
PrivateKey []byte
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,6 @@ import (
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/crypto"
|
||||
"github.com/filecoin-project/lotus/chain/actors/policy"
|
||||
"github.com/filecoin-project/lotus/chain/gen"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
@ -62,7 +61,7 @@ func MakeMessageSigningVectors() []vectors.MessageSigningVector {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
blsk, err := w.WalletNew(context.Background(), crypto.SigTypeBLS)
|
||||
blsk, err := w.WalletNew(context.Background(), types.KTBLS)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@ -86,7 +85,7 @@ func MakeMessageSigningVectors() []vectors.MessageSigningVector {
|
||||
Signature: &bmsg.Signature,
|
||||
}
|
||||
|
||||
secpk, err := w.WalletNew(context.Background(), crypto.SigTypeBLS)
|
||||
secpk, err := w.WalletNew(context.Background(), types.KTBLS)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
@ -10,13 +10,17 @@ import (
|
||||
"github.com/filecoin-project/lotus/lib/sigs"
|
||||
)
|
||||
|
||||
func GenerateKey(typ crypto.SigType) (*Key, error) {
|
||||
pk, err := sigs.Generate(typ)
|
||||
func GenerateKey(typ types.KeyType) (*Key, error) {
|
||||
ctyp := ActSigType(typ)
|
||||
if ctyp == crypto.SigTypeUnknown {
|
||||
return nil, xerrors.Errorf("unknown sig type: %s", typ)
|
||||
}
|
||||
pk, err := sigs.Generate(ctyp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ki := types.KeyInfo{
|
||||
Type: kstoreSigType(typ),
|
||||
Type: typ,
|
||||
PrivateKey: pk,
|
||||
}
|
||||
return NewKey(ki)
|
||||
@ -41,41 +45,30 @@ func NewKey(keyinfo types.KeyInfo) (*Key, error) {
|
||||
}
|
||||
|
||||
switch k.Type {
|
||||
case KTSecp256k1:
|
||||
case types.KTSecp256k1:
|
||||
k.Address, err = address.NewSecp256k1Address(k.PublicKey)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("converting Secp256k1 to address: %w", err)
|
||||
}
|
||||
case KTBLS:
|
||||
case types.KTBLS:
|
||||
k.Address, err = address.NewBLSAddress(k.PublicKey)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("converting BLS to address: %w", err)
|
||||
}
|
||||
default:
|
||||
return nil, xerrors.Errorf("unknown key type")
|
||||
return nil, xerrors.Errorf("unsupported key type: %s", k.Type)
|
||||
}
|
||||
return k, nil
|
||||
|
||||
}
|
||||
|
||||
func kstoreSigType(typ crypto.SigType) string {
|
||||
func ActSigType(typ types.KeyType) crypto.SigType {
|
||||
switch typ {
|
||||
case crypto.SigTypeBLS:
|
||||
return KTBLS
|
||||
case crypto.SigTypeSecp256k1:
|
||||
return KTSecp256k1
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
func ActSigType(typ string) crypto.SigType {
|
||||
switch typ {
|
||||
case KTBLS:
|
||||
case types.KTBLS:
|
||||
return crypto.SigTypeBLS
|
||||
case KTSecp256k1:
|
||||
case types.KTSecp256k1:
|
||||
return crypto.SigTypeSecp256k1
|
||||
default:
|
||||
return 0
|
||||
return crypto.SigTypeUnknown
|
||||
}
|
||||
}
|
||||
|
242
chain/wallet/ledger/ledger.go
Normal file
242
chain/wallet/ledger/ledger.go
Normal file
@ -0,0 +1,242 @@
|
||||
package ledgerwallet
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/ipfs/go-cid"
|
||||
"github.com/ipfs/go-datastore"
|
||||
"github.com/ipfs/go-datastore/query"
|
||||
logging "github.com/ipfs/go-log"
|
||||
ledgerfil "github.com/whyrusleeping/ledger-filecoin-go"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/crypto"
|
||||
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
||||
)
|
||||
|
||||
var log = logging.Logger("wallet-ledger")
|
||||
|
||||
type LedgerWallet struct {
|
||||
ds datastore.Datastore
|
||||
}
|
||||
|
||||
func NewWallet(ds dtypes.MetadataDS) *LedgerWallet {
|
||||
return &LedgerWallet{ds}
|
||||
}
|
||||
|
||||
type LedgerKeyInfo struct {
|
||||
Address address.Address
|
||||
Path []uint32
|
||||
}
|
||||
|
||||
var _ api.WalletAPI = (*LedgerWallet)(nil)
|
||||
|
||||
func (lw LedgerWallet) WalletSign(ctx context.Context, signer address.Address, toSign []byte, meta api.MsgMeta) (*crypto.Signature, error) {
|
||||
ki, err := lw.getKeyInfo(signer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
fl, err := ledgerfil.FindLedgerFilecoinApp()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer fl.Close() // nolint:errcheck
|
||||
if meta.Type != api.MTChainMsg {
|
||||
return nil, fmt.Errorf("ledger can only sign chain messages")
|
||||
}
|
||||
|
||||
{
|
||||
var cmsg types.Message
|
||||
if err := cmsg.UnmarshalCBOR(bytes.NewReader(meta.Extra)); err != nil {
|
||||
return nil, xerrors.Errorf("unmarshalling message: %w", err)
|
||||
}
|
||||
|
||||
_, bc, err := cid.CidFromBytes(toSign)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("getting cid from signing bytes: %w", err)
|
||||
}
|
||||
|
||||
if !cmsg.Cid().Equals(bc) {
|
||||
return nil, xerrors.Errorf("cid(meta.Extra).bytes() != toSign")
|
||||
}
|
||||
}
|
||||
|
||||
sig, err := fl.SignSECP256K1(ki.Path, meta.Extra)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &crypto.Signature{
|
||||
Type: crypto.SigTypeSecp256k1,
|
||||
Data: sig.SignatureBytes(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (lw LedgerWallet) getKeyInfo(addr address.Address) (*LedgerKeyInfo, error) {
|
||||
kib, err := lw.ds.Get(keyForAddr(addr))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var out LedgerKeyInfo
|
||||
if err := json.Unmarshal(kib, &out); err != nil {
|
||||
return nil, xerrors.Errorf("unmarshalling ledger key info: %w", err)
|
||||
}
|
||||
|
||||
return &out, nil
|
||||
}
|
||||
|
||||
func (lw LedgerWallet) WalletDelete(ctx context.Context, k address.Address) error {
|
||||
return lw.ds.Delete(keyForAddr(k))
|
||||
}
|
||||
|
||||
func (lw LedgerWallet) WalletExport(ctx context.Context, k address.Address) (*types.KeyInfo, error) {
|
||||
return nil, fmt.Errorf("cannot export keys from ledger wallets")
|
||||
}
|
||||
|
||||
func (lw LedgerWallet) WalletHas(ctx context.Context, k address.Address) (bool, error) {
|
||||
_, err := lw.ds.Get(keyForAddr(k))
|
||||
if err == nil {
|
||||
return true, nil
|
||||
}
|
||||
if err == datastore.ErrNotFound {
|
||||
return false, nil
|
||||
}
|
||||
return false, err
|
||||
}
|
||||
|
||||
func (lw LedgerWallet) WalletImport(ctx context.Context, kinfo *types.KeyInfo) (address.Address, error) {
|
||||
var ki LedgerKeyInfo
|
||||
if err := json.Unmarshal(kinfo.PrivateKey, &ki); err != nil {
|
||||
return address.Undef, err
|
||||
}
|
||||
return lw.importKey(ki)
|
||||
}
|
||||
|
||||
func (lw LedgerWallet) importKey(ki LedgerKeyInfo) (address.Address, error) {
|
||||
if ki.Address == address.Undef {
|
||||
return address.Undef, fmt.Errorf("no address given in imported key info")
|
||||
}
|
||||
if len(ki.Path) != filHdPathLen {
|
||||
return address.Undef, fmt.Errorf("bad hd path len: %d, expected: %d", len(ki.Path), filHdPathLen)
|
||||
}
|
||||
bb, err := json.Marshal(ki)
|
||||
if err != nil {
|
||||
return address.Undef, xerrors.Errorf("marshaling key info: %w", err)
|
||||
}
|
||||
|
||||
if err := lw.ds.Put(keyForAddr(ki.Address), bb); err != nil {
|
||||
return address.Undef, err
|
||||
}
|
||||
|
||||
return ki.Address, nil
|
||||
}
|
||||
|
||||
func (lw LedgerWallet) WalletList(ctx context.Context) ([]address.Address, error) {
|
||||
res, err := lw.ds.Query(query.Query{Prefix: dsLedgerPrefix})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer res.Close() // nolint:errcheck
|
||||
|
||||
var out []address.Address
|
||||
for {
|
||||
res, ok := res.NextSync()
|
||||
if !ok {
|
||||
break
|
||||
}
|
||||
|
||||
var ki LedgerKeyInfo
|
||||
if err := json.Unmarshal(res.Value, &ki); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
out = append(out, ki.Address)
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
const hdHard = 0x80000000
|
||||
|
||||
var filHDBasePath = []uint32{hdHard | 44, hdHard | 461, hdHard, 0}
|
||||
var filHdPathLen = 5
|
||||
|
||||
func (lw LedgerWallet) WalletNew(ctx context.Context, t types.KeyType) (address.Address, error) {
|
||||
if t != types.KTSecp256k1Ledger {
|
||||
return address.Undef, fmt.Errorf("unsupported key type: '%s', only '%s' supported",
|
||||
t, types.KTSecp256k1Ledger)
|
||||
}
|
||||
|
||||
res, err := lw.ds.Query(query.Query{Prefix: dsLedgerPrefix})
|
||||
if err != nil {
|
||||
return address.Undef, err
|
||||
}
|
||||
defer res.Close() // nolint:errcheck
|
||||
|
||||
var maxi int64 = -1
|
||||
for {
|
||||
res, ok := res.NextSync()
|
||||
if !ok {
|
||||
break
|
||||
}
|
||||
|
||||
var ki LedgerKeyInfo
|
||||
if err := json.Unmarshal(res.Value, &ki); err != nil {
|
||||
return address.Undef, err
|
||||
}
|
||||
if i := ki.Path[filHdPathLen-1]; maxi == -1 || maxi < int64(i) {
|
||||
maxi = int64(i)
|
||||
}
|
||||
}
|
||||
|
||||
fl, err := ledgerfil.FindLedgerFilecoinApp()
|
||||
if err != nil {
|
||||
return address.Undef, xerrors.Errorf("finding ledger: %w", err)
|
||||
}
|
||||
defer fl.Close() // nolint:errcheck
|
||||
|
||||
path := append(append([]uint32(nil), filHDBasePath...), uint32(maxi+1))
|
||||
_, _, addr, err := fl.GetAddressPubKeySECP256K1(path)
|
||||
if err != nil {
|
||||
return address.Undef, xerrors.Errorf("getting public key from ledger: %w", err)
|
||||
}
|
||||
|
||||
log.Warnf("creating key: %s, accept the key in ledger device", addr)
|
||||
_, _, addr, err = fl.ShowAddressPubKeySECP256K1(path)
|
||||
if err != nil {
|
||||
return address.Undef, xerrors.Errorf("verifying public key with ledger: %w", err)
|
||||
}
|
||||
|
||||
a, err := address.NewFromString(addr)
|
||||
if err != nil {
|
||||
return address.Undef, fmt.Errorf("parsing address: %w", err)
|
||||
}
|
||||
|
||||
var lki LedgerKeyInfo
|
||||
lki.Address = a
|
||||
lki.Path = path
|
||||
|
||||
return lw.importKey(lki)
|
||||
}
|
||||
|
||||
func (lw *LedgerWallet) Get() api.WalletAPI {
|
||||
if lw == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return lw
|
||||
}
|
||||
|
||||
var dsLedgerPrefix = "/ledgerkey/"
|
||||
|
||||
func keyForAddr(addr address.Address) datastore.Key {
|
||||
return datastore.NewKey(dsLedgerPrefix + addr.String())
|
||||
}
|
170
chain/wallet/multi.go
Normal file
170
chain/wallet/multi.go
Normal file
@ -0,0 +1,170 @@
|
||||
package wallet
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"go.uber.org/fx"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/crypto"
|
||||
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
ledgerwallet "github.com/filecoin-project/lotus/chain/wallet/ledger"
|
||||
"github.com/filecoin-project/lotus/chain/wallet/remotewallet"
|
||||
)
|
||||
|
||||
type MultiWallet struct {
|
||||
fx.In // "constructed" with fx.In instead of normal constructor
|
||||
|
||||
Local *LocalWallet `optional:"true"`
|
||||
Remote *remotewallet.RemoteWallet `optional:"true"`
|
||||
Ledger *ledgerwallet.LedgerWallet `optional:"true"`
|
||||
}
|
||||
|
||||
type getif interface {
|
||||
api.WalletAPI
|
||||
|
||||
// workaround for the fact that iface(*struct(nil)) != nil
|
||||
Get() api.WalletAPI
|
||||
}
|
||||
|
||||
func firstNonNil(wallets ...getif) api.WalletAPI {
|
||||
for _, w := range wallets {
|
||||
if w.Get() != nil {
|
||||
return w
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func nonNil(wallets ...getif) []api.WalletAPI {
|
||||
var out []api.WalletAPI
|
||||
for _, w := range wallets {
|
||||
if w.Get() == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
out = append(out, w)
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
func (m MultiWallet) find(ctx context.Context, address address.Address, wallets ...getif) (api.WalletAPI, error) {
|
||||
ws := nonNil(wallets...)
|
||||
|
||||
for _, w := range ws {
|
||||
have, err := w.WalletHas(ctx, address)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if have {
|
||||
return w, nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (m MultiWallet) WalletNew(ctx context.Context, keyType types.KeyType) (address.Address, error) {
|
||||
var local getif = m.Local
|
||||
if keyType == types.KTSecp256k1Ledger {
|
||||
local = m.Ledger
|
||||
}
|
||||
|
||||
w := firstNonNil(m.Remote, local)
|
||||
if w == nil {
|
||||
return address.Undef, xerrors.Errorf("no wallet backends supporting key type: %s", keyType)
|
||||
}
|
||||
|
||||
return w.WalletNew(ctx, keyType)
|
||||
}
|
||||
|
||||
func (m MultiWallet) WalletHas(ctx context.Context, address address.Address) (bool, error) {
|
||||
w, err := m.find(ctx, address, m.Remote, m.Ledger, m.Local)
|
||||
return w != nil, err
|
||||
}
|
||||
|
||||
func (m MultiWallet) WalletList(ctx context.Context) ([]address.Address, error) {
|
||||
var out []address.Address
|
||||
seen := map[address.Address]struct{}{}
|
||||
|
||||
ws := nonNil(m.Remote, m.Ledger, m.Local)
|
||||
for _, w := range ws {
|
||||
l, err := w.WalletList(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, a := range l {
|
||||
if _, ok := seen[a]; ok {
|
||||
continue
|
||||
}
|
||||
seen[a] = struct{}{}
|
||||
|
||||
out = append(out, a)
|
||||
}
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (m MultiWallet) WalletSign(ctx context.Context, signer address.Address, toSign []byte, meta api.MsgMeta) (*crypto.Signature, error) {
|
||||
w, err := m.find(ctx, signer, m.Remote, m.Ledger, m.Local)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if w == nil {
|
||||
return nil, xerrors.Errorf("key not found")
|
||||
}
|
||||
|
||||
return w.WalletSign(ctx, signer, toSign, meta)
|
||||
}
|
||||
|
||||
func (m MultiWallet) WalletExport(ctx context.Context, address address.Address) (*types.KeyInfo, error) {
|
||||
w, err := m.find(ctx, address, m.Remote, m.Local)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if w == nil {
|
||||
return nil, xerrors.Errorf("key not found")
|
||||
}
|
||||
|
||||
return w.WalletExport(ctx, address)
|
||||
}
|
||||
|
||||
func (m MultiWallet) WalletImport(ctx context.Context, info *types.KeyInfo) (address.Address, error) {
|
||||
var local getif = m.Local
|
||||
if info.Type == types.KTSecp256k1Ledger {
|
||||
local = m.Ledger
|
||||
}
|
||||
|
||||
w := firstNonNil(m.Remote, local)
|
||||
if w == nil {
|
||||
return address.Undef, xerrors.Errorf("no wallet backends configured")
|
||||
}
|
||||
|
||||
return w.WalletImport(ctx, info)
|
||||
}
|
||||
|
||||
func (m MultiWallet) WalletDelete(ctx context.Context, address address.Address) error {
|
||||
for {
|
||||
w, err := m.find(ctx, address, m.Remote, m.Ledger, m.Local)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if w == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := w.WalletDelete(ctx, address); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var _ api.WalletAPI = MultiWallet{}
|
@ -40,3 +40,11 @@ func SetupRemoteWallet(info string) func(mctx helpers.MetricsCtx, lc fx.Lifecycl
|
||||
return &RemoteWallet{wapi}, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (w *RemoteWallet) Get() api.WalletAPI {
|
||||
if w == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return w
|
||||
}
|
||||
|
@ -26,8 +26,6 @@ const (
|
||||
KNamePrefix = "wallet-"
|
||||
KTrashPrefix = "trash-"
|
||||
KDefault = "default"
|
||||
KTBLS = "bls"
|
||||
KTSecp256k1 = "secp256k1"
|
||||
)
|
||||
|
||||
type LocalWallet struct {
|
||||
@ -236,7 +234,7 @@ func (w *LocalWallet) SetDefault(a address.Address) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (w *LocalWallet) WalletNew(ctx context.Context, typ crypto.SigType) (address.Address, error) {
|
||||
func (w *LocalWallet) WalletNew(ctx context.Context, typ types.KeyType) (address.Address, error) {
|
||||
w.lk.Lock()
|
||||
defer w.lk.Unlock()
|
||||
|
||||
@ -300,6 +298,14 @@ func (w *LocalWallet) WalletDelete(ctx context.Context, addr address.Address) er
|
||||
return nil
|
||||
}
|
||||
|
||||
func (w *LocalWallet) Get() api.WalletAPI {
|
||||
if w == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return w
|
||||
}
|
||||
|
||||
var _ api.WalletAPI = &LocalWallet{}
|
||||
|
||||
func swapMainnetForTestnetPrefix(addr string) (string, error) {
|
||||
@ -312,3 +318,16 @@ func swapMainnetForTestnetPrefix(addr string) (string, error) {
|
||||
aChars[0] = prefixRunes[0]
|
||||
return string(aChars), nil
|
||||
}
|
||||
|
||||
type nilDefault struct{}
|
||||
|
||||
func (n nilDefault) GetDefault() (address.Address, error) {
|
||||
return address.Undef, nil
|
||||
}
|
||||
|
||||
func (n nilDefault) SetDefault(a address.Address) error {
|
||||
return xerrors.Errorf("not supported; local wallet disabled")
|
||||
}
|
||||
|
||||
var NilDefault nilDefault
|
||||
var _ Default = NilDefault
|
||||
|
67
cli/chain.go
67
cli/chain.go
@ -3,6 +3,7 @@ package cli
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
@ -53,6 +54,7 @@ var chainCmd = &cli.Command{
|
||||
slashConsensusFault,
|
||||
chainGasPriceCmd,
|
||||
chainInspectUsage,
|
||||
chainDecodeCmd,
|
||||
},
|
||||
}
|
||||
|
||||
@ -1234,3 +1236,68 @@ var chainGasPriceCmd = &cli.Command{
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
var chainDecodeCmd = &cli.Command{
|
||||
Name: "decode",
|
||||
Usage: "decode various types",
|
||||
Subcommands: []*cli.Command{
|
||||
chainDecodeParamsCmd,
|
||||
},
|
||||
}
|
||||
|
||||
var chainDecodeParamsCmd = &cli.Command{
|
||||
Name: "params",
|
||||
Usage: "Decode message params",
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "tipset",
|
||||
},
|
||||
},
|
||||
ArgsUsage: "[toAddr method hexParams]",
|
||||
Action: func(cctx *cli.Context) error {
|
||||
api, closer, err := GetFullNodeAPI(cctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer closer()
|
||||
ctx := ReqContext(cctx)
|
||||
|
||||
if cctx.Args().Len() != 3 {
|
||||
return ShowHelp(cctx, fmt.Errorf("incorrect number of arguments"))
|
||||
}
|
||||
|
||||
to, err := address.NewFromString(cctx.Args().First())
|
||||
if err != nil {
|
||||
return xerrors.Errorf("parsing toAddr: %w", err)
|
||||
}
|
||||
|
||||
method, err := strconv.ParseInt(cctx.Args().Get(1), 10, 64)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("parsing method id: %w", err)
|
||||
}
|
||||
|
||||
params, err := hex.DecodeString(cctx.Args().Get(2))
|
||||
if err != nil {
|
||||
return xerrors.Errorf("parsing hex params: %w", err)
|
||||
}
|
||||
|
||||
ts, err := LoadTipSet(ctx, cctx, api)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
act, err := api.StateGetActor(ctx, to, ts.Key())
|
||||
if err != nil {
|
||||
return xerrors.Errorf("getting actor: %w", err)
|
||||
}
|
||||
|
||||
pstr, err := jsonParams(act.Code, abi.MethodNum(method), params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Println(pstr)
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
@ -29,7 +29,6 @@ import (
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/chain/events"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/chain/wallet"
|
||||
builder "github.com/filecoin-project/lotus/node/test"
|
||||
)
|
||||
|
||||
@ -415,7 +414,7 @@ func startTwoNodesOneMiner(ctx context.Context, t *testing.T, blocktime time.Dur
|
||||
bm.MineBlocks()
|
||||
|
||||
// Send some funds to register the receiver
|
||||
receiverAddr, err := paymentReceiver.WalletNew(ctx, wallet.ActSigType("secp256k1"))
|
||||
receiverAddr, err := paymentReceiver.WalletNew(ctx, types.KTSecp256k1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -17,7 +17,6 @@ import (
|
||||
"github.com/filecoin-project/go-state-types/crypto"
|
||||
|
||||
types "github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/chain/wallet"
|
||||
"github.com/filecoin-project/lotus/lib/tablewriter"
|
||||
)
|
||||
|
||||
@ -55,7 +54,7 @@ var walletNew = &cli.Command{
|
||||
t = "secp256k1"
|
||||
}
|
||||
|
||||
nk, err := api.WalletNew(ctx, wallet.ActSigType(t))
|
||||
nk, err := api.WalletNew(ctx, types.KeyType(t))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -329,9 +328,9 @@ var walletImport = &cli.Command{
|
||||
ki.PrivateKey = gk.PrivateKey
|
||||
switch gk.SigType {
|
||||
case 1:
|
||||
ki.Type = wallet.KTSecp256k1
|
||||
ki.Type = types.KTSecp256k1
|
||||
case 2:
|
||||
ki.Type = wallet.KTBLS
|
||||
ki.Type = types.KTBLS
|
||||
default:
|
||||
return fmt.Errorf("unrecognized key type: %d", gk.SigType)
|
||||
}
|
||||
|
@ -7,8 +7,6 @@ import (
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/crypto"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
@ -61,7 +59,7 @@ var runCmd = &cli.Command{
|
||||
func sendSmallFundsTxs(ctx context.Context, api api.FullNode, from address.Address, rate int) error {
|
||||
var sendSet []address.Address
|
||||
for i := 0; i < 20; i++ {
|
||||
naddr, err := api.WalletNew(ctx, crypto.SigTypeSecp256k1)
|
||||
naddr, err := api.WalletNew(ctx, types.KTSecp256k1)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -22,7 +22,6 @@ import (
|
||||
"github.com/filecoin-project/lotus/api/test"
|
||||
"github.com/filecoin-project/lotus/chain/actors/policy"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/chain/wallet"
|
||||
"github.com/filecoin-project/lotus/node"
|
||||
builder "github.com/filecoin-project/lotus/node/test"
|
||||
)
|
||||
@ -53,7 +52,7 @@ func TestEndToEnd(t *testing.T) {
|
||||
fmt.Println(balance)
|
||||
|
||||
// Create a wallet on the lite node
|
||||
liteWalletAddr, err := lite.WalletNew(ctx, wallet.ActSigType("secp256k1"))
|
||||
liteWalletAddr, err := lite.WalletNew(ctx, types.KTSecp256k1)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Send some funds from the full node to the lite node
|
||||
@ -77,7 +76,7 @@ func TestEndToEnd(t *testing.T) {
|
||||
// Create some wallets on the lite node to use for testing multisig
|
||||
var walletAddrs []address.Address
|
||||
for i := 0; i < 4; i++ {
|
||||
addr, err := lite.WalletNew(ctx, wallet.ActSigType("secp256k1"))
|
||||
addr, err := lite.WalletNew(ctx, types.KTSecp256k1)
|
||||
require.NoError(t, err)
|
||||
|
||||
walletAddrs = append(walletAddrs, addr)
|
||||
|
@ -5,7 +5,7 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/crypto"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/chain/wallet"
|
||||
_ "github.com/filecoin-project/lotus/lib/sigs/bls"
|
||||
_ "github.com/filecoin-project/lotus/lib/sigs/secp"
|
||||
@ -30,12 +30,12 @@ func main() {
|
||||
return err
|
||||
}
|
||||
|
||||
var kt crypto.SigType
|
||||
var kt types.KeyType
|
||||
switch cctx.String("type") {
|
||||
case "bls":
|
||||
kt = crypto.SigTypeBLS
|
||||
kt = types.KTBLS
|
||||
case "secp256k1":
|
||||
kt = crypto.SigTypeSecp256k1
|
||||
kt = types.KTSecp256k1
|
||||
default:
|
||||
return fmt.Errorf("unrecognized key type: %q", cctx.String("type"))
|
||||
}
|
||||
|
@ -21,7 +21,6 @@ import (
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
"github.com/filecoin-project/go-state-types/crypto"
|
||||
"github.com/filecoin-project/lotus/extern/sector-storage/zerocomm"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/market"
|
||||
|
||||
@ -93,7 +92,7 @@ func PreSeal(maddr address.Address, spt abi.RegisteredSealProof, offset abi.Sect
|
||||
return nil, nil, err
|
||||
}
|
||||
} else {
|
||||
minerAddr, err = wallet.GenerateKey(crypto.SigTypeBLS)
|
||||
minerAddr, err = wallet.GenerateKey(types.KTBLS)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
@ -32,10 +32,10 @@ import (
|
||||
_ "github.com/filecoin-project/lotus/lib/sigs/secp"
|
||||
)
|
||||
|
||||
var validTypes = []string{wallet.KTBLS, wallet.KTSecp256k1, lp2p.KTLibp2pHost}
|
||||
var validTypes = []types.KeyType{types.KTBLS, types.KTSecp256k1, lp2p.KTLibp2pHost}
|
||||
|
||||
type keyInfoOutput struct {
|
||||
Type string
|
||||
Type types.KeyType
|
||||
Address string
|
||||
PublicKey string
|
||||
}
|
||||
@ -86,7 +86,7 @@ var keyinfoVerifyCmd = &cli.Command{
|
||||
return xerrors.Errorf("decoding key: '%s': %w", fileName, err)
|
||||
}
|
||||
|
||||
if string(name) != keyInfo.Type {
|
||||
if types.KeyType(name) != keyInfo.Type {
|
||||
return fmt.Errorf("%s of type %s is incorrect", fileName, keyInfo.Type)
|
||||
}
|
||||
case modules.KTJwtHmacSecret:
|
||||
@ -98,7 +98,7 @@ var keyinfoVerifyCmd = &cli.Command{
|
||||
if string(name) != modules.JWTSecretName {
|
||||
return fmt.Errorf("%s of type %s is incorrect", fileName, keyInfo.Type)
|
||||
}
|
||||
case wallet.KTSecp256k1, wallet.KTBLS:
|
||||
case types.KTSecp256k1, types.KTBLS:
|
||||
keystore := wallet.NewMemKeyStore()
|
||||
w, err := wallet.NewWallet(keystore)
|
||||
if err != nil {
|
||||
@ -214,7 +214,7 @@ var keyinfoImportCmd = &cli.Command{
|
||||
fmt.Printf("%s\n", peerid.String())
|
||||
|
||||
break
|
||||
case wallet.KTSecp256k1, wallet.KTBLS:
|
||||
case types.KTSecp256k1, types.KTBLS:
|
||||
w, err := wallet.NewWallet(keystore)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -317,7 +317,7 @@ var keyinfoInfoCmd = &cli.Command{
|
||||
kio.PublicKey = base64.StdEncoding.EncodeToString(pkBytes)
|
||||
|
||||
break
|
||||
case wallet.KTSecp256k1, wallet.KTBLS:
|
||||
case types.KTSecp256k1, types.KTBLS:
|
||||
kio.Type = keyInfo.Type
|
||||
|
||||
key, err := wallet.NewKey(keyInfo)
|
||||
@ -366,7 +366,7 @@ var keyinfoNewCmd = &cli.Command{
|
||||
return fmt.Errorf("please specify a type to generate")
|
||||
}
|
||||
|
||||
keyType := cctx.Args().First()
|
||||
keyType := types.KeyType(cctx.Args().First())
|
||||
flagOutput := cctx.String("output")
|
||||
|
||||
if i := SliceIndex(len(validTypes), func(i int) bool {
|
||||
@ -404,8 +404,8 @@ var keyinfoNewCmd = &cli.Command{
|
||||
keyInfo = ki
|
||||
|
||||
break
|
||||
case wallet.KTSecp256k1, wallet.KTBLS:
|
||||
key, err := wallet.GenerateKey(wallet.ActSigType(keyType))
|
||||
case types.KTSecp256k1, types.KTBLS:
|
||||
key, err := wallet.GenerateKey(keyType)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -418,7 +418,7 @@ var keyinfoNewCmd = &cli.Command{
|
||||
|
||||
filename := flagOutput
|
||||
filename = strings.ReplaceAll(filename, "<addr>", keyAddr)
|
||||
filename = strings.ReplaceAll(filename, "<type>", keyType)
|
||||
filename = strings.ReplaceAll(filename, "<type>", string(keyType))
|
||||
|
||||
file, err := os.OpenFile(filename, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0600)
|
||||
if err != nil {
|
||||
|
248
cmd/lotus-shed/ledger.go
Normal file
248
cmd/lotus-shed/ledger.go
Normal file
@ -0,0 +1,248 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/urfave/cli/v2"
|
||||
ledgerfil "github.com/whyrusleeping/ledger-filecoin-go"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
ledgerwallet "github.com/filecoin-project/lotus/chain/wallet/ledger"
|
||||
lcli "github.com/filecoin-project/lotus/cli"
|
||||
)
|
||||
|
||||
var ledgerCmd = &cli.Command{
|
||||
Name: "ledger",
|
||||
Usage: "Ledger interactions",
|
||||
Flags: []cli.Flag{},
|
||||
Subcommands: []*cli.Command{
|
||||
ledgerListAddressesCmd,
|
||||
ledgerKeyInfoCmd,
|
||||
ledgerSignTestCmd,
|
||||
},
|
||||
}
|
||||
|
||||
const hdHard = 0x80000000
|
||||
|
||||
var ledgerListAddressesCmd = &cli.Command{
|
||||
Name: "list",
|
||||
Flags: []cli.Flag{
|
||||
&cli.BoolFlag{
|
||||
Name: "print-balances",
|
||||
Usage: "print balances",
|
||||
Aliases: []string{"b"},
|
||||
},
|
||||
},
|
||||
Action: func(cctx *cli.Context) error {
|
||||
var api api.FullNode
|
||||
if cctx.Bool("print-balances") {
|
||||
a, closer, err := lcli.GetFullNodeAPI(cctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
api = a
|
||||
|
||||
defer closer()
|
||||
}
|
||||
ctx := lcli.ReqContext(cctx)
|
||||
|
||||
fl, err := ledgerfil.FindLedgerFilecoinApp()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
end := 20
|
||||
for i := 0; i < end; i++ {
|
||||
if err := ctx.Err(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
p := []uint32{hdHard | 44, hdHard | 461, hdHard, 0, uint32(i)}
|
||||
pubk, err := fl.GetPublicKeySECP256K1(p)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
addr, err := address.NewSecp256k1Address(pubk)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if cctx.Bool("print-balances") && api != nil { // api check makes linter happier
|
||||
b, err := api.WalletBalance(ctx, addr)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("getting balance: %w", err)
|
||||
}
|
||||
if !b.IsZero() {
|
||||
end = i + 21 // BIP32 spec, stop after 20 empty addresses
|
||||
}
|
||||
|
||||
fmt.Printf("%s %s %s\n", addr, printHDPath(p), types.FIL(b))
|
||||
} else {
|
||||
fmt.Printf("%s %s\n", addr, printHDPath(p))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
func parseHDPath(s string) ([]uint32, error) {
|
||||
parts := strings.Split(s, "/")
|
||||
if parts[0] != "m" {
|
||||
return nil, fmt.Errorf("expected HD path to start with 'm'")
|
||||
}
|
||||
|
||||
var out []uint32
|
||||
for _, p := range parts[1:] {
|
||||
var hard bool
|
||||
if strings.HasSuffix(p, "'") {
|
||||
p = p[:len(p)-1]
|
||||
hard = true
|
||||
}
|
||||
|
||||
v, err := strconv.ParseUint(p, 10, 32)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if v >= hdHard {
|
||||
return nil, fmt.Errorf("path element %s too large", p)
|
||||
}
|
||||
|
||||
if hard {
|
||||
v += hdHard
|
||||
}
|
||||
out = append(out, uint32(v))
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func printHDPath(pth []uint32) string {
|
||||
s := "m"
|
||||
for _, p := range pth {
|
||||
s += "/"
|
||||
|
||||
hard := p&hdHard != 0
|
||||
p &^= hdHard // remove hdHard bit
|
||||
|
||||
s += fmt.Sprint(p)
|
||||
if hard {
|
||||
s += "'"
|
||||
}
|
||||
}
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
var ledgerKeyInfoCmd = &cli.Command{
|
||||
Name: "key-info",
|
||||
Flags: []cli.Flag{
|
||||
&cli.BoolFlag{
|
||||
Name: "verbose",
|
||||
Aliases: []string{"v"},
|
||||
},
|
||||
},
|
||||
Action: func(cctx *cli.Context) error {
|
||||
if !cctx.Args().Present() {
|
||||
return cli.ShowCommandHelp(cctx, cctx.Command.Name)
|
||||
}
|
||||
|
||||
fl, err := ledgerfil.FindLedgerFilecoinApp()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
p, err := parseHDPath(cctx.Args().First())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
pubk, _, addr, err := fl.GetAddressPubKeySECP256K1(p)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if cctx.Bool("verbose") {
|
||||
fmt.Println(addr)
|
||||
fmt.Println(pubk)
|
||||
}
|
||||
|
||||
a, err := address.NewFromString(addr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var pd ledgerwallet.LedgerKeyInfo
|
||||
pd.Address = a
|
||||
pd.Path = p
|
||||
|
||||
b, err := json.Marshal(pd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var ki types.KeyInfo
|
||||
ki.Type = types.KTSecp256k1Ledger
|
||||
ki.PrivateKey = b
|
||||
|
||||
out, err := json.Marshal(ki)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Println(string(out))
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
var ledgerSignTestCmd = &cli.Command{
|
||||
Name: "sign",
|
||||
Action: func(cctx *cli.Context) error {
|
||||
if !cctx.Args().Present() {
|
||||
return cli.ShowCommandHelp(cctx, cctx.Command.Name)
|
||||
}
|
||||
|
||||
fl, err := ledgerfil.FindLedgerFilecoinApp()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
p, err := parseHDPath(cctx.Args().First())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
addr, err := address.NewFromString("f1xc3hws5n6y5m3m44gzb3gyjzhups6wzmhe663ji")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
m := &types.Message{
|
||||
To: addr,
|
||||
From: addr,
|
||||
}
|
||||
|
||||
b, err := m.ToStorageBlock()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
sig, err := fl.SignSECP256K1(p, b.RawData())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Println(sig.SignatureBytes())
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
@ -41,6 +41,7 @@ func main() {
|
||||
syncCmd,
|
||||
stateTreePruneCmd,
|
||||
datastoreCmd,
|
||||
ledgerCmd,
|
||||
}
|
||||
|
||||
app := &cli.App{
|
||||
|
@ -27,7 +27,6 @@ import (
|
||||
cborutil "github.com/filecoin-project/go-cbor-util"
|
||||
paramfetch "github.com/filecoin-project/go-paramfetch"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
crypto2 "github.com/filecoin-project/go-state-types/crypto"
|
||||
sectorstorage "github.com/filecoin-project/lotus/extern/sector-storage"
|
||||
"github.com/filecoin-project/lotus/extern/sector-storage/ffiwrapper"
|
||||
"github.com/filecoin-project/lotus/extern/sector-storage/stores"
|
||||
@ -624,7 +623,7 @@ func createStorageMiner(ctx context.Context, api lapi.FullNode, peerid peer.ID,
|
||||
if cctx.String("worker") != "" {
|
||||
worker, err = address.NewFromString(cctx.String("worker"))
|
||||
} else if cctx.Bool("create-worker-key") { // TODO: Do we need to force this if owner is Secpk?
|
||||
worker, err = api.WalletNew(ctx, crypto2.SigTypeBLS)
|
||||
worker, err = api.WalletNew(ctx, types.KTBLS)
|
||||
}
|
||||
// TODO: Transfer some initial funds to worker
|
||||
if err != nil {
|
||||
|
@ -19,13 +19,8 @@ type LoggedWallet struct {
|
||||
under api.WalletAPI
|
||||
}
|
||||
|
||||
func (c *LoggedWallet) WalletNew(ctx context.Context, typ crypto.SigType) (address.Address, error) {
|
||||
n, err := typ.Name()
|
||||
if err != nil {
|
||||
return address.Address{}, err
|
||||
}
|
||||
|
||||
log.Infow("WalletNew", "type", n)
|
||||
func (c *LoggedWallet) WalletNew(ctx context.Context, typ types.KeyType) (address.Address, error) {
|
||||
log.Infow("WalletNew", "type", typ)
|
||||
|
||||
return c.under.WalletNew(ctx, typ)
|
||||
}
|
||||
|
@ -11,8 +11,11 @@ import (
|
||||
"github.com/urfave/cli/v2"
|
||||
|
||||
"github.com/filecoin-project/go-jsonrpc"
|
||||
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/chain/wallet"
|
||||
ledgerwallet "github.com/filecoin-project/lotus/chain/wallet/ledger"
|
||||
lcli "github.com/filecoin-project/lotus/cli"
|
||||
"github.com/filecoin-project/lotus/lib/lotuslog"
|
||||
"github.com/filecoin-project/lotus/node/repo"
|
||||
@ -60,6 +63,10 @@ var runCmd = &cli.Command{
|
||||
Usage: "host address and port the wallet api will listen on",
|
||||
Value: "0.0.0.0:1777",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "ledger",
|
||||
Usage: "use a ledger device instead of an on-disk wallet",
|
||||
},
|
||||
},
|
||||
Action: func(cctx *cli.Context) error {
|
||||
log.Info("Starting lotus wallet")
|
||||
@ -94,11 +101,24 @@ var runCmd = &cli.Command{
|
||||
return err
|
||||
}
|
||||
|
||||
w, err := wallet.NewWallet(ks)
|
||||
lw, err := wallet.NewWallet(ks)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var w api.WalletAPI = lw
|
||||
if cctx.Bool("ledger") {
|
||||
ds, err := lr.Datastore("/metadata")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
w = wallet.MultiWallet{
|
||||
Local: lw,
|
||||
Ledger: ledgerwallet.NewWallet(ds),
|
||||
}
|
||||
}
|
||||
|
||||
address := cctx.String("listen")
|
||||
mux := mux.NewRouter()
|
||||
|
||||
|
@ -4710,7 +4710,7 @@ Inputs:
|
||||
Response:
|
||||
```json
|
||||
{
|
||||
"Type": "string value",
|
||||
"Type": "bls",
|
||||
"PrivateKey": "Ynl0ZSBhcnJheQ=="
|
||||
}
|
||||
```
|
||||
@ -4740,7 +4740,7 @@ Inputs:
|
||||
```json
|
||||
[
|
||||
{
|
||||
"Type": "string value",
|
||||
"Type": "bls",
|
||||
"PrivateKey": "Ynl0ZSBhcnJheQ=="
|
||||
}
|
||||
]
|
||||
@ -4760,6 +4760,8 @@ Response: `null`
|
||||
|
||||
### WalletNew
|
||||
WalletNew creates a new address in the wallet with the given sigType.
|
||||
Available key types: bls, secp256k1, secp256k1-ledger
|
||||
Support for numerical types: 1 - secp256k1, 2 - BLS is deprecated
|
||||
|
||||
|
||||
Perms: write
|
||||
@ -4767,7 +4769,7 @@ Perms: write
|
||||
Inputs:
|
||||
```json
|
||||
[
|
||||
2
|
||||
"bls"
|
||||
]
|
||||
```
|
||||
|
||||
|
2
extern/oni
vendored
2
extern/oni
vendored
@ -1 +1 @@
|
||||
Subproject commit dbee44e4f940a502971f17116ccbba61ceaf2674
|
||||
Subproject commit 10ed9ef576836186de3b8513c03cdc3fb18c44ed
|
4
go.mod
4
go.mod
@ -20,7 +20,7 @@ require (
|
||||
github.com/drand/kyber v1.1.2
|
||||
github.com/dustin/go-humanize v1.0.0
|
||||
github.com/elastic/go-sysinfo v1.3.0
|
||||
github.com/fatih/color v1.8.0
|
||||
github.com/fatih/color v1.9.0
|
||||
github.com/filecoin-project/filecoin-ffi v0.30.4-0.20200716204036-cddc56607e1d
|
||||
github.com/filecoin-project/go-address v0.0.4
|
||||
github.com/filecoin-project/go-amt-ipld/v2 v2.1.1-0.20201006184820-924ee87a1349 // indirect
|
||||
@ -104,6 +104,7 @@ require (
|
||||
github.com/libp2p/go-libp2p-tls v0.1.3
|
||||
github.com/libp2p/go-libp2p-yamux v0.2.8
|
||||
github.com/libp2p/go-maddr-filter v0.1.0
|
||||
github.com/mattn/go-colorable v0.1.6 // indirect
|
||||
github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1
|
||||
github.com/mitchellh/go-homedir v1.1.0
|
||||
github.com/multiformats/go-base32 v0.0.3
|
||||
@ -120,6 +121,7 @@ require (
|
||||
github.com/urfave/cli/v2 v2.2.0
|
||||
github.com/whyrusleeping/bencher v0.0.0-20190829221104-bb6607aa8bba
|
||||
github.com/whyrusleeping/cbor-gen v0.0.0-20200826160007-0b9f6c5fb163
|
||||
github.com/whyrusleeping/ledger-filecoin-go v0.9.1-0.20201010031517-c3dcc1bddce4
|
||||
github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7
|
||||
github.com/whyrusleeping/pubsub v0.0.0-20131020042734-02de8aa2db3d
|
||||
github.com/xorcare/golden v0.6.1-0.20191112154924-b87f686d7542
|
||||
|
16
go.sum
16
go.sum
@ -221,6 +221,8 @@ github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5/go.mod h1:Jp
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/fatih/color v1.8.0 h1:5bzFgL+oy7JITMTxUPJ00n7VxmYd/PdMp5mHFX40/RY=
|
||||
github.com/fatih/color v1.8.0/go.mod h1:3l45GVGkyrnYNl9HoIjnp2NnNWvh6hLAqD8yTfGjnw8=
|
||||
github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s=
|
||||
github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
|
||||
github.com/fd/go-nat v1.0.0/go.mod h1:BTBu/CKvMmOMUPkKVef1pngt2WFH/lg7E6yQnulfp6E=
|
||||
github.com/filecoin-project/go-address v0.0.3 h1:eVfbdjEbpbzIrbiSa+PiGUY+oDK9HnUn+M1R/ggoHf8=
|
||||
github.com/filecoin-project/go-address v0.0.3/go.mod h1:jr8JxKsYx+lQlQZmF5i2U0Z+cGQ59wMIps/8YW/lDj8=
|
||||
@ -1047,11 +1049,16 @@ github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcncea
|
||||
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||
github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA=
|
||||
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||
github.com/mattn/go-colorable v0.1.6 h1:6Su7aK7lXmJ/U79bYtBjLNaha4Fs1Rg9plHpcH+vvnE=
|
||||
github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE=
|
||||
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
|
||||
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||
github.com/mattn/go-runewidth v0.0.7 h1:Ei8KR0497xHyKJPAv59M1dkC+rOZCMBJ+t3fZ+twI54=
|
||||
github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
@ -1424,6 +1431,8 @@ github.com/whyrusleeping/go-smux-multiplex v3.0.16+incompatible/go.mod h1:34LEDb
|
||||
github.com/whyrusleeping/go-smux-multistream v2.0.2+incompatible/go.mod h1:dRWHHvc4HDQSHh9gbKEBbUZ+f2Q8iZTPG3UOGYODxSQ=
|
||||
github.com/whyrusleeping/go-smux-yamux v2.0.8+incompatible/go.mod h1:6qHUzBXUbB9MXmw3AUdB52L8sEb/hScCqOdW2kj/wuI=
|
||||
github.com/whyrusleeping/go-smux-yamux v2.0.9+incompatible/go.mod h1:6qHUzBXUbB9MXmw3AUdB52L8sEb/hScCqOdW2kj/wuI=
|
||||
github.com/whyrusleeping/ledger-filecoin-go v0.9.1-0.20201010031517-c3dcc1bddce4 h1:NwiwjQDB3CzQ5XH0rdMh1oQqzJH7O2PSLWxif/w3zsY=
|
||||
github.com/whyrusleeping/ledger-filecoin-go v0.9.1-0.20201010031517-c3dcc1bddce4/go.mod h1:K+EVq8d5QcQ2At5VECsA+SNZvWefyBXh8TnIsxo1OvQ=
|
||||
github.com/whyrusleeping/mafmt v1.2.8/go.mod h1:faQJFPbLSxzD9xpA02ttW/tS9vZykNvXwGvqIpk20FA=
|
||||
github.com/whyrusleeping/mdns v0.0.0-20180901202407-ef14215e6b30/go.mod h1:j4l84WPFclQPj320J9gp0XwNKBb3U0zt5CBqjPp22G4=
|
||||
github.com/whyrusleeping/mdns v0.0.0-20190826153040-b9b60ed33aa9/go.mod h1:j4l84WPFclQPj320J9gp0XwNKBb3U0zt5CBqjPp22G4=
|
||||
@ -1445,6 +1454,10 @@ github.com/xorcare/golden v0.6.1-0.20191112154924-b87f686d7542 h1:oWgZJmC1DorFZD
|
||||
github.com/xorcare/golden v0.6.1-0.20191112154924-b87f686d7542/go.mod h1:7T39/ZMvaSEZlBPoYfVFmsBLmUl3uz9IuzWj/U6FtvQ=
|
||||
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/zondax/hid v0.9.0 h1:eiT3P6vNxAEVxXMw66eZUAAnU2zD33JBkfG/EnfAKl8=
|
||||
github.com/zondax/hid v0.9.0/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM=
|
||||
github.com/zondax/ledger-go v0.12.1 h1:hYRcyznPRJp+5mzF2sazTLP2nGvGjYDD2VzhHhFomLU=
|
||||
github.com/zondax/ledger-go v0.12.1/go.mod h1:KatxXrVDzgWwbssUWsF5+cOJHXPvzQ09YSlzGNuhOEo=
|
||||
go.dedis.ch/fixbuf v1.0.3 h1:hGcV9Cd/znUxlusJ64eAlExS+5cJDIyTyEG+otu5wQs=
|
||||
go.dedis.ch/fixbuf v1.0.3/go.mod h1:yzJMt34Wa5xD37V5RTdmp38cz3QhMagdGoem9anUalw=
|
||||
go.dedis.ch/kyber/v3 v3.0.4/go.mod h1:OzvaEnPvKlyrWyp3kGXlFdp7ap1VC6RkZDTaPikqhsQ=
|
||||
@ -1517,6 +1530,7 @@ golang.org/x/crypto v0.0.0-20190618222545-ea8f1a30c443/go.mod h1:yigFU9vqHzYiE8U
|
||||
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200117160349-530e935923ad/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
@ -1660,11 +1674,13 @@ golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191025021431-6c3a3bfe00ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191025090151-53bf42e6b339/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
|
@ -44,6 +44,7 @@ import (
|
||||
"github.com/filecoin-project/lotus/chain/metrics"
|
||||
"github.com/filecoin-project/lotus/chain/stmgr"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
ledgerwallet "github.com/filecoin-project/lotus/chain/wallet/ledger"
|
||||
"github.com/filecoin-project/lotus/chain/wallet/remotewallet"
|
||||
sectorstorage "github.com/filecoin-project/lotus/extern/sector-storage"
|
||||
"github.com/filecoin-project/lotus/extern/sector-storage/ffiwrapper"
|
||||
@ -251,8 +252,8 @@ func Online() Option {
|
||||
Override(new(*stmgr.StateManager), stmgr.NewStateManagerWithUpgradeSchedule),
|
||||
Override(new(stmgr.StateManagerAPI), From(new(*stmgr.StateManager))),
|
||||
Override(new(*wallet.LocalWallet), wallet.NewWallet),
|
||||
Override(new(api.WalletAPI), From(new(*wallet.LocalWallet))),
|
||||
Override(new(wallet.Default), From(new(*wallet.LocalWallet))),
|
||||
Override(new(api.WalletAPI), From(new(wallet.MultiWallet))),
|
||||
Override(new(*messagesigner.MessageSigner), messagesigner.NewMessageSigner),
|
||||
|
||||
Override(new(dtypes.ChainGCLocker), blockstore.NewGCLocker),
|
||||
@ -459,8 +460,16 @@ func ConfigFullNode(c interface{}) Option {
|
||||
If(cfg.Metrics.HeadNotifs,
|
||||
Override(HeadMetricsKey, metrics.SendHeadNotifs(cfg.Metrics.Nickname)),
|
||||
),
|
||||
|
||||
If(cfg.Wallet.RemoteBackend != "",
|
||||
Override(new(api.WalletAPI), remotewallet.SetupRemoteWallet(cfg.Wallet.RemoteBackend)),
|
||||
Override(new(*remotewallet.RemoteWallet), remotewallet.SetupRemoteWallet(cfg.Wallet.RemoteBackend)),
|
||||
),
|
||||
If(cfg.Wallet.EnableLedger,
|
||||
Override(new(*ledgerwallet.LedgerWallet), ledgerwallet.NewWallet),
|
||||
),
|
||||
If(cfg.Wallet.DisableLocal,
|
||||
Unset(new(*wallet.LocalWallet)),
|
||||
Override(new(wallet.Default), wallet.NilDefault),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
@ -110,6 +110,8 @@ type Client struct {
|
||||
|
||||
type Wallet struct {
|
||||
RemoteBackend string
|
||||
EnableLedger bool
|
||||
DisableLocal bool
|
||||
}
|
||||
|
||||
func defCommon() Common {
|
||||
|
@ -21,7 +21,7 @@ var log = logging.Logger("p2pnode")
|
||||
|
||||
const (
|
||||
KLibp2pHost = "libp2p-host"
|
||||
KTLibp2pHost = KLibp2pHost
|
||||
KTLibp2pHost types.KeyType = KLibp2pHost
|
||||
)
|
||||
|
||||
type Libp2pOpts struct {
|
||||
|
@ -1,11 +1,11 @@
|
||||
#!/bin/bash
|
||||
# vim: set expandtab ts=2 sw=2:
|
||||
|
||||
token=$(lotus auth create-token --perm admin)
|
||||
_lotus_token=$(./lotus auth create-token --perm admin)
|
||||
|
||||
runAPI() {
|
||||
curl -X POST \
|
||||
-H "Content-Type: application/json" \
|
||||
--data '{"jsonrpc":"2.0","id":2,"method":"Filecoin.'"$1"'","params":'"${2:-null}"'}' \
|
||||
'http://127.0.0.1:1234/rpc/v0?token='"$token"
|
||||
'http://127.0.0.1:1234/rpc/v0?token='"$_lotus_token"
|
||||
}
|
||||
|
@ -7,7 +7,6 @@ import (
|
||||
commcid "github.com/filecoin-project/go-fil-commcid"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
"github.com/filecoin-project/go-state-types/crypto"
|
||||
"github.com/filecoin-project/lotus/extern/sector-storage/mock"
|
||||
|
||||
market0 "github.com/filecoin-project/specs-actors/actors/builtin/market"
|
||||
@ -20,7 +19,7 @@ import (
|
||||
)
|
||||
|
||||
func PreSeal(ssize abi.SectorSize, maddr address.Address, sectors int) (*genesis.Miner, *types.KeyInfo, error) {
|
||||
k, err := wallet.GenerateKey(crypto.SigTypeBLS)
|
||||
k, err := wallet.GenerateKey(types.KTBLS)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user