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

Agoric offer signer endo maker #64

Closed
wants to merge 62 commits into from
Closed

Agoric offer signer endo maker #64

wants to merge 62 commits into from

Conversation

dckc
Copy link
Owner

@dckc dckc commented Nov 19, 2023

See also:


  • tx client with signAndBroadcast and a short-cut for sendTokens
    • factor out cosmosFecth network worker with makeRPCClient, makeLCDClient
      • test: recorded network activity should be at LCD/RPC layer, not fetch
  • smartWalletKit with tx, query
  • take the HdWallet, not the mnemonic, as an arg to smartWallet
    • keep the mnemonic in one worker and network access in another.
      • needs CopyBytes
  • signAndSubmit integration testing
  • move out of fincaps package?
  • move out of finquick repo?
  • clean up tests
  • or maybe having the signer know about keychain items is a bad idea... just use E(signerFactory).fromMnemonic(await keychainItem.get())

@dckc
Copy link
Owner Author

dckc commented Nov 19, 2023

SES_EVAL_REJECTED in protobufjs

tried testing...

fincaps$ endo make src/hdWallet.js -n w1
CapTP cli exception: (RemoteSyntaxError(error:captp:Endo#20001)#1)
RemoteSyntaxError(error:captp:Endo#20001)#1: Possible direct eval expression rejected at <unknown>:12. (SES_EVAL_REJECTED)

  at decodeErrorCommon (packages/marshal/src/marshal.js:281:28)
  at decodeErrorFromCapData (packages/marshal/src/marshal.js:297:14)
  at decodeFromCapData (packages/marshal/src/encodeToCapData.js:404:27)
  at fromCapData (packages/marshal/src/marshal.js:359:23)
  at CTP_RETURN (packages/captp/src/captp.js:697:24)
  at dispatch (packages/captp/src/captp.js:776:7)
  at packages/daemon/src/connection.js:34:7
  

worker log is not much help:

Endo worker started on pid 167205
Temporary logging of sent error (SyntaxError#1)
SyntaxError#1: Possible direct eval expression rejected at <unknown>:12. (SES_EVAL_REJECTED)

  at rejectSomeDirectEvalExpressions (packages/ses/src/transforms.js:222:9)
  at applyTransforms (packages/ses/src/transforms.js:252:14)
  at safeEvaluate (packages/ses/src/make-safe-evaluator.js:65:14)

so I used the b2zip.sh idiom:

#!/bin/sh
bundle=$1
zip=$2
jq -r .endoZipBase64 b.json| base64 -d > $2

And I found eval in @protobufjs/inquire-v1.1.0/index.js

and then jq -r .source @protobufjs/inquire-v1.1.0/index.js|less -N
to see... sure enough...

   12         var mod = eval("quire".replace(/^/,"re"))(moduleName); // eslint-disable-line no-eval

@dckc dckc force-pushed the ag-offer-sign branch 2 times, most recently from a4de447 to 4db7401 Compare November 19, 2023 22:40
@dckc
Copy link
Owner Author

dckc commented Nov 19, 2023

signing client can sendTokens

check balance before:

~/projects/gimix$ yarn docker:make balance-q
$ docker-compose exec agd make -C /workspace balance-q
agd query bank balances agoric1a3zu5aqw255q0tuxzy9aftvgheekw2wedz3xwq
balances:
- amount: "329930000"
  denom: ubld

send tokens using endo:

finquick/packages/fincaps$ make send-tokens
++ Send tokens
endo eval "E(client).sendTokens(\
  'agoric14pfrxg63jn6ha0cp6wxkm4nlvswtscrh2pymwm', \
  'agoric1a3zu5aqw255q0tuxzy9aftvgheekw2wedz3xwq', \
  [{ denom: 'ubld', amount: '12345' }], 'auto').then( \
  tx => tx.code === 0 ? tx.transactionHash : assert.fail(tx.rawLog))" client:validator-client
EABABE9AEF40D07E8185C3E608DE29F9CFECA0B653772FFFC01D299C5FA61EBA

balance after:

~/projects/gimix$ yarn docker:make balance-q
...
balances:
- amount: "329942345"
  denom: ubld

2023-11-19 16:39 4db7401 docs: send-tokens with endo (Makefile target)
2023-11-19 14:25 9e87d73 test: regen fixture
2023-11-19 14:25 ed07d38 test: replay fetch() utility
2023-11-19 14:25 6f3c7e4 feat: RpcClient using explicit access to the network
2023-11-19 09:45 a353b1a feat: smartWallet endo component
2023-11-19 08:39 0130695 feat: hdWallet endo plugin / module
2023-11-18 21:50 6ebc1e1 feat: offerSigner endo plug-in
2023-11-18 21:50 213e21f lock packages with cosmjs
2023-11-18 21:50 f0b8cd9 build(fincaps): cosmjs, @agoric/cosmic-proto

@dckc
Copy link
Owner Author

dckc commented Nov 20, 2023

endo smartWallet plugin can query vstorage, execute offers

This endo plug-in has the essential features of a client in the Smart Wallet Dapp Architecture. It can

  • query the chain to look up things like brands and contract instances
  • sign and broadcast offers
    • track offers until they complete
~/projects/finquick/packages/fincaps$ make reserve-add
++ look up IST in user1 marshal context
endo eval "E(kit.query).lookup('agoricNames', 'brand', 'IST')" -n u1-ist kit:user1-kit
Object [Alleged: IST brand] {}
++ Add to reserve
endo eval "E(reserve).addToReserve(kit.smartWallet, \
  { brand, value: 7_000_000n }, 'add2')" \
  reserve:reserve-tool kit:user1-kit brand:u1-ist
{
  status: {
    id: 'add2',
    invitationSpec: {
      callPipe: [Array],
      instancePath: [Array],
      source: 'agoricContract'
    },
    numWantsSatisfied: 1,
    payouts: { Collateral: [Object] },
    proposal: { give: [Object] },
    result: 'added Collateral to the Reserve'
  },
  tx: {
    height: 270595,
    transactionHash: '4789F93D1BC8262AE8DFB598923BF1267EFED05F287328EC78C888A6EB49EA5C'
  }
}

2023-11-20 01:04 568c38d docs: reserve-add demo using smartWallet.js

@0xpatrickdev
Copy link

#64 (comment)

How were you able to get around this?

*/
const getJSON = (href, options = {}) => {
const opts = {
keepalive: true,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does LCD stand for?

Also, curious why you are choosing to use keepalive? My MDN search is not providing helpful clues for this context

The keepalive option can be used to allow the request to outlive the page. Fetch with the keepalive flag is a replacement for the Navigator.sendBeacon() API.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LCD = Light client daemon

I copied keepAlive from something else... IOU some git spelunking.


for await (const record of history) {
// TODO: mustMatch(record, OfferStatusShape)
if (record.updated === 'offerStatus' && record.status.id === id) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a really helpful pattern

};

/** @param {import('./secret-tool').PassKey} item */
const fromPassKey = async item => {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is PassKey? It seems like secret-tool.js wasn't checked in.... Does this read from a YubiKey? Or does secret-tool just get a secret from process.env?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's there: secret-tool.js

It lets you access the FreeDesktop Secret Sevice, analogous to keychain.

from the package readme:

Plugins with POLA: Google Sheets, Desktop Secrets, sqlite3

Each of these plugins provdes POLA-shaped access:

  • ...
  • secret-tool.js - SecretTool.makePasskey(attrs1)
    makes a PassKey. From there, E(p).subKey(attrs2)
    attenuates access to items with { ...attrs2, ...attrs1 }.

@0xpatrickdev
Copy link

Finally got around to reading this, looks awesome! I would like to port this to gimix, but am not sure I understand how we can preserve all of the security properties created here in the REST api context.

Some questions (from a novice endo-er):

  1. does everything need a compartment? Or just the privileged resources
    a. should the fastify instance (makeApp) go in its own compartment?
    b. should different fastify “route groups” go in different compartments?
    i.e., oracelAccept, sendJobReport, and ghOauth require different powers

  2. where do we grant powers?
    a. is there one entry point, or should we make multiple entry points? (In current gimix, there’s just one entry point and one resource (fastify app) created)
    b. would the fastify app ever call the steps to load a wallet / signer, or would we just give it a pointer to a highly scoped (yet powerful) function like signAndSubmitJobOfferReport

@dckc
Copy link
Owner Author

dckc commented Nov 22, 2023

How were you able to get around [SES_EVAL_REJECTED in protobufjs]?

with --UNSAFE :-/

The protobuf code is fundamentally just moving bits around in memory; it has no need for I/O etc. It's a perfect candidate to run fully confined. But it looks like it might do a direct eval, so I'm running it un-confined, with all the ambient authority of normal node code.

@kumavis
Copy link

kumavis commented Nov 29, 2023

@dckc
Copy link
Owner Author

dckc commented Mar 17, 2024

@dckc dckc closed this Mar 17, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants