Agoric / agoric-sdk

monorepo for the Agoric Javascript smart contract platform
Apache License 2.0
305 stars 194 forks source link

Ensure Ledger users can sign Agoric transactions #3628

Closed rowgraus closed 1 year ago

rowgraus commented 2 years ago

As an Agoric user who manages my assets with a hardware wallet (Ledger), I need to be able to sign transactions with Agoric offers (e.g., create a vault, trade on AMM, add liquidity on AMM) using my hardware wallet.

Our on-chain wallet design may handle this natively through Keplr. This should be explicitly tested.

Must have:

Nice/prefer to have:

Tartuffo commented 2 years ago

@rowgraus What is the open question here?

rowgraus commented 2 years ago

Story updated. Assigned to Michael. Should be estimated as non-zero now @Tartuffo @michaelfig

michaelfig commented 2 years ago

Using a Ledger to sign wallet spend transactions (including offers) should require only minimal testing, as Keplr makes that process transparent to our software. This issue entails working through the main wallet flows using a hardware wallet supported by Keplr.

I consider the nice-to-haves to be out of scope for this issue. Trezor is not supported by Keplr, and for now, Keplr is our only supported signer. It would be great if there are other signers available (MetaMask snaps and Cosmostation come to mind), but integrating and testing each one of them should be a separate issue, ideally not waiting on the Agoric team.

Offer legibility on hardware wallets will require coordination with Keplr around SIGN_MODE_TEXTUAL (#4529). There will likely be broader Cosmos ecosystem support for Ledger+SIGN_MODE_TEXTUAL, and integrating or driving that will require significant resources, so I'm considering it out of scope for Mainnet 1.

If any of these nice-to-haves become necessary for Mainnet 1, let's create separate issues.

michaelfig commented 2 years ago

Fallback plan is initially to use SIGN_MODE_AMINO_JSON for the wallet transactions so that Ledger can sign them. SIGN_MODE_TEXTUAL (#4529) can wait if necessary.

dckc commented 2 years ago

I'm struggling with amino-json too.

Note: to get the wallet-action CLI working, I made a tweak or two: ed0b3bf

cc @JimLarson

agd wallet-action cli

To diagnose issues with sending from js (#5761) I tried golang cli support. No joy, so far:

connolly@dcpc:~/projects/agoric-sdk/packages/cosmic-swingset$ make FROM_KEY=lx wallet-action
Waiting for localhost:26657 to come live....... done!
../../golang/cosmos/build/agd \
  --home=t1/bootstrap --keyring-backend=test --from=lx \
  tx swingset wallet-action '{"action":1}' \
  --gas=auto --gas-adjustment=1.2 --broadcast-mode=block --yes --chain-id=agoric
Default sign-mode 'direct' not supported by Ledger, using sign-mode 'amino-json'.
gas estimate: 79152
panic: expected *legacytx.LegacyMsg when using amino JSON

goroutine 1 [running]:
github.com/cosmos/cosmos-sdk/x/auth/legacy/legacytx.StdSignBytes({0x7ffd1cafff06, 0x6}, 0x9, 0x0, 0x0, {{0x0?, 0x1f?, 0xc00149e138?}, 0x4582fc?}, {0xc000d61d30, ...}, ...)
        /home/connolly/go/pkg/mod/github.com/agoric-labs/cosmos-sdk@v0.45.1-alpha.agoric.4/x/auth/legacy/legacytx/stdsign.go:58 +0x398
github.com/cosmos/cosmos-sdk/x/auth/tx.signModeLegacyAminoJSONHandler.GetSignBytes({}, 0x457e70?, {{0x7ffd1cafff06?, 0xc00149e240?}, 0x413f25?, 0xc00149e200?}, {0x2011860?, 0xc000f29080?})
        /home/connolly/go/pkg/mod/github.com/agoric-labs/cosmos-sdk@v0.45.1-alpha.agoric.4/x/auth/tx/legacy_amino_json.go:49 +0x1a7
github.com/cosmos/cosmos-sdk/x/auth/signing.SignModeHandlerMap.GetSignBytes({0x1, {0xc000682aa0, 0x2, 0x2}, 0xc000d1cf30}, 0x20233b0?, {{0x7ffd1cafff06, 0x6}, 0x9, 0x0}, ...)
        /home/connolly/go/pkg/mod/github.com/agoric-labs/cosmos-sdk@v0.45.1-alpha.agoric.4/x/auth/signing/handler_map.go:59 +0xa2
github.com/cosmos/cosmos-sdk/client/tx.Sign({{0x2032c58, 0xc000f28b40}, {0x202cb38, 0xc0000c3640}, {0x2024e20, 0x2e09dc8}, 0x9, 0x0, 0x13530, 0x0, ...}, ...)
        /home/connolly/go/pkg/mod/github.com/agoric-labs/cosmos-sdk@v0.45.1-alpha.agoric.4/client/tx/tx.go:441 +0x389
github.com/cosmos/cosmos-sdk/client/tx.BroadcastTx({{0xc000565f38, 0x14, 0x18}, {0x2037ef8, 0xc000f48f00}, {0x7ffd1cafff06, 0x6}, {0x2027e10, 0xc000142910}, {0x2032078, ...}, ...}, ...)
        /home/connolly/go/pkg/mod/github.com/agoric-labs/cosmos-sdk@v0.45.1-alpha.agoric.4/client/tx/tx.go:132 +0x68d
github.com/cosmos/cosmos-sdk/client/tx.GenerateOrBroadcastTxWithFactory({{0xc000565f38, 0x14, 0x18}, {0x2037ef8, 0xc000f48f00}, {0x7ffd1cafff06, 0x6}, {0x2027e10, 0xc000142910}, {0x2032078, ...}, ...}, ...)
        /home/connolly/go/pkg/mod/github.com/agoric-labs/cosmos-sdk@v0.45.1-alpha.agoric.4/client/tx/tx.go:51 +0x11f
github.com/cosmos/cosmos-sdk/client/tx.GenerateOrBroadcastTxCLI({{0xc000565f38, 0x14, 0x18}, {0x2037ef8, 0xc000f48f00}, {0x7ffd1cafff06, 0x6}, {0x2027e10, 0xc000142910}, {0x2032078, ...}, ...}, ...)
        /home/connolly/go/pkg/mod/github.com/agoric-labs/cosmos-sdk@v0.45.1-alpha.agoric.4/client/tx/tx.go:31 +0x113
github.com/Agoric/agoric-sdk/golang/cosmos/x/swingset/client/cli.GetCmdWalletAction.func1(0xc0012d7180?, {0xc000d30510, 0x1, 0x9?})
        /home/connolly/projects/agoric-sdk/golang/cosmos/x/swingset/client/cli/tx.go:197 +0x391
github.com/spf13/cobra.(*Command).execute(0xc0012d7180, {0xc000d30480, 0x9, 0x9})
        /home/connolly/go/pkg/mod/github.com/spf13/cobra@v1.2.1/command.go:856 +0x67c
github.com/spf13/cobra.(*Command).ExecuteC(0xc000d68000)
        /home/connolly/go/pkg/mod/github.com/spf13/cobra@v1.2.1/command.go:974 +0x3b4
github.com/spf13/cobra.(*Command).Execute(...)
        /home/connolly/go/pkg/mod/github.com/spf13/cobra@v1.2.1/command.go:902
github.com/spf13/cobra.(*Command).ExecuteContext(...)
        /home/connolly/go/pkg/mod/github.com/spf13/cobra@v1.2.1/command.go:895
github.com/cosmos/cosmos-sdk/server/cmd.Execute(0xc000249260?, {0xc000240f60, 0x16})
        /home/connolly/go/pkg/mod/github.com/agoric-labs/cosmos-sdk@v0.45.1-alpha.agoric.4/server/cmd/execute.go:36 +0x1eb
github.com/Agoric/agoric-sdk/golang/cosmos/daemon.RunWithController(0xc0000021a0?)
        /home/connolly/projects/agoric-sdk/golang/cosmos/daemon/main.go:74 +0x10c
main.main()
        /home/connolly/projects/agoric-sdk/golang/cosmos/cmd/agd/main.go:33 +0x4c
make: *** [Makefile:221: wallet-action] Error 2

--sign-mode=amino-json doesn't seem to help:

packages/cosmic-swingset$ make FROM_KEY=lx SIGN_MODE=--sign-mode=amino-json wallet-action
Waiting for localhost:26657 to come live...... done!
../../golang/cosmos/build/agd \
  --home=t1/bootstrap --keyring-backend=test --from=lx --sign-mode=amino-json\
  tx swingset wallet-action '{"action":1}' \
  --gas=auto --gas-adjustment=1.2 --broadcast-mode=block --yes --chain-id=agoric
gas estimate: 79152
panic: expected *legacytx.LegacyMsg when using amino JSON

goroutine 1 [running]:
github.com/cosmos/cosmos-sdk/x/auth/legacy/legacytx.StdSignBytes({0x7ffc58338ec4, 0x6}, 0x9, 0x0, 0x0, {{0x0?, 0x1f?, 0xc00111e138?}, 0x4582fc?}, {0xc0010f03c0, ...}, ...)
        /home/connolly/go/pkg/mod/github.com/agoric-labs/cosmos-sdk@v0.45.1-alpha.agoric.4/x/auth/legacy/legacytx/stdsign.go:58 +0x398
github.com/cosmos/cosmos-sdk/x/auth/tx.signModeLegacyAminoJSONHandler.GetSignBytes({}, 0x48e54eb8?, {{0x7ffc58338ec4?, 0xc00111e240?}, 0x413f25?, 0x7fdb70c74a68?}, {0x2011860?, 0xc0000c2d40?})
        /home/connolly/go/pkg/mod/github.com/agoric-labs/cosmos-sdk@v0.45.1-alpha.agoric.4/x/auth/tx/legacy_amino_json.go:49 +0x1a7
github.com/cosmos/cosmos-sdk/x/auth/signing.SignModeHandlerMap.GetSignBytes({0x1, {0xc000d0a008, 0x2, 0x2}, 0xc000d7e870}, 0x20233b0?, {{0x7ffc58338ec4, 0x6}, 0x9, 0x0}, ...)
        /home/connolly/go/pkg/mod/github.com/agoric-labs/cosmos-sdk@v0.45.1-alpha.agoric.4/x/auth/signing/handler_map.go:59 +0xa2
github.com/cosmos/cosmos-sdk/client/tx.Sign({{0x2032c58, 0xc0001f4740}, {0x202cb38, 0xc000d50000}, {0x2024e20, 0x2e09dc8}, 0x9, 0x0, 0x13530, 0x0, ...}, ...)
        /home/connolly/go/pkg/mod/github.com/agoric-labs/cosmos-sdk@v0.45.1-alpha.agoric.4/client/tx/tx.go:441 +0x389
github.com/cosmos/cosmos-sdk/client/tx.BroadcastTx({{0xc0005add28, 0x14, 0x18}, {0x2037ef8, 0xc0005bd350}, {0x7ffc58338ec4, 0x6}, {0x2027e10, 0xc000dae020}, {0x2032078, ...}, ...}, ...)
        /home/connolly/go/pkg/mod/github.com/agoric-labs/cosmos-sdk@v0.45.1-alpha.agoric.4/client/tx/tx.go:132 +0x68d
github.com/cosmos/cosmos-sdk/client/tx.GenerateOrBroadcastTxWithFactory({{0xc0005add28, 0x14, 0x18}, {0x2037ef8, 0xc0005bd350}, {0x7ffc58338ec4, 0x6}, {0x2027e10, 0xc000dae020}, {0x2032078, ...}, ...}, ...)
        /home/connolly/go/pkg/mod/github.com/agoric-labs/cosmos-sdk@v0.45.1-alpha.agoric.4/client/tx/tx.go:51 +0x11f
github.com/cosmos/cosmos-sdk/client/tx.GenerateOrBroadcastTxCLI({{0xc0005add28, 0x14, 0x18}, {0x2037ef8, 0xc0005bd350}, {0x7ffc58338ec4, 0x6}, {0x2027e10, 0xc000dae020}, {0x2032078, ...}, ...}, ...)
        /home/connolly/go/pkg/mod/github.com/agoric-labs/cosmos-sdk@v0.45.1-alpha.agoric.4/client/tx/tx.go:31 +0x113
github.com/Agoric/agoric-sdk/golang/cosmos/x/swingset/client/cli.GetCmdWalletAction.func1(0xc0005f2a00?, {0xc000d03860, 0x1, 0xa?})
        /home/connolly/projects/agoric-sdk/golang/cosmos/x/swingset/client/cli/tx.go:197 +0x391
github.com/spf13/cobra.(*Command).execute(0xc0005f2a00, {0xc000d03720, 0xa, 0xa})
        /home/connolly/go/pkg/mod/github.com/spf13/cobra@v1.2.1/command.go:856 +0x67c
github.com/spf13/cobra.(*Command).ExecuteC(0xc000e62280)
        /home/connolly/go/pkg/mod/github.com/spf13/cobra@v1.2.1/command.go:974 +0x3b4
github.com/spf13/cobra.(*Command).Execute(...)
        /home/connolly/go/pkg/mod/github.com/spf13/cobra@v1.2.1/command.go:902
github.com/spf13/cobra.(*Command).ExecuteContext(...)
        /home/connolly/go/pkg/mod/github.com/spf13/cobra@v1.2.1/command.go:895
github.com/cosmos/cosmos-sdk/server/cmd.Execute(0xc0000c41e0?, {0xc0001e8f48, 0x16})
        /home/connolly/go/pkg/mod/github.com/agoric-labs/cosmos-sdk@v0.45.1-alpha.agoric.4/server/cmd/execute.go:36 +0x1eb
github.com/Agoric/agoric-sdk/golang/cosmos/daemon.RunWithController(0xc0000021a0?)
        /home/connolly/projects/agoric-sdk/golang/cosmos/daemon/main.go:74 +0x10c
main.main()
        /home/connolly/projects/agoric-sdk/golang/cosmos/cmd/agd/main.go:33 +0x4c
make: *** [Makefile:222: wallet-action] Error 2
dckc commented 2 years ago

Some methods were missing; 8e3825d8b shows how to fix it.

connolly@dcpc:~/projects/agoric-sdk/packages/cosmic-swingset$ make wallet-action FROM_KEY=lx
Waiting for localhost:26657 to come live..... done!
../../golang/cosmos/build/agd \
  --home=t1/bootstrap --keyring-backend=test --from=lx \
  tx swingset wallet-action '{"action":1}' \
  --gas=auto --gas-adjustment=1.2 --broadcast-mode=block --yes --chain-id=agoric
Default sign-mode 'direct' not supported by Ledger, using sign-mode 'amino-json'.
gas estimate: 79044
code: 0
codespace: ""
data: 0A220A202F61676F7269632E7377696E677365742E4D736757616C6C6574416374696F6E
events:
- attributes:
  - index: true
    key: ZmVl
    value: ""
  type: tx
- attributes:
  - index: true
    key: YWNjX3NlcQ==
    value: YWdvcmljMTY4cnAzdWdtcHUwanRsYTV3amtkbHFnMjBycHY2NXh4emtoOHlwLzA=
  type: tx
- attributes:
  - index: true
    key: c2lnbmF0dXJl
    value: eXFpalZUd1k3UlJhcEtwdDZKSHZkeEFPOWgvQ0doYjlYTTI1VnJ4VVRFTTZPWjdqd2l4YklZc09rcGVWL2hXUFJ2MmdtUWorNkRpWWdVd1VxRXZORGc9PQ==
  type: tx
- attributes:
  - index: true
    key: YWN0aW9u
    value: L2Fnb3JpYy5zd2luZ3NldC5Nc2dXYWxsZXRBY3Rpb24=
  type: message
gas_used: "66038"
gas_wanted: "79044"
height: "39"
info: ""
logs:
- events:
  - attributes:
    - key: action
      value: /agoric.swingset.MsgWalletAction
    type: message
  log: ""
  msg_index: 0
raw_log: '[{"events":[{"type":"message","attributes":[{"key":"action","value":"/agoric.swingset.MsgWalletAction"}]}]}]'
timestamp: ""
tx: null
txhash: 875042D8D0F945A0F96038D2AD8F3844097B08CAE3DF17CE48EEF224ACB4D018
dckc commented 1 year ago

Still struggling. As noted in 7e95186:

grant needs fix in cosmos-sdk 0.46

grant fails due to a known problem (https://github.com/cosmos/cosmos-sdk/issues/11190) in cosmos-sdk pre 0.46:

aminotypes.ts:38 Uncaught (in promise) Error: The message type '/cosmos.authz.v1beta1.MsgGrant' cannot be signed using the Amino JSON sign mode because this is not supported by chain.
    at AminoTypes.toAmino (aminotypes.ts:38:13)
    at signingstargateclient.ts:351:56
    at Array.map (<anonymous>)
    at SigningStargateClient.signAmino (signingstargateclient.ts:351:27)
    at async SigningStargateClient.signAndBroadcast (signingstargateclient.ts:295:19)
    at async Object.authorizeLocalKey (keyManagement.js:350:18)

We're still on 0.45:

https://github.com/Agoric/agoric-sdk/blob/dbdd77861de4f8602c796277f243bdb9fa02a057/go.mod#L7

Why does submit offer fail to broacast?

Uncaught (in promise) Error: Broadcasting transaction failed with code 4 (codespace: sdk). Log: signature verification failed; please verify account number (14), sequence (0) and chain-id (agoric): unauthorized
    at SigningStargateClient.broadcastTx (stargateclient.ts:413:9)
    at async Object.submitSpendAction (keyManagement.js:381:18)
Tartuffo commented 1 year ago

Works with the CLI.