@tatumio/flow 2.0.1-alpha.351 → 2.0.1-alpha.353

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. package/package.json +10 -8
  2. package/src/index.d.ts +1 -0
  3. package/src/index.js +1 -0
  4. package/src/index.js.map +1 -1
  5. package/src/lib/flow.constants.d.ts +12 -0
  6. package/src/lib/flow.constants.js +13 -1
  7. package/src/lib/flow.constants.js.map +1 -1
  8. package/src/lib/flow.sdk.d.ts +64 -51
  9. package/src/lib/flow.sdk.errors.d.ts +4 -2
  10. package/src/lib/flow.sdk.errors.js +8 -5
  11. package/src/lib/flow.sdk.errors.js.map +1 -1
  12. package/src/lib/flow.sdk.js +12 -1
  13. package/src/lib/flow.sdk.js.map +1 -1
  14. package/src/lib/flow.types.d.ts +56 -0
  15. package/src/lib/flow.types.js +38 -0
  16. package/src/lib/flow.types.js.map +1 -0
  17. package/src/lib/services/flow.blockchain.js +7 -7
  18. package/src/lib/services/flow.blockchain.js.map +1 -1
  19. package/src/lib/services/flow.kms.d.ts +11 -9
  20. package/src/lib/services/flow.kms.js +22 -10
  21. package/src/lib/services/flow.kms.js.map +1 -1
  22. package/src/lib/services/flow.provider.d.ts +11 -0
  23. package/src/lib/services/flow.provider.js +17 -0
  24. package/src/lib/services/flow.provider.js.map +1 -0
  25. package/src/lib/services/flow.tx.d.ts +86 -94
  26. package/src/lib/services/flow.tx.js +389 -307
  27. package/src/lib/services/flow.tx.js.map +1 -1
  28. package/src/lib/services/flow.tx.templates.d.ts +1 -0
  29. package/src/lib/services/flow.tx.templates.js +23 -12
  30. package/src/lib/services/flow.tx.templates.js.map +1 -1
  31. package/src/lib/services/flow.virtualAccount.d.ts +31 -0
  32. package/src/lib/services/flow.virtualAccount.js +20 -0
  33. package/src/lib/services/flow.virtualAccount.js.map +1 -0
  34. package/src/lib/utils/flow.utils.d.ts +6 -0
  35. package/src/lib/utils/flow.utils.js +18 -0
  36. package/src/lib/utils/flow.utils.js.map +1 -0
@@ -1,33 +1,23 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.flowTxService = exports.FLOW_MAINNET_ADDRESSES = exports.FLOW_TESTNET_ADDRESSES = void 0;
3
+ exports.flowTxService = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const elliptic = tslib_1.__importStar(require("elliptic"));
6
6
  const fcl = tslib_1.__importStar(require("@onflow/fcl"));
7
7
  const types = tslib_1.__importStar(require("@onflow/types"));
8
8
  const util_encode_key_1 = require("@onflow/util-encode-key");
9
9
  const sha3_1 = tslib_1.__importDefault(require("sha3"));
10
- const shared_core_1 = require("@tatumio/shared-core");
11
10
  const flow_tx_templates_1 = require("./flow.tx.templates");
12
11
  const flow_sdk_wallet_1 = require("./flow.sdk.wallet");
13
- const flow_blockchain_1 = require("./flow.blockchain");
14
12
  const flow_sdk_errors_1 = require("../flow.sdk.errors");
15
13
  const shared_abstract_sdk_1 = require("@tatumio/shared-abstract-sdk");
16
- exports.FLOW_TESTNET_ADDRESSES = {
17
- FlowToken: '0x7e60df042a9c0868',
18
- FungibleToken: '0x9a0766d93b6608b7',
19
- FUSD: '0xe223d8a629e49c68',
20
- TatumMultiNFT: '0x87fe4ebd0cddde06',
21
- };
22
- exports.FLOW_MAINNET_ADDRESSES = {
23
- FlowToken: '0x1654653399040a61',
24
- FungibleToken: '0xf233dcee88fe0abe',
25
- FUSD: '0x3c5959b568896393',
26
- TatumMultiNFT: '0x354e6721564ccd2c',
27
- };
28
- const flowTxService = (args) => {
14
+ const flow_constants_1 = require("../flow.constants");
15
+ const shared_core_1 = require("@tatumio/shared-core");
16
+ const api_client_1 = require("@tatumio/api-client");
17
+ const bignumber_js_1 = tslib_1.__importDefault(require("bignumber.js"));
18
+ const lodash_1 = tslib_1.__importDefault(require("lodash"));
19
+ const flowTxService = (provider, apiCalls) => {
29
20
  const flowSdkWallet = (0, flow_sdk_wallet_1.flowWallet)();
30
- const flowSdkBlockchain = (0, flow_blockchain_1.flowBlockchain)(args);
31
21
  const txTemplates = (0, flow_tx_templates_1.flowTxTemplates)();
32
22
  const sign = (pk, msg) => {
33
23
  const keyPair = new elliptic.ec('secp256k1').keyFromPrivate(pk);
@@ -38,34 +28,261 @@ const flowTxService = (args) => {
38
28
  };
39
29
  const getSigner = (pk, address, keyId = 0) => {
40
30
  return {
41
- signer: (account) => {
42
- return Object.assign(Object.assign({}, account), { tempId: `${address}-${keyId}`, addr: fcl.sansPrefix(address), keyId: Number(keyId), signingFunction: (data) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
31
+ signer: (account) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
32
+ return Object.assign(Object.assign({}, account), { tempId: `${address}-${keyId}`, addr: fcl.sansPrefix(address), keyId: Number(keyId), signingFunction: (data) => {
43
33
  return {
44
34
  addr: fcl.withPrefix(address),
45
35
  keyId: Number(keyId),
46
36
  signature: sign(pk, Buffer.from(data.message, 'hex')),
47
37
  };
48
- }) });
49
- },
38
+ } });
39
+ }),
50
40
  };
51
41
  };
52
42
  const getApiSigner = (isPayer) => {
53
- const keyHash = Date.now();
43
+ const hash = Date.now();
44
+ const keyHash = `FLOW_PROPOSAL_KEY_${hash}`;
54
45
  const signer = (account) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
55
- const { address, keyId } = yield flowSdkBlockchain.getSignKey(isPayer);
46
+ const { address, keyId } = yield getProposalKeyOrFetch(keyHash, isPayer);
56
47
  if (!isPayer) {
57
- process.env[`FLOW_PROPOSAL_KEY_${keyHash}`] = `${keyId}`;
48
+ storeProposalKey(keyHash, address, keyId);
58
49
  }
59
50
  return Object.assign(Object.assign({}, account), { tempId: `${address}-${keyId}`, addr: fcl.sansPrefix(address), keyId, signingFunction: (data) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
60
51
  return {
61
52
  addr: fcl.withPrefix(address),
62
53
  keyId: Number(keyId),
63
- signature: (yield flowSdkBlockchain.signWithKey(data.message, isPayer)).signature,
54
+ signature: (yield apiCalls.signWithKey(data.message, isPayer)).signature,
64
55
  };
65
56
  }) });
66
57
  });
67
- return { signer, keyHash: `FLOW_PROPOSAL_KEY_${keyHash}` };
58
+ return { signer, keyHash: keyHash };
68
59
  };
60
+ const sendCreateAccountFromPublicKey = (body, proposer, payer) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
61
+ var _a;
62
+ const code = txTemplates.prepareCreateAccountWithFUSDFromPublicKeyTxTemplate(provider.isTestnet());
63
+ const encodedPublicKey = (0, util_encode_key_1.encodeKey)(body.publicKey, util_encode_key_1.ECDSA_secp256k1, util_encode_key_1.SHA3_256, 1000);
64
+ const txArgs = [{ type: 'String', value: encodedPublicKey }];
65
+ const pk = yield getPrivateKey(body);
66
+ if (!pk)
67
+ throw new flow_sdk_errors_1.FlowSdkError({ code: shared_abstract_sdk_1.SdkErrorCode.FLOW_MISSING_PRIVATE_KEY });
68
+ const auth = getSigner(pk, body.account).signer;
69
+ const { signer: proposalSigner, keyHash } = proposer ? proposer(false) : getApiSigner(false);
70
+ const { signer: payerSigner } = payer ? payer(true) : getApiSigner(true);
71
+ const result = yield _sendTransaction({
72
+ code,
73
+ txArgs,
74
+ proposer: proposalSigner,
75
+ authorizations: [auth],
76
+ payer: payerSigner,
77
+ keyHash,
78
+ });
79
+ return {
80
+ txId: result.id,
81
+ address: (_a = result.events.find((e) => e.type === 'flow.AccountCreated')) === null || _a === void 0 ? void 0 : _a.data.address,
82
+ };
83
+ });
84
+ const sendAddPublicKeyToAccount = (body, proposer, payer) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
85
+ const code = txTemplates.prepareAddPublicKeyToAccountTxTemplate();
86
+ const encodedPublicKey = (0, util_encode_key_1.encodeKey)(body.publicKey, util_encode_key_1.ECDSA_secp256k1, util_encode_key_1.SHA3_256, body.weight || 0);
87
+ const txArgs = [{ type: 'String', value: encodedPublicKey }];
88
+ const pk = yield getPrivateKey(body);
89
+ if (!pk)
90
+ throw new flow_sdk_errors_1.FlowSdkError({ code: shared_abstract_sdk_1.SdkErrorCode.FLOW_MISSING_PRIVATE_KEY });
91
+ const auth = getSigner(pk, body.account).signer;
92
+ const { signer: proposalSigner, keyHash } = proposer ? proposer(false) : getApiSigner(false);
93
+ const { signer: payerSigner } = payer ? payer(true) : getApiSigner(true);
94
+ const result = yield _sendTransaction({
95
+ code,
96
+ txArgs,
97
+ proposer: proposalSigner,
98
+ authorizations: [auth],
99
+ keyHash,
100
+ payer: payerSigner,
101
+ });
102
+ return { txId: result.id, address: result.events[0].data.address };
103
+ });
104
+ const getNftMetadata = (account, id, contractAddress) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
105
+ const code = txTemplates.metadataNftTokenScript(provider.isTestnet());
106
+ const scriptArgs = [
107
+ { type: 'Address', value: account },
108
+ { type: 'UInt64', value: id },
109
+ { type: 'String', value: contractAddress },
110
+ ];
111
+ return sendScript(code, scriptArgs);
112
+ });
113
+ const getNftTokenByAddress = (account, tokenType) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
114
+ const code = txTemplates.tokenByAddressNftTokenScript(provider.isTestnet());
115
+ const scriptArgs = [
116
+ { type: 'Address', value: account },
117
+ { type: 'String', value: tokenType },
118
+ ];
119
+ return sendScript(code, scriptArgs);
120
+ });
121
+ const sendNftMintToken = (body, proposer, payer) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
122
+ var _b;
123
+ const bodyWithChain = Object.assign(Object.assign({}, body), { chain: shared_core_1.Blockchain.FLOW });
124
+ const code = txTemplates.mintNftTokenTxTemplate(provider.isTestnet());
125
+ const { url, contractAddress: tokenType, to, account } = bodyWithChain;
126
+ const txArgs = [
127
+ { type: 'Address', value: to },
128
+ { type: 'String', value: url },
129
+ { type: 'String', value: tokenType },
130
+ ];
131
+ const pk = yield getPrivateKey(bodyWithChain);
132
+ if (!pk)
133
+ throw new flow_sdk_errors_1.FlowSdkError({ code: shared_abstract_sdk_1.SdkErrorCode.FLOW_MISSING_PRIVATE_KEY });
134
+ const auth = getSigner(pk, account).signer;
135
+ const { signer: proposalSigner, keyHash } = proposer ? proposer(false) : getApiSigner(false);
136
+ const { signer: payerSigner } = payer ? payer(true) : getApiSigner(true);
137
+ const result = yield _sendTransaction({
138
+ code,
139
+ txArgs,
140
+ proposer: proposalSigner,
141
+ authorizations: [auth],
142
+ keyHash,
143
+ payer: payerSigner,
144
+ });
145
+ return {
146
+ txId: result.id,
147
+ tokenId: `${(_b = result.events.find((e) => e.type.includes('TatumMultiNFT.Minted'))) === null || _b === void 0 ? void 0 : _b.data.id}`,
148
+ };
149
+ });
150
+ const sendNftMintMultipleToken = (body, proposer, payer) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
151
+ const bodyWithChain = Object.assign(Object.assign({}, body), { chain: shared_core_1.Blockchain.FLOW });
152
+ const code = txTemplates.mintMultipleNftTokenTxTemplate(provider.isTestnet());
153
+ const { url, contractAddress: tokenType, to, account } = bodyWithChain;
154
+ const txArgs = [
155
+ { type: 'Array', subType: 'Address', value: to },
156
+ {
157
+ type: 'Array',
158
+ subType: 'String',
159
+ value: url,
160
+ },
161
+ { type: 'String', value: tokenType },
162
+ ];
163
+ const pk = yield getPrivateKey(bodyWithChain);
164
+ if (!pk)
165
+ throw new flow_sdk_errors_1.FlowSdkError({ code: shared_abstract_sdk_1.SdkErrorCode.FLOW_MISSING_PRIVATE_KEY });
166
+ const auth = getSigner(pk, account).signer;
167
+ const { signer: proposalSigner, keyHash } = proposer ? proposer(false) : getApiSigner(false);
168
+ const { signer: payerSigner } = payer ? payer(true) : getApiSigner(true);
169
+ const result = yield _sendTransaction({
170
+ code,
171
+ txArgs,
172
+ proposer: proposalSigner,
173
+ authorizations: [auth],
174
+ payer: payerSigner,
175
+ keyHash,
176
+ });
177
+ return {
178
+ txId: result.id,
179
+ tokenId: result.events
180
+ .filter((e) => e.type.includes('TatumMultiNFT.Minted'))
181
+ .map((e) => e.data.id),
182
+ };
183
+ });
184
+ const sendNftTransferToken = (body, proposer, payer) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
185
+ const bodyWithChain = Object.assign(Object.assign({}, body), { chain: shared_core_1.Blockchain.FLOW });
186
+ const code = txTemplates.transferNftTokenTxTemplate(provider.isTestnet());
187
+ const { tokenId, to, account } = bodyWithChain;
188
+ const txArgs = [
189
+ { type: 'Address', value: to },
190
+ { type: 'UInt64', value: tokenId },
191
+ ];
192
+ const pk = yield getPrivateKey(bodyWithChain);
193
+ if (!pk)
194
+ throw new flow_sdk_errors_1.FlowSdkError({ code: shared_abstract_sdk_1.SdkErrorCode.FLOW_MISSING_PRIVATE_KEY });
195
+ const auth = getSigner(pk, account).signer;
196
+ const { signer: proposalSigner, keyHash } = proposer ? proposer(false) : getApiSigner(false);
197
+ const { signer: payerSigner } = payer ? payer(true) : getApiSigner(true);
198
+ const result = yield _sendTransaction({
199
+ code,
200
+ txArgs,
201
+ proposer: proposalSigner,
202
+ authorizations: [auth],
203
+ payer: payerSigner,
204
+ keyHash,
205
+ });
206
+ return { txId: result.id };
207
+ });
208
+ const sendNftBurnToken = (body, proposer, payer) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
209
+ const bodyWithChain = Object.assign(Object.assign({}, body), { chain: shared_core_1.Blockchain.FLOW });
210
+ const code = txTemplates.burnNftTokenTxTemplate(provider.isTestnet());
211
+ const { tokenId, contractAddress: tokenType, account } = bodyWithChain;
212
+ const txArgs = [
213
+ { type: 'UInt64', value: tokenId },
214
+ { type: 'String', value: tokenType },
215
+ ];
216
+ const pk = yield getPrivateKey(bodyWithChain);
217
+ if (!pk)
218
+ throw new flow_sdk_errors_1.FlowSdkError({ code: shared_abstract_sdk_1.SdkErrorCode.FLOW_MISSING_PRIVATE_KEY });
219
+ const auth = getSigner(pk, account).signer;
220
+ const { signer: proposalSigner, keyHash } = proposer ? proposer(false) : getApiSigner(false);
221
+ const { signer: payerSigner } = payer ? payer(true) : getApiSigner(true);
222
+ const result = yield _sendTransaction({
223
+ code,
224
+ txArgs,
225
+ proposer: proposalSigner,
226
+ authorizations: [auth],
227
+ payer: payerSigner,
228
+ keyHash,
229
+ });
230
+ return { txId: result.id };
231
+ });
232
+ const sendCustomTransaction = (body, proposer, payer) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
233
+ const pk = yield getPrivateKey(body);
234
+ if (!pk)
235
+ throw new flow_sdk_errors_1.FlowSdkError({ code: shared_abstract_sdk_1.SdkErrorCode.FLOW_MISSING_PRIVATE_KEY });
236
+ const auth = getSigner(pk, body.account).signer;
237
+ const { signer: proposalSigner, keyHash } = proposer ? proposer(false) : getApiSigner(false);
238
+ const { signer: payerSigner } = payer ? payer(true) : getApiSigner(true);
239
+ const result = yield _sendTransaction({
240
+ code: body.transaction,
241
+ txArgs: body.args,
242
+ proposer: proposalSigner,
243
+ authorizations: [auth],
244
+ keyHash,
245
+ payer: payerSigner,
246
+ });
247
+ return { txId: result.id, events: result.events };
248
+ });
249
+ const sendTransaction = (body, proposer, payer) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
250
+ const testnet = provider.isTestnet();
251
+ let tokenAddress;
252
+ let tokenName;
253
+ let tokenStorage;
254
+ if (body.currency === shared_core_1.Blockchain.FLOW) {
255
+ tokenAddress = testnet ? flow_constants_1.FLOW_TESTNET_ADDRESSES.FlowToken : flow_constants_1.FLOW_MAINNET_ADDRESSES.FlowToken;
256
+ tokenName = 'FlowToken';
257
+ tokenStorage = 'flowToken';
258
+ }
259
+ else {
260
+ tokenAddress = testnet ? flow_constants_1.FLOW_TESTNET_ADDRESSES.FUSD : flow_constants_1.FLOW_MAINNET_ADDRESSES.FUSD;
261
+ tokenName = 'FUSD';
262
+ tokenStorage = 'fusd';
263
+ }
264
+ const code = txTemplates.prepareTransferTxTemplate(testnet, tokenAddress, tokenName, tokenStorage);
265
+ const txArgs = [
266
+ { value: parseFloat(body.amount).toFixed(8), type: 'UFix64' },
267
+ { value: body.to, type: 'Address' },
268
+ ];
269
+ const pk = yield getPrivateKey(body);
270
+ if (!pk)
271
+ throw new flow_sdk_errors_1.FlowSdkError({ code: shared_abstract_sdk_1.SdkErrorCode.FLOW_MISSING_PRIVATE_KEY });
272
+ yield checkBalanceOrThrow(body.account, tokenAddress, tokenName, tokenStorage, body.amount);
273
+ const auth = getSigner(pk, body.account).signer;
274
+ const { signer: proposalSigner, keyHash } = proposer ? proposer(false) : getApiSigner(false);
275
+ const { signer: payerSigner } = payer ? payer(true) : getApiSigner(true);
276
+ const result = yield _sendTransaction({
277
+ code,
278
+ txArgs,
279
+ proposer: proposalSigner,
280
+ authorizations: [auth],
281
+ payer: payerSigner,
282
+ keyHash,
283
+ });
284
+ return { txId: result.id };
285
+ });
69
286
  return {
70
287
  sign,
71
288
  getSigner,
@@ -73,294 +290,124 @@ const flowTxService = (args) => {
73
290
  /**
74
291
  * Create account on the FLOW network. It automatically creates 100 0-weight proposal keys, which are managed by Tatum API - index 1-100.
75
292
  * Main 1000 weight authorizer key is stored as a first one on index 0.
76
- * @param testnet if we use testnet or not
77
- * @param publicKey public key to assign to address as authorizer (1000 weight) key
78
- * @param signerAddress address of the authorizer creator of the address on the chain
79
- * @param signerPrivateKey private key of the authorizer creator of the address on the chain
80
- * @param proposer function to obtain proposer key from
81
- * @param payer function to obtain payer key from
82
- */
83
- createAccountFromPublicKey: (testnet, publicKey, signerAddress, signerPrivateKey, proposer, payer) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
84
- var _a;
85
- const code = txTemplates.prepareCreateAccountWithFUSDFromPublicKeyTxTemplate(testnet);
86
- const encodedPublicKey = (0, util_encode_key_1.encodeKey)(publicKey, util_encode_key_1.ECDSA_secp256k1, util_encode_key_1.SHA3_256, 1000);
87
- const args = [{ type: 'String', value: encodedPublicKey }];
88
- const auth = getSigner(signerPrivateKey, signerAddress).signer;
89
- const { signer: proposalSigner, keyHash } = proposer ? proposer(false) : getApiSigner(false);
90
- const result = yield _sendTransaction(testnet, {
91
- code,
92
- args,
93
- proposer: proposer ? proposer(false) : proposalSigner,
94
- authorizations: [auth],
95
- payer: payer ? payer(true) : getApiSigner(true).signer,
96
- keyHash,
97
- });
98
- return {
99
- txId: result.id,
100
- address: (_a = result.events.find((e) => e.type === 'flow.AccountCreated')) === null || _a === void 0 ? void 0 : _a.data.address,
101
- };
102
- }),
103
- /**
104
- * Add public key to existing blockchain address with defined weight
105
- * @param testnet
106
- * @param publicKey key to add
107
- * @param signerAddress address of the authorizer key
108
- * @param signerPrivateKey key of the authorize key
109
- * @param weight defaults to 1000 - weight of the key
110
- * @param proposer function to obtain proposer key from
111
- * @param payer function to obtain payer key from
112
- */
113
- addPublicKeyToAccount: (testnet, publicKey, signerAddress, signerPrivateKey, weight = 0, proposer, payer) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
114
- const code = txTemplates.prepareAddPublicKeyToAccountTxTemplate();
115
- const encodedPublicKey = (0, util_encode_key_1.encodeKey)(publicKey, util_encode_key_1.ECDSA_secp256k1, util_encode_key_1.SHA3_256, weight);
116
- const args = [{ type: 'String', value: encodedPublicKey }];
117
- const auth = getSigner(signerPrivateKey, signerAddress).signer;
118
- const { signer: proposalSigner, keyHash } = proposer ? proposer(false) : getApiSigner(false);
119
- const result = yield _sendTransaction(testnet, {
120
- code,
121
- args,
122
- proposer: proposer ? proposer(false) : proposalSigner,
123
- authorizations: [auth],
124
- keyHash,
125
- payer: payer ? payer(true) : getApiSigner(true).signer,
126
- });
127
- return { txId: result.id, address: result.events[0].data.address };
128
- }),
129
- getNftMetadata: (testnet, account, id, contractAddress) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
130
- const code = txTemplates.metadataNftTokenScript(testnet);
131
- const args = [
132
- { type: 'Address', value: account },
133
- { type: 'UInt64', value: id },
134
- { type: 'String', value: contractAddress },
135
- ];
136
- return sendScript(testnet, code, args);
137
- }),
138
- getNftTokenByAddress: (testnet, account, tokenType) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
139
- const code = txTemplates.tokenByAddressNftTokenScript(testnet);
140
- const args = [
141
- { type: 'Address', value: account },
142
- { type: 'String', value: tokenType },
143
- ];
144
- return sendScript(testnet, code, args);
145
- }),
146
- /**
147
- * Send Flow NFT mint token transaction to the blockchain. This method broadcasts signed transaction to the blockchain.
148
- * This operation is irreversible.
149
- * @param testnet
150
- * @param body content of the transaction to broadcast
151
- * @param proposer function to obtain proposer key from
152
- * @param payer function to obtain payer key from
153
- * @returns txId id of the transaction in the blockchain
154
- */
155
- sendNftMintToken: (testnet, body, proposer, payer) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
156
- var _b;
157
- const bodyWithChain = Object.assign(Object.assign({}, body), { chain: shared_core_1.Blockchain.FLOW });
158
- const code = txTemplates.mintNftTokenTxTemplate(testnet);
159
- const { url, contractAddress: tokenType, to, account } = bodyWithChain;
160
- const args = [
161
- { type: 'Address', value: to },
162
- { type: 'String', value: url },
163
- { type: 'String', value: tokenType },
164
- ];
165
- const pk = yield getPrivateKey(bodyWithChain);
166
- if (!pk)
167
- throw new flow_sdk_errors_1.FlowSdkError(shared_abstract_sdk_1.SdkErrorCode.FLOW_MISSING_PRIVATE_KEY);
168
- const auth = getSigner(pk, account).signer;
169
- const { signer: proposalSigner, keyHash } = proposer ? proposer(false) : getApiSigner(false);
170
- const result = yield _sendTransaction(testnet, {
171
- code,
172
- args,
173
- proposer: proposer ? proposer(false) : proposalSigner,
174
- authorizations: [auth],
175
- keyHash,
176
- payer: payer ? payer(true) : getApiSigner(true).signer,
177
- });
178
- return {
179
- txId: result.id,
180
- tokenId: `${(_b = result.events.find((e) => e.type.includes('TatumMultiNFT.Minted'))) === null || _b === void 0 ? void 0 : _b.data.id}`,
181
- };
182
- }),
183
- /**
184
- * Send Flow NFT mint multiple tokens transaction to the blockchain. This method broadcasts signed transaction to the blockchain.
185
- * This operation is irreversible.
186
- * @param testnet
187
293
  * @param body content of the transaction to broadcast
188
294
  * @param proposer function to obtain proposer key from
189
295
  * @param payer function to obtain payer key from
190
- * @returns txId id of the transaction in the blockchain
191
296
  */
192
- sendNftMintMultipleToken: (testnet, body, proposer, payer) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
193
- const bodyWithChain = Object.assign(Object.assign({}, body), { chain: shared_core_1.Blockchain.FLOW });
194
- const code = txTemplates.mintMultipleNftTokenTxTemplate(testnet);
195
- const { url, contractAddress: tokenType, to, account } = bodyWithChain;
196
- const args = [
197
- { type: 'Array', subType: 'Address', value: to },
198
- {
199
- type: 'Array',
200
- subType: 'String',
201
- value: url,
202
- },
203
- { type: 'String', value: tokenType },
204
- ];
205
- const pk = yield getPrivateKey(bodyWithChain);
206
- if (!pk)
207
- throw new flow_sdk_errors_1.FlowSdkError(shared_abstract_sdk_1.SdkErrorCode.FLOW_MISSING_PRIVATE_KEY);
208
- const { signer: proposalSigner, keyHash } = proposer ? proposer(false) : getApiSigner(false);
209
- const auth = getSigner(pk, account).signer;
210
- const result = yield _sendTransaction(testnet, {
211
- code,
212
- args,
213
- proposer: proposer ? proposer(false) : proposalSigner,
214
- authorizations: [auth],
215
- payer: payer ? payer(true) : getApiSigner(true).signer,
216
- keyHash,
217
- });
218
- return {
219
- txId: result.id,
220
- tokenId: result.events
221
- .filter((e) => e.type.includes('TatumMultiNFT.Minted'))
222
- .map((e) => e.data.id),
223
- };
297
+ createAccountFromPublicKey: (body, proposer, payer) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
298
+ if (body.signatureId) {
299
+ return api_client_1.ApiServices.blockchain.flow.flowCreateAddressFromPubKey(body);
300
+ }
301
+ return sendCreateAccountFromPublicKey(body, proposer, payer);
224
302
  }),
225
303
  /**
226
- * Send Flow NFT transfer token transaction to the blockchain. This method broadcasts signed transaction to the blockchain.
227
- * This operation is irreversible.
228
- * @param testnet
304
+ * Add public key to existing blockchain address with defined weight
229
305
  * @param body content of the transaction to broadcast
230
306
  * @param proposer function to obtain proposer key from
231
307
  * @param payer function to obtain payer key from
232
- * @returns {txId: string, events: any[]} id of the transaction in the blockchain and events this tx produced
233
308
  */
234
- sendNftTransferToken: (testnet, body, proposer, payer) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
235
- const bodyWithChain = Object.assign(Object.assign({}, body), { chain: shared_core_1.Blockchain.FLOW });
236
- const code = txTemplates.transferNftTokenTxTemplate(testnet);
237
- const { tokenId, to, account } = bodyWithChain;
238
- const args = [
239
- { type: 'Address', value: to },
240
- { type: 'UInt64', value: tokenId },
241
- ];
242
- const pk = yield getPrivateKey(bodyWithChain);
243
- if (!pk)
244
- throw new flow_sdk_errors_1.FlowSdkError(shared_abstract_sdk_1.SdkErrorCode.FLOW_MISSING_PRIVATE_KEY);
245
- const { signer: proposalSigner, keyHash } = proposer ? proposer(false) : getApiSigner(false);
246
- const auth = getSigner(pk, account).signer;
247
- const result = yield _sendTransaction(testnet, {
248
- code,
249
- args,
250
- proposer: proposer ? proposer(false) : proposalSigner,
251
- authorizations: [auth],
252
- payer: payer ? payer(true) : getApiSigner(true).signer,
253
- keyHash,
254
- });
255
- return { txId: result.id };
309
+ addPublicKeyToAccount: (body, proposer, payer) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
310
+ if (body.signatureId) {
311
+ return api_client_1.ApiServices.blockchain.flow.flowAddPubKeyToAddress(body);
312
+ }
313
+ return sendAddPublicKeyToAccount(body, proposer, payer);
256
314
  }),
315
+ nft: {
316
+ getNftMetadata,
317
+ getNftTokenByAddress,
318
+ /**
319
+ * Send Flow NFT mint token transaction to the blockchain. This method broadcasts signed transaction to the blockchain.
320
+ * This operation is irreversible.
321
+ * @param body content of the transaction to broadcast
322
+ * @param proposer function to obtain proposer key from
323
+ * @param payer function to obtain payer key from
324
+ * @returns txId id of the transaction in the blockchain
325
+ */
326
+ sendNftMintToken: (body, proposer, payer) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
327
+ if (body.signatureId) {
328
+ return api_client_1.NftErc721OrCompatibleService.nftMintErc721(body);
329
+ }
330
+ return sendNftMintToken(body, proposer, payer);
331
+ }),
332
+ /**
333
+ * Send Flow NFT mint multiple tokens transaction to the blockchain. This method broadcasts signed transaction to the blockchain.
334
+ * This operation is irreversible.
335
+ * @param body content of the transaction to broadcast
336
+ * @param proposer function to obtain proposer key from
337
+ * @param payer function to obtain payer key from
338
+ * @returns txId id of the transaction in the blockchain
339
+ */
340
+ sendNftMintMultipleToken: (body, proposer, payer) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
341
+ if (body.signatureId) {
342
+ return api_client_1.NftErc721OrCompatibleService.nftMintMultipleErc721(body);
343
+ }
344
+ return sendNftMintMultipleToken(body, proposer, payer);
345
+ }),
346
+ /**
347
+ * Send Flow NFT transfer token transaction to the blockchain. This method broadcasts signed transaction to the blockchain.
348
+ * This operation is irreversible.
349
+ * @param body content of the transaction to broadcast
350
+ * @param proposer function to obtain proposer key from
351
+ * @param payer function to obtain payer key from
352
+ * @returns {txId: string, events: any[]} id of the transaction in the blockchain and events this tx produced
353
+ */
354
+ sendNftTransferToken: (body, proposer, payer) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
355
+ if (body.signatureId) {
356
+ return api_client_1.NftErc721OrCompatibleService.nftTransferErc721(body);
357
+ }
358
+ return sendNftTransferToken(body, proposer, payer);
359
+ }),
360
+ /**
361
+ * Send Flow NFT burn token transaction to the blockchain. This method broadcasts signed transaction to the blockchain.
362
+ * This operation is irreversible.
363
+ * @param body content of the transaction to broadcast
364
+ * @param proposer function to obtain proposer key from
365
+ * @param payer function to obtain payer key from
366
+ * @returns txId id of the transaction in the blockchain
367
+ */
368
+ sendNftBurnToken: (body, proposer, payer) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
369
+ if (body.signatureId) {
370
+ return api_client_1.NftErc721OrCompatibleService.nftBurnErc721(body);
371
+ }
372
+ return sendNftBurnToken(body, proposer, payer);
373
+ }),
374
+ },
257
375
  /**
258
- * Send Flow NFT burn token transaction to the blockchain. This method broadcasts signed transaction to the blockchain.
259
- * This operation is irreversible.
260
- * @param testnet
376
+ * Send FLOW or FUSD from account to account.
261
377
  * @param body content of the transaction to broadcast
262
378
  * @param proposer function to obtain proposer key from
263
379
  * @param payer function to obtain payer key from
264
380
  * @returns txId id of the transaction in the blockchain
265
381
  */
266
- sendNftBurnToken: (testnet, body, proposer, payer) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
267
- const bodyWithChain = Object.assign(Object.assign({}, body), { chain: shared_core_1.Blockchain.FLOW });
268
- const code = txTemplates.burnNftTokenTxTemplate(testnet);
269
- const { tokenId, contractAddress: tokenType, account } = bodyWithChain;
270
- const args = [
271
- { type: 'UInt64', value: tokenId },
272
- { type: 'String', value: tokenType },
273
- ];
274
- const pk = yield getPrivateKey(bodyWithChain);
275
- if (!pk)
276
- throw new flow_sdk_errors_1.FlowSdkError(shared_abstract_sdk_1.SdkErrorCode.FLOW_MISSING_PRIVATE_KEY);
277
- const { signer: proposalSigner, keyHash } = proposer ? proposer(false) : getApiSigner(false);
278
- const auth = getSigner(pk, account).signer;
279
- const result = yield _sendTransaction(testnet, {
280
- code,
281
- args,
282
- proposer: proposer ? proposer(false) : proposalSigner,
283
- authorizations: [auth],
284
- payer: payer ? payer(true) : getApiSigner(true).signer,
285
- keyHash,
286
- });
287
- return { txId: result.id };
382
+ sendTransaction: (body, proposer, payer) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
383
+ if (body.signatureId) {
384
+ return api_client_1.ApiServices.blockchain.flow.flowTransferBlockchain(body);
385
+ }
386
+ return sendTransaction(body, proposer, payer);
288
387
  }),
289
388
  /**
290
389
  * Send custom transaction to the FLOW network
291
- * @param testnet
292
- * @param body content of the transaction to broadcast
293
- * @param proposer function to obtain proposer key from
294
- * @param payer function to obtain payer key from
295
- * @returns txId id of the transaction in the blockchain
296
- */
297
- sendCustomTransaction: (testnet, body, proposer, payer) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
298
- const pk = yield getPrivateKey(body);
299
- if (!pk)
300
- throw new flow_sdk_errors_1.FlowSdkError(shared_abstract_sdk_1.SdkErrorCode.FLOW_MISSING_PRIVATE_KEY);
301
- const auth = getSigner(pk, body.account).signer;
302
- const { signer: proposalSigner, keyHash } = proposer ? proposer(false) : getApiSigner(false);
303
- const result = yield _sendTransaction(testnet, {
304
- code: body.transaction,
305
- args: body.args,
306
- proposer: proposer ? proposer(false) : proposalSigner,
307
- authorizations: [auth],
308
- keyHash,
309
- payer: payer ? payer(true) : getApiSigner(true).signer,
310
- });
311
- return { txId: result.id, events: result.events };
312
- }),
313
- /**
314
- * Send FLOW or FUSD from account to account.
315
- * @param testnet
316
390
  * @param body content of the transaction to broadcast
317
391
  * @param proposer function to obtain proposer key from
318
392
  * @param payer function to obtain payer key from
319
393
  * @returns txId id of the transaction in the blockchain
320
394
  */
321
- sendTransaction: (testnet, body, proposer, payer) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
322
- let tokenAddress;
323
- let tokenName;
324
- let tokenStorage;
325
- if (body.currency === shared_core_1.Blockchain.FLOW) {
326
- tokenAddress = testnet ? exports.FLOW_TESTNET_ADDRESSES.FlowToken : exports.FLOW_MAINNET_ADDRESSES.FlowToken;
327
- tokenName = 'FlowToken';
328
- tokenStorage = 'flowToken';
329
- }
330
- else {
331
- tokenAddress = testnet ? exports.FLOW_TESTNET_ADDRESSES.FUSD : exports.FLOW_MAINNET_ADDRESSES.FUSD;
332
- tokenName = 'FUSD';
333
- tokenStorage = 'fusd';
395
+ sendCustomTransaction: (body, proposer, payer) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
396
+ if (body.signatureId) {
397
+ return api_client_1.ApiServices.blockchain.flow.flowTransferCustomBlockchain(body);
334
398
  }
335
- const code = txTemplates.prepareTransferTxTemplate(testnet, tokenAddress, tokenName, tokenStorage);
336
- const args = [
337
- { value: parseFloat(body.amount).toFixed(8), type: 'UFix64' },
338
- { value: body.to, type: 'Address' },
339
- ];
340
- const pk = yield getPrivateKey(body);
341
- if (!pk)
342
- throw new flow_sdk_errors_1.FlowSdkError(shared_abstract_sdk_1.SdkErrorCode.FLOW_MISSING_PRIVATE_KEY);
343
- const { signer: proposalSigner, keyHash } = proposer ? proposer(false) : getApiSigner(false);
344
- const auth = getSigner(pk, body.account).signer;
345
- const result = yield _sendTransaction(testnet, {
346
- code,
347
- args,
348
- proposer: proposer ? proposer(false) : proposalSigner,
349
- authorizations: [auth],
350
- payer: payer ? payer(true) : getApiSigner(true).signer,
351
- keyHash,
352
- });
353
- return { txId: result.id };
399
+ return sendCustomTransaction(body, proposer, payer);
354
400
  }),
401
+ templates: Object.assign({}, txTemplates),
355
402
  };
356
- function _sendTransaction(testnet, { code, args, proposer, authorizations, payer, keyHash }) {
403
+ function _sendTransaction({ code, txArgs, proposer, authorizations, payer, keyHash, }) {
357
404
  return tslib_1.__awaiter(this, void 0, void 0, function* () {
358
- fcl.config().put('accessNode.api', networkUrl(testnet));
405
+ fcl.config().put('accessNode.api', provider.getProvider());
359
406
  let response;
360
407
  try {
361
408
  response = yield fcl.send([
362
409
  fcl.transaction(code),
363
- fcl.args(args.map((arg) => fcl.arg(UInt64ArgValue(arg), ArrayArgValue(arg)))),
410
+ fcl.args(txArgs.map((arg) => fcl.arg(arg.value, ArrayArgValue(arg)))),
364
411
  fcl.proposer(proposer),
365
412
  fcl.authorizations(authorizations),
366
413
  fcl.payer(payer),
@@ -368,22 +415,14 @@ const flowTxService = (args) => {
368
415
  ]);
369
416
  }
370
417
  catch (e) {
371
- try {
372
- if (keyHash) {
373
- yield flowSdkBlockchain.broadcast('', undefined, proposalKey(keyHash));
374
- delete process.env[keyHash];
375
- }
376
- }
377
- catch (_) {
378
- throw new flow_sdk_errors_1.FlowSdkError(_);
379
- }
380
- throw new flow_sdk_errors_1.FlowSdkError(e);
418
+ yield unlockProposalKey(keyHash);
419
+ throw new flow_sdk_errors_1.FlowSdkError({ error: e });
381
420
  }
382
421
  const { transactionId } = response;
383
422
  try {
384
423
  const { error, events } = yield fcl.tx(response).onceSealed();
385
424
  if (error) {
386
- throw new flow_sdk_errors_1.FlowSdkError(error);
425
+ throw new flow_sdk_errors_1.FlowSdkError({ error: error });
387
426
  }
388
427
  return {
389
428
  id: transactionId,
@@ -391,12 +430,28 @@ const flowTxService = (args) => {
391
430
  };
392
431
  }
393
432
  catch (e) {
394
- throw new flow_sdk_errors_1.FlowSdkError(e);
433
+ throw new flow_sdk_errors_1.FlowSdkError({ error: e });
395
434
  }
396
435
  finally {
397
- if (keyHash) {
398
- yield flowSdkBlockchain.broadcast(transactionId, undefined, proposalKey(keyHash));
399
- delete process.env[keyHash];
436
+ yield unlockProposalKey(keyHash);
437
+ }
438
+ });
439
+ }
440
+ function checkBalanceOrThrow(account, tokenAddress, tokenName, tokenStorage, amount) {
441
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
442
+ const balanceTx = txTemplates.prepareBalanceTxTemplate(provider.isTestnet(), tokenAddress, tokenName, tokenStorage);
443
+ const balanceArgs = [{ value: account, type: 'Address' }];
444
+ let result;
445
+ try {
446
+ result = yield sendScript(balanceTx, balanceArgs);
447
+ }
448
+ catch (_e) { }
449
+ if (result) {
450
+ if (new bignumber_js_1.default(result).lt(new bignumber_js_1.default(amount))) {
451
+ throw new flow_sdk_errors_1.FlowSdkError({
452
+ code: shared_abstract_sdk_1.SdkErrorCode.INSUFFICIENT_FUNDS,
453
+ error: new Error(`Insufficient funds. Balance: ${result} on account ${account} is less than ${amount.toString()}`),
454
+ });
400
455
  }
401
456
  }
402
457
  });
@@ -408,36 +463,63 @@ const flowTxService = (args) => {
408
463
  return privateKey;
409
464
  }
410
465
  else {
411
- if (mnemonic && index && index >= 0) {
466
+ if (mnemonic && !lodash_1.default.isNil(index) && index >= 0) {
412
467
  return flowSdkWallet.generatePrivateKeyFromMnemonic(mnemonic, index);
413
468
  }
414
469
  else
415
- throw new flow_sdk_errors_1.FlowSdkError(shared_abstract_sdk_1.SdkErrorCode.FLOW_MISSING_MNEMONIC);
470
+ throw new flow_sdk_errors_1.FlowSdkError({ code: shared_abstract_sdk_1.SdkErrorCode.FLOW_MISSING_MNEMONIC });
416
471
  }
417
472
  });
418
473
  }
419
- function sendScript(testnet, code, args) {
474
+ function sendScript(code, scriptArgs) {
420
475
  return tslib_1.__awaiter(this, void 0, void 0, function* () {
421
- fcl.config().put('accessNode.api', networkUrl(testnet));
476
+ fcl.config().put('accessNode.api', provider.getProvider());
422
477
  const response = yield fcl.send([
423
478
  fcl.script(code),
424
- fcl.args(args.map((arg) => fcl.arg(UInt64ArgValue(arg), types[arg.type]))),
479
+ fcl.args(scriptArgs.map((arg) => fcl.arg(arg.value, types[arg.type]))),
425
480
  ]);
426
481
  return fcl.decode(response);
427
482
  });
428
483
  }
429
- function proposalKey(keyHash) {
430
- return keyHash ? parseInt(process.env[keyHash] || '0') : undefined;
484
+ function getProposalKeyOrFetch(keyHash, isPayer) {
485
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
486
+ const value = process.env[keyHash];
487
+ if (value) {
488
+ return JSON.parse(value);
489
+ }
490
+ else {
491
+ return apiCalls.getSignKey(isPayer);
492
+ }
493
+ });
431
494
  }
432
- function networkUrl(testnet) {
433
- return testnet ? 'https://access-testnet.onflow.org' : 'https://access-mainnet-beta.onflow.org';
495
+ function storeProposalKey(keyHash, address, keyId) {
496
+ process.env[keyHash] = JSON.stringify({ address, keyId });
434
497
  }
435
- function UInt64ArgValue(arg) {
436
- return arg.type === 'UInt64' ? parseInt(arg.value) : arg.value;
498
+ function proposalKey(keyHash) {
499
+ const value = process.env[keyHash];
500
+ if (!value)
501
+ return undefined;
502
+ return keyHash ? JSON.parse(value) : undefined;
437
503
  }
438
504
  function ArrayArgValue(arg) {
439
505
  return arg.type === 'Array' ? types[arg.type](types[arg.subType]) : types[arg.type];
440
506
  }
507
+ function unlockProposalKey(keyHash) {
508
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
509
+ try {
510
+ if (keyHash) {
511
+ const key = proposalKey(keyHash);
512
+ if (key) {
513
+ yield apiCalls.broadcast('', undefined, key.keyId);
514
+ delete process.env[keyHash];
515
+ }
516
+ }
517
+ }
518
+ catch (e) {
519
+ throw new flow_sdk_errors_1.FlowSdkError({ error: e });
520
+ }
521
+ });
522
+ }
441
523
  };
442
524
  exports.flowTxService = flowTxService;
443
525
  //# sourceMappingURL=flow.tx.js.map