o1-labs / o1js

TypeScript framework for zk-SNARKs and zkApps

Home Page:https://docs.minaprotocol.com/en/zkapps/how-to-write-a-zkapp

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

track required signers within type system

harrysolovay opened this issue · comments

Could we track specific PublicKeys / AccountUpdates within the type system and use this type information to provide errors when required PrivateKeys are not supplied to sign?

Instead defining methods like so:

@method
async setAdmin() {
  const admin = this.admin.getAndRequireEquals()
  AccountUpdate.createSigned(admin)
  this.admin.set(admin)
}

We could use generators and yield account update statements. This way, the signature of setAdmin contains types returned from the createSigned call.

@method
*setAdmin() {
  const admin = this.admin.getAndRequireEquals()
  yield AccountUpdate.createSigned(admin)
  this.admin.set(admin)
}

We'd need a unique symbol with which to later specify the key of admin. I would imagine that one would attach this symbol to the given PublicKey type.

const adminKey = Symbol()

//

class MyContract {
  @state(PublicKey) admin = state<PublicKey<typeof adminKey>>()

  // ...
}

Finally, one would sign with a record like so.

tx.sign({
  [adminKey]: admin.privateKey
})

Note: devs could tag their PublicKeys with any keyof any.

If the dev forgets to include the given private key...

Argument of type '{}' is not assignable to parameter of type '{ [adminKey]: PrivateKey; }'.
  Property '[adminKey]' is missing in type '{}' but required in type '{ [adminKey]: PrivateKey; }'.ts(2345)

One noteworthy caveat, nested method calls would need to be yield*ed.

@method
*a() {
  // ...
}

@method
*b() {
  const aResult = yield* this.a()
}

As I reflect on this issue, I feel less and less confident that this would be a usability gain. The narrower typing of sign likely isn't worth scaring off generator-opposed devs, nor the internal refactoring that would need to take place. Also, signing will likely be handled in other envs such as wallets. Still going to submit this issue, incase it's thought provoking. Please feel free to close immediately :)