Skip to content

Commit

Permalink
feat: function to create self-delegated app-side signers
Browse files Browse the repository at this point in the history
This means, they already include the self-delegation authorization from the encryptor
  • Loading branch information
cygnusv committed Nov 7, 2024
1 parent 409aa5e commit fa6633c
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 2 deletions.
35 changes: 34 additions & 1 deletion packages/taco-auth/src/providers/encryptor/self-delegate.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,53 @@
import { ethers } from 'ethers';
import { ethers, Wallet } from 'ethers';
import { z } from 'zod';

// import { Bytes } from "@ethersproject/bytes";

import { AuthSignature } from '../../auth-sig';
import { LocalStorage } from '../../storage';

export const ENCRYPTOR_SELF_DELEGATE_AUTH_METHOD = 'EncryptorSelfDelegate'

export const SelfDelegateTypedDataSchema = z.string();


// TODO: Create generic EncryptorSigner class/interface, which can be
// instantiated with ethers' Signers and Wallets, but also with our custom
// classes
export class DelegatedSigner extends Wallet { // TODO: extend from generic Signer

authSignature?: AuthSignature;

async authenticate(selfDelegateProvider: SelfDelegateProvider){
const appSideSignerAddress = await this.getAddress();
this.authSignature = await selfDelegateProvider.getOrCreateAuthSignature(appSideSignerAddress);
}

override async signMessage(message: any): Promise<string> { // TODO: Restrict input type to Bytes | string
if (typeof this.authSignature === 'undefined'){
throw new Error('Encryptor must authenticate app signer first');
}
const appSignature = await super.signMessage(message);
return appSignature.concat(this.authSignature.signature)
}
}


export class SelfDelegateProvider {
private readonly storage: LocalStorage;

constructor(private readonly signer: ethers.Signer) {
this.storage = new LocalStorage();
}

public async createSelfDelegatedAppSideSigner(
ephemeralPrivateKey: any // TODO: Find a stricter type
): Promise<DelegatedSigner> {
const appSideSigner = new DelegatedSigner(ephemeralPrivateKey);
await appSideSigner.authenticate(this);
return appSideSigner;
}

public async getOrCreateAuthSignature(
ephemeralPublicKeyOrAddress: string
): Promise<AuthSignature> {
Expand Down
9 changes: 8 additions & 1 deletion packages/taco-auth/test/auth-provider.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,11 +140,18 @@ describe('encryptor self-delegate provider authorization', () => {
const provider = fakeProvider(bobSecretKeyBytes);
const signer = provider.getSigner();
const selfDelegateProvider = new SelfDelegateProvider(signer);

it('creates a new self-delegated app signer', async () => {
const appSideSignerAddress = await applicationSideSigner.getAddress();
const [newSigner, newAuthSignature] = await selfDelegateProvider.createSelfDelegatedAppSideSigner(aliceSecretKeyBytes);
expect(await newSigner.getAddress()).toEqual(appSideSignerAddress);
expect(newAuthSignature.typedData).toEqual(appSideSignerAddress);
});

const applicationSideProvider = fakeProvider(aliceSecretKeyBytes);
const applicationSideSigner = applicationSideProvider.getSigner();

it('creates a new message', async () => {
it('creates a new auth signature', async () => {
const appSideSignerAddress = await applicationSideSigner.getAddress();
const typedSignature = await selfDelegateProvider.getOrCreateAuthSignature(appSideSignerAddress);
expect(typedSignature.signature).toBeDefined();
Expand Down

0 comments on commit fa6633c

Please sign in to comment.