generated from PolymeshAssociation/typescript-boilerplate
/
controllerTransfer.ts
100 lines (85 loc) · 2.39 KB
/
controllerTransfer.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
import BigNumber from 'bignumber.js';
import { DefaultPortfolio, PolymeshError, Procedure, SecurityToken } from '~/internal';
import { ErrorCode, PortfolioLike, RoleType, TxTags } from '~/types';
import { ProcedureAuthorization } from '~/types/internal';
import {
numberToBalance,
portfolioIdToMeshPortfolioId,
portfolioIdToPortfolio,
portfolioLikeToPortfolioId,
stringToTicker,
} from '~/utils/conversion';
export interface ControllerTransferParams {
/**
* portfolio (or portfolio ID) from which tokens will be transferred
*/
originPortfolio: PortfolioLike;
/**
* amount of tokens to transfer
*/
amount: BigNumber;
}
/**
* @hidden
*/
export type Params = { ticker: string } & ControllerTransferParams;
/**
* @hidden
*/
export async function prepareControllerTransfer(
this: Procedure<Params, void>,
args: Params
): Promise<void> {
const {
context: {
polymeshApi: { tx },
},
context,
} = this;
const { ticker, originPortfolio, amount } = args;
const token = new SecurityToken({ ticker }, context);
const originPortfolioId = portfolioLikeToPortfolioId(originPortfolio);
const fromPortfolio = portfolioIdToPortfolio(originPortfolioId, context);
const [{ free }] = await fromPortfolio.getTokenBalances({
tokens: [token],
});
if (free.lt(amount)) {
throw new PolymeshError({
code: ErrorCode.ValidationError,
message: 'The Portfolio does not have enough free balance for this transfer',
data: { free },
});
}
this.addTransaction(
tx.asset.controllerTransfer,
{},
stringToTicker(ticker, context),
numberToBalance(amount, context),
portfolioIdToMeshPortfolioId(originPortfolioId, context)
);
}
/**
* @hidden
*/
export async function getAuthorization(
this: Procedure<Params, void>,
{ ticker }: Params
): Promise<ProcedureAuthorization> {
const { context } = this;
const token = new SecurityToken({ ticker }, context);
const { did } = await context.getCurrentIdentity();
const portfolioId = { did };
return {
roles: [{ type: RoleType.PortfolioCustodian, portfolioId }],
permissions: {
tokens: [token],
transactions: [TxTags.asset.ControllerTransfer],
portfolios: [new DefaultPortfolio({ did }, context)],
},
};
}
/**
* @hidden
*/
export const controllerTransfer = (): Procedure<Params, void> =>
new Procedure(prepareControllerTransfer, getAuthorization);