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

feat: viem account from gcp hsm #2

Merged
merged 13 commits into from
Apr 19, 2024
Merged

Conversation

jeanregisser
Copy link
Member

Full working implementation with support for signing transactions, messages and typed data.

Ported from https://github.com/celo-org/developer-tooling/tree/0c61e7e02c741fe10ecd1d733a33692d324cdc82/packages/sdk/wallets/wallet-hsm-gcp

Send script run

❯ GCLOUD_PROJECT=valora-viem-hsm-test yarn ts-node ./scripts/send.ts
yarn run v1.22.21
$ /Users/jean/src/github.com/valora-inc/viem-account-hsm-gcp/node_modules/.bin/ts-node ./scripts/send.ts
Viem HSM Account: 0x6AD01Ac6841b67f27DC1A039FefBF5804003d6a4
Balance: 0.997207 CELO
Sending 0.001 CELO from Viem HSM Account...
Waiting for transaction hash: 0x834f5cfc42ddfe293ec81d5e154c1fac37cf3e5772a6d322e2d99c1b6e503e50
TX status: success
✨  Done in 12.94s.

Next up: add e2e test for CI, README, automated publish to NPM

Fixes RET-1037

src/index.ts Outdated
*
* https://www.ssl.com/guide/pem-der-crt-and-cer-x-509-encodings-and-conversions/#:~:text=DER%20(Distinguished%20Encoding%20Rules)%20is,commonly%20seen%20in%20Java%20contexts.
*/
function pemToDerEncode(pem: string): string {
Copy link

Choose a reason for hiding this comment

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

So, the KMS client returns the typical human-readable (PEM) public key that we're used to dealing with - this function removes the begin/end statements and trims whitespace, resulting in the base64 representation of the DER format key (the only difference between PEM and DER are presumably the comments present in PEM files). Taking a buffer of the base64 DER key presumably gives you the "canonical" (read: binary) representation of DER keys.

By my understanding, ASN.1 refers to the abstract syntax tree of the underlying data, not its encoding scheme (both PEM and DER are encodings of ASN.1 data, I believe; this article helped clarify). Given that, the name of the function publicKeyFromAsn1 is a bit confusing, since what's really important is the encoding scheme used for the input argument, which in this case is the binary DER encoding. I can't tell from publicKeyFromAsn1 whether the input should be PEM, binary DER, or b64 encoded. Maybe publicKeyFromDer might be more useful?

Copy link
Member Author

Choose a reason for hiding this comment

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

oh I see, I didn't put much thought to this as this was the name used in the implementation I ported.
Renaming now, makes more sense, thanks.

src/index.ts Outdated
return pem.split('\n').slice(1, -2).join('').trim()
}

function publicKeyFromAsn1(bytes: Uint8Array): Hex {
Copy link

Choose a reason for hiding this comment

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

What format exactly is this resulting public key?

Copy link

Choose a reason for hiding this comment

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

Ah, okay - this is ECDSA public key (just a long hex string), and the eth address is just the hash of the first chunk of it?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes that's right.

const signableTransaction = (() => {
// For EIP-4844 Transactions, we want to sign the transaction payload body (tx_payload_body) without the sidecars (ie. without the network wrapper).
// See: https://github.com/ethereum/EIPs/blob/e00f4daa66bd56e2dbd5f1d36d09fd613811a48b/EIPS/eip-4844.md#networking
if (transaction.type === 'eip4844')
Copy link

Choose a reason for hiding this comment

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

i can't say i fully understand this, but makes me wonder if there are other transaction types that we need to care about/do special stuff for here? if someone tries to use this for some new TX type from some new EIP down the line that requires special treatment, it seems like this wouldn't necessarily work? i guess there's not much to do about that besides allow-listing a subset of transaction types, but that definitely seems like overkill.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes me neither, it's a bit odd it's at this level.
I copied what was done in viem: https://github.com/wevm/viem/blob/e6c47807f32d14ded53c40831177ee80c5a47a10/src/accounts/utils/signTransaction.ts
It feels like this should be put somewhere else in viem so each custom Account implementation doesn't have to deal with this.
I'll give this feedback to the viem authors.

Copy link

@bakoushin bakoushin left a comment

Choose a reason for hiding this comment

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

🚀 Amazing!

I like how compact it actually is!

@jeanregisser
Copy link
Member Author

I like how compact it actually is!

Yes same, it looks small and simple.

@jeanregisser jeanregisser enabled auto-merge (squash) April 19, 2024 09:27
@jeanregisser jeanregisser merged commit 951d233 into main Apr 19, 2024
5 checks passed
@jeanregisser jeanregisser deleted the jeanregisser/viem-hsm-gcp branch April 19, 2024 09:27
Copy link

🎉 This PR is included in version 1.0.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants