Add signAsync to SubmittableExtrinsic (#1626)

This commit is contained in:
Caio
2019-12-03 14:58:18 +01:00
committed by Jaco Greeff
parent 74cf8aa30c
commit 46efc10939
3 changed files with 39 additions and 9 deletions
+12
View File
@@ -78,4 +78,16 @@ describe('ApiPromise', (): void => {
).toEqual(SIG);
});
});
describe('decorator.signAsync', (): void => {
it('signs a transfer using an external signer', async (): Promise<void> => {
const api = await ApiPromise.create({ provider, registry });
api.setSigner(new SingleAccountSigner(registry, keyring.alice_session));
const transfer = api.tx.balances.transfer(keyring.eve.address, 12345);
const dummySignature = '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000';
expect(transfer.signature.toHex()).toEqual(dummySignature);
await transfer.signAsync(keyring.alice_session, {});
expect(transfer.signature.toHex()).not.toEqual(dummySignature);
});
});
});
+25 -9
View File
@@ -49,15 +49,23 @@ export default function createClass <ApiType extends ApiTypes> ({ api, apiType,
this._ignoreStatusCb = apiType === 'rxjs';
}
// sign a transaction, returning the this to allow cianing, i.e. .sign(...).send()
// sign a transaction, returning the this to allow chaining, i.e. .sign(...).send()
public sign (account: IKeyringPair, optionsOrNonce: Partial<SignerOptions>): this {
// NOTE here we actually override nonce if it was specified (backwards compat for
// the previous signature - don't let userspace break, but allow then time to upgrade)
const options: Partial<SignerOptions> = isBn(optionsOrNonce) || isNumber(optionsOrNonce)
? { nonce: optionsOrNonce }
: optionsOrNonce;
super.sign(account, this._makeSignOptions(this._optionsOrNonce(optionsOrNonce), {}));
super.sign(account, this._makeSignOptions(options, {}));
return this;
}
// signs a transaction, returning `this` to allow chaining. E.g.: `sign(...).send()`
//
// also supports signing through external signers
public async signAsync (account: IKeyringPair, optionsOrNonce: Partial<SignerOptions>): Promise<this> {
if (this._api.signer) {
const options = this._makeSignOptions(this._optionsOrNonce(optionsOrNonce), {});
await this._signViaSigner(account.address, options, null);
} else {
this.sign(account, optionsOrNonce);
}
return this;
}
@@ -129,13 +137,13 @@ export default function createClass <ApiType extends ApiTypes> ({ api, apiType,
return [options, statusCb];
}
private async _signViaSigner (address: string, optionsWithEra: SignatureOptions, header: Header | null): Promise<number> {
private async _signViaSigner (address: string, options: SignatureOptions, header: Header | null): Promise<number> {
if (!this._api.signer) {
throw new Error('no signer attached');
}
const payload = createType(this.registry, 'SignerPayload', {
...optionsWithEra,
...options,
address,
method: this.method,
blockNumber: header ? header.number : 0
@@ -258,5 +266,13 @@ export default function createClass <ApiType extends ApiTypes> ({ api, apiType,
})
);
}
// NOTE here we actually override nonce if it was specified (backwards compat for
// the previous signature - don't let userspace break, but allow then time to upgrade)
private _optionsOrNonce = (optionsOrNonce: Partial<SignerOptions>): Partial<SignerOptions> => {
return isBn(optionsOrNonce) || isNumber(optionsOrNonce)
? { nonce: optionsOrNonce }
: optionsOrNonce;
}
};
}
+2
View File
@@ -48,6 +48,8 @@ export interface SubmittableExtrinsic<ApiType extends ApiTypes> extends IExtrins
sign(account: IKeyringPair, _options: Partial<SignatureOptions>): this;
signAsync(account: IKeyringPair, _options: Partial<SignatureOptions>): Promise<this>;
signAndSend(account: IKeyringPair | string | AccountId | Address, options?: Partial<SignerOptions>): SubmittableResultResult<ApiType>;
signAndSend(account: IKeyringPair | string | AccountId | Address, statusCb: Callback<SubmittableResultImpl>): SubmittableResultSubscription<ApiType>;