Skip to content

Commit

Permalink
api, api-{augment, base, contract, derive}, rpc-{augment, core, provi…
Browse files Browse the repository at this point in the history
…der}, types, types-{augment, codec, create, known} 12.0.1
  • Loading branch information
github-actions[bot] committed Jun 25, 2024
1 parent 29949b7 commit b2f7285
Show file tree
Hide file tree
Showing 21 changed files with 116 additions and 29 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## master

- api, api-{augment, base, contract, derive}, rpc-{augment, core, provider}, types, types-{augment, codec, create, known} 12.0.1
- phishing 0.22.9
- api, api-{augment, base, contract, derive}, rpc-{augment, core, provider}, types, types-{augment, codec, create, known} 11.3.1
- api, api-{augment, base, contract, derive}, rpc-{augment, core, provider}, types, types-{augment, codec, create, known} 11.2.1
Expand Down
2 changes: 1 addition & 1 deletion api-augment/packageInfo.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@


export const packageInfo = { name: '@polkadot/api-augment', path: new URL(import.meta.url).pathname, type: 'deno', version: '11.3.1' };
export const packageInfo = { name: '@polkadot/api-augment', path: new URL(import.meta.url).pathname, type: 'deno', version: '12.0.1' };
2 changes: 1 addition & 1 deletion api-base/packageInfo.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@


export const packageInfo = { name: '@polkadot/api-base', path: new URL(import.meta.url).pathname, type: 'deno', version: '11.3.1' };
export const packageInfo = { name: '@polkadot/api-base', path: new URL(import.meta.url).pathname, type: 'deno', version: '12.0.1' };
10 changes: 10 additions & 0 deletions api-base/types/submittable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,16 @@ export interface SubmittableExtrinsic<ApiType extends ApiTypes, R extends ISubmi

signAsync (account: AddressOrPair, _options?: Partial<SignerOptions>): PromiseOrObs<ApiType, this>;

/**
* @description Sign and broadcast the constructued transaction.
*
* Note for injected signers:
* As of v12.0.1 and up the `SignerResult` return type for `signPayload` allows for the `signedTransaction` field.
* This allows the signer to input a signed transaction that will be directly broadcasted. This
* bypasses the api adding the signature to the payload. The api will ensure that the Call Data is not changed before it broadcasts the
* transaction. This allows for the signer to modify the payload to add things like `mode`, and `metadataHash` for
* signedExtensions such as `CheckMetadataHash`.
*/
signAndSend (account: AddressOrPair, options?: Partial<SignerOptions>): SubmittableResultResult<ApiType, R>;

signAndSend (account: AddressOrPair, statusCb: Callback<R>): SubmittableResultSubscription<ApiType>;
Expand Down
2 changes: 1 addition & 1 deletion api-contract/packageInfo.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@


export const packageInfo = { name: '@polkadot/api-contract', path: new URL(import.meta.url).pathname, type: 'deno', version: '11.3.1' };
export const packageInfo = { name: '@polkadot/api-contract', path: new URL(import.meta.url).pathname, type: 'deno', version: '12.0.1' };
2 changes: 1 addition & 1 deletion api-derive/packageInfo.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@


export const packageInfo = { name: '@polkadot/api-derive', path: new URL(import.meta.url).pathname, type: 'deno', version: '11.3.1' };
export const packageInfo = { name: '@polkadot/api-derive', path: new URL(import.meta.url).pathname, type: 'deno', version: '12.0.1' };
15 changes: 10 additions & 5 deletions api-derive/staking/stakerRewards.ts
Original file line number Diff line number Diff line change
Expand Up @@ -165,11 +165,15 @@ export function _stakerRewardsEras (instanceId: string, api: DeriveApi): (eras:
}

export function _stakerRewards (instanceId: string, api: DeriveApi): (accountIds: (Uint8Array | string)[], eras: EraIndex[], withActive?: boolean) => Observable<DeriveStakerReward[][]> {
return memo(instanceId, (accountIds: (Uint8Array | string)[], eras: EraIndex[], withActive = false): Observable<DeriveStakerReward[][]> =>
combineLatest([
return memo(instanceId, (accountIds: (Uint8Array | string)[], eras: EraIndex[], withActive = false): Observable<DeriveStakerReward[][]> => {
// Ensures that when number or string types are passed in they are sanitized
// Ref: https://github.com/polkadot-js/api/issues/5910
const sanitizedEras: EraIndex[] = eras.map((e) => typeof e === 'number' || typeof e === 'string' ? api.registry.createType('u32', e) : e);

return combineLatest([
api.derive.staking.queryMulti(accountIds, { withClaimedRewardsEras: true, withLedger: true }),
api.derive.staking._stakerExposures(accountIds, eras, withActive),
api.derive.staking._stakerRewardsEras(eras, withActive)
api.derive.staking._stakerExposures(accountIds, sanitizedEras, withActive),
api.derive.staking._stakerRewardsEras(sanitizedEras, withActive)
]).pipe(
switchMap(([queries, exposures, erasResult]): Observable<DeriveStakerReward[][]> => {
const allRewards = queries.map(({ claimedRewardsEras, stakingLedger, stashId }, index): DeriveStakerReward[] =>
Expand Down Expand Up @@ -205,7 +209,8 @@ export function _stakerRewards (instanceId: string, api: DeriveApi): (accountIds
)
);
})
)
);
}
);
}

Expand Down
10 changes: 7 additions & 3 deletions api-derive/tx/signingInfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,13 @@ function latestNonce (api: DeriveApi, address: string): Observable<Index> {
}

function nextNonce (api: DeriveApi, address: string): Observable<Index> {
return api.rpc.system?.accountNextIndex
? api.rpc.system.accountNextIndex(address)
: latestNonce(api, address);
if (api.call.accountNonceApi) {
return api.call.accountNonceApi.accountNonce(address);
} else {
return api.rpc.system?.accountNextIndex
? api.rpc.system.accountNextIndex(address)
: latestNonce(api, address);
}
}

function signingHeader (api: DeriveApi): Observable<Header> {
Expand Down
2 changes: 1 addition & 1 deletion api/packageInfo.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@


export const packageInfo = { name: '@polkadot/api', path: new URL(import.meta.url).pathname, type: 'deno', version: '11.3.1' };
export const packageInfo = { name: '@polkadot/api', path: new URL(import.meta.url).pathname, type: 'deno', version: '12.0.1' };
58 changes: 50 additions & 8 deletions api/submittable/createClass.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import type { Observable } from 'https://esm.sh/rxjs@7.8.1';
import type { Address, ApplyExtrinsicResult, Call, Extrinsic, ExtrinsicEra, ExtrinsicStatus, Hash, Header, Index, RuntimeDispatchInfo, SignerPayload } from 'https://deno.land/x/polkadot/types/interfaces/index.ts';
import type { Callback, Codec, CodecClass, ISubmittableResult, SignatureOptions } from 'https://deno.land/x/polkadot/types/types/index.ts';
import type { Registry } from 'https://deno.land/x/polkadot/types-codec/types/index.ts';
import type { HexString } from 'https://deno.land/x/polkadot/util/types.ts';
import type { ApiBase } from '../base/index.ts';
import type { ApiInterfaceRx, ApiTypes, PromiseOrObs, SignerResult } from '../types/index.ts';
import type { AddressOrPair, SignerOptions, SubmittableDryRunResult, SubmittableExtrinsic, SubmittablePaymentResult, SubmittableResultResult, SubmittableResultSubscription } from './types.ts';
Expand All @@ -26,6 +27,12 @@ interface SubmittableOptions<ApiType extends ApiTypes> {
interface UpdateInfo {
options: SignatureOptions;
updateId: number;
signedTransaction: HexString | Uint8Array | null;
}

interface SignerInfo {
id: number;
signedTransaction?: HexString | Uint8Array;
}

function makeEraOptions (api: ApiInterfaceRx, registry: Registry, partialOptions: Partial<SignerOptions>, { header, mortalLength, nonce }: { header: Header | null; mortalLength: number; nonce: Index }): SignatureOptions {
Expand Down Expand Up @@ -244,14 +251,21 @@ export function createClass <ApiType extends ApiTypes> ({ api, apiType, blockHas
mergeMap(async (signingInfo): Promise<UpdateInfo> => {
const eraOptions = makeEraOptions(api, this.registry, options, signingInfo);
let updateId = -1;
let signedTx = null;

if (isKeyringPair(account)) {
this.sign(account, eraOptions);
} else {
updateId = await this.#signViaSigner(address, eraOptions, signingInfo.header);
const result = await this.#signViaSigner(address, eraOptions, signingInfo.header);

updateId = result.id;

if (result.signedTransaction) {
signedTx = result.signedTransaction;
}
}

return { options: eraOptions, updateId };
return { options: eraOptions, signedTransaction: signedTx, updateId };
})
);
};
Expand Down Expand Up @@ -286,18 +300,18 @@ export function createClass <ApiType extends ApiTypes> ({ api, apiType, blockHas
);
};

#observeSend = (info: UpdateInfo): Observable<Hash> => {
return api.rpc.author.submitExtrinsic(this).pipe(
#observeSend = (info?: UpdateInfo): Observable<Hash> => {
return api.rpc.author.submitExtrinsic(info?.signedTransaction || this).pipe(
tap((hash): void => {
this.#updateSigner(hash, info);
})
);
};

#observeSubscribe = (info: UpdateInfo): Observable<ISubmittableResult> => {
#observeSubscribe = (info?: UpdateInfo): Observable<ISubmittableResult> => {
const txHash = this.hash;

return api.rpc.author.submitAndWatchExtrinsic(this).pipe(
return api.rpc.author.submitAndWatchExtrinsic(info?.signedTransaction || this).pipe(
switchMap((status): Observable<ISubmittableResult> =>
this.#observeStatus(txHash, status)
),
Expand All @@ -307,7 +321,7 @@ export function createClass <ApiType extends ApiTypes> ({ api, apiType, blockHas
);
};

#signViaSigner = async (address: Address | string | Uint8Array, options: SignatureOptions, header: Header | null): Promise<number> => {
#signViaSigner = async (address: Address | string | Uint8Array, options: SignatureOptions, header: Header | null): Promise<SignerInfo> => {
const signer = options.signer || api.signer;

if (!signer) {
Expand All @@ -323,6 +337,20 @@ export function createClass <ApiType extends ApiTypes> ({ api, apiType, blockHas

if (isFunction(signer.signPayload)) {
result = await signer.signPayload(payload.toPayload());

// When the signedTransaction is included by the signer, we no longer add
// the signature to the parent class, but instead broadcast the signed transaction directly.
if (result.signedTransaction) {
const ext = this.registry.createTypeUnsafe<Extrinsic>('Extrinsic', [result.signedTransaction]);

if (!ext.isSigned) {
throw new Error(`When using the signedTransaction field, the transaction must be signed. Recieved isSigned: ${ext.isSigned}`);
}

this.#validateSignedTransaction(payload, ext);

return { id: result.id, signedTransaction: result.signedTransaction };
}
} else if (isFunction(signer.signRaw)) {
result = await signer.signRaw(payload.toRaw());
} else {
Expand All @@ -334,7 +362,7 @@ export function createClass <ApiType extends ApiTypes> ({ api, apiType, blockHas
// payload data is not modified from our inputs, but the signer
super.addSignature(address, result.signature, payload.toPayload());

return result.id;
return { id: result.id };
};

#updateSigner = (status: Hash | ISubmittableResult, info?: UpdateInfo): void => {
Expand All @@ -347,6 +375,20 @@ export function createClass <ApiType extends ApiTypes> ({ api, apiType, blockHas
}
}
};

/**
* When a signer includes `signedTransaction` within the SignerResult this will validate
* specific fields within the signed extrinsic against the original payload that was passed
* to the signer.
*/
#validateSignedTransaction = (signerPayload: SignerPayload, signedExt: Extrinsic): void => {
const payload = signerPayload.toPayload();
const errMsg = (field: string) => `signAndSend: ${field} does not match the original payload`;

if (payload.method !== signedExt.method.toHex()) {
throw new Error(errMsg('call data'));
}
};
}

return Submittable;
Expand Down
2 changes: 1 addition & 1 deletion rpc-augment/packageInfo.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@


export const packageInfo = { name: '@polkadot/rpc-augment', path: new URL(import.meta.url).pathname, type: 'deno', version: '11.3.1' };
export const packageInfo = { name: '@polkadot/rpc-augment', path: new URL(import.meta.url).pathname, type: 'deno', version: '12.0.1' };
2 changes: 1 addition & 1 deletion rpc-core/packageInfo.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@


export const packageInfo = { name: '@polkadot/rpc-core', path: new URL(import.meta.url).pathname, type: 'deno', version: '11.3.1' };
export const packageInfo = { name: '@polkadot/rpc-core', path: new URL(import.meta.url).pathname, type: 'deno', version: '12.0.1' };
2 changes: 1 addition & 1 deletion rpc-provider/packageInfo.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@


export const packageInfo = { name: '@polkadot/rpc-provider', path: new URL(import.meta.url).pathname, type: 'deno', version: '11.3.1' };
export const packageInfo = { name: '@polkadot/rpc-provider', path: new URL(import.meta.url).pathname, type: 'deno', version: '12.0.1' };
2 changes: 1 addition & 1 deletion types-augment/packageInfo.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@


export const packageInfo = { name: '@polkadot/types-augment', path: new URL(import.meta.url).pathname, type: 'deno', version: '11.3.1' };
export const packageInfo = { name: '@polkadot/types-augment', path: new URL(import.meta.url).pathname, type: 'deno', version: '12.0.1' };
2 changes: 1 addition & 1 deletion types-codec/packageInfo.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@


export const packageInfo = { name: '@polkadot/types-codec', path: new URL(import.meta.url).pathname, type: 'deno', version: '11.3.1' };
export const packageInfo = { name: '@polkadot/types-codec', path: new URL(import.meta.url).pathname, type: 'deno', version: '12.0.1' };
2 changes: 1 addition & 1 deletion types-create/packageInfo.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@


export const packageInfo = { name: '@polkadot/types-create', path: new URL(import.meta.url).pathname, type: 'deno', version: '11.3.1' };
export const packageInfo = { name: '@polkadot/types-create', path: new URL(import.meta.url).pathname, type: 'deno', version: '12.0.1' };
2 changes: 1 addition & 1 deletion types-known/packageInfo.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@


export const packageInfo = { name: '@polkadot/types-known', path: new URL(import.meta.url).pathname, type: 'deno', version: '11.3.1' };
export const packageInfo = { name: '@polkadot/types-known', path: new URL(import.meta.url).pathname, type: 'deno', version: '12.0.1' };
8 changes: 8 additions & 0 deletions types/extrinsic/Extrinsic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,13 @@ abstract class ExtrinsicBase<A extends AnyTuple> extends AbstractBase<ExtrinsicV
return this.inner.signature.metadataHash;
}

/**
* @description Forward compat
*/
public get mode (): INumber {
return this.inner.signature.mode;
}

/**
* @description Returns the raw transaction version (not flagged with signing information)
*/
Expand Down Expand Up @@ -330,6 +337,7 @@ export class GenericExtrinsic<A extends AnyTuple = AnyTuple> extends ExtrinsicBa
assetId: this.assetId ? this.assetId.toHuman(isExpanded, disableAscii) : null,
era: this.era.toHuman(isExpanded, disableAscii),
metadataHash: this.metadataHash ? this.metadataHash.toHex() : null,
mode: this.mode.toHuman(),
nonce: this.nonce.toHuman(isExpanded, disableAscii),
signature: this.signature.toHex(),
signer: this.signer.toHuman(isExpanded, disableAscii),
Expand Down
7 changes: 7 additions & 0 deletions types/extrinsic/v4/ExtrinsicSignature.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,13 @@ export class GenericExtrinsicSignatureV4 extends Struct implements IExtrinsicSig
return this.getT('assetId');
}

/**
* @description the [[u32]] mode
*/
public get mode (): INumber {
return this.getT('mode');
}

/**
* @description The [[Hash]] for the metadata
*/
Expand Down
2 changes: 1 addition & 1 deletion types/packageInfo.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@


export const packageInfo = { name: '@polkadot/types', path: new URL(import.meta.url).pathname, type: 'deno', version: '11.3.1' };
export const packageInfo = { name: '@polkadot/types', path: new URL(import.meta.url).pathname, type: 'deno', version: '12.0.1' };
10 changes: 10 additions & 0 deletions types/types/extrinsic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,16 @@ export interface SignerResult {
* @description The resulting signature in hex
*/
signature: HexString;

/**
* @description The payload constructed by the signer. This allows the
* inputted signed transaction to bypass `signAndSend` from adding the signature to the payload,
* and instead broadcasting the transaction directly. There is a small validation layer. Please refer
* to the implementation for more information. If the inputted signed transaction is not actually signed, it will fail with an error.
*
* NOTE: This is only implemented for `signPayload`.
*/
signedTransaction?: HexString | Uint8Array;
}

export interface Signer {
Expand Down

0 comments on commit b2f7285

Please sign in to comment.