Skip to content

Commit

Permalink
feat: instance api with mnemonics
Browse files Browse the repository at this point in the history
  • Loading branch information
shuffledex committed Jan 13, 2021
1 parent b28337f commit 6b380f1
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 5 deletions.
29 changes: 27 additions & 2 deletions src/Polymesh.ts
Expand Up @@ -131,10 +131,20 @@ export class Polymesh {
* @param params.nodeUrl - URL of the Polymesh node this instance will be connecting to
* @param params.signer - injected signer object (optional, only relevant if using a wallet browser extension)
* @param params.middleware - middleware API URL and key (optional, used for historic queries)
* @param params.accountUri - account URI or mnemonic
* @param params.accountUri - account URI
*/
static async connect(params: ConnectParamsBase & { accountUri: string }): Promise<Polymesh>;

/**
* Create the instance and connect to the Polymesh node using an account mnemonic
*
* @param params.nodeUrl - URL of the Polymesh node this instance will be connecting to
* @param params.signer - injected signer object (optional, only relevant if using a wallet browser extension)
* @param params.middleware - middleware API URL and key (optional, used for historic queries)
* @param params.accountMnemonic - account mnemonic
*/
static async connect(params: ConnectParamsBase & { accountMnemonic: string }): Promise<Polymesh>;

/**
* Create the instance and connect to the Polymesh node without an account
*
Expand All @@ -150,10 +160,19 @@ export class Polymesh {
accountSeed?: string;
keyring?: CommonKeyring | UiKeyring;
accountUri?: string;
accountMnemonic?: string;
middleware?: MiddlewareConfig;
}
): Promise<Polymesh> {
const { nodeUrl, accountSeed, keyring, accountUri, signer, middleware } = params;
const {
nodeUrl,
accountSeed,
keyring,
accountUri,
accountMnemonic,
signer,
middleware,
} = params;
let context: Context;

try {
Expand Down Expand Up @@ -227,6 +246,12 @@ export class Polymesh {
middlewareApi,
uri: accountUri,
});
} else if (accountMnemonic) {
context = await Context.create({
polymeshApi,
middlewareApi,
mnemonic: accountMnemonic,
});
} else {
context = await Context.create({
polymeshApi,
Expand Down
18 changes: 18 additions & 0 deletions src/__tests__/Polymesh.ts
Expand Up @@ -148,6 +148,24 @@ describe('Polymesh Class', () => {
});
});

test('should instantiate Context with a mnemonic and return a Polymesh instance', async () => {
const accountMnemonic =
'lorem ipsum dolor sit amet consectetur adipiscing elit nam hendrerit consectetur sagittis';
const createStub = dsMockUtils.getContextCreateStub();

await Polymesh.connect({
nodeUrl: 'wss://some.url',
accountMnemonic,
});

sinon.assert.calledOnce(createStub);
sinon.assert.calledWith(createStub, {
polymeshApi: dsMockUtils.getApiInstance(),
middlewareApi: null,
mnemonic: accountMnemonic,
});
});

test('should instantiate Context with middleware credentials and return a Polymesh instance', async () => {
const accountUri = '//uri';
const createStub = dsMockUtils.getContextCreateStub();
Expand Down
11 changes: 10 additions & 1 deletion src/base/Context.ts
Expand Up @@ -133,6 +133,12 @@ export class Context {
uri: string;
}): Promise<Context>;

static async create(params: {
polymeshApi: ApiPromise;
middlewareApi: ApolloClient<NormalizedCacheObject> | null;
mnemonic: string;
}): Promise<Context>;

static async create(params: {
polymeshApi: ApiPromise;
middlewareApi: ApolloClient<NormalizedCacheObject> | null;
Expand All @@ -147,8 +153,9 @@ export class Context {
seed?: string;
keyring?: CommonKeyring;
uri?: string;
mnemonic?: string;
}): Promise<Context> {
const { polymeshApi, middlewareApi, seed, keyring: passedKeyring, uri } = params;
const { polymeshApi, middlewareApi, seed, keyring: passedKeyring, uri, mnemonic } = params;

let keyring: CommonKeyring = new Keyring({ type: 'sr25519' });
let currentPair: KeyringPair | undefined;
Expand All @@ -168,6 +175,8 @@ export class Context {
currentPair = keyring.addFromSeed(hexToU8a(seed), undefined, 'sr25519');
} else if (uri) {
currentPair = keyring.addFromUri(uri);
} else if (mnemonic) {
currentPair = keyring.addFromMnemonic(mnemonic);
}

if (currentPair) {
Expand Down
22 changes: 22 additions & 0 deletions src/base/__tests__/Context.ts
Expand Up @@ -191,6 +191,28 @@ describe('Context class', () => {
expect(context.currentPair).toEqual(newPair);
});

test('should create a Context object from a mnemonic with Pair attached', async () => {
const newPair = {
address: 'someAddress',
meta: {},
publicKey: 'publicKey',
};
dsMockUtils.configureMocks({
keyringOptions: {
addFromMnemonic: newPair,
},
});

const context = await Context.create({
polymeshApi: dsMockUtils.getApiInstance(),
middlewareApi: dsMockUtils.getMiddlewareApi(),
mnemonic:
'lorem ipsum dolor sit amet consectetur adipiscing elit nam hendrerit consectetur sagittis',
});

expect(context.currentPair).toEqual(newPair);
});

test('should create a Context object without Pair attached', async () => {
const newPair = {
address: 'someAddress',
Expand Down
6 changes: 5 additions & 1 deletion src/testUtils/mocks/dataSources.ts
Expand Up @@ -238,6 +238,7 @@ interface KeyringOptions {
getPairs?: Pair[];
addFromUri?: Pair;
addFromSeed?: Pair;
addFromMnemonic?: Pair;
/**
* @hidden
* Whether keyring functions should throw
Expand Down Expand Up @@ -484,6 +485,7 @@ const defaultKeyringOptions: KeyringOptions = {
getPairs: [{ address: 'address', meta: {}, publicKey: 'publicKey2' }],
addFromSeed: { address: 'address', meta: {}, publicKey: 'publicKey3' },
addFromUri: { address: 'address', meta: {}, publicKey: 'publicKey4' },
addFromMnemonic: { address: 'address', meta: {}, publicKey: 'publicKey4' },
};
let keyringOptions: KeyringOptions = defaultKeyringOptions;

Expand Down Expand Up @@ -684,7 +686,7 @@ function initApi(): void {
* @hidden
*/
function configureKeyring(opts: KeyringOptions): void {
const { error, getPair, getPairs, addFromUri, addFromSeed } = opts;
const { error, getPair, getPairs, addFromUri, addFromSeed, addFromMnemonic } = opts;

const err = new Error('Error');

Expand All @@ -693,13 +695,15 @@ function configureKeyring(opts: KeyringOptions): void {
getPairs: sinon.stub().returns(getPairs),
addFromSeed: sinon.stub().returns(addFromSeed),
addFromUri: sinon.stub().returns(addFromUri),
addFromMnemonic: sinon.stub().returns(addFromMnemonic),
};

if (error) {
keyringInstance.getPair.throws(err);
keyringInstance.getPairs.throws(err);
keyringInstance.addFromSeed.throws(err);
keyringInstance.addFromUri.throws(err);
keyringInstance.addFromMnemonic.throws(err);
}

Object.assign(mockInstanceContainer.keyringInstance, (keyringInstance as unknown) as Keyring);
Expand Down
5 changes: 4 additions & 1 deletion src/types/index.ts
Expand Up @@ -467,7 +467,10 @@ export interface MiddlewareConfig {
key: string;
}

export type CommonKeyring = Pick<Keyring, 'getPair' | 'getPairs' | 'addFromSeed' | 'addFromUri'>;
export type CommonKeyring = Pick<
Keyring,
'getPair' | 'getPairs' | 'addFromSeed' | 'addFromUri' | 'addFromMnemonic'
>;

export interface UiKeyring {
keyring: CommonKeyring;
Expand Down

0 comments on commit 6b380f1

Please sign in to comment.