Skip to content

Commit

Permalink
Refactor Api to be able to sign with an injected signer from en exten…
Browse files Browse the repository at this point in the history
…sions (#110)

* [integriteeWorker] separate sending from signing a trusted call, and prepare passing the signer from the injection

* [integriteeWorker] split getters into creating, signing and sending (internally only for now)

* [integriteeWorker] rename getter methods

* [integriteeWorker] wip introduce submittable getter.

* [integriteeWorker] fix: consistent accountOrPair typing

* [integriteeWorker] fix: await signingPayload in getter

* [integriteeWorker] update mrenclave in tests

* [integriteeWorker] add nonce getter.

* v0.15.0-alpha.0

* fix package import

* v0.15.0-alpha.1

* fix generics

* v0.15.0-alpha.2

* ungenerify submittable getter

* v0.15.0-alpha.3

* Revert "ungenerify submittable getter"

This reverts commit 8001631.

* fix: interfaces can't be used as fields

* v0.15.0-alpha.4

* fix: define interfaces in proper order

* v0.15.0-alpha.5

* [integriteeWorker] add signer arg to getters

* v0.15.0-alpha.6

* [integriteeWorker] fix ordering of trustedCallArgs

* v0.15.0-alpha.7

* [integriteeWorker] don't check for signer === undefined

* [integriteeWorker] fix passing through signer

* [integriteeWorker] also adapt signer options arg

* [integriteeWorker] rename `CallOptions` to `RequestOptions` and introduce `TrustedSignerOptions`

* [integriteeWorker] remove unused import

* [integriteeWorker] remove unused import 2

* v0.15.0-alpha.8

* [integriteeWorker] log encoded trusted getter

* v0.15.0-alpha.9

* [integriteeWorker] skip tests that need a running setup

* fix grammar

* minor cleanup

* log trusted call signed

* v0.15.0-alpha.10

* allow passing the nonce in the signer options

* v0.15.0-y.0

* v0.15.0-0.15.0-alpha.10.0

* v0.15.0-alpha.10

* v0.15.0-alpha.11

* remove extra logs
  • Loading branch information
clangenb authored Oct 4, 2024
1 parent fb3b340 commit 26e9653
Show file tree
Hide file tree
Showing 15 changed files with 299 additions and 116 deletions.
2 changes: 1 addition & 1 deletion lerna.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@
"publishConfig": {
"directory": "build"
},
"version": "0.14.2"
"version": "0.15.0-alpha.11"
}
4 changes: 2 additions & 2 deletions packages/node-api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@
},
"sideEffects": false,
"type": "module",
"version": "0.14.2",
"version": "0.15.0-alpha.11",
"main": "index.js",
"dependencies": {
"@encointer/types": "^0.14.2",
"@encointer/types": "^0.15.0-alpha.11",
"@polkadot/api": "^11.2.1",
"tslib": "^2.6.2"
},
Expand Down
2 changes: 1 addition & 1 deletion packages/types/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
},
"sideEffects": false,
"type": "module",
"version": "0.14.2",
"version": "0.15.0-alpha.11",
"main": "index.js",
"scripts": {
"generate:defs": "node --experimental-specifier-resolution=node --loader ts-node/esm ../../node_modules/.bin/polkadot-types-from-defs --package @encointer/types/interfaces --input ./src/interfaces",
Expand Down
2 changes: 1 addition & 1 deletion packages/util/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"sideEffects": false,
"type": "module",
"types": "./index.d.ts",
"version": "0.14.2",
"version": "0.15.0-alpha.11",
"main": "index.js",
"dependencies": {
"@babel/runtime": "^7.18.9",
Expand Down
38 changes: 38 additions & 0 deletions packages/util/src/common.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import type { KeyringPair } from "@polkadot/keyring/types";
import { Keyring } from "@polkadot/keyring";
import BN from "bn.js";
import type {AddressOrPair} from "@polkadot/api-base/types/submittable";
import type {IKeyringPair, Signer} from "@polkadot/types/types";
import {hexToU8a, isFunction, u8aToHex} from "@polkadot/util";
import type {AccountId, Address} from "@polkadot/types/interfaces/runtime";

// interface assertLengthFunc {
// (upper: number, lower: number): number
Expand Down Expand Up @@ -44,6 +48,40 @@ export const unlockKeypair = (pair: PubKeyPinPair, keyring: Keyring): KeyringPai
return keyPair;
}

/**
* Slightly different from polkadot-js' approach, but we want to handle the same interface like they
* do.
* @param account
* @param payload
* @param signer
*/
export async function signPayload(account: AddressOrPair, payload: Uint8Array, signer?: Signer): Promise<Uint8Array> {
if (isKeyringPair(account)) {
return account.sign(payload);
}

// console.log(`signer: ${JSON.stringify(signer)}`)

if (signer === undefined) {
throw new Error('Invalid signer, either pass a Pair as account or a Signer.');
}

if (isFunction(signer.signRaw)) {
const address = asString(account);
const result = await signer.signRaw({address, type: "bytes", data: u8aToHex(payload) });
return hexToU8a(result.signature);
} else {
throw new Error('Invalid signer interface, `signRaw` has to be defined.');
}
}

export function asString(addressOrPair: AddressOrPair): string {
return isKeyringPair(addressOrPair) ? addressOrPair.address : addressOrPair.toString();
}

export function isKeyringPair (account: string | IKeyringPair | AccountId | Address): account is IKeyringPair {
return isFunction((account as IKeyringPair).sign);
}

/**
* Our fixed point integer values go until I64, which means that it may be > 53 bits.
Expand Down
8 changes: 4 additions & 4 deletions packages/worker-api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@
"sideEffects": false,
"type": "module",
"types": "./index.d.ts",
"version": "0.14.2",
"version": "0.15.0-alpha.11",
"main": "index.js",
"dependencies": {
"@encointer/node-api": "^0.14.2",
"@encointer/types": "^0.14.2",
"@encointer/util": "^0.14.2",
"@encointer/node-api": "^0.15.0-alpha.11",
"@encointer/types": "^0.15.0-alpha.11",
"@encointer/util": "^0.15.0-alpha.11",
"@peculiar/webcrypto": "^1.4.6",
"@polkadot/api": "^11.2.1",
"@polkadot/keyring": "^12.6.2",
Expand Down
28 changes: 14 additions & 14 deletions packages/worker-api/src/encointerWorker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import type {
Attestation,
} from '@encointer/types';

import {type CallOptions, Request} from './interface.js';
import {type RequestOptions, Request} from './interface.js';
import {callGetter} from './sendRequest.js';
import {PubKeyPinPair, toAccount} from "@encointer/util/common";
import type {KeyringPair} from "@polkadot/keyring/types";
Expand All @@ -24,70 +24,70 @@ export class EncointerWorker extends Worker {
return communityIdentifierFromString(this.registry(), cidStr);
}

public async getNonce(accountOrPubKey: KeyringPair | PubKeyPinPair, cid: string, options: CallOptions = {} as CallOptions): Promise<u32> {
public async getNonce(accountOrPubKey: KeyringPair | PubKeyPinPair, cid: string, options: RequestOptions = {} as RequestOptions): Promise<u32> {
return await callGetter<u32>(this, [Request.TrustedGetter, 'nonce', 'u32'], {
shard: cid,
account: toAccount(accountOrPubKey, this.keyring())
}, options)
}

public async getTotalIssuance(cid: string, options: CallOptions = {} as CallOptions): Promise<Balance> {
public async getTotalIssuance(cid: string, options: RequestOptions = {} as RequestOptions): Promise<Balance> {
return await callGetter<Balance>(this, [Request.PublicGetter, 'total_issuance', 'Balance'], {cid}, options)
}

public async getParticipantCount(cid: string, options: CallOptions = {} as CallOptions): Promise<number> {
public async getParticipantCount(cid: string, options: RequestOptions = {} as RequestOptions): Promise<number> {
return (await callGetter<u64>(this, [Request.PublicGetter, 'participant_count', 'u64'], {cid}, options)).toNumber()
}

public async getMeetupCount(cid: string, options: CallOptions = {} as CallOptions): Promise<number> {
public async getMeetupCount(cid: string, options: RequestOptions = {} as RequestOptions): Promise<number> {
return (await callGetter<u64>(this, [Request.PublicGetter, 'meetup_count', 'u64'], {cid}, options)).toNumber()
}

public async getCeremonyReward(cid: string, options: CallOptions = {} as CallOptions): Promise<number> {
public async getCeremonyReward(cid: string, options: RequestOptions = {} as RequestOptions): Promise<number> {
return await callGetter<number>(this, [Request.PublicGetter, 'ceremony_reward', 'I64F64'], {cid}, options)
}

public async getLocationTolerance(cid: string, options: CallOptions = {} as CallOptions): Promise<number> {
public async getLocationTolerance(cid: string, options: RequestOptions = {} as RequestOptions): Promise<number> {
return (await callGetter<u32>(this, [Request.PublicGetter, 'location_tolerance', 'u32'], {cid}, options)).toNumber()
}

public async getTimeTolerance(cid: string, options: CallOptions = {} as CallOptions): Promise<Moment> {
public async getTimeTolerance(cid: string, options: RequestOptions = {} as RequestOptions): Promise<Moment> {
return await callGetter<Moment>(this, [Request.PublicGetter, 'time_tolerance', 'Moment'], {cid}, options)
}

public async getSchedulerState(cid: string, options: CallOptions = {} as CallOptions): Promise<SchedulerState> {
public async getSchedulerState(cid: string, options: RequestOptions = {} as RequestOptions): Promise<SchedulerState> {
return await callGetter<SchedulerState>(this, [Request.PublicGetter, 'scheduler_state', 'SchedulerState'], {cid}, options)
}

public async getBalance(accountOrPubKey: KeyringPair | PubKeyPinPair, cid: string, options: CallOptions = {} as CallOptions): Promise<Balance> {
public async getBalance(accountOrPubKey: KeyringPair | PubKeyPinPair, cid: string, options: RequestOptions = {} as RequestOptions): Promise<Balance> {
return await callGetter<Balance>(this, [Request.TrustedGetter, 'free_balance', 'Balance'], {
shard: cid,
account: toAccount(accountOrPubKey,this.keyring())
}, options)
}

public async getParticipantIndex(accountOrPubKey: KeyringPair | PubKeyPinPair, cid: string, options: CallOptions = {} as CallOptions): Promise<ParticipantIndexType> {
public async getParticipantIndex(accountOrPubKey: KeyringPair | PubKeyPinPair, cid: string, options: RequestOptions = {} as RequestOptions): Promise<ParticipantIndexType> {
return await callGetter<ParticipantIndexType>(this, [Request.TrustedGetter, 'participant_index', 'ParticipantIndexType'], {
cid,
account: toAccount(accountOrPubKey,this.keyring())
}, options)
}

public async getMeetupIndex(accountOrPubKey: KeyringPair | PubKeyPinPair, cid: string, options: CallOptions = {} as CallOptions): Promise<MeetupIndexType> {
public async getMeetupIndex(accountOrPubKey: KeyringPair | PubKeyPinPair, cid: string, options: RequestOptions = {} as RequestOptions): Promise<MeetupIndexType> {
return await callGetter<MeetupIndexType>(this, [Request.TrustedGetter, 'meetup_index', 'MeetupIndexType'], {
cid,
account: toAccount(accountOrPubKey,this.keyring())
}, options)
}

public async getAttestations(accountOrPubKey: KeyringPair | PubKeyPinPair, cid: string, options: CallOptions = {} as CallOptions): Promise<Vec<Attestation>> {
public async getAttestations(accountOrPubKey: KeyringPair | PubKeyPinPair, cid: string, options: RequestOptions = {} as RequestOptions): Promise<Vec<Attestation>> {
return await callGetter<Vec<Attestation>>(this, [Request.TrustedGetter, 'attestations', 'Vec<Attestation>'], {
cid,
account: toAccount(accountOrPubKey,this.keyring())
}, options)
}

public async getMeetupRegistry(accountOrPubKey: KeyringPair | PubKeyPinPair, cid: string, options: CallOptions = {} as CallOptions): Promise<Vec<AccountId>> {
public async getMeetupRegistry(accountOrPubKey: KeyringPair | PubKeyPinPair, cid: string, options: RequestOptions = {} as RequestOptions): Promise<Vec<AccountId>> {
return await callGetter<Vec<AccountId>>(this, [Request.TrustedGetter, 'meetup_registry', 'Vec<AccountId>'], {
cid,
account: toAccount(accountOrPubKey, this.keyring())
Expand Down
24 changes: 22 additions & 2 deletions packages/worker-api/src/integriteeWorker.spec.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { Keyring } from '@polkadot/api';
import { cryptoWaitReady } from '@polkadot/util-crypto';
import { localDockerNetwork } from './testUtils/networks.js';
import { paseoNetwork} from './testUtils/networks.js';
import { IntegriteeWorker } from './integriteeWorker.js';
import WS from 'websocket';
import {type KeyringPair} from "@polkadot/keyring/types";

const {w3cwebsocket: WebSocket} = WS;

describe('worker', () => {
const network = localDockerNetwork();
const network = paseoNetwork();
let keyring: Keyring;
let worker: IntegriteeWorker;
let alice: KeyringPair;
Expand Down Expand Up @@ -64,6 +64,16 @@ describe('worker', () => {
});
});

describe('getBalanceGetter', () => {
it('should return value', async () => {
const getter = await worker.getBalanceGetter(charlie, network.mrenclave);
console.log(`BalanceGetter: ${JSON.stringify(getter)}`);
const result = await getter.send();
console.log('getBalance toNumber:', result.toString(10));
expect(result).toBeDefined();
});
});

describe('getNonce', () => {
it('should return value', async () => {
const result = await worker.getNonce(alice, network.mrenclave);
Expand All @@ -72,6 +82,16 @@ describe('worker', () => {
});
});

describe('getNonceGetter', () => {
it('should return value', async () => {
const getter = await worker.getNonceGetter(charlie, network.mrenclave);
console.log(`NonceGetter: ${JSON.stringify(getter)}`);
const result = await getter.send();
console.log('getNonce', result);
expect(result).toBeDefined();
});
});

describe('balance transfer should work', () => {
it('should return value', async () => {
const shard = network.chosenCid;
Expand Down
Loading

0 comments on commit 26e9653

Please sign in to comment.