Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SPIKE: signing wallet actions with keplr, ledger #5761

Closed
wants to merge 54 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
96d0387
chore: handle WalletAction in walletFactory (WIP)
dckc Jul 12, 2022
a8c0f42
refactor(wallet): SuggestChain: separate IO from compute
dckc Jul 12, 2022
ac4b836
chore: toward keplr/ledger demo: copy SuggestChain.js
dckc Jul 13, 2022
54ca889
build: cosmjs, parcel, ... for keplr/ledger demo
dckc Jul 13, 2022
5c1c576
feat: sign simple msg/doc with keplr/ledger (WIP)
dckc Jul 13, 2022
a9b84d9
chore: figured out offlignSigner.signAmino() API
dckc Jul 13, 2022
65b0983
feat: sign WALLET_ACTION with keplr, ledger
dckc Jul 13, 2022
92d980d
style(vats): explicitly drop assignBundle promise in test
dckc Jul 13, 2022
175f809
chore(SuggestChain): allow partial io options
dckc Jul 13, 2022
c3445ac
fixup! chore: handle WalletAction in walletFactory
dckc Jul 14, 2022
a2acd43
fix(vats): fromBridge return value is ignored
dckc Jul 14, 2022
3408a02
fixup! chore: handle WalletAction in walletFactory (WIP)
dckc Jul 14, 2022
29b68b5
chore: send signed transaction to chain (WIP)
dckc Jul 14, 2022
36fdb13
fixup! chore(SuggestChain): allow partial io options
dckc Jul 14, 2022
b2c4511
build: JS stubs for swingset/msgs.proto (WIP)
dckc Jul 14, 2022
ba0aa4c
KLUDGE: symlink proto stuff or something
dckc Jul 15, 2022
ece6e26
build: generated google protobuf stuff
dckc Jul 15, 2022
a916eb5
build: generated swingset protobuf stubs (KLUDGE)
dckc Jul 15, 2022
0120186
chore: pass connectWithSigner authority explicitly
dckc Jul 15, 2022
84ab4a1
chore: integrate MsgWalletAction proto stub via registry
dckc Jul 15, 2022
98ac911
fix: MsgWalletAction.owner is bytes, not string
dckc Jul 15, 2022
cf294d7
fix: provide enough gas
dckc Jul 15, 2022
0930864
fix(golang): register amino codec for WalletAction, SpendAction
dckc Jul 15, 2022
ab950b5
feat(cosmic-swingset): fund-acct Makefile stanza
dckc Jul 15, 2022
742cc98
fix(golang): swingset wallet-action was not quite wired up
dckc Jul 18, 2022
cff5235
test(cosmic-swingset): wallet-action testing stanza
dckc Jul 18, 2022
ed0b3bf
WIP: debug logging for WALLET_ACTION
dckc Jul 18, 2022
8e3825d
fix(golang): support ledger for MsgWalletAction
dckc Jul 18, 2022
d6082f3
chore(demo-signing): replace misleading chainId etc.
dckc Jul 18, 2022
bcf0601
feat(demo-signing): sign and broadcast WalletAction
dckc Jul 18, 2022
d63caa7
feat(demo-signing): authz grant to ephemeral key (WIP)
dckc Jul 19, 2022
3a39005
fixup! feat(demo-signing): authz grant to ephemeral key (WIP)
dckc Jul 20, 2022
9a932f6
feat(demo-signing): basic fee grant to messaging key
dckc Jul 20, 2022
a7ceba7
chore(demo-signing): misc static types
dckc Jul 20, 2022
a921199
feat(demo-signing): use ephemeral messaging key to do actions (WIP)
dckc Jul 20, 2022
30a9374
fixup! feat(demo-signing): use ephemeral messaging key to do actions …
dckc Jul 22, 2022
a33b5d8
fixup! feat(demo-signing): authz grant to ephemeral key (WIP)
dckc Jul 22, 2022
5fbedd0
feat(demo-signing): query WalletAction grants
dckc Jul 22, 2022
73818b2
workaround: cosmjs lacks support for fee-account in MsgExec
dckc Jul 22, 2022
9a62a8c
fixup! test(cosmic-swingset): wallet-action testing stanza
dckc Jul 22, 2022
2e5be92
build(demo-signing): keplr types package
dckc Jul 22, 2022
d6661ce
chore(demo-signing): factor out keyManagement.js
dckc Jul 22, 2022
f210921
fixup! chore(demo-signing): factor out keyManagement.js
dckc Jul 23, 2022
93df134
fixup! fixup! chore(demo-signing): factor out keyManagement.js
dckc Jul 23, 2022
7e95186
chore(demo-signing): check ledger status: nope
dckc Jul 23, 2022
64237c0
fixup! test(cosmic-swingset): wallet-action testing stanza
dckc Jul 23, 2022
3934c7c
chore: move keyManagement.js to wallet/ui/src
dckc Jul 29, 2022
7315688
fix(cosmic-swingset): urun->uist in Makefile
dckc Jul 29, 2022
6d6016f
build(wallet/ui): cosmjs misc (WIP)
dckc Jul 29, 2022
9561b4c
build: yarn.lock after cosmjs stuff
dckc Jul 29, 2022
31d1d08
chore: .js stuff
dckc Jul 29, 2022
90b06a8
WIP: kludge around import cycle
dckc Jul 29, 2022
4ae8049
fix(wallet/ui): handle local-chain rpcAddr
dckc Jul 29, 2022
2dd05ed
feat(wallet/ui): sign offer-like JSON (WIP)
dckc Jul 29, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions golang/cosmos/x/swingset/client/cli/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ func GetTxCmd(storeKey string) *cobra.Command {
GetCmdDeliver(),
GetCmdProvisionOne(),
GetCmdInstallBundle(),
GetCmdWalletAction(),
)

return swingsetTxCmd
Expand Down
6 changes: 4 additions & 2 deletions golang/cosmos/x/swingset/keeper/msg_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package keeper
import (
"context"
"fmt"
"os"

"github.com/Agoric/agoric-sdk/golang/cosmos/vm"
"github.com/Agoric/agoric-sdk/golang/cosmos/x/swingset/types"
Expand Down Expand Up @@ -69,6 +70,7 @@ type walletAction struct {
}

func (keeper msgServer) WalletAction(goCtx context.Context, msg *types.MsgWalletAction) (*types.MsgWalletActionResponse, error) {
fmt.Fprintf(os.Stderr, "WalletAction()...\n")
ctx := sdk.UnwrapSDKContext(goCtx)

action := &walletAction{
Expand All @@ -78,10 +80,10 @@ func (keeper msgServer) WalletAction(goCtx context.Context, msg *types.MsgWallet
BlockHeight: ctx.BlockHeight(),
BlockTime: ctx.BlockTime().Unix(),
}
// fmt.Fprintf(os.Stderr, "Context is %+v\n", ctx)
fmt.Fprintf(os.Stderr, "WalletAction: action %+v , context %+v\n", action, ctx)

err := keeper.PushAction(ctx, action)
// fmt.Fprintln(os.Stderr, "Returned from SwingSet", out, err)
fmt.Fprintln(os.Stderr, "Returned from SwingSet", err)
if err != nil {
return nil, err
}
Expand Down
2 changes: 2 additions & 0 deletions golang/cosmos/x/swingset/types/codec.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ func init() {
func RegisterCodec(cdc *codec.LegacyAmino) {
cdc.RegisterConcrete(&MsgDeliverInbound{}, ModuleName+"/DeliverInbound", nil)
cdc.RegisterConcrete(&MsgProvision{}, ModuleName+"/Provision", nil)
cdc.RegisterConcrete(&MsgWalletAction{}, ModuleName+"/WalletAction", nil)
cdc.RegisterConcrete(&MsgWalletSpendAction{}, ModuleName+"/WalletSpendAction", nil)
}

// RegisterInterfaces registers the x/swingset interfaces types with the interface registry
Expand Down
22 changes: 22 additions & 0 deletions golang/cosmos/x/swingset/types/msgs.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,28 @@ func (msg MsgWalletAction) GetSigners() []sdk.AccAddress {
return []sdk.AccAddress{msg.Owner}
}

// GetSignBytes encodes the message for signing
func (msg MsgWalletAction) GetSignBytes() []byte {
return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&msg))
}

// GetSignBytes encodes the message for signing
func (msg MsgWalletSpendAction) GetSignBytes() []byte {
return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&msg))
}

// Route should return the name of the module
func (msg MsgWalletAction) Route() string { return RouterKey }

// Type should return the action
func (msg MsgWalletAction) Type() string { return "wallet_action" }

// Route should return the name of the module
func (msg MsgWalletSpendAction) Route() string { return RouterKey }

// Type should return the action
func (msg MsgWalletSpendAction) Type() string { return "wallet_spend_action" }

// ValidateBasic runs stateless checks on the message
func (msg MsgWalletAction) ValidateBasic() error {
if msg.Owner.Empty() {
Expand Down
27 changes: 23 additions & 4 deletions packages/cosmic-swingset/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ scenario1-run-chain:
scenario1-run-client:
AG_SOLO_BASEDIR=$$PWD/t9/$(BASE_PORT) $(AG_SOLO) setup --network-config=http://localhost:8001/network-config --webport=$(BASE_PORT)

BOOT_COINS=1000000000000000ubld,500000000000000urun,100provisionpass,100sendpacketpass,1000000000000ibc/usdc1234,1000000000000ibc/atom1234
BOOT_COINS=1000000000000000ubld,500000000000000uist,100provisionpass,100sendpacketpass,1000000000000ibc/usdc1234,1000000000000ibc/atom1234

scenario2-setup: all scenario2-setup-nobuild
scenario2-setup-nobuild:
Expand Down Expand Up @@ -181,7 +181,7 @@ scenario2-run-client: t1-provision-one-with-powers t1-start-ag-solo

# Provision the ag-solo from an provisionpass-holding address (idempotent).
AGORIC_POWERS = agoric.ALL_THE_POWERS
SOLO_COINS = 13000000ubld,12345000000urun,1122000000ibc/usdc1234,3344000000ibc/atom1234
SOLO_COINS = 13000000ubld,12345000000uist,1122000000ibc/usdc1234,3344000000ibc/atom1234
COSMOS_RPC_HOST = localhost
COSMOS_RPC_PORT = 26657
wait-for-cosmos:
Expand Down Expand Up @@ -210,6 +210,25 @@ t1-provision-one-with-powers: wait-for-cosmos
--gas=auto --gas-adjustment=$(GAS_ADJUSTMENT) --broadcast-mode=block --yes --chain-id=$(CHAIN_ID) \
t1/$(BASE_PORT) $$addr $(AGORIC_POWERS) -ojson | tee /dev/stderr | grep -q '"code":0'; }

fund-acct: wait-for-cosmos
$(AGCH) \
--home=t1/bootstrap --keyring-backend=test --from=bootstrap \
tx bank send bootstrap $(ACCT_ADDR) $(SOLO_COINS) \
--gas=auto --gas-adjustment=$(GAS_ADJUSTMENT) --broadcast-mode=block --yes --chain-id=$(CHAIN_ID)

FROM_KEY=bootstrap
SIGN_MODE=
wallet-action: wait-for-cosmos
$(AGCH) \
--home=t1/bootstrap --keyring-backend=test --from=$(FROM_KEY) $(SIGN_MODE)\
tx swingset wallet-action '{"give": 10, "want": 1}' \
--gas=auto --gas-adjustment=$(GAS_ADJUSTMENT) --broadcast-mode=block --yes --chain-id=$(CHAIN_ID)

wallet-action-gen:
$(AGCH) --chain-id=$(CHAIN_ID) \
--home=t1/bootstrap --keyring-backend=test --from=$$(cat t1/bootstrap-address) $(SIGN_MODE)\
tx swingset wallet-action '{"action":1}' \
--generate-only --offline

t1-provision-one: wait-for-cosmos
@addrfile=t1/$(BASE_PORT)/cosmos-client-account; \
Expand All @@ -234,7 +253,7 @@ t1/$(BASE_PORT)/cosmos-fee-account.setup:
test ! -f t1/$(BASE_PORT)/cosmos-fee-account || \
$(AGCH) --home=t1/$(BASE_PORT)/owner --keyring-backend=test tx feegrant grant \
--gas=auto --gas-adjustment=$(GAS_ADJUSTMENT) --broadcast-mode=block --yes --chain-id=$(CHAIN_ID) --from=owner \
--period=5 --period-limit=200urun $$(cat t1/$(BASE_PORT)/cosmos-fee-account) $$(cat t1/$(BASE_PORT)/ag-cosmos-helper-address)
--period=5 --period-limit=200uist $$(cat t1/$(BASE_PORT)/cosmos-fee-account) $$(cat t1/$(BASE_PORT)/ag-cosmos-helper-address)
date > $@

# Actually start the ag-solo.
Expand All @@ -243,7 +262,7 @@ t1-start-ag-solo: t1/$(BASE_PORT)/cosmos-client-account.setup t1/$(BASE_PORT)/co
$(AGCH) query auth account $$addr >/dev/null 2>&1 || \
$(AGCH) --home=t1/bootstrap tx bank send --keyring-backend=test --from=bootstrap \
--gas=auto --gas-adjustment=$(GAS_ADJUSTMENT) --broadcast-mode=block --yes --chain-id=$(CHAIN_ID) \
bootstrap $$addr 1urun
bootstrap $$addr 1uist
cd t1/$(BASE_PORT) && \
SOLO_OTEL_EXPORTER_PROMETHEUS_PORT=$(SOLO_OTEL_EXPORTER_PROMETHEUS_PORT) \
$(AG_SOLO) start
Expand Down
4 changes: 2 additions & 2 deletions packages/vats/src/bridge.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import { Far } from '@endo/far';

/**
* @typedef {object} BridgeHandler An object that can receive messages from the bridge device
* @property {(srcId: string, obj: any) => Promise<any>} fromBridge Handle an inbound message
* @property {(srcId: string, obj: any) => Promise<undefined>} fromBridge Handle an inbound message
*
* @typedef {object} BridgeManager The object to manage this bridge
* @property {(dstID: string, obj: any) => any} toBridge
Expand Down Expand Up @@ -46,7 +46,7 @@ export function makeBridgeManager(E, D, bridgeDevice) {
// );

// Notify the specific handler, if there was one.
E(srcHandlers.get(srcID)).fromBridge(srcID, obj);
void E(srcHandlers.get(srcID)).fromBridge(srcID, obj);

// No return value.
}
Expand Down
8 changes: 6 additions & 2 deletions packages/vats/src/core/basic-behaviors.js
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,7 @@ export const makeClientBanks = async ({
client,
chainStorage,
bankManager,
bridgeManager: bridgeManagerP,
zoe,
},
installation: {
Expand All @@ -241,12 +242,15 @@ export const makeClientBanks = async ({
}) => {
const STORAGE_PATH = 'wallet';

const storageNode = await getChildNode(chainStorage, STORAGE_PATH);
const [storageNode, bridgeManager] = await Promise.all([
getChildNode(chainStorage, STORAGE_PATH),
bridgeManagerP,
]);
const { creatorFacet } = await E(zoe).startInstance(
walletFactory,
{},
{ agoricNames, namesByAddress, board },
{ storageNode },
{ storageNode, bridgeManager },
);
return E(client).assignBundle([
address => {
Expand Down
1 change: 1 addition & 0 deletions packages/vats/src/core/manifest.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ const SHARED_CHAIN_BOOTSTRAP_MANIFEST = harden({
namesByAddress: true,
namesByAddressAdmin: true,
bankManager: 'bank',
bridgeManager: true,
board: 'board',
client: true,
chainStorage: true,
Expand Down
2 changes: 1 addition & 1 deletion packages/vats/test/test-clientBundle.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ test('connectFaucet produces payments', async t => {
board: true,
zoe: true,
};
E(client).assignBundle([_a => stub]);
void E(client).assignBundle([_a => stub]);
};

const vatPowers = {
Expand Down
1 change: 1 addition & 0 deletions packages/wallet/contract/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"@agoric/deploy-script-support": "^0.9.0",
"@agoric/store": "^0.7.2",
"@agoric/vat-data": "^0.3.1",
"@agoric/vats": "^0.10.0",
"@agoric/zoe": "^0.24.0",
"@agoric/notifier": "^0.4.0",
"@endo/far": "^0.2.5"
Expand Down
34 changes: 32 additions & 2 deletions packages/wallet/contract/src/walletFactory.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ import '@agoric/zoe/exported.js';

import { makeAtomicProvider } from '@agoric/store/src/stores/store-utils';
import { makeScalarBigMapStore } from '@agoric/vat-data';
import { Far } from '@endo/far';
import * as BRIDGE_ID from '@agoric/vats/src/bridge-ids.js';
import { E, Far } from '@endo/far';
import { makeSmartWallet } from './smartWallet';

/**
Expand All @@ -19,13 +20,22 @@ import { makeSmartWallet } from './smartWallet';
* board: Board,
* namesByAddress: NameHub,
* }} SmartWalletContractTerms
*
* @typedef {{
* type: string, // WALLET_ACTION
* owner: string,
* spendAction: string,
* blockHeight: unknown, // int64
* blockTime: unknown, // int64
* }} WalletAction
*/

/**
*
* @param {ZCF<SmartWalletContractTerms>} zcf
* @param {{
* storageNode?: ERef<StorageNode>,
* bridgeManager?: BridgeManager,
* }} privateArgs
*/
export const start = async (zcf, privateArgs) => {
Expand All @@ -34,12 +44,32 @@ export const start = async (zcf, privateArgs) => {
assert(namesByAddress, 'missing namesByAddress');
assert(agoricNames, 'missing agoricNames');
const zoe = zcf.getZoeService();
const { storageNode } = privateArgs;
const { storageNode, bridgeManager } = privateArgs;

/** @type {MapStore<string, import('./smartWallet').SmartWallet>} */
const walletsByAddress = makeScalarBigMapStore('walletsByAddress');
const provider = makeAtomicProvider(walletsByAddress);

const handleWalletAction = Far('walletActionHandler', {
/**
*
* @param {string} srcID
* @param {WalletAction} obj
*/
fromBridge: async (srcID, obj) => {
console.log('walletFactory.fromBridge:', srcID, obj);
assert(obj, 'missing wallet action');
assert.typeof(obj, 'object');
assert.typeof(obj.owner, 'string');
const wallet = walletsByAddress.get(obj.owner); // or throw
console.log('walletFactory:', { wallet });
return E(wallet).performAction(obj); // TODO: add performAction to lib-wallet.js
},
});

await (bridgeManager &&
E(bridgeManager).register(BRIDGE_ID.WALLET, handleWalletAction));

const shared = {
agoricNames,
board,
Expand Down
21 changes: 21 additions & 0 deletions packages/wallet/ui/demo-signing/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"scripts": {
"build:proto-prep": "mkdir -p proto; cd proto; ln -s ../../../../../golang/cosmos/proto/agoric/swingset .; ln -s ../../../../../golang/cosmos/third_party/proto/gogoproto .; ln -s ../node_modules/protobufjs/google .",
"install:protoc": "sudo apt install protobuf-compiler",
"build:proto": "mkdir -p src/gen && protoc --plugin=node_modules/ts-proto/protoc-gen-ts_proto --ts_proto_opt='esModuleInterop=true,forceLong=long,useOptionals=true' --ts_proto_out=./src/gen ./proto/swingset/msgs.proto -I./proto",
"build:proto-js": "tsc --downlevelIteration --target esnext --allowSyntheticDefaultImports --moduleResolution node ./src/gen/**/*.ts",
"start": "parcel src/keplr-ledger-demo.html"
},
"devDependencies": {
"@keplr-wallet/types": "^0.10.13",
"crypto-browserify": "^3.12.0",
"parcel": "^2.6.2",
"path-browserify": "^1.0.1",
"stream-browserify": "^3.0.0",
"ts-proto": "^1.117.0",
"typescript": "^4.7.4"
},
"dependencies": {
"@cosmjs/stargate": "^0.28.10"
}
}
1 change: 1 addition & 0 deletions packages/wallet/ui/demo-signing/proto/gogoproto
1 change: 1 addition & 0 deletions packages/wallet/ui/demo-signing/proto/google
1 change: 1 addition & 0 deletions packages/wallet/ui/demo-signing/proto/swingset
Loading