Skip to content

Commit

Permalink
feat: allow signerless account registration (#16)
Browse files Browse the repository at this point in the history
  • Loading branch information
johnletey authored Aug 29, 2024
1 parent dd5f499 commit 6bfe328
Show file tree
Hide file tree
Showing 8 changed files with 355 additions and 20 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- Allow accounts with a balance to be registered signerlessly. ([#17](https://github.com/noble-assets/forwarding/pull/17))
6 changes: 6 additions & 0 deletions proto/noble/forwarding/v1/account.proto
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,9 @@ message ForwardingAccount {
string recipient = 3;
int64 created_at = 4;
}

message ForwardingPubKey {
option (gogoproto.goproto_stringer) = false;

bytes key = 1;
}
53 changes: 53 additions & 0 deletions x/forwarding/ante.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,12 @@ package forwarding
import (
cctptypes "github.com/circlefin/noble-cctp/x/cctp/types"
fiattokenfactorytypes "github.com/circlefin/noble-fiattokenfactory/x/fiattokenfactory/types"
storetypes "github.com/cosmos/cosmos-sdk/store/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/tx/signing"
"github.com/cosmos/cosmos-sdk/x/auth/ante"
authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
"github.com/cosmos/cosmos-sdk/x/authz"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
"github.com/noble-assets/forwarding/x/forwarding/keeper"
Expand Down Expand Up @@ -120,3 +124,52 @@ func (d Decorator) CheckMessages(ctx sdk.Context, msgs []sdk.Msg) error {

return nil
}

//

func SigVerificationGasConsumer(
meter storetypes.GasMeter, sig signing.SignatureV2, params authtypes.Params,
) error {
switch sig.PubKey.(type) {
case *types.ForwardingPubKey:
return nil
default:
return ante.DefaultSigVerificationGasConsumer(meter, sig, params)
}
}

//

type SigVerificationDecorator struct {
underlying ante.SigVerificationDecorator
bank types.BankKeeper
}

var _ sdk.AnteDecorator = SigVerificationDecorator{}

func NewSigVerificationDecorator(ak ante.AccountKeeper, bk types.BankKeeper, signModeHandler authsigning.SignModeHandler) SigVerificationDecorator {
return SigVerificationDecorator{
underlying: ante.NewSigVerificationDecorator(ak, signModeHandler),
bank: bk,
}
}

func (d SigVerificationDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) {
if msgs := tx.GetMsgs(); len(msgs) == 1 {
msg, ok := msgs[0].(*types.MsgRegisterAccount)
if !ok {
return d.underlying.AnteHandle(ctx, tx, simulate, next)
}

address := types.GenerateAddress(msg.Channel, msg.Recipient)
balance := d.bank.GetAllBalances(ctx, address)

if balance.IsZero() || msg.Signer != address.String() {
return d.underlying.AnteHandle(ctx, tx, simulate, next)
}

return next(ctx, tx, simulate)
}

return d.underlying.AnteHandle(ctx, tx, simulate, next)
}
69 changes: 69 additions & 0 deletions x/forwarding/client/cli/tx.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
package cli

import (
"fmt"

"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/client/tx"
signingtypes "github.com/cosmos/cosmos-sdk/types/tx/signing"
"github.com/noble-assets/forwarding/x/forwarding/types"
"github.com/spf13/cobra"
)
Expand All @@ -15,6 +18,7 @@ func GetTxCmd() *cobra.Command {
}

cmd.AddCommand(TxRegisterAccount())
cmd.AddCommand(TxRegisterAccountSignerlessly())
cmd.AddCommand(TxClearAccount())

return cmd
Expand Down Expand Up @@ -46,6 +50,71 @@ func TxRegisterAccount() *cobra.Command {
return cmd
}

func TxRegisterAccountSignerlessly() *cobra.Command {
cmd := &cobra.Command{
Use: "register-account-signerlessly [channel] [recipient]",
Short: "Signerlessly register a forwarding account for a channel and recipient",
Args: cobra.ExactArgs(2),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientTxContext(cmd)
if err != nil {
return err
}

address := types.GenerateAddress(args[0], args[1])
msg := &types.MsgRegisterAccount{
Signer: address.String(),
Recipient: args[1],
Channel: args[0],
}
if err := msg.ValidateBasic(); err != nil {
return err
}

factory := tx.NewFactoryCLI(clientCtx, cmd.Flags())
builder, err := factory.BuildUnsignedTx(msg)
if err != nil {
return err
}

err = builder.SetSignatures(signingtypes.SignatureV2{
PubKey: &types.ForwardingPubKey{Key: address},
Data: &signingtypes.SingleSignatureData{
SignMode: signingtypes.SignMode_SIGN_MODE_DIRECT,
Signature: []byte(""),
},
})
if err != nil {
return err
}

if clientCtx.GenerateOnly {
bz, err := clientCtx.TxConfig.TxJSONEncoder()(builder.GetTx())
if err != nil {
return err
}

return clientCtx.PrintString(fmt.Sprintf("%s\n", bz))
}

bz, err := clientCtx.TxConfig.TxEncoder()(builder.GetTx())
if err != nil {
return err
}
res, err := clientCtx.BroadcastTx(bz)
if err != nil {
return err
}

return clientCtx.PrintProto(res)
},
}

flags.AddTxFlagsToCmd(cmd)

return cmd
}

func TxClearAccount() *cobra.Command {
cmd := &cobra.Command{
Use: "clear-account [address]",
Expand Down
4 changes: 3 additions & 1 deletion x/forwarding/keeper/msg_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@ func (k *Keeper) RegisterAccount(goCtx context.Context, msg *types.MsgRegisterAc
if k.authKeeper.HasAccount(ctx, address) {
rawAccount := k.authKeeper.GetAccount(ctx, address)
if rawAccount.GetPubKey() != nil || rawAccount.GetSequence() != 0 {
return nil, fmt.Errorf("attempting to register an existing user account with address: %s", address.String())
if !rawAccount.GetPubKey().Equals(&types.ForwardingPubKey{Key: address}) {
return nil, fmt.Errorf("attempting to register an existing user account with address: %s", address.String())
}
}

switch account := rawAccount.(type) {
Expand Down
28 changes: 28 additions & 0 deletions x/forwarding/types/account.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package types

import (
"bytes"
"fmt"

cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/address"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
Expand Down Expand Up @@ -30,3 +32,29 @@ func (fa *ForwardingAccount) Validate() error {

return fa.BaseAccount.Validate()
}

//

var _ cryptotypes.PubKey = &ForwardingPubKey{}

func (fpk *ForwardingPubKey) String() string {
return fmt.Sprintf("PubKeyForwarding{%X}", fpk.Key)
}

func (fpk *ForwardingPubKey) Address() cryptotypes.Address { return fpk.Key }

func (fpk *ForwardingPubKey) Bytes() []byte { return fpk.Key }

func (*ForwardingPubKey) VerifySignature(_ []byte, _ []byte) bool {
panic("PubKeyForwarding.VerifySignature should never be invoked")
}

func (fpk *ForwardingPubKey) Equals(other cryptotypes.PubKey) bool {
if _, ok := other.(*ForwardingPubKey); !ok {
return false
}

return bytes.Equal(fpk.Bytes(), other.Bytes())
}

func (*ForwardingPubKey) Type() string { return "forwarding" }
Loading

0 comments on commit 6bfe328

Please sign in to comment.