@taqueria/plugin-taquito 0.22.2 → 0.23.0-rc.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -18,6 +18,9 @@ taq install @taqueria/plugin-taquito
18
18
 
19
19
  The target networks, sandboxes, and environments are configured in the Taqueria project's `config.json` file. For additional information on configuring network, documentation can be found [here](/docs/config/networks/)
20
20
 
21
+ > ### :page_with_curl: Note
22
+ > Network environments have the notion of Taqueria Operator Account. This account is meant to be used internally and it is generated for you if it doesn't already exist. Instructions on how to fund the account is provided by the `taq` binary when the account is first generated
23
+
21
24
  ## The `taq originate` task
22
25
 
23
26
  Basic usage is:
@@ -40,10 +43,14 @@ After origination, an alias will be created to refer to the originated contract'
40
43
 
41
44
  - To target a different environment, use the `--env` flag with the named Taqueria environment you want to target. E.g. `taq originate filename -env kathmandunetEnv`
42
45
 
46
+ - By default, the amount of mutez sent is `0`. Use the `--mutez` flag to specify an amount you want
47
+
43
48
  - To originate a contract with a specific storage value, use the `--storage` flag and supply the name of the storage file that contains the storage value. E.g. `taq originate contractName --storage someStorage.tz`
44
49
 
45
50
  - To provide an alias for the originated contract explicitly, use the `--alias` flag and supply a name
46
51
 
52
+ - By default, it uses the Taqueria Operator Account to do the operation, but you may override it with an account of your choice by providing the `--sender` flag. E.g. `--sender alice`
53
+
47
54
  ## The `taq transfer` task
48
55
 
49
56
  Basic usage is:
@@ -62,21 +69,47 @@ This allows interactions from implicit accounts to implicit or smart contract ac
62
69
 
63
70
  - To target a different environment, use the `--env` flag with the named Taqueria environment you want to target
64
71
 
65
- - By default, the amount of tez sent is `0`. Use the `--tez` flag to specify an amount you want
72
+ - By default, the amount of mutez sent is `0`. Use the `--mutez` flag to specify an amount you want
66
73
 
67
74
  - By default, the parameter is `Unit`. Use the `--param` flag to specify a filename, in `artifacts`, that contains the content of the parameter for the transfer/call
68
75
 
69
76
  - By default, the entrypoint is `default`, which points to no specific annotated entrypoint. Use `--entrypoint` to specify an annotated entrypoint to call. E.g. if the parameter type of a Michelson contract is `(or (or (int %decrement) (int %increment)) (unit %reset))`, then there are two ways to call the `increment` entrypoint, with parameter `(Left (Right 14))` or with parameter `14` if your command contains `--entrypoint increment`
70
77
 
78
+ - By default, it uses the Taqueria Operator Account to do the operation, but you may override it with an account of your choice by providing the `--sender` flag. E.g. `--sender alice`
79
+
71
80
  ### Examples
72
81
 
73
- `taq transfer counter --param counter.parameter.param1.tz` will call a smart contract aliased as `counter` in the default environment with the parameter contained in that `.tz` file, transferring `0` tez
82
+ `taq transfer counter --param counter.parameter.param1.tz` will call a smart contract aliased as `counter` in the default environment with the parameter contained in that `.tz` file, transferring `0` mutez
74
83
 
75
- `taq transfer tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb --tez 20` will transfer `20` tez to that address, which is some implicit account
84
+ `taq transfer tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb --mutez 20` will transfer `20` mutez to that address, which is some implicit account
76
85
 
77
86
  > ### :page_with_curl: Note
78
87
  > `transfer` and `call` are exactly the same task. They are synonyms
79
88
 
89
+ ## The `taq instantiate-account` task
90
+
91
+ Basic usage is:
92
+
93
+ ```shell
94
+ taq instantiate-account
95
+ ```
96
+
97
+ ### Basic description
98
+
99
+ It instantiates all accounts in the `accounts` field at the root level of `.taq/config.json` (referred as "declared accounts") to a target environment. The accounts instantiated are referred as "instantiated accounts". E.g. `taq instantiate-account --env testing`
100
+
101
+ ## The `taq fund` task
102
+
103
+ Basic usage is:
104
+
105
+ ```shell
106
+ taq fund
107
+ ```
108
+
109
+ ### Basic description
110
+
111
+ It funds all the instantiated accounts in a target environment up to the amount declared in the `accounts` field at the root level of `.taq/config.json` where the funder is the Taqueria Operator Account in that environment. E.g. `taq fund --env testing`
112
+
80
113
  ## Plugin Architecture
81
114
 
82
115
  This is a plugin developed for Taqueria built on NodeJS using the Taqueria Node SDK and distributed via NPM
package/_readme.eta CHANGED
@@ -20,6 +20,10 @@ taq install @taqueria/plugin-taquito
20
20
 
21
21
  The target networks, sandboxes, and environments are configured in the Taqueria project's `config.json` file. For additional information on configuring network, documentation can be found [here](/docs/config/networks/)
22
22
 
23
+ <%~ it.noteOpenAdmonition %>
24
+ Network environments have the notion of Taqueria Operator Account. This account is meant to be used internally and it is generated for you if it doesn't already exist. Instructions on how to fund the account is provided by the `taq` binary when the account is first generated
25
+ <%= it.closeAdmonition %>
26
+
23
27
  ## The `taq originate` task
24
28
 
25
29
  Basic usage is:
@@ -42,10 +46,14 @@ After origination, an alias will be created to refer to the originated contract'
42
46
 
43
47
  - To target a different environment, use the `--env` flag with the named Taqueria environment you want to target. E.g. `taq originate filename -env kathmandunetEnv`
44
48
 
49
+ - By default, the amount of mutez sent is `0`. Use the `--mutez` flag to specify an amount you want
50
+
45
51
  - To originate a contract with a specific storage value, use the `--storage` flag and supply the name of the storage file that contains the storage value. E.g. `taq originate contractName --storage someStorage.tz`
46
52
 
47
53
  - To provide an alias for the originated contract explicitly, use the `--alias` flag and supply a name
48
54
 
55
+ - By default, it uses the Taqueria Operator Account to do the operation, but you may override it with an account of your choice by providing the `--sender` flag. E.g. `--sender alice`
56
+
49
57
  ## The `taq transfer` task
50
58
 
51
59
  Basic usage is:
@@ -64,22 +72,48 @@ This allows interactions from implicit accounts to implicit or smart contract ac
64
72
 
65
73
  - To target a different environment, use the `--env` flag with the named Taqueria environment you want to target
66
74
 
67
- - By default, the amount of tez sent is `0`. Use the `--tez` flag to specify an amount you want
75
+ - By default, the amount of mutez sent is `0`. Use the `--mutez` flag to specify an amount you want
68
76
 
69
77
  - By default, the parameter is `Unit`. Use the `--param` flag to specify a filename, in `artifacts`, that contains the content of the parameter for the transfer/call
70
78
 
71
79
  - By default, the entrypoint is `default`, which points to no specific annotated entrypoint. Use `--entrypoint` to specify an annotated entrypoint to call. E.g. if the parameter type of a Michelson contract is `(or (or (int %decrement) (int %increment)) (unit %reset))`, then there are two ways to call the `increment` entrypoint, with parameter `(Left (Right 14))` or with parameter `14` if your command contains `--entrypoint increment`
72
80
 
81
+ - By default, it uses the Taqueria Operator Account to do the operation, but you may override it with an account of your choice by providing the `--sender` flag. E.g. `--sender alice`
82
+
73
83
  ### Examples
74
84
 
75
- `taq transfer counter --param counter.parameter.param1.tz` will call a smart contract aliased as `counter` in the default environment with the parameter contained in that `.tz` file, transferring `0` tez
85
+ `taq transfer counter --param counter.parameter.param1.tz` will call a smart contract aliased as `counter` in the default environment with the parameter contained in that `.tz` file, transferring `0` mutez
76
86
 
77
- `taq transfer tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb --tez 20` will transfer `20` tez to that address, which is some implicit account
87
+ `taq transfer tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb --mutez 20` will transfer `20` mutez to that address, which is some implicit account
78
88
 
79
89
  <%~ it.noteOpenAdmonition %>
80
90
  `transfer` and `call` are exactly the same task. They are synonyms
81
91
  <%= it.closeAdmonition %>
82
92
 
93
+ ## The `taq instantiate-account` task
94
+
95
+ Basic usage is:
96
+
97
+ ```shell
98
+ taq instantiate-account
99
+ ```
100
+
101
+ ### Basic description
102
+
103
+ It instantiates all accounts in the `accounts` field at the root level of `.taq/config.json` (referred as "declared accounts") to a target environment. The accounts instantiated are referred as "instantiated accounts". E.g. `taq instantiate-account --env testing`
104
+
105
+ ## The `taq fund` task
106
+
107
+ Basic usage is:
108
+
109
+ ```shell
110
+ taq fund
111
+ ```
112
+
113
+ ### Basic description
114
+
115
+ It funds all the instantiated accounts in a target environment up to the amount declared in the `accounts` field at the root level of `.taq/config.json` where the funder is the Taqueria Operator Account in that environment. E.g. `taq fund --env testing`
116
+
83
117
  ## Plugin Architecture
84
118
 
85
119
  This is a plugin developed for Taqueria built on NodeJS using the Taqueria Node SDK and distributed via NPM
package/common.ts ADDED
@@ -0,0 +1,194 @@
1
+ import {
2
+ getAccountPrivateKey,
3
+ getDefaultSandboxAccount,
4
+ getNetworkConfig,
5
+ getSandboxConfig,
6
+ sendAsyncErr,
7
+ TAQ_OPERATOR_ACCOUNT,
8
+ } from '@taqueria/node-sdk';
9
+ import { Environment, NetworkConfig, RequestArgs, SandboxAccountConfig, SandboxConfig } from '@taqueria/node-sdk/types';
10
+ import { importKey, InMemorySigner } from '@taquito/signer';
11
+ import { TezosToolkit } from '@taquito/taquito';
12
+
13
+ export interface OriginateOpts extends RequestArgs.ProxyRequestArgs {
14
+ contract: string;
15
+ storage: string;
16
+ alias?: string;
17
+ sender?: string;
18
+ mutez?: string;
19
+ }
20
+
21
+ export interface TransferOpts extends RequestArgs.ProxyRequestArgs {
22
+ contract: string;
23
+ mutez?: string;
24
+ param?: string;
25
+ entrypoint?: string;
26
+ sender?: string;
27
+ }
28
+
29
+ export interface InstantiateAccountOpts extends RequestArgs.ProxyRequestArgs {
30
+ }
31
+
32
+ export interface FundOpts extends RequestArgs.ProxyRequestArgs {
33
+ }
34
+
35
+ // To be used for the main entrypoint of the plugin
36
+ export type IntersectionOpts = OriginateOpts & TransferOpts & InstantiateAccountOpts & FundOpts;
37
+
38
+ // To be used for common functions in this file
39
+ type UnionOpts = OriginateOpts | TransferOpts | InstantiateAccountOpts | FundOpts;
40
+
41
+ export const getEnvTypeAndNodeConfig = (
42
+ parsedArgs: UnionOpts,
43
+ env: Environment.t,
44
+ ): Promise<['Network', NetworkConfig.t] | ['Sandbox', SandboxConfig.t]> => {
45
+ const targetConstraintErrMsg = 'Each environment can only have one target, be it a network or a sandbox';
46
+ if (env.networks?.length === 1 && env.sandboxes?.length === 1) return sendAsyncErr(targetConstraintErrMsg);
47
+ if (env.networks?.length === 1) {
48
+ const networkName = env.networks[0];
49
+ const network = getNetworkConfig(parsedArgs)(networkName);
50
+ if (!network) {
51
+ return sendAsyncErr(
52
+ `The current environment is configured to use a network called '${networkName}'; however, no network of this name has been configured in .taq/config.json`,
53
+ );
54
+ }
55
+ return Promise.resolve(['Network', network]);
56
+ }
57
+ if (env.sandboxes?.length === 1) {
58
+ const sandboxName = env.sandboxes[0];
59
+ const sandbox = getSandboxConfig(parsedArgs)(sandboxName);
60
+ if (!sandbox) {
61
+ return sendAsyncErr(
62
+ `The current environment is configured to use a sandbox called '${sandboxName}'; however, no sandbox of this name has been configured in .taq/config.json`,
63
+ );
64
+ }
65
+ return Promise.resolve(['Sandbox', sandbox]);
66
+ }
67
+ return sendAsyncErr(targetConstraintErrMsg);
68
+ };
69
+
70
+ export const configureToolKitForSandbox = async (sandbox: SandboxConfig.t, sender?: string): Promise<TezosToolkit> => {
71
+ let accountKey: string;
72
+ if (sender && sender !== 'default') {
73
+ const accounts = getSandboxInstantiatedAccounts(sandbox);
74
+ if (accounts.hasOwnProperty(sender)) {
75
+ accountKey = accounts[sender].secretKey;
76
+ } else {
77
+ return sendAsyncErr(
78
+ `${sender} is not an account instantiated in the current environment. Check .taq/config.json`,
79
+ );
80
+ }
81
+ } else {
82
+ const defaultAccount = getDefaultSandboxAccount(sandbox);
83
+ if (!defaultAccount) {
84
+ return sendAsyncErr(
85
+ `No default account is specified in the sandbox to perform the operation. Please use the --sender flag to explicitly specify the account to use as the sender of the operation`,
86
+ );
87
+ }
88
+ accountKey = defaultAccount.secretKey;
89
+ }
90
+
91
+ const tezos = new TezosToolkit(sandbox.rpcUrl as string);
92
+ tezos.setProvider({ signer: new InMemorySigner(accountKey.replace(/^unencrypted:/, '')) });
93
+ return tezos;
94
+ };
95
+
96
+ export const configureToolKitForNetwork = async (
97
+ parsedArgs: UnionOpts,
98
+ network: NetworkConfig.t,
99
+ sender?: string,
100
+ ): Promise<TezosToolkit> => {
101
+ let account: string;
102
+ if (sender && sender !== TAQ_OPERATOR_ACCOUNT) {
103
+ const accounts = getNetworkInstantiatedAccounts(network);
104
+ if (accounts.hasOwnProperty(sender)) {
105
+ account = sender;
106
+ } else {
107
+ return sendAsyncErr(
108
+ `${sender} is not an account instantiated in the current environment. Check .taq/config.json`,
109
+ );
110
+ }
111
+ } else {
112
+ account = TAQ_OPERATOR_ACCOUNT;
113
+ }
114
+
115
+ const tezos = new TezosToolkit(network.rpcUrl as string);
116
+ const key = await getAccountPrivateKey(parsedArgs, network, account);
117
+ await importKey(tezos, key);
118
+ return tezos;
119
+ };
120
+
121
+ export const getDeclaredAccounts = (parsedArgs: UnionOpts): Record<string, number> =>
122
+ Object.entries(parsedArgs.config.accounts).reduce(
123
+ (acc, declaredAccount) => {
124
+ const alias: string = declaredAccount[0];
125
+ const mutez: string | number = declaredAccount[1];
126
+ return {
127
+ ...acc,
128
+ [alias]: typeof mutez === 'string' ? parseFloat(mutez) : mutez,
129
+ };
130
+ },
131
+ {} as Record<string, number>,
132
+ );
133
+
134
+ export const getSandboxInstantiatedAccounts = (sandbox: SandboxConfig.t): Record<string, SandboxAccountConfig.t> =>
135
+ (sandbox?.accounts)
136
+ ? Object.entries(sandbox.accounts).reduce(
137
+ (acc, instantiatedAccount) => {
138
+ const alias: string = instantiatedAccount[0];
139
+ const keys = instantiatedAccount[1];
140
+ return alias !== 'default'
141
+ ? {
142
+ ...acc,
143
+ [alias]: keys,
144
+ }
145
+ : acc;
146
+ },
147
+ {},
148
+ )
149
+ : {};
150
+
151
+ export const getNetworkInstantiatedAccounts = (network: NetworkConfig.t): Record<string, any> =>
152
+ network.accounts
153
+ ? Object.entries(network.accounts).reduce(
154
+ (acc, instantiatedAccount) => {
155
+ const alias: string = instantiatedAccount[0];
156
+ const keys = instantiatedAccount[1];
157
+ return alias !== TAQ_OPERATOR_ACCOUNT
158
+ ? {
159
+ ...acc,
160
+ [alias]: keys,
161
+ }
162
+ : acc;
163
+ },
164
+ {},
165
+ )
166
+ : {};
167
+
168
+ export const generateAccountKeys = async (
169
+ parsedArgs: UnionOpts,
170
+ network: NetworkConfig.t,
171
+ account: string,
172
+ ): Promise<void> => {
173
+ const tezos = new TezosToolkit(network.rpcUrl as string);
174
+ const key = await getAccountPrivateKey(parsedArgs, network, account);
175
+ await importKey(tezos, key);
176
+ };
177
+
178
+ export const handleOpsError = (err: unknown, env: string): Promise<never> => {
179
+ if (err instanceof Error) {
180
+ const msg = err.message;
181
+ if (/ENOTFOUND/.test(msg)) return sendAsyncErr('The RPC URL may be invalid. Check ./.taq/config.json');
182
+ if (/ECONNREFUSED/.test(msg)) return sendAsyncErr('The RPC URL may be down or the sandbox is not running');
183
+ if (/empty_implicit_contract/.test(msg)) {
184
+ const result = msg.match(/(?<="implicit":")tz[^"]+(?=")/);
185
+ const publicKeyHash = result ? result[0] : undefined;
186
+ if (publicKeyHash) {
187
+ return sendAsyncErr(
188
+ `The account ${publicKeyHash} for the target environment, "${env}", may not be funded\nTo fund this account:\n1. Go to https://teztnets.xyz and click "Faucet" of the target testnet\n2. Copy and paste the above key into the wallet address field\n3. Request some Tez (Note that you might need to wait for a few seconds for the network to register the funds)`,
189
+ );
190
+ }
191
+ }
192
+ }
193
+ return sendAsyncErr(`Error while performing operation:\n${err} ${JSON.stringify(err, null, 2)}`);
194
+ };
package/fund.ts ADDED
@@ -0,0 +1,92 @@
1
+ import {
2
+ getCurrentEnvironment,
3
+ getCurrentEnvironmentConfig,
4
+ sendAsyncErr,
5
+ sendJsonRes,
6
+ sendWarn,
7
+ } from '@taqueria/node-sdk';
8
+ import { TezosToolkit } from '@taquito/taquito';
9
+ import {
10
+ configureToolKitForNetwork,
11
+ FundOpts as Opts,
12
+ getDeclaredAccounts,
13
+ getEnvTypeAndNodeConfig,
14
+ getNetworkInstantiatedAccounts,
15
+ } from './common';
16
+ import { ContractInfo, performTransferOps } from './transfer';
17
+
18
+ type TableRow = {
19
+ accountAlias: string;
20
+ accountAddress: string;
21
+ mutezFunded: string;
22
+ };
23
+
24
+ const getAccountsInfo = (
25
+ parsedArgs: Opts,
26
+ tezos: TezosToolkit,
27
+ instantiatedAccounts: Record<string, any>,
28
+ ): Promise<ContractInfo[]> =>
29
+ Promise.all(
30
+ Object.entries(instantiatedAccounts)
31
+ .map(async (instantiatedAccount: [string, any]) => {
32
+ const alias = instantiatedAccount[0];
33
+ const aliasInfo = instantiatedAccount[1];
34
+
35
+ const declaredMutez: number | undefined = getDeclaredAccounts(parsedArgs)[alias];
36
+ const currentBalanceInMutez = (await tezos.tz.getBalance(aliasInfo.publicKeyHash)).toNumber();
37
+ const amountToFillInMutez = declaredMutez ? Math.max(declaredMutez - currentBalanceInMutez, 0) : 0;
38
+
39
+ if (!declaredMutez) {
40
+ sendWarn(
41
+ `Warning: ${alias} is instantiated in the target environment but not declared in the root level "accounts" field of ./.taq/config.json so ${alias} will not be funded as you don't have a declared tez amount set there for ${alias}\n`,
42
+ );
43
+ }
44
+
45
+ return {
46
+ contractAlias: alias,
47
+ contractAddress: aliasInfo.publicKeyHash,
48
+ parameter: 'Unit',
49
+ entrypoint: 'default',
50
+ mutezTransfer: parseInt(amountToFillInMutez.toString()),
51
+ };
52
+ }),
53
+ )
54
+ .then(accountsInfo => accountsInfo.filter(accountInfo => accountInfo.mutezTransfer !== 0))
55
+ .catch(err => sendAsyncErr(`Something went wrong while extracting account information - ${err}`));
56
+
57
+ const prepAccountsInfoForDisplay = (accountsInfo: ContractInfo[]): TableRow[] =>
58
+ accountsInfo.map(accountInfo => {
59
+ return {
60
+ accountAlias: accountInfo.contractAlias,
61
+ accountAddress: accountInfo.contractAddress,
62
+ mutezFunded: accountInfo.mutezTransfer.toString(),
63
+ };
64
+ });
65
+
66
+ const fund = async (parsedArgs: Opts): Promise<void> => {
67
+ const env = getCurrentEnvironmentConfig(parsedArgs);
68
+ if (!env) return sendAsyncErr(`There is no environment called ${parsedArgs.env} in your config.json`);
69
+ try {
70
+ const [envType, nodeConfig] = await getEnvTypeAndNodeConfig(parsedArgs, env);
71
+ if (envType !== 'Network') return sendAsyncErr('taq fund can only be executed in a network environment');
72
+ const tezos = await configureToolKitForNetwork(parsedArgs, nodeConfig);
73
+
74
+ const instantiatedAccounts = getNetworkInstantiatedAccounts(nodeConfig);
75
+
76
+ const accountsInfo = await getAccountsInfo(parsedArgs, tezos, instantiatedAccounts);
77
+ if (accountsInfo.length === 0) {
78
+ return sendJsonRes(
79
+ `All instantiated accounts in the current environment, "${parsedArgs.env}", are funded up to or beyond the declared amount`,
80
+ );
81
+ }
82
+
83
+ await performTransferOps(tezos, getCurrentEnvironment(parsedArgs), accountsInfo);
84
+
85
+ const accountsInfoForDisplay = prepAccountsInfoForDisplay(accountsInfo);
86
+ return sendJsonRes(accountsInfoForDisplay);
87
+ } catch {
88
+ return sendAsyncErr('No operations performed');
89
+ }
90
+ };
91
+
92
+ export default fund;