@ledgerhq/coin-solana 0.29.0-nightly.2 → 0.29.0

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.
Files changed (74) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/CHANGELOG.md +23 -23
  3. package/lib/bridge.integration.test.js +0 -1
  4. package/lib/bridge.integration.test.js.map +1 -1
  5. package/lib/buildTransaction.d.ts.map +1 -1
  6. package/lib/buildTransaction.js +0 -5
  7. package/lib/buildTransaction.js.map +1 -1
  8. package/lib/getTransactionStatus.d.ts.map +1 -1
  9. package/lib/getTransactionStatus.js +0 -2
  10. package/lib/getTransactionStatus.js.map +1 -1
  11. package/lib/prepareTransaction.d.ts.map +1 -1
  12. package/lib/prepareTransaction.js +61 -4
  13. package/lib/prepareTransaction.js.map +1 -1
  14. package/lib/prepareTransaction.test.js +52 -37
  15. package/lib/prepareTransaction.test.js.map +1 -1
  16. package/lib/signOperation.d.ts.map +1 -1
  17. package/lib/signOperation.js +0 -16
  18. package/lib/signOperation.js.map +1 -1
  19. package/lib/specs.d.ts.map +1 -1
  20. package/lib/specs.js +0 -1
  21. package/lib/specs.js.map +1 -1
  22. package/lib/transaction.d.ts.map +1 -1
  23. package/lib/transaction.js +20 -14
  24. package/lib/transaction.js.map +1 -1
  25. package/lib/tx-fees.js +0 -1
  26. package/lib/tx-fees.js.map +1 -1
  27. package/lib/types.d.ts +2 -10
  28. package/lib/types.d.ts.map +1 -1
  29. package/lib-es/bridge.integration.test.js +0 -1
  30. package/lib-es/bridge.integration.test.js.map +1 -1
  31. package/lib-es/buildTransaction.d.ts.map +1 -1
  32. package/lib-es/buildTransaction.js +0 -5
  33. package/lib-es/buildTransaction.js.map +1 -1
  34. package/lib-es/getTransactionStatus.d.ts.map +1 -1
  35. package/lib-es/getTransactionStatus.js +0 -2
  36. package/lib-es/getTransactionStatus.js.map +1 -1
  37. package/lib-es/prepareTransaction.d.ts.map +1 -1
  38. package/lib-es/prepareTransaction.js +60 -3
  39. package/lib-es/prepareTransaction.js.map +1 -1
  40. package/lib-es/prepareTransaction.test.js +52 -37
  41. package/lib-es/prepareTransaction.test.js.map +1 -1
  42. package/lib-es/signOperation.d.ts.map +1 -1
  43. package/lib-es/signOperation.js +0 -16
  44. package/lib-es/signOperation.js.map +1 -1
  45. package/lib-es/specs.d.ts.map +1 -1
  46. package/lib-es/specs.js +0 -1
  47. package/lib-es/specs.js.map +1 -1
  48. package/lib-es/transaction.d.ts.map +1 -1
  49. package/lib-es/transaction.js +20 -14
  50. package/lib-es/transaction.js.map +1 -1
  51. package/lib-es/tx-fees.js +0 -1
  52. package/lib-es/tx-fees.js.map +1 -1
  53. package/lib-es/types.d.ts +2 -10
  54. package/lib-es/types.d.ts.map +1 -1
  55. package/package.json +7 -7
  56. package/src/bridge.integration.test.ts +0 -1
  57. package/src/buildTransaction.ts +0 -5
  58. package/src/getTransactionStatus.ts +0 -2
  59. package/src/prepareTransaction.test.ts +71 -31
  60. package/src/prepareTransaction.ts +100 -3
  61. package/src/signOperation.ts +0 -24
  62. package/src/specs.ts +0 -1
  63. package/src/transaction.ts +20 -17
  64. package/src/tx-fees.ts +0 -1
  65. package/src/types.ts +1 -13
  66. package/lib/rawTransaction.d.ts +0 -5
  67. package/lib/rawTransaction.d.ts.map +0 -1
  68. package/lib/rawTransaction.js +0 -52
  69. package/lib/rawTransaction.js.map +0 -1
  70. package/lib-es/rawTransaction.d.ts +0 -5
  71. package/lib-es/rawTransaction.d.ts.map +0 -1
  72. package/lib-es/rawTransaction.js +0 -44
  73. package/lib-es/rawTransaction.js.map +0 -1
  74. package/src/rawTransaction.ts +0 -59
@@ -88,8 +88,6 @@ function formatCommand(mainAccount: Account, tx: Transaction, command: Command)
88
88
  return formatStakeWithdraw(mainAccount, tx, command);
89
89
  case "stake.split":
90
90
  return formatStakeSplit(mainAccount, tx, command);
91
- case "raw":
92
- return formatRaw(tx);
93
91
  default:
94
92
  return assertUnreachable(command);
95
93
  }
@@ -107,7 +105,9 @@ function formatStakeCreateAccount(
107
105
  ` AMOUNT: ${amount}${tx.useAllAmount ? " (ALL)" : ""}`,
108
106
  ` SEED: ${command.seed}`,
109
107
  ` VALIDATOR: ${command.delegate.voteAccAddress}`,
110
- ].join("\n");
108
+ ]
109
+ .filter(Boolean)
110
+ .join("\n");
111
111
 
112
112
  return "\n" + str;
113
113
  }
@@ -157,7 +157,7 @@ function formatCreateATA(mainAccount: Account, command: TokenCreateATACommand) {
157
157
  if (!token) {
158
158
  throw new Error(`token for mint "${command.mint}" not found`);
159
159
  }
160
- const str = [` OPT IN TOKEN: ${token.ticker}`].join("\n");
160
+ const str = [` OPT IN TOKEN: ${token.ticker}`].filter(Boolean).join("\n");
161
161
  return "\n" + str;
162
162
  }
163
163
 
@@ -186,7 +186,9 @@ function formatCreateApprove(
186
186
  ` APPROVE: ${command.account}`,
187
187
  ` DELEGATE: ${command.recipientDescriptor.walletAddress}`,
188
188
  ` AMOUNT: ${amount}${tx.useAllAmount ? " (ALL)" : ""}`,
189
- ].join("\n");
189
+ ]
190
+ .filter(Boolean)
191
+ .join("\n");
190
192
  return "\n" + str;
191
193
  }
192
194
 
@@ -203,17 +205,21 @@ function formatCreateRevoke(
203
205
  throw new Error("token subaccount expected");
204
206
  }
205
207
 
206
- const str = [` OWNER: ${command.owner}`, ` REVOKE: ${command.account}`].join("\n");
208
+ const str = [` OWNER: ${command.owner}`, ` REVOKE: ${command.account}`]
209
+ .filter(Boolean)
210
+ .join("\n");
207
211
  return "\n" + str;
208
212
  }
209
213
 
210
214
  function formatStakeDelegate(command: StakeDelegateCommand) {
211
- const str = [` DELEGATE: ${command.stakeAccAddr}`, ` TO: ${command.voteAccAddr}`].join("\n");
215
+ const str = [` DELEGATE: ${command.stakeAccAddr}`, ` TO: ${command.voteAccAddr}`]
216
+ .filter(Boolean)
217
+ .join("\n");
212
218
  return "\n" + str;
213
219
  }
214
220
 
215
221
  function formatStakeUndelegate(command: StakeUndelegateCommand) {
216
- const str = [` UNDELEGATE: ${command.stakeAccAddr}`].join("\n");
222
+ const str = [` UNDELEGATE: ${command.stakeAccAddr}`].filter(Boolean).join("\n");
217
223
  return "\n" + str;
218
224
  }
219
225
 
@@ -223,7 +229,9 @@ function formatStakeWithdraw(mainAccount: Account, tx: Transaction, command: Sta
223
229
  ` WITHDRAW FROM: ${command.stakeAccAddr}`,
224
230
  ` AMOUNT: ${amount}${tx.useAllAmount ? " (ALL)" : ""}`,
225
231
  ` TO: ${command.toAccAddr}`,
226
- ].join("\n");
232
+ ]
233
+ .filter(Boolean)
234
+ .join("\n");
227
235
  return "\n" + str;
228
236
  }
229
237
 
@@ -233,14 +241,9 @@ function formatStakeSplit(mainAccount: Account, tx: Transaction, command: StakeS
233
241
  ` SPLIT: ${command.stakeAccAddr}`,
234
242
  ` AMOUNT: ${amount}${tx.useAllAmount ? " (ALL)" : ""}`,
235
243
  ` TO: ${command.splitStakeAccAddr}`,
236
- ].join("\n");
237
- return "\n" + str;
238
- }
239
-
240
- function formatRaw(tx: Transaction) {
241
- const str = [` SEND RAW: ${tx.useAllAmount ? " (ALL)" : ""}`, ` TO: ${tx.recipient}`].join(
242
- "\n",
243
- );
244
+ ]
245
+ .filter(Boolean)
246
+ .join("\n");
244
247
  return "\n" + str;
245
248
  }
246
249
 
package/src/tx-fees.ts CHANGED
@@ -58,7 +58,6 @@ const createDummyTx = (address: string, kind: TransactionModel["kind"]) => {
58
58
  return createDummyTokenRevokeTx(address);
59
59
  case "stake.split":
60
60
  case "token.createATA":
61
- case "raw":
62
61
  throw new Error(`not implemented for <${kind}>`);
63
62
  default:
64
63
  return assertUnreachable(kind);
package/src/types.ts CHANGED
@@ -121,11 +121,6 @@ export type TokenTransferCommand = {
121
121
  };
122
122
  };
123
123
 
124
- export type RawCommand = {
125
- kind: "raw";
126
- raw: string;
127
- };
128
-
129
124
  export type Command =
130
125
  | TransferCommand
131
126
  | TokenTransferCommand
@@ -136,8 +131,7 @@ export type Command =
136
131
  | StakeDelegateCommand
137
132
  | StakeUndelegateCommand
138
133
  | StakeWithdrawCommand
139
- | StakeSplitCommand
140
- | RawCommand;
134
+ | StakeSplitCommand;
141
135
 
142
136
  export type CommandDescriptor = {
143
137
  command: Command;
@@ -220,11 +214,6 @@ export type StakeSplitTransaction = {
220
214
  };
221
215
  };
222
216
 
223
- export type RawTransaction = {
224
- kind: "raw";
225
- uiState: object;
226
- };
227
-
228
217
  export type TransactionModel = { commandDescriptor?: CommandDescriptor } & (
229
218
  | TransferTransaction
230
219
  | TokenTransferTransaction
@@ -236,7 +225,6 @@ export type TransactionModel = { commandDescriptor?: CommandDescriptor } & (
236
225
  | StakeUndelegateTransaction
237
226
  | StakeWithdrawTransaction
238
227
  | StakeSplitTransaction
239
- | RawTransaction
240
228
  );
241
229
 
242
230
  export type Transaction = TransactionCommon & {
@@ -1,5 +0,0 @@
1
- import { ChainAPI } from "./network";
2
- import { Transaction } from "./types";
3
- export declare function toLiveTransaction(api: ChainAPI, serializedTransaction: string): Promise<Transaction>;
4
- export declare function deriveRawCommandDescriptor(tx: Transaction, api: ChainAPI): Promise<import("./types").CommandDescriptor>;
5
- //# sourceMappingURL=rawTransaction.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"rawTransaction.d.ts","sourceRoot":"","sources":["../src/rawTransaction.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrC,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AA0BtC,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,QAAQ,EACb,qBAAqB,EAAE,MAAM,GAC5B,OAAO,CAAC,WAAW,CAAC,CAQtB;AAED,wBAAsB,0BAA0B,CAAC,EAAE,EAAE,WAAW,EAAE,GAAG,EAAE,QAAQ,gDAkB9E"}
@@ -1,52 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.deriveRawCommandDescriptor = exports.toLiveTransaction = void 0;
7
- const web3_js_1 = require("@solana/web3.js");
8
- const bignumber_js_1 = __importDefault(require("bignumber.js"));
9
- function buildRawTransaction(raw, estimatedFees) {
10
- return {
11
- raw,
12
- family: "solana",
13
- amount: (0, bignumber_js_1.default)(0),
14
- recipient: "",
15
- model: {
16
- kind: "raw",
17
- uiState: {},
18
- commandDescriptor: {
19
- command: {
20
- kind: "raw",
21
- raw,
22
- },
23
- fee: estimatedFees ?? 0,
24
- warnings: {},
25
- errors: {},
26
- },
27
- },
28
- };
29
- }
30
- async function toLiveTransaction(api, serializedTransaction) {
31
- const solanaTransaction = web3_js_1.VersionedTransaction.deserialize(Buffer.from(serializedTransaction, "base64"));
32
- const estimatedFees = await api.getFeeForMessage(solanaTransaction.message);
33
- return buildRawTransaction(serializedTransaction, estimatedFees);
34
- }
35
- exports.toLiveTransaction = toLiveTransaction;
36
- async function deriveRawCommandDescriptor(tx, api) {
37
- if (!tx.raw) {
38
- throw new Error("Raw transaction is required to derive command descriptor");
39
- }
40
- const liveTx = await toLiveTransaction(api, tx.raw);
41
- return (liveTx.model.commandDescriptor || {
42
- command: {
43
- kind: "raw",
44
- raw: tx.raw,
45
- },
46
- fee: tx.model.commandDescriptor?.fee ?? 0,
47
- warnings: {},
48
- errors: {},
49
- });
50
- }
51
- exports.deriveRawCommandDescriptor = deriveRawCommandDescriptor;
52
- //# sourceMappingURL=rawTransaction.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"rawTransaction.js","sourceRoot":"","sources":["../src/rawTransaction.ts"],"names":[],"mappings":";;;;;;AAEA,6CAAuD;AACvD,gEAAqC;AAErC,SAAS,mBAAmB,CAAC,GAAW,EAAE,aAA4B;IACpE,OAAO;QACL,GAAG;QACH,MAAM,EAAE,QAAQ;QAChB,MAAM,EAAE,IAAA,sBAAS,EAAC,CAAC,CAAC;QACpB,SAAS,EAAE,EAAE;QACb,KAAK,EAAE;YACL,IAAI,EAAE,KAAK;YACX,OAAO,EAAE,EAAE;YACX,iBAAiB,EAAE;gBACjB,OAAO,EAAE;oBACP,IAAI,EAAE,KAAK;oBACX,GAAG;iBACJ;gBACD,GAAG,EAAE,aAAa,IAAI,CAAC;gBACvB,QAAQ,EAAE,EAAE;gBACZ,MAAM,EAAE,EAAE;aACX;SACF;KACF,CAAC;AACJ,CAAC;AAEM,KAAK,UAAU,iBAAiB,CACrC,GAAa,EACb,qBAA6B;IAE7B,MAAM,iBAAiB,GAAG,8BAAoB,CAAC,WAAW,CACxD,MAAM,CAAC,IAAI,CAAC,qBAAqB,EAAE,QAAQ,CAAC,CAC7C,CAAC;IAEF,MAAM,aAAa,GAAG,MAAM,GAAG,CAAC,gBAAgB,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC;IAE5E,OAAO,mBAAmB,CAAC,qBAAqB,EAAE,aAAa,CAAC,CAAC;AACnE,CAAC;AAXD,8CAWC;AAEM,KAAK,UAAU,0BAA0B,CAAC,EAAe,EAAE,GAAa;IAC7E,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,0DAA0D,CAAC,CAAC;IAC9E,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,iBAAiB,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC;IAEpD,OAAO,CACL,MAAM,CAAC,KAAK,CAAC,iBAAiB,IAAI;QAChC,OAAO,EAAE;YACP,IAAI,EAAE,KAAK;YACX,GAAG,EAAE,EAAE,CAAC,GAAG;SACZ;QACD,GAAG,EAAE,EAAE,CAAC,KAAK,CAAC,iBAAiB,EAAE,GAAG,IAAI,CAAC;QACzC,QAAQ,EAAE,EAAE;QACZ,MAAM,EAAE,EAAE;KACX,CACF,CAAC;AACJ,CAAC;AAlBD,gEAkBC"}
@@ -1,5 +0,0 @@
1
- import { ChainAPI } from "./network";
2
- import { Transaction } from "./types";
3
- export declare function toLiveTransaction(api: ChainAPI, serializedTransaction: string): Promise<Transaction>;
4
- export declare function deriveRawCommandDescriptor(tx: Transaction, api: ChainAPI): Promise<import("./types").CommandDescriptor>;
5
- //# sourceMappingURL=rawTransaction.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"rawTransaction.d.ts","sourceRoot":"","sources":["../src/rawTransaction.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrC,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AA0BtC,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,QAAQ,EACb,qBAAqB,EAAE,MAAM,GAC5B,OAAO,CAAC,WAAW,CAAC,CAQtB;AAED,wBAAsB,0BAA0B,CAAC,EAAE,EAAE,WAAW,EAAE,GAAG,EAAE,QAAQ,gDAkB9E"}
@@ -1,44 +0,0 @@
1
- import { VersionedTransaction } from "@solana/web3.js";
2
- import BigNumber from "bignumber.js";
3
- function buildRawTransaction(raw, estimatedFees) {
4
- return {
5
- raw,
6
- family: "solana",
7
- amount: BigNumber(0),
8
- recipient: "",
9
- model: {
10
- kind: "raw",
11
- uiState: {},
12
- commandDescriptor: {
13
- command: {
14
- kind: "raw",
15
- raw,
16
- },
17
- fee: estimatedFees ?? 0,
18
- warnings: {},
19
- errors: {},
20
- },
21
- },
22
- };
23
- }
24
- export async function toLiveTransaction(api, serializedTransaction) {
25
- const solanaTransaction = VersionedTransaction.deserialize(Buffer.from(serializedTransaction, "base64"));
26
- const estimatedFees = await api.getFeeForMessage(solanaTransaction.message);
27
- return buildRawTransaction(serializedTransaction, estimatedFees);
28
- }
29
- export async function deriveRawCommandDescriptor(tx, api) {
30
- if (!tx.raw) {
31
- throw new Error("Raw transaction is required to derive command descriptor");
32
- }
33
- const liveTx = await toLiveTransaction(api, tx.raw);
34
- return (liveTx.model.commandDescriptor || {
35
- command: {
36
- kind: "raw",
37
- raw: tx.raw,
38
- },
39
- fee: tx.model.commandDescriptor?.fee ?? 0,
40
- warnings: {},
41
- errors: {},
42
- });
43
- }
44
- //# sourceMappingURL=rawTransaction.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"rawTransaction.js","sourceRoot":"","sources":["../src/rawTransaction.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,SAAS,MAAM,cAAc,CAAC;AAErC,SAAS,mBAAmB,CAAC,GAAW,EAAE,aAA4B;IACpE,OAAO;QACL,GAAG;QACH,MAAM,EAAE,QAAQ;QAChB,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC;QACpB,SAAS,EAAE,EAAE;QACb,KAAK,EAAE;YACL,IAAI,EAAE,KAAK;YACX,OAAO,EAAE,EAAE;YACX,iBAAiB,EAAE;gBACjB,OAAO,EAAE;oBACP,IAAI,EAAE,KAAK;oBACX,GAAG;iBACJ;gBACD,GAAG,EAAE,aAAa,IAAI,CAAC;gBACvB,QAAQ,EAAE,EAAE;gBACZ,MAAM,EAAE,EAAE;aACX;SACF;KACF,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,GAAa,EACb,qBAA6B;IAE7B,MAAM,iBAAiB,GAAG,oBAAoB,CAAC,WAAW,CACxD,MAAM,CAAC,IAAI,CAAC,qBAAqB,EAAE,QAAQ,CAAC,CAC7C,CAAC;IAEF,MAAM,aAAa,GAAG,MAAM,GAAG,CAAC,gBAAgB,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC;IAE5E,OAAO,mBAAmB,CAAC,qBAAqB,EAAE,aAAa,CAAC,CAAC;AACnE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAAC,EAAe,EAAE,GAAa;IAC7E,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,0DAA0D,CAAC,CAAC;IAC9E,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,iBAAiB,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC;IAEpD,OAAO,CACL,MAAM,CAAC,KAAK,CAAC,iBAAiB,IAAI;QAChC,OAAO,EAAE;YACP,IAAI,EAAE,KAAK;YACX,GAAG,EAAE,EAAE,CAAC,GAAG;SACZ;QACD,GAAG,EAAE,EAAE,CAAC,KAAK,CAAC,iBAAiB,EAAE,GAAG,IAAI,CAAC;QACzC,QAAQ,EAAE,EAAE;QACZ,MAAM,EAAE,EAAE;KACX,CACF,CAAC;AACJ,CAAC"}
@@ -1,59 +0,0 @@
1
- import { ChainAPI } from "./network";
2
- import { Transaction } from "./types";
3
- import { VersionedTransaction } from "@solana/web3.js";
4
- import BigNumber from "bignumber.js";
5
-
6
- function buildRawTransaction(raw: string, estimatedFees: number | null): Transaction {
7
- return {
8
- raw,
9
- family: "solana",
10
- amount: BigNumber(0),
11
- recipient: "",
12
- model: {
13
- kind: "raw",
14
- uiState: {},
15
- commandDescriptor: {
16
- command: {
17
- kind: "raw",
18
- raw,
19
- },
20
- fee: estimatedFees ?? 0,
21
- warnings: {},
22
- errors: {},
23
- },
24
- },
25
- };
26
- }
27
-
28
- export async function toLiveTransaction(
29
- api: ChainAPI,
30
- serializedTransaction: string,
31
- ): Promise<Transaction> {
32
- const solanaTransaction = VersionedTransaction.deserialize(
33
- Buffer.from(serializedTransaction, "base64"),
34
- );
35
-
36
- const estimatedFees = await api.getFeeForMessage(solanaTransaction.message);
37
-
38
- return buildRawTransaction(serializedTransaction, estimatedFees);
39
- }
40
-
41
- export async function deriveRawCommandDescriptor(tx: Transaction, api: ChainAPI) {
42
- if (!tx.raw) {
43
- throw new Error("Raw transaction is required to derive command descriptor");
44
- }
45
-
46
- const liveTx = await toLiveTransaction(api, tx.raw);
47
-
48
- return (
49
- liveTx.model.commandDescriptor || {
50
- command: {
51
- kind: "raw",
52
- raw: tx.raw,
53
- },
54
- fee: tx.model.commandDescriptor?.fee ?? 0,
55
- warnings: {},
56
- errors: {},
57
- }
58
- );
59
- }