Skip to content

Commit

Permalink
Alpha into beta (PolymeshAssociation#850)
Browse files Browse the repository at this point in the history
* feat: 🎸 allow for exempted identities to be removed

when a user does not pass exempted identities that are exempt when
calling setTransferRestrictions the procedure will unset those
permissions

BREAKING CHANGE: 🧨 non passed exempted identities are removed when calling
setTransferRestriction

* refactor: 💡 fix code smells

* test: 💍 add missing coverage

* test: 💍 clean up test assertions for restrictions

* test: 💍 add case for restriction type to stat type conversion

* refactor: 💡 address pr comments

* docs: ✏️ add comments to transformInput for set restrictions

* refactor: 💡 use function for pushing exemption transactions

* refactor: 💡 adjust exemption record structure

* docs: ✏️ add comments to addExemptionIfNotPresent method

* refactor: 💡 remove unused default

* style: 💄 add line break after sizeOf definition

* refactor: 💡 Make StatType internal as users never need it

The stat type is inferred from the TransferRestrictionType they are
interacting with. This eliminates the redundant StatisticsOpType and use
StatType through out

* docs: ✏️ add docs around StatType

* refactor: 💡 address PR comments

* refactor: 💡 use destructre for cleaner syntax

* Beta into alpha (PolymeshAssociation#825)

* docs: ✏️ update compatible version and docs url in readme.md

* feat: 🎸 bump supported chain version to 5.0.2

* fix: 🐛 add warning to use the new npm repository

* chore: 🤖 update references to use association signing managers

* fix: 🐛 missing readme from npm

* fix: 🐛 update polymathnetwork to association references (PolymeshAssociation#817)

* Update README.md

Co-authored-by: Prashant Bajpai <34747455+prashantasdeveloper@users.noreply.github.com>

* fix: 🐛 Fix inviteAccount method by updating the permission type (PolymeshAssociation#821)

* fix: 🐛 Fix transfer with memo (PolymeshAssociation#822)

use long type name when creating memos. Also replace lodash padEnd with
the built in function

Co-authored-by: Victor Vicente <VictorVicente@users.noreply.github.com>

* Merge pull request PolymeshAssociation#818 from PolymeshAssociation/beta (PolymeshAssociation#824)

Co-authored-by: Victor Vicente <VictorVicente@users.noreply.github.com>

Co-authored-by: Victor <victor.g.vicente@gmail.com>
Co-authored-by: Victor Vicente <VictorVicente@users.noreply.github.com>
Co-authored-by: Prashant Bajpai <34747455+prashantasdeveloper@users.noreply.github.com>

* Feat/da 148 eliminate transaction queues (PolymeshAssociation#785)

* feat: remove Transaction Queues

The `TransactionQueue` class has been removed. Most of its methods have been moved over to
`PolymeshTransaction` and `PolymeshTransactionBatch`. Methods that returned a `TransactionQueue`
(all endpoints that write to the blockchain, such as `sdk.assets.registerTicker`) now return
either a `PolymeshTransaction` or `PolymeshTransactionBatch`. This means that all operations
in the SDK are now atomic and not prone to race conditions or half-states

- The `onProcessedByMiddleware` method has been moved to `PolymeshTransaction` and
  `PolymeshTransactionBase`
- The `Fees` interface now contains a `total` property which is the sum of `free`
  and `locked`
- The `PayingAccountType` enum now includes a `Caller` member, to represent cases
  where the calling Account has to pay for a transaction’s fees

BREAKING CHANGES:

- Remove the `inputArgs` property from `PolymeshTransaction`. Replaced by the `args`
  property. Arguments for `PolymeshTransaction` and `PolymeshTransactionBatch` are now
  available at any point in time (previously they could depend on the result of a previous
  transaction in the queue)
- Remove the `isCritical` property from both `PolymeshTransaction` and `PolymeshTransactionBatch`.
  It no longer makes sense without Transaction Queues
- Change the `run` method in `PolymeshTransaction` and `PolymeshTransactionBatch` to work similarly
  to the `run` method in `TransactionQueue`. The method will check if the caller account has
  enough balance for fees, the transaction will be run and its status updated. The method returns
  a Promise that resolves to the result of running the transaction. For example, calling `run` on
  the transaction returned by `asset.registerTicker` will return a Promise that resolves to a
  `TickerReservation` entity
- Change the argument received by the callback passed to `onStatusChange` to
  `PolymeshTransactionBase`. If type refinement is required, the `isPolymeshTransaction`
  and `isPolymeshTransactionBatch` typeguards can be used (they can be imported from `types`)
- Change the return type of `getFees` in `PolymeshTransaction` and `PolymeshTransactionBatch`
  to `PayingAccountFees`, which contains details about the Account that will pay for the fees,
  its remaining balance (before paying), and the fees themselves
- Remove the `getPayingAccount` method from `PolymeshTransaction` and `PolymeshTransactionBatch`.
  Its result is now contained in `getFees`
- Change the `PayingAccount` type to now only contain `allowance: BigNumber` when `type` is
  `Subsidy`. For `Caller` and `Other`, there is no `allowance`

* perf: ⚡️ use a single call to fetch latest finalized block

* chore: 🤖 implement a way of discriminating batch events

* feat: 🎸 Allow passing of `nonce` as part of `ProcedureOptions`

* refactor: 💡 Remove unnecessary nonce value from txSpec

* feat: 🎸 Add `currentNonce` method to `Account`

* chore: 🤖 Allow async values for nonce

* Update src/types/index.ts

* feat: support merging transactions into batches

- Add an `sdk.createTransactionBatch` endpoint that takes an array of SDK transactions and returns
  them all batched in a single transaction. The result of running this batch is an array of the
  results of each transaction in the same order
- Fix documentation to reflect the fact that transaction queues no longer exist
- Improve transaction fee calculation algorithm to avoid edge cases where estimated fees were
  different than the actual fees
- Expose `getProtocolFees` from `PolymeshTransaction` and `PolymeshTransactionBatch`
- Expose the `GenericPolymeshTransaction` type
  (returned by most endpoints that create transactions)

BREAKING CHANGES:

- Rename `getFees` to `getTotalFees` in `PolymeshTransaction` and `PolymeshTransactionBatch`

* feat: 🎸 expose the `MapTxWithData` type

* docs: ✏️ improve rendered documentation to handle code snippets

* test: 💍 use proper type in assertion

* feat: 🎸 support splitting batches

Add a `splitTransactions` method to the `PolymeshTransactionBatch` class
that returns all individual transactions in the batch. This method is
useful when the caller is being subsidized, since batches do not support
subsidies

* fix: 🐛 carry manual fees over when simplifying a batch

When a procedure that normally produces batches produced a single
transaction, we weren't passing manual fee data over

* test: 💍 polymathnetwork -> polymeshassociation in import path

Co-authored-by: Prashant Bajpai <prashant.bajpai19@gmail.com>
Co-authored-by: Victor Vicente <VictorVicente@users.noreply.github.com>
Co-authored-by: Prashant Bajpai <34747455+prashantasdeveloper@users.noreply.github.com>
Co-authored-by: Eric <ericrichardson@polymath.network>

* feat: 🎸 release elimination of transaction queues (PolymeshAssociation#828)

triggers release of latest alpha as the previous merge had older commits
skipped be semver bot

Feat/da 148 eliminate transaction queues (PolymeshAssociation#785)

* feat: remove Transaction Queues

The `TransactionQueue` class has been removed. Most of its methods have been moved over to
`PolymeshTransaction` and `PolymeshTransactionBatch`. Methods that returned a `TransactionQueue`
(all endpoints that write to the blockchain, such as `sdk.assets.registerTicker`) now return
either a `PolymeshTransaction` or `PolymeshTransactionBatch`. This means that all operations
in the SDK are now atomic and not prone to race conditions or half-states

- The `onProcessedByMiddleware` method has been moved to `PolymeshTransaction` and
  `PolymeshTransactionBase`
- The `Fees` interface now contains a `total` property which is the sum of `free`
  and `locked`
- The `PayingAccountType` enum now includes a `Caller` member, to represent cases
  where the calling Account has to pay for a transaction’s fees

* perf: ⚡️ use a single call to fetch latest finalized block

* chore: 🤖 implement a way of discriminating batch events

* feat: 🎸 Allow passing of `nonce` as part of `ProcedureOptions`

* refactor: 💡 Remove unnecessary nonce value from txSpec

* feat: 🎸 Add `currentNonce` method to `Account`

* chore: 🤖 Allow async values for nonce

* Update src/types/index.ts

* feat: support merging transactions into batches

* feat: 🎸 expose the `MapTxWithData` type

* docs: ✏️ improve rendered documentation to handle code snippets

* test: 💍 use proper type in assertion

* feat: 🎸 support splitting batches

* fix: 🐛 carry manual fees over when simplifying a batch

Add a `splitTransactions` method to the `PolymeshTransactionBatch` class
that returns all individual transactions in the batch. This method is
useful when the caller is being subsidized, since batches do not support
subsidies

When a procedure that normally produces batches produced a single
transaction, we weren't passing manual fee data over

- Add an `sdk.createTransactionBatch` endpoint that takes an array of SDK transactions and returns
  them all batched in a single transaction. The result of running this batch is an array of the
  results of each transaction in the same order
- Fix documentation to reflect the fact that transaction queues no longer exist
- Improve transaction fee calculation algorithm to avoid edge cases where estimated fees were
  different than the actual fees
- Expose `getProtocolFees` from `PolymeshTransaction` and `PolymeshTransactionBatch`
- Expose the `GenericPolymeshTransaction` type
  (returned by most endpoints that create transactions)

BREAKING CHANGES:

- Remove the `inputArgs` property from `PolymeshTransaction`. Replaced by the `args`
  property. Arguments for `PolymeshTransaction` and `PolymeshTransactionBatch` are now
  available at any point in time (previously they could depend on the result of a previous
  transaction in the queue)
- Remove the `isCritical` property from both `PolymeshTransaction` and `PolymeshTransactionBatch`.
  It no longer makes sense without Transaction Queues
- Change the `run` method in `PolymeshTransaction` and `PolymeshTransactionBatch` to work similarly
  to the `run` method in `TransactionQueue`. The method will check if the caller account has
  enough balance for fees, the transaction will be run and its status updated. The method returns
  a Promise that resolves to the result of running the transaction. For example, calling `run` on
  the transaction returned by `asset.registerTicker` will return a Promise that resolves to a
  `TickerReservation` entity
- Change the argument received by the callback passed to `onStatusChange` to
  `PolymeshTransactionBase`. If type refinement is required, the `isPolymeshTransaction`
  and `isPolymeshTransactionBatch` typeguards can be used (they can be imported from `types`)
- Change the return type of `getFees` in `PolymeshTransaction` and `PolymeshTransactionBatch`
  to `PayingAccountFees`, which contains details about the Account that will pay for the fees,
  its remaining balance (before paying), and the fees themselves
- Remove the `getPayingAccount` method from `PolymeshTransaction` and `PolymeshTransactionBatch`.
  Its result is now contained in `getFees`
- Change the `PayingAccount` type to now only contain `allowance: BigNumber` when `type` is
  `Subsidy`. For `Caller` and `Other`, there is no `allowance`
- Rename `getFees` to `getTotalFees` in `PolymeshTransaction` and `PolymeshTransactionBatch`

* feat: 🎸 use a more specific type for onStatusChange in txBase (PolymeshAssociation#829)

use GenericPolymeshTransaction<ReturnValue, TransformedReturnValue> in
onStatusChange handler defined in PolymeshTransactionBase. This makes it
easier to define functions to be passed to it

* chore: 🤖 improve typing around `assembleBatchTransaction`

This reduces the need to use the `tuple` util, hopefully making the code
a bit more idiomatic

* fix: 🐛 fix bug where only the default signer was used (PolymeshAssociation#831)

in Procedure `prepare` method, the passed in, non modified `context` was
used, when `ctx` was supposed to be used instead

* fix: 🐛 improve the typing of `splitTransactions`

The original types weren't being properly reflected by the compiler,
resulting in an array of only 2 transactions always. Also, when batching
transactions that had a transformed return value, the compiler was
throwing errors. Since we don't care about the original return value,
only the transformed one, using `any` is acceptable

* test: 💍 add missing coverage in setTransferRestriction

also remove unnessesary type assertions in createMock functions

* test: 💍 fix jest timer in PolymeshTransactionBase

* refactor: 💡 remove redundant await

* style: 💄 remove commented out code

Co-authored-by: Victor Vicente <VictorVicente@users.noreply.github.com>
Co-authored-by: Victor <victor.g.vicente@gmail.com>
Co-authored-by: Prashant Bajpai <34747455+prashantasdeveloper@users.noreply.github.com>
Co-authored-by: Jeremías Díaz <monitz87@gmail.com>
Co-authored-by: Prashant Bajpai <prashant.bajpai19@gmail.com>
  • Loading branch information
6 people committed Sep 15, 2022
1 parent 8cd3368 commit 84cda4d
Show file tree
Hide file tree
Showing 238 changed files with 5,909 additions and 6,156 deletions.
1 change: 1 addition & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
"POLYX",
"prashantasdeveloper",
"Promisified",
"promisifying",
"PUIS",
"Ristretto",
"satoshi",
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ This document assumes you are already familiar with [Security Tokens](https://th

### Technical Pre-requisites

In order to use the Polymath SDK, you must install [node](https://nodejs.org/) \(version 10\) and [npm](https://www.npmjs.com/). The library is written in [typescript](https://www.typescriptlang.org/), but can also be used in plain javascript. This document will assume you are using typescript, but the translation to javascript is very simple.
In order to use the Polymath SDK, you must install [node](https://nodejs.org/) \(version 14\) and [npm](https://www.npmjs.com/). The library is written in [typescript](https://www.typescriptlang.org/), but can also be used in plain javascript. This document will assume you are using typescript, but the translation to javascript is very simple.

### Documentation

Expand Down
45 changes: 33 additions & 12 deletions scripts/prepareCodeForDocs.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,23 +17,38 @@ const replace = require('replace-in-file');
const path = require('path');

const methodRegex =
/\*\/\n\s+?public ((?:abstract )?\w+?)!?: ((?:NoArgs)?ProcedureMethod<[\w\W]+?>);/gs;
/\*\/\n\s+?public ((?:abstract )?\w+?)!?: ((?:(:?NoArgs)|(?:CreateTransactionBatch))?ProcedureMethod(?:<[\w\W]+?>)?);/gs;
const importRegex = /(import .+? from '.+?';\n)\n/s;

/**
* Get type arguments from a `ProcedureMethod` or `NoArgsProcedureMethod` type declaration
* Get type arguments from a `ProcedureMethod`, `NoArgsProcedureMethod` or `CreateTransactionBatchProcedureMethod` type declaration
*
* - calling the function with `ProcedureMethod<Foo, Bar, Baz>` will yield `{ methodArgs: 'Foo', procedureReturnValue: 'Bar', returnValue: 'Baz', kind: 'ProcedureMethod' }`
* - calling the function with `ProcedureMethod<Foo, Bar>` will yield `{ methodArgs: 'Foo', procedureReturnValue: 'Bar', returnValue: undefined, kind: 'ProcedureMethod' }`
* - calling the function with `NoArgsProcedureMethod<Foo, Bar>` will yield `{ procedureReturnValue: 'Foo', returnValue: 'Bar', kind: 'NoArgsProcedureMethod' }`
* - calling the function with `NoArgsProcedureMethod<Foo>` will yield `{ procedureReturnValue: 'Foo', returnValue: undefined, kind: 'NoArgsProcedureMethod' }`
* - calling the function with `ProcedureMethod<Foo, Bar, Baz>` will return `{ methodArgs: 'Foo', procedureReturnValue: 'Bar', returnValue: 'Baz', kind: 'ProcedureMethod' }`
* - calling the function with `ProcedureMethod<Foo, Bar>` will return `{ methodArgs: 'Foo', procedureReturnValue: 'Bar', returnValue: undefined, kind: 'ProcedureMethod' }`
* - calling the function with `NoArgsProcedureMethod<Foo, Bar>` will return `{ procedureReturnValue: 'Foo', returnValue: 'Bar', kind: 'NoArgsProcedureMethod' }`
* - calling the function with `NoArgsProcedureMethod<Foo>` will return `{ procedureReturnValue: 'Foo', returnValue: undefined, kind: 'NoArgsProcedureMethod' }`
* - calling the function with `CreateTransactionBatchProcedureMethod` will return `{ methodArgs: 'CreateTransactionBatchParams<ReturnValues>', procedureReturnValue: 'ReturnValues', returnValue: undefined, kind: 'CreateTransactionBatchProcedureMethod' }`
*/
const getTypeArgumentsFromProcedureMethod = typeString => {
const source = ts.createSourceFile('temp', typeString);

// NOTE @monitz87: this is very ugly but it's the quickest way I found of getting the type arguments
const signature = source.getChildren(source)[0].getChildren(source)[0].getChildren(source)[0];
const kind = signature.getChildren(source)[0].getText(source);
let kind = signature.getText(source);

// this is the case where the type has generic arguments (e.g. `ProcedureMethod<Foo, Bar>`, as opposed to `CreateTransactionMethodProcedureArgs`)
if (signature.getChildren(source).length > 0) {
kind = signature.getChildren(source)[0].getText(source);
}

if (kind === 'CreateTransactionBatchProcedureMethod') {
return {
methodArgs: 'CreateTransactionBatchParams<ReturnValues>',
procedureReturnValue: 'ReturnValues',
kind,
};
}

const [first, , second, , third] = signature
.getChildren(source)[2]
.getChildren(source)
Expand Down Expand Up @@ -61,13 +76,19 @@ const getTypeArgumentsFromProcedureMethod = typeString => {
const createReplacementSignature = (_, funcName, type) => {
const { methodArgs, returnValue, procedureReturnValue, kind } =
getTypeArgumentsFromProcedureMethod(type);
const returnValueString = returnValue ? `, ${returnValue}` : '';
const returnType = `Promise<TransactionQueue<${procedureReturnValue}${returnValueString}>>`;
const returnValueString = `, ${returnValue || procedureReturnValue}`;
const returnType = `Promise<GenericPolymeshTransaction<${procedureReturnValue}${returnValueString}>>`;

const args = `args: ${methodArgs}, `;
const funcArgs = `(${kind === 'ProcedureMethod' ? args : ''}opts?: ProcedureOpts)`;
const funcArgs = `(${
['ProcedureMethod', 'CreateTransactionBatchProcedureMethod'].includes(kind) ? args : ''
}opts?: ProcedureOpts)`;
const name = funcName.replace('abstract ', '');
const isAbstract = name !== funcName;
const genericParams =
kind === 'CreateTransactionBatchProcedureMethod'
? '<ReturnValues extends readonly [...unknown[]]>'
: '';

// NOTE @monitz87: we make the function return a type asserted value to avoid compilation errors
const implementation = ` {
Expand All @@ -78,11 +99,11 @@ const createReplacementSignature = (_, funcName, type) => {
* @note this method is of type {@link types!${kind} | ${kind}}, which means you can call {@link types!${kind}.checkAuthorization | ${name}.checkAuthorization}
* on it to see whether the signing Account and Identity have the required roles and permissions to run it
*/
public ${funcName}${funcArgs}: ${returnType}${isAbstract ? ';' : implementation}`;
public ${funcName}${genericParams}${funcArgs}: ${returnType}${isAbstract ? ';' : implementation}`;
};

const createReplacementImport = (_, importStatement) =>
`${importStatement}import { ProcedureOpts } from '~/types';\nimport { TransactionQueue } from '~/internal';\n\n`;
`${importStatement}import { CreateTransactionBatchParams, GenericPolymeshTransaction, ProcedureOpts } from '~/types';\n\n`;

const results = replace.sync({
files: 'src/**/*.ts',
Expand Down
18 changes: 16 additions & 2 deletions scripts/processDocs.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/* eslint-disable */
const path = require('path');
const replace = require('replace-in-file');
const fs = require('fs');
const { camelCase, startCase } = require('lodash');

Expand Down Expand Up @@ -40,7 +41,8 @@ const convertModulesToHierarchy = function (modules) {

/**
* Returns a single markdown formatted link shifted by depth * 2 spaces
* For example - ` - [Asset](../wiki/api.entities.Asset)`
*
* @example ` - [Asset](../wiki/api.entities.Asset)`
*/
const getLink = function (label, link, depth) {
const spaces = ' '.repeat(depth * 2);
Expand All @@ -49,14 +51,18 @@ const getLink = function (label, link, depth) {

/**
* Returns a dropdown formatted markdown string with a specific heading and description
* For example -
*
* @example
*
* ```markdown
* <details>
* <summary>
* <b>Client</b>
* </summary>
*
* ....Nested links....
* </details>
* ```
*
* Note that the blank line after the </summary> tag is must for correct formatting of dropdown content
*/
Expand Down Expand Up @@ -119,3 +125,11 @@ fs.writeFileSync(
${markdownLinks}
`
);

// this is required for markdown to interpret code snippets in comments correctly
replace.sync({
files: 'docs/**/*.md',
from: /^ ```.*/gs,
// remove the first character (space)
to: ([, ...tail]) => tail.join(''),
});
2 changes: 1 addition & 1 deletion sonar-project.properties
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
sonar.organization=polymeshassociation
sonar.projectKey=PolymeshAssociation_polymesh-sdk
sonar.sources=src
sonar.coverage.exclusions=**/testUtils/**,**/polkadot/**,**/__tests__/**,**/generated/**,src/utils/typeguards.ts
sonar.coverage.exclusions=**/testUtils/**,**/polkadot/**,**/__tests__/**,**/generated/**,src/utils/typeguards.ts,src/types/internal.ts
sonar.cpd.exclusions=**/__tests__/**,**/polkadot/**
sonar.exclusions=**/polkadot/augment-**
sonar.javascript.environments=node
Expand Down
20 changes: 13 additions & 7 deletions src/api/client/Network.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,14 +53,14 @@ export class Network {
}

/**
* Retrieve the number of the latest block in the chain
* Retrieve the number of the latest finalized block in the chain
*/
public getLatestBlock(): Promise<BigNumber> {
return this.context.getLatestBlock();
}

/**
* Fetch the current network version (i.e. 3.1.0)
* Fetch the current network version (e.g. 3.1.0)
*/
public async getVersion(): Promise<string> {
return this.context.getNetworkVersion();
Expand Down Expand Up @@ -98,7 +98,7 @@ export class Network {
/**
* Retrieve the protocol fees associated with running specific transactions
*
* @param args.tags - list of transaction tags (i.e. [TxTags.asset.CreateAsset, TxTags.asset.RegisterTicker] or ["asset.createAsset", "asset.registerTicker"])
* @param args.tags - list of transaction tags (e.g. [TxTags.asset.CreateAsset, TxTags.asset.RegisterTicker] or ["asset.createAsset", "asset.registerTicker"])
*/
public getProtocolFees(args: { tags: TxTag[] }): Promise<ProtocolFees[]> {
return this.context.getProtocolFees(args);
Expand Down Expand Up @@ -395,6 +395,8 @@ export class Network {
context.getProtocolFees({ tags: [txTag], blockHash }),
]);

const gas = balanceToBigNumber(partialFee);

return {
blockNumber: new BigNumber(blockNumber),
blockHash,
Expand All @@ -408,8 +410,9 @@ export class Network {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
extrinsicHash: extrinsicHash!,
fee: {
gas: balanceToBigNumber(partialFee),
gas,
protocol: protocolFees,
total: gas.plus(protocolFees),
},
};
}
Expand Down Expand Up @@ -479,11 +482,13 @@ export class Network {
block: { extrinsics: blockExtrinsics },
} = await getBlock(rawBlockHash);

const [{ partialFee }, [{ fees: protocolFees }]] = await Promise.all([
const [{ partialFee }, [{ fees: protocol }]] = await Promise.all([
queryInfo(blockExtrinsics[extrinsicIdx].toHex(), rawBlockHash),
context.getProtocolFees({ tags: [txTag], blockHash }),
]);

const gas = balanceToBigNumber(partialFee);

return {
blockNumber: new BigNumber(blockNumber),
blockHash,
Expand All @@ -497,8 +502,9 @@ export class Network {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
extrinsicHash: extrinsicHash!,
fee: {
gas: balanceToBigNumber(partialFee),
protocol: protocolFees,
gas,
protocol,
total: gas.plus(protocol),
},
};
}
Expand Down
59 changes: 53 additions & 6 deletions src/api/client/Polymesh.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,16 @@ import { HttpLink } from 'apollo-link-http';
import fetch from 'cross-fetch';
import schema from 'polymesh-types/schema';

import { Account, Context, Identity, PolymeshError } from '~/internal';
import { Account, Context, createTransactionBatch, Identity, PolymeshError } from '~/internal';
import { heartbeat } from '~/middleware/queries';
import { ErrorCode, MiddlewareConfig } from '~/types';
import {
CreateTransactionBatchProcedureMethod,
ErrorCode,
MiddlewareConfig,
UnsubCallback,
} from '~/types';
import { signerToString } from '~/utils/conversion';
import { assertExpectedChainVersion } from '~/utils/internal';
import { assertExpectedChainVersion, createProcedureMethod } from '~/utils/internal';

import { AccountManagement } from './AccountManagement';
import { Assets } from './Assets';
Expand Down Expand Up @@ -110,6 +115,13 @@ export class Polymesh {
this.accountManagement = new AccountManagement(context);
this.identities = new Identities(context);
this.assets = new Assets(context);

this.createTransactionBatch = createProcedureMethod(
{
getProcedureAndArgs: args => [createTransactionBatch, { ...args }],
},
context
) as CreateTransactionBatchProcedureMethod;
}

/**
Expand Down Expand Up @@ -185,7 +197,7 @@ export class Polymesh {
*
* @returns an unsubscribe callback
*/
public onConnectionError(callback: (...args: unknown[]) => unknown): () => void {
public onConnectionError(callback: (...args: unknown[]) => unknown): UnsubCallback {
const {
context: { polymeshApi },
} = this;
Expand All @@ -202,7 +214,7 @@ export class Polymesh {
*
* @returns an unsubscribe callback
*/
public onDisconnect(callback: (...args: unknown[]) => unknown): () => void {
public onDisconnect(callback: (...args: unknown[]) => unknown): UnsubCallback {
const {
context: { polymeshApi },
} = this;
Expand Down Expand Up @@ -230,7 +242,7 @@ export class Polymesh {
*
* @throws if the passed Account is not present in the Signing Manager (or there is no Signing Manager)
*/
public async setSigningAccount(signer: string | Account): Promise<void> {
public setSigningAccount(signer: string | Account): Promise<void> {
return this.context.setSigningAddress(signerToString(signer));
}

Expand All @@ -241,6 +253,41 @@ export class Polymesh {
return this.context.setSigningManager(signingManager);
}

/**
* Create a batch transaction from a list of separate transactions. The list can contain batch transactions as well.
* The result of running this transaction will be an array of the results of each transaction in the list, in the same order.
* Transactions with no return value will produce `undefined` in the resulting array
*
* @param args.transactions - list of {@link base/PolymeshTransaction!PolymeshTransaction} or {@link base/PolymeshTransactionBatch!PolymeshTransactionBatch}
*
* @example Batching 3 ticker reservation transactions
*
* ```typescript
* const tx1 = await sdk.assets.reserveTicker({ ticker: 'FOO' });
* const tx2 = await sdk.assets.reserveTicker({ ticker: 'BAR' });
* const tx3 = await sdk.assets.reserveTicker({ ticker: 'BAZ' });
*
* const batch = sdk.createTransactionBatch({ transactions: [tx1, tx2, tx3] as const });
*
* const [res1, res2, res3] = await batch.run();
* ```
*
* @example Specifying the signer account for the whole batch
*
* ```typescript
* const batch = sdk.createTransactionBatch({ transactions: [tx1, tx2, tx3] as const }, { signingAccount: 'someAddress' });
*
* const [res1, res2, res3] = await batch.run();
* ```
*
* @note it is mandatory to use the `as const` type assertion when passing in the transaction array to the method in order to get the correct types
* for the results of running the batch
* @note if a signing Account is not specified, the default one will be used (the one returned by `sdk.accountManagement.getSigningAccount()`)
* @note all fees in the resulting batch must be paid by the calling Account, regardless of any exceptions that would normally be made for
* the individual transactions (such as subsidies or accepting invitations to join an Identity)
*/
public createTransactionBatch: CreateTransactionBatchProcedureMethod;

/* eslint-disable @typescript-eslint/naming-convention */
/* istanbul ignore next: not part of the official public API */
/**
Expand Down
Loading

0 comments on commit 84cda4d

Please sign in to comment.