[WIP] - ZeroTrust Accounts will provide a decentralized, secure, and self-sovereign approach to Ethereum smart contract accounts. <br> Repos: zerotrust-accounts: https://github.com/ZeroTrustOrg/zerotrust-accounts SDK : https://github.com/ZeroTrustOrg/sdk/tree/master/packages/accounts zerotrust-starter-kit: https://github.com/ZeroTrustOrg/zerotrust-starter-kit Focusing on these goals: 1. Non-custodial signer like passkey or other self-sovereign signer [Done] 2. Server-free information access: Eliminate the need for any server hosting of information associated with the account or the signer, ensuring a decentralized and trustless environment to access the account. 3. Inbuilt or modular session key plugin/feature using zero-knowledge proofs 4. Decentralized recovery options: Enable decentralized recovery mechanisms to regain account access without relying on centralized entities or services.
This repository allows users to use SimplePasskeyAccount, a smart contract account where Passkey is a signer for submitting ERC4337 UserOperations.
Smart contracts for accounts zerotrust-accounts
The sample react application using this repo zerotrust-starter-kit
To get started with using SimplePasskeyAccount, follow these steps:
This repository has two peer dependencies: permissionless
and viem
.
npm install @zero-trust-org/accounts permissionless@0.0.17 view@1.21.0
When creating a new Passkey, it is important to save the publicKey and credential ID as they are only extractable at creation time.
import { Passkey } from "@zero-trust-org/accounts";
const passkeyCreateCredentialResponse = await Passkey.create({
appName: 'MyTestDapp',
displayName: 'TestUser',
name: 'TestUser',
yubikeyOnly: false,
});
This will return an object of type PasskeyCreateCredentialResponse
containing the publicKeyCredential
and authenticatorAttestationResponse
{
publicKeyCredential: PublicKeyCredential ;
authenticatorAttestationResponse: AuthenticatorAttestationResponse;
}
You can extract the credentialId
and publicKey
of Passkey from this response.
const credentialId = passkeyCreateCredentialResponse.publicKeyCredential.id;
const publicKey = authenticatorAttestationResponse.getPublicKey();
Once you have the credentialId
and publicKey
of the Passkey, you can create an instance of SimplePasskeyAccount using passkeyToSimplePasskeyAccount
import { PasskeyToSimplePasskeyAccountParameters, SimplePasskeyAccount, passkeyToSimplePasskeyAccount } from "@zero-trust-org/accounts";
const passkeyToSimplePasskeyAccountParameters: PasskeyToSimplePasskeyAccountParameters = {
credentialId: credentialId,
publicKey: publicKey,
entryPoint: entryPointAddress,
factoryAddress: accountFactoryAddress,
index: 0,
};
const simplePasskeyAccount:SimplePasskeyAccount = await passkeyToSimplePasskeyAccount(
publicClient,
passkeyToSimplePasskeyAccountParameters,
);
The SimplePasskeyAccount instance exposes properties and methods such as signing user operations via Passkey, encoding calldata, getting the account's nonce, and getting the init code of the account.
const senderAddress = simplePasskeyAccount.address;
const nonce = await simplePasskeyAccount.getNonce();
const initCode = await simplePasskeyAccount.getInitCode();
const sendEthCalldata = await simplePasskeyAccount.encodeCallData({
to,
value,
data
});
const userOperation: UserOperation= {
callData: sendEthCalldata,
initCode: nonce === BigInt(0) ? initCode : '0x',
sender: senderAddress,
nonce: nonce,
maxFeePerGas: BigInt(2000000),
maxPriorityFeePerGas: BigInt(2000000),
callGasLimit: BigInt(2000000),
preVerificationGas: BigInt(2000000),
verificationGasLimit: BigInt(2000000),
paymasterAndData:'0x',
signature: await simplePasskeyAccount.getDummySignature()
};
const signature = await simplePasskeyAccount.signUserOperation(userOperation);
Feel free to use these steps to integrate SimplePasskeyAccount into your project.