@ledgerhq/coin-aptos 1.10.0-nightly.0 → 2.0.0-nightly.1

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 (175) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/.unimportedrc.json +18 -6
  3. package/CHANGELOG.md +6 -0
  4. package/jest.integ.config.js +8 -0
  5. package/lib/__tests__/api/index.integ.test.d.ts +2 -0
  6. package/lib/__tests__/api/index.integ.test.d.ts.map +1 -0
  7. package/lib/__tests__/api/index.integ.test.js +22 -0
  8. package/lib/__tests__/api/index.integ.test.js.map +1 -0
  9. package/lib/__tests__/api/index.test.js +48 -460
  10. package/lib/__tests__/api/index.test.js.map +1 -1
  11. package/lib/__tests__/bridge/broadcast.test.js +5 -5
  12. package/lib/__tests__/bridge/broadcast.test.js.map +1 -1
  13. package/lib/__tests__/bridge/buildTransaction.test.js +6 -6
  14. package/lib/__tests__/bridge/buildTransaction.test.js.map +1 -1
  15. package/lib/__tests__/bridge/getFeesForTransaction.test.js +9 -9
  16. package/lib/__tests__/bridge/getFeesForTransaction.test.js.map +1 -1
  17. package/lib/__tests__/bridge/prepareTransaction.test.js +3 -3
  18. package/lib/__tests__/bridge/prepareTransaction.test.js.map +1 -1
  19. package/lib/__tests__/bridge/signOperation.test.js +3 -2
  20. package/lib/__tests__/bridge/signOperation.test.js.map +1 -1
  21. package/lib/__tests__/bridge/synchronisation.test.js +6 -6
  22. package/lib/__tests__/bridge/synchronisation.test.js.map +1 -1
  23. package/lib/__tests__/network/client.test.d.ts +2 -0
  24. package/lib/__tests__/network/client.test.d.ts.map +1 -0
  25. package/lib/__tests__/network/client.test.js +478 -0
  26. package/lib/__tests__/network/client.test.js.map +1 -0
  27. package/lib/api/index.d.ts +4 -33
  28. package/lib/api/index.d.ts.map +1 -1
  29. package/lib/api/index.js +26 -196
  30. package/lib/api/index.js.map +1 -1
  31. package/lib/bridge/broadcast.d.ts +3 -2
  32. package/lib/bridge/broadcast.d.ts.map +1 -1
  33. package/lib/bridge/broadcast.js +4 -3
  34. package/lib/bridge/broadcast.js.map +1 -1
  35. package/lib/bridge/buildTransaction.d.ts +1 -1
  36. package/lib/bridge/buildTransaction.d.ts.map +1 -1
  37. package/lib/bridge/buildTransaction.js.map +1 -1
  38. package/lib/bridge/estimateMaxSpendable.js +2 -2
  39. package/lib/bridge/estimateMaxSpendable.js.map +1 -1
  40. package/lib/bridge/getFeesForTransaction.d.ts +1 -1
  41. package/lib/bridge/getFeesForTransaction.d.ts.map +1 -1
  42. package/lib/bridge/index.d.ts +1 -1
  43. package/lib/bridge/index.d.ts.map +1 -1
  44. package/lib/bridge/prepareTransaction.d.ts.map +1 -1
  45. package/lib/bridge/prepareTransaction.js +2 -2
  46. package/lib/bridge/prepareTransaction.js.map +1 -1
  47. package/lib/bridge/signOperation.js +3 -3
  48. package/lib/bridge/signOperation.js.map +1 -1
  49. package/lib/bridge/synchronisation.js +3 -3
  50. package/lib/bridge/synchronisation.js.map +1 -1
  51. package/lib/config.d.ts +13 -0
  52. package/lib/config.d.ts.map +1 -0
  53. package/lib/config.js +9 -0
  54. package/lib/config.js.map +1 -0
  55. package/lib/network/client.d.ts +34 -0
  56. package/lib/network/client.d.ts.map +1 -0
  57. package/lib/network/client.js +213 -0
  58. package/lib/network/client.js.map +1 -0
  59. package/lib/network/graphql/queries.d.ts.map +1 -0
  60. package/lib/network/graphql/queries.js.map +1 -0
  61. package/lib/network/graphql/types.d.ts.map +1 -0
  62. package/lib/{api → network}/graphql/types.js.map +1 -1
  63. package/lib/network/index.d.ts +2 -1
  64. package/lib/network/index.d.ts.map +1 -1
  65. package/lib/network/index.js +15 -0
  66. package/lib/network/index.js.map +1 -1
  67. package/lib/types/assets.d.ts +3 -0
  68. package/lib/types/assets.d.ts.map +1 -0
  69. package/lib/types/assets.js +3 -0
  70. package/lib/types/assets.js.map +1 -0
  71. package/lib-es/__tests__/api/index.integ.test.d.ts +2 -0
  72. package/lib-es/__tests__/api/index.integ.test.d.ts.map +1 -0
  73. package/lib-es/__tests__/api/index.integ.test.js +20 -0
  74. package/lib-es/__tests__/api/index.integ.test.js.map +1 -0
  75. package/lib-es/__tests__/api/index.test.js +52 -464
  76. package/lib-es/__tests__/api/index.test.js.map +1 -1
  77. package/lib-es/__tests__/bridge/broadcast.test.js +2 -2
  78. package/lib-es/__tests__/bridge/broadcast.test.js.map +1 -1
  79. package/lib-es/__tests__/bridge/buildTransaction.test.js +2 -2
  80. package/lib-es/__tests__/bridge/buildTransaction.test.js.map +1 -1
  81. package/lib-es/__tests__/bridge/getFeesForTransaction.test.js +2 -2
  82. package/lib-es/__tests__/bridge/getFeesForTransaction.test.js.map +1 -1
  83. package/lib-es/__tests__/bridge/prepareTransaction.test.js +2 -2
  84. package/lib-es/__tests__/bridge/prepareTransaction.test.js.map +1 -1
  85. package/lib-es/__tests__/bridge/signOperation.test.js +3 -2
  86. package/lib-es/__tests__/bridge/signOperation.test.js.map +1 -1
  87. package/lib-es/__tests__/bridge/synchronisation.test.js +3 -3
  88. package/lib-es/__tests__/bridge/synchronisation.test.js.map +1 -1
  89. package/lib-es/__tests__/network/client.test.d.ts +2 -0
  90. package/lib-es/__tests__/network/client.test.d.ts.map +1 -0
  91. package/lib-es/__tests__/network/client.test.js +473 -0
  92. package/lib-es/__tests__/network/client.test.js.map +1 -0
  93. package/lib-es/api/index.d.ts +4 -33
  94. package/lib-es/api/index.d.ts.map +1 -1
  95. package/lib-es/api/index.js +24 -194
  96. package/lib-es/api/index.js.map +1 -1
  97. package/lib-es/bridge/broadcast.d.ts +3 -2
  98. package/lib-es/bridge/broadcast.d.ts.map +1 -1
  99. package/lib-es/bridge/broadcast.js +4 -3
  100. package/lib-es/bridge/broadcast.js.map +1 -1
  101. package/lib-es/bridge/buildTransaction.d.ts +1 -1
  102. package/lib-es/bridge/buildTransaction.d.ts.map +1 -1
  103. package/lib-es/bridge/buildTransaction.js.map +1 -1
  104. package/lib-es/bridge/estimateMaxSpendable.js +1 -1
  105. package/lib-es/bridge/estimateMaxSpendable.js.map +1 -1
  106. package/lib-es/bridge/getFeesForTransaction.d.ts +1 -1
  107. package/lib-es/bridge/getFeesForTransaction.d.ts.map +1 -1
  108. package/lib-es/bridge/index.d.ts +1 -1
  109. package/lib-es/bridge/index.d.ts.map +1 -1
  110. package/lib-es/bridge/prepareTransaction.d.ts.map +1 -1
  111. package/lib-es/bridge/prepareTransaction.js +1 -1
  112. package/lib-es/bridge/prepareTransaction.js.map +1 -1
  113. package/lib-es/bridge/signOperation.js +1 -1
  114. package/lib-es/bridge/signOperation.js.map +1 -1
  115. package/lib-es/bridge/synchronisation.js +1 -1
  116. package/lib-es/bridge/synchronisation.js.map +1 -1
  117. package/lib-es/config.d.ts +13 -0
  118. package/lib-es/config.d.ts.map +1 -0
  119. package/lib-es/config.js +4 -0
  120. package/lib-es/config.js.map +1 -0
  121. package/lib-es/network/client.d.ts +34 -0
  122. package/lib-es/network/client.d.ts.map +1 -0
  123. package/lib-es/network/client.js +206 -0
  124. package/lib-es/network/client.js.map +1 -0
  125. package/lib-es/network/graphql/queries.d.ts.map +1 -0
  126. package/lib-es/network/graphql/queries.js.map +1 -0
  127. package/lib-es/network/graphql/types.d.ts.map +1 -0
  128. package/lib-es/{api → network}/graphql/types.js.map +1 -1
  129. package/lib-es/network/index.d.ts +2 -1
  130. package/lib-es/network/index.d.ts.map +1 -1
  131. package/lib-es/network/index.js +1 -0
  132. package/lib-es/network/index.js.map +1 -1
  133. package/lib-es/types/assets.d.ts +3 -0
  134. package/lib-es/types/assets.d.ts.map +1 -0
  135. package/lib-es/types/assets.js +2 -0
  136. package/lib-es/types/assets.js.map +1 -0
  137. package/package.json +2 -1
  138. package/src/__tests__/api/index.integ.test.ts +24 -0
  139. package/src/__tests__/api/index.test.ts +58 -547
  140. package/src/__tests__/bridge/broadcast.test.ts +2 -2
  141. package/src/__tests__/bridge/buildTransaction.test.ts +2 -2
  142. package/src/__tests__/bridge/getFeesForTransaction.test.ts +2 -2
  143. package/src/__tests__/bridge/prepareTransaction.test.ts +2 -2
  144. package/src/__tests__/bridge/signOperation.test.ts +6 -3
  145. package/src/__tests__/bridge/synchronisation.test.ts +4 -4
  146. package/src/__tests__/network/client.test.ts +569 -0
  147. package/src/api/index.ts +30 -250
  148. package/src/bridge/broadcast.ts +7 -7
  149. package/src/bridge/buildTransaction.ts +1 -1
  150. package/src/bridge/estimateMaxSpendable.ts +1 -1
  151. package/src/bridge/getFeesForTransaction.ts +1 -1
  152. package/src/bridge/index.ts +1 -1
  153. package/src/bridge/prepareTransaction.ts +2 -1
  154. package/src/bridge/signOperation.ts +1 -1
  155. package/src/bridge/synchronisation.ts +1 -1
  156. package/src/config.ts +19 -0
  157. package/src/network/client.ts +265 -0
  158. package/src/network/index.ts +2 -1
  159. package/src/types/assets.ts +3 -0
  160. package/lib/api/graphql/queries.d.ts.map +0 -1
  161. package/lib/api/graphql/queries.js.map +0 -1
  162. package/lib/api/graphql/types.d.ts.map +0 -1
  163. package/lib-es/api/graphql/queries.d.ts.map +0 -1
  164. package/lib-es/api/graphql/queries.js.map +0 -1
  165. package/lib-es/api/graphql/types.d.ts.map +0 -1
  166. /package/lib/{api → network}/graphql/queries.d.ts +0 -0
  167. /package/lib/{api → network}/graphql/queries.js +0 -0
  168. /package/lib/{api → network}/graphql/types.d.ts +0 -0
  169. /package/lib/{api → network}/graphql/types.js +0 -0
  170. /package/lib-es/{api → network}/graphql/queries.d.ts +0 -0
  171. /package/lib-es/{api → network}/graphql/queries.js +0 -0
  172. /package/lib-es/{api → network}/graphql/types.d.ts +0 -0
  173. /package/lib-es/{api → network}/graphql/types.js +0 -0
  174. /package/src/{api → network}/graphql/queries.ts +0 -0
  175. /package/src/{api → network}/graphql/types.ts +0 -0
package/src/api/index.ts CHANGED
@@ -1,252 +1,32 @@
1
- import { ApolloClient, InMemoryCache } from "@apollo/client";
2
-
3
- import {
4
- AccountData,
5
- Aptos,
6
- AptosApiType,
7
- AptosConfig,
8
- Ed25519PublicKey,
9
- GasEstimation,
10
- InputEntryFunctionData,
11
- InputGenerateTransactionOptions,
12
- MimeType,
13
- post,
14
- RawTransaction,
15
- SimpleTransaction,
16
- TransactionResponse,
17
- UserTransactionResponse,
18
- PostRequestOptions,
19
- Block,
20
- } from "@aptos-labs/ts-sdk";
21
- import { getEnv } from "@ledgerhq/live-env";
22
- import network from "@ledgerhq/live-network";
23
- import BigNumber from "bignumber.js";
24
- import isUndefined from "lodash/isUndefined";
25
- import { APTOS_ASSET_ID } from "../constants";
26
- import { isTestnet } from "../bridge/logic";
27
- import type { AptosTransaction, TransactionOptions } from "../types";
28
- import { GetAccountTransactionsData, GetAccountTransactionsDataGt } from "./graphql/queries";
29
- import {
30
- GetAccountTransactionsDataQuery,
31
- GetAccountTransactionsDataGtQueryVariables,
32
- } from "./graphql/types";
33
- import { TokenCurrency } from "@ledgerhq/types-cryptoassets";
34
-
35
- const getApiEndpoint = (currencyId: string) =>
36
- isTestnet(currencyId) ? getEnv("APTOS_TESTNET_API_ENDPOINT") : getEnv("APTOS_API_ENDPOINT");
37
- const getIndexerEndpoint = (currencyId: string) =>
38
- isTestnet(currencyId)
39
- ? getEnv("APTOS_TESTNET_INDEXER_ENDPOINT")
40
- : getEnv("APTOS_INDEXER_ENDPOINT");
41
-
42
- export class AptosAPI {
43
- private apiUrl: string;
44
- private indexerUrl: string;
45
- private aptosConfig: AptosConfig;
46
- private aptosClient: Aptos;
47
- private apolloClient: ApolloClient<object>;
48
-
49
- constructor(currencyId: string) {
50
- this.apiUrl = getApiEndpoint(currencyId);
51
- this.indexerUrl = getIndexerEndpoint(currencyId);
52
- this.aptosConfig = new AptosConfig({
53
- fullnode: this.apiUrl,
54
- indexer: this.indexerUrl,
55
- });
56
- this.aptosClient = new Aptos(this.aptosConfig);
57
- this.apolloClient = new ApolloClient({
58
- uri: this.indexerUrl,
59
- cache: new InMemoryCache(),
60
- headers: {
61
- "x-client": "ledger-live",
62
- },
63
- });
64
- }
65
-
66
- async getAccount(address: string): Promise<AccountData> {
67
- return this.aptosClient.getAccountInfo({ accountAddress: address });
68
- }
69
-
70
- async getAccountInfo(address: string, startAt?: string) {
71
- const [balance, transactions, blockHeight] = await Promise.all([
72
- this.getCoinBalance(address, APTOS_ASSET_ID),
73
- this.fetchTransactions(address, startAt),
74
- this.getHeight(),
75
- ]);
76
-
77
- return {
78
- balance,
79
- transactions,
80
- blockHeight,
81
- };
82
- }
83
-
84
- async estimateGasPrice(): Promise<GasEstimation> {
85
- return this.aptosClient.getGasPriceEstimation();
86
- }
87
-
88
- async generateTransaction(
89
- address: string,
90
- payload: InputEntryFunctionData,
91
- options: TransactionOptions,
92
- ): Promise<RawTransaction> {
93
- const opts: Partial<InputGenerateTransactionOptions> = {};
94
- if (!isUndefined(options.maxGasAmount)) {
95
- opts.maxGasAmount = Number(options.maxGasAmount);
96
- }
97
-
98
- if (!isUndefined(options.gasUnitPrice)) {
99
- opts.gasUnitPrice = Number(options.gasUnitPrice);
100
- }
101
-
102
- try {
103
- const { ledger_timestamp } = await this.aptosClient.getLedgerInfo();
104
- opts.expireTimestamp = Number(Math.ceil(+ledger_timestamp / 1_000_000 + 2 * 60)); // in milliseconds
105
- } catch {
106
- // skip
107
- }
108
-
109
- return this.aptosClient.transaction.build
110
- .simple({
111
- sender: address,
112
- data: payload,
113
- options: opts,
114
- })
115
- .then(t => t.rawTransaction)
116
- .catch(error => {
117
- throw error;
118
- });
119
- }
120
-
121
- async simulateTransaction(
122
- address: Ed25519PublicKey,
123
- tx: RawTransaction,
124
- options = {
125
- estimateGasUnitPrice: true,
126
- estimateMaxGasAmount: true,
127
- estimatePrioritizedGasUnitPrice: false,
1
+ import type { Api } from "@ledgerhq/coin-framework/api/index";
2
+ import type { AptosConfig as AptosConfigApi } from "../config";
3
+ import type { Balance, FeeEstimation, Operation } from "@ledgerhq/coin-framework/api/types";
4
+ import coinConfig from "../config";
5
+ import type { AptosAsset } from "../types/assets";
6
+ import { AptosAPI } from "../network";
7
+
8
+ export function createApi(config: AptosConfigApi): Api<AptosAsset> {
9
+ coinConfig.setCoinConfig(() => ({ ...config, status: { type: "active" } }));
10
+
11
+ const client = new AptosAPI(config.aptosSettings);
12
+
13
+ return {
14
+ broadcast: (tx: string) => client.broadcast(tx),
15
+ combine: (_tx, _signature, _pubkey): string => {
16
+ throw new Error("Not Implemented");
128
17
  },
129
- ): Promise<UserTransactionResponse[]> {
130
- return this.aptosClient.transaction.simulate.simple({
131
- signerPublicKey: address,
132
- transaction: { rawTransaction: tx } as SimpleTransaction,
133
- options,
134
- });
135
- }
136
-
137
- async broadcast(signature: string): Promise<string> {
138
- const txBytes = Uint8Array.from(Buffer.from(signature, "hex"));
139
- const pendingTx = await post<PostRequestOptions, TransactionResponse>({
140
- contentType: MimeType.BCS_SIGNED_TRANSACTION,
141
- aptosConfig: this.aptosClient.config,
142
- body: txBytes,
143
- path: "transactions",
144
- type: AptosApiType.FULLNODE,
145
- originMethod: "",
146
- });
147
- return pendingTx.data.hash;
148
- }
149
-
150
- async getBalance(address: string, token: TokenCurrency): Promise<BigNumber> {
151
- let balance = new BigNumber(0);
152
- if (token.tokenType === "coin") {
153
- balance = await this.getCoinBalance(address, token.contractAddress);
154
- } else {
155
- balance = await this.getFABalance(address, token.contractAddress);
156
- }
157
- return balance;
158
- }
159
-
160
- async getCoinBalance(address: string, contract_address: string): Promise<BigNumber> {
161
- try {
162
- const [balanceStr] = await this.aptosClient.view<[string]>({
163
- payload: {
164
- function: "0x1::coin::balance",
165
- typeArguments: [contract_address],
166
- functionArguments: [address],
167
- },
168
- });
169
- const balance = parseInt(balanceStr, 10);
170
- return new BigNumber(balance);
171
- } catch (_) {
172
- return new BigNumber(0);
173
- }
174
- }
175
-
176
- async getFABalance(address: string, contract_address: string): Promise<BigNumber> {
177
- try {
178
- const [balanceStr] = await this.aptosClient.view<[string]>({
179
- payload: {
180
- function: "0x1::primary_fungible_store::balance",
181
- typeArguments: ["0x1::object::ObjectCore"],
182
- functionArguments: [address, contract_address],
183
- },
184
- });
185
- const balance = parseInt(balanceStr, 10);
186
- return new BigNumber(balance);
187
- } catch (_) {
188
- return new BigNumber(0);
189
- }
190
- }
191
-
192
- private async fetchTransactions(address: string, gt?: string) {
193
- if (!address) {
194
- return [];
195
- }
196
-
197
- let query = GetAccountTransactionsData;
198
- if (gt) {
199
- query = GetAccountTransactionsDataGt;
200
- }
201
-
202
- const queryResponse = await this.apolloClient.query<
203
- GetAccountTransactionsDataQuery,
204
- GetAccountTransactionsDataGtQueryVariables
205
- >({
206
- query,
207
- variables: {
208
- address,
209
- limit: 1000,
210
- gt,
211
- },
212
- fetchPolicy: "network-only",
213
- });
214
-
215
- return Promise.all(
216
- queryResponse.data.account_transactions.map(({ transaction_version }) => {
217
- return this.richItemByVersion(transaction_version);
218
- }),
219
- );
220
- }
221
-
222
- private async richItemByVersion(version: number): Promise<AptosTransaction | null> {
223
- try {
224
- const tx: TransactionResponse = await this.aptosClient.getTransactionByVersion({
225
- ledgerVersion: version,
226
- });
227
- const block = await this.getBlock(version);
228
- return {
229
- ...tx,
230
- block,
231
- } as AptosTransaction;
232
- } catch (error) {
233
- return null;
234
- }
235
- }
236
-
237
- private async getHeight(): Promise<number> {
238
- const { data } = await network<Block>({
239
- method: "GET",
240
- url: this.apiUrl,
241
- });
242
- return parseInt(data.block_height);
243
- }
244
-
245
- private async getBlock(version: number) {
246
- const block = await this.aptosClient.getBlockByVersion({ ledgerVersion: version });
247
- return {
248
- height: parseInt(block.block_height),
249
- hash: block.block_hash,
250
- };
251
- }
18
+ craftTransaction: (_transactionIntent, _customFees): Promise<string> => {
19
+ throw new Error("Not Implemented");
20
+ },
21
+ estimateFees: (_transactionIntent): Promise<FeeEstimation<never>> => {
22
+ throw new Error("Not Implemented");
23
+ },
24
+ getBalance: (_address): Promise<Balance<AptosAsset>[]> => {
25
+ throw new Error("Not Implemented");
26
+ },
27
+ lastBlock: () => client.getLastBlock(),
28
+ listOperations: (_address, _pagination): Promise<[Operation<AptosAsset>[], string]> => {
29
+ throw new Error("Not Implemented");
30
+ },
31
+ };
252
32
  }
@@ -1,16 +1,16 @@
1
1
  import type { Account, Operation, SignedOperation } from "@ledgerhq/types-live";
2
2
  import { patchOperationWithHash } from "@ledgerhq/coin-framework/operation";
3
- import { AptosAPI } from "../api";
3
+ import { AptosAPI } from "../network";
4
4
 
5
- const broadcast = async ({
6
- signedOperation,
7
- account,
8
- }: {
5
+ type broadcastFunc = {
9
6
  signedOperation: SignedOperation;
10
7
  account: Account;
11
- }): Promise<Operation> => {
8
+ };
9
+
10
+ const broadcast = async ({ signedOperation, account }: broadcastFunc): Promise<Operation> => {
12
11
  const { signature, operation } = signedOperation;
13
- const hash = await new AptosAPI(account.currency.id).broadcast(signature);
12
+ const client = new AptosAPI(account.currency.id);
13
+ const hash = await client.broadcast(signature);
14
14
  return patchOperationWithHash(operation, hash);
15
15
  };
16
16
 
@@ -1,8 +1,8 @@
1
1
  import { InputEntryFunctionData, RawTransaction } from "@aptos-labs/ts-sdk";
2
2
  import type { Account, TokenAccount } from "@ledgerhq/types-live";
3
3
  import { findSubAccountById, isTokenAccount } from "@ledgerhq/coin-framework/account/index";
4
- import { AptosAPI } from "../api";
5
4
  import { APTOS_ASSET_ID, SUPPORTED_TOKEN_TYPES } from "../constants";
5
+ import { AptosAPI } from "../network";
6
6
  import { normalizeTransactionOptions } from "./logic";
7
7
  import type { Transaction } from "../types";
8
8
 
@@ -1,7 +1,7 @@
1
1
  import type { Account, AccountLike } from "@ledgerhq/types-live";
2
2
  import { BigNumber } from "bignumber.js";
3
3
  import { getMainAccount } from "@ledgerhq/coin-framework/account/index";
4
- import { AptosAPI } from "../api";
4
+ import { AptosAPI } from "../network";
5
5
  import { getEstimatedGas } from "./getFeesForTransaction";
6
6
  import { DEFAULT_GAS, DEFAULT_GAS_PRICE, getMaxSendBalance } from "./logic";
7
7
  import type { Transaction } from "../types";
@@ -3,7 +3,7 @@ import { log } from "@ledgerhq/logs";
3
3
  import type { Account } from "@ledgerhq/types-live";
4
4
  import BigNumber from "bignumber.js";
5
5
  import { makeLRUCache, seconds } from "@ledgerhq/live-network/cache";
6
- import { AptosAPI } from "../api";
6
+ import { AptosAPI } from "../network";
7
7
  import buildTransaction from "./buildTransaction";
8
8
  import { DEFAULT_GAS, DEFAULT_GAS_PRICE, ESTIMATE_GAS_MUL, getTokenAccount } from "./logic";
9
9
  import type { Transaction, TransactionErrors } from "../types";
@@ -6,7 +6,7 @@ import {
6
6
  updateTransaction,
7
7
  } from "@ledgerhq/coin-framework/bridge/jsHelpers";
8
8
  import getAddressWrapper from "@ledgerhq/coin-framework/bridge/getAddressWrapper";
9
- import { SignerContext } from "@ledgerhq/coin-framework/signer";
9
+ import type { SignerContext } from "@ledgerhq/coin-framework/signer";
10
10
  import type { Account, AccountBridge, CurrencyBridge } from "@ledgerhq/types-live";
11
11
  import resolver from "../signer";
12
12
  import type { Transaction, TransactionStatus, AptosSigner } from "../types";
@@ -1,6 +1,7 @@
1
1
  import type { Account } from "@ledgerhq/types-live";
2
2
  import BigNumber from "bignumber.js";
3
- import { AptosAPI } from "../api";
3
+
4
+ import { AptosAPI } from "../network";
4
5
  import { getEstimatedGas } from "./getFeesForTransaction";
5
6
  import type { Transaction } from "../types";
6
7
  import { DEFAULT_GAS, DEFAULT_GAS_PRICE, getMaxSendBalance } from "./logic";
@@ -4,7 +4,7 @@ import { encodeOperationId } from "@ledgerhq/coin-framework/operation";
4
4
  import buildTransaction from "./buildTransaction";
5
5
  import BigNumber from "bignumber.js";
6
6
  import type { Account, AccountBridge, Operation, OperationType } from "@ledgerhq/types-live";
7
- import { AptosAPI } from "../api";
7
+ import { AptosAPI } from "../network";
8
8
 
9
9
  import { SignerContext } from "@ledgerhq/coin-framework/signer";
10
10
  import { AptosSigner } from "../types";
@@ -2,7 +2,7 @@ import { inferSubOperations } from "@ledgerhq/coin-framework/serialization/index
2
2
  import { decodeAccountId, encodeAccountId } from "@ledgerhq/coin-framework/account";
3
3
  import type { GetAccountShape } from "@ledgerhq/coin-framework/bridge/jsHelpers";
4
4
  import { mergeOps } from "@ledgerhq/coin-framework/bridge/jsHelpers";
5
- import { AptosAPI } from "../api";
5
+ import { AptosAPI } from "../network";
6
6
  import { txsToOps } from "./logic";
7
7
  import type { AptosAccount } from "../types";
8
8
  import { Account, Operation, TokenAccount } from "@ledgerhq/types-live";
package/src/config.ts ADDED
@@ -0,0 +1,19 @@
1
+ import { type AptosSettings } from "@aptos-labs/ts-sdk";
2
+ import buildCoinConfig, {
3
+ type CoinConfig,
4
+ type CurrencyConfig,
5
+ } from "@ledgerhq/coin-framework/config";
6
+ import type { CryptoCurrency } from "@ledgerhq/types-cryptoassets";
7
+
8
+ export type AptosConfig = {
9
+ aptosSettings: AptosSettings;
10
+ };
11
+
12
+ export type AptosCoinConfig = CurrencyConfig & AptosConfig;
13
+
14
+ const coinConfig: {
15
+ setCoinConfig: (config: CoinConfig<AptosCoinConfig>) => void;
16
+ getCoinConfig: (currency?: CryptoCurrency) => AptosCoinConfig;
17
+ } = buildCoinConfig<AptosCoinConfig>();
18
+
19
+ export default coinConfig;
@@ -0,0 +1,265 @@
1
+ import { ApolloClient, InMemoryCache } from "@apollo/client";
2
+
3
+ import {
4
+ AccountData,
5
+ Aptos,
6
+ AptosApiType,
7
+ AptosConfig,
8
+ Ed25519PublicKey,
9
+ GasEstimation,
10
+ InputEntryFunctionData,
11
+ InputGenerateTransactionOptions,
12
+ MimeType,
13
+ post,
14
+ RawTransaction,
15
+ SimpleTransaction,
16
+ TransactionResponse,
17
+ UserTransactionResponse,
18
+ PostRequestOptions,
19
+ Block,
20
+ AptosSettings,
21
+ } from "@aptos-labs/ts-sdk";
22
+ import { getEnv } from "@ledgerhq/live-env";
23
+ import network from "@ledgerhq/live-network";
24
+ import BigNumber from "bignumber.js";
25
+ import isUndefined from "lodash/isUndefined";
26
+ import { APTOS_ASSET_ID } from "../constants";
27
+ import { isTestnet } from "../bridge/logic";
28
+ import type { AptosTransaction, TransactionOptions } from "../types";
29
+ import { GetAccountTransactionsData, GetAccountTransactionsDataGt } from "./graphql/queries";
30
+ import {
31
+ GetAccountTransactionsDataQuery,
32
+ GetAccountTransactionsDataGtQueryVariables,
33
+ } from "./graphql/types";
34
+ import { TokenCurrency } from "@ledgerhq/types-cryptoassets";
35
+ import { BlockInfo } from "@ledgerhq/coin-framework/api/types";
36
+
37
+ const getApiEndpoint = (currencyId: string) =>
38
+ isTestnet(currencyId) ? getEnv("APTOS_TESTNET_API_ENDPOINT") : getEnv("APTOS_API_ENDPOINT");
39
+ const getIndexerEndpoint = (currencyId: string) =>
40
+ isTestnet(currencyId)
41
+ ? getEnv("APTOS_TESTNET_INDEXER_ENDPOINT")
42
+ : getEnv("APTOS_INDEXER_ENDPOINT");
43
+
44
+ export class AptosAPI {
45
+ private aptosConfig: AptosConfig;
46
+ private aptosClient: Aptos;
47
+ private apolloClient: ApolloClient<object>;
48
+
49
+ constructor(currencyIdOrSettings: AptosSettings | string) {
50
+ if (typeof currencyIdOrSettings === "string") {
51
+ this.aptosConfig = new AptosConfig({
52
+ fullnode: getApiEndpoint(currencyIdOrSettings),
53
+ indexer: getIndexerEndpoint(currencyIdOrSettings),
54
+ });
55
+ } else {
56
+ this.aptosConfig = new AptosConfig(currencyIdOrSettings);
57
+ }
58
+
59
+ this.aptosClient = new Aptos(this.aptosConfig);
60
+ this.apolloClient = new ApolloClient({
61
+ uri: this.aptosConfig.indexer || "",
62
+ cache: new InMemoryCache(),
63
+ headers: {
64
+ "x-client": "ledger-live",
65
+ },
66
+ });
67
+ }
68
+
69
+ async getAccount(address: string): Promise<AccountData> {
70
+ return this.aptosClient.getAccountInfo({ accountAddress: address });
71
+ }
72
+
73
+ async getAccountInfo(address: string, startAt?: string) {
74
+ const [balance, transactions, blockHeight] = await Promise.all([
75
+ this.getCoinBalance(address, APTOS_ASSET_ID),
76
+ this.fetchTransactions(address, startAt),
77
+ this.getHeight(),
78
+ ]);
79
+
80
+ return {
81
+ balance,
82
+ transactions,
83
+ blockHeight,
84
+ };
85
+ }
86
+
87
+ async estimateGasPrice(): Promise<GasEstimation> {
88
+ return this.aptosClient.getGasPriceEstimation();
89
+ }
90
+
91
+ async generateTransaction(
92
+ address: string,
93
+ payload: InputEntryFunctionData,
94
+ options: TransactionOptions,
95
+ ): Promise<RawTransaction> {
96
+ const opts: Partial<InputGenerateTransactionOptions> = {};
97
+ if (!isUndefined(options.maxGasAmount)) {
98
+ opts.maxGasAmount = Number(options.maxGasAmount);
99
+ }
100
+
101
+ if (!isUndefined(options.gasUnitPrice)) {
102
+ opts.gasUnitPrice = Number(options.gasUnitPrice);
103
+ }
104
+
105
+ try {
106
+ const { ledger_timestamp } = await this.aptosClient.getLedgerInfo();
107
+ opts.expireTimestamp = Number(Math.ceil(+ledger_timestamp / 1_000_000 + 2 * 60)); // in milliseconds
108
+ } catch {
109
+ // skip
110
+ }
111
+
112
+ return this.aptosClient.transaction.build
113
+ .simple({
114
+ sender: address,
115
+ data: payload,
116
+ options: opts,
117
+ })
118
+ .then(t => t.rawTransaction)
119
+ .catch(error => {
120
+ throw error;
121
+ });
122
+ }
123
+
124
+ async simulateTransaction(
125
+ address: Ed25519PublicKey,
126
+ tx: RawTransaction,
127
+ options = {
128
+ estimateGasUnitPrice: true,
129
+ estimateMaxGasAmount: true,
130
+ estimatePrioritizedGasUnitPrice: false,
131
+ },
132
+ ): Promise<UserTransactionResponse[]> {
133
+ return this.aptosClient.transaction.simulate.simple({
134
+ signerPublicKey: address,
135
+ transaction: { rawTransaction: tx } as SimpleTransaction,
136
+ options,
137
+ });
138
+ }
139
+
140
+ async broadcast(signature: string): Promise<string> {
141
+ const txBytes = Uint8Array.from(Buffer.from(signature, "hex"));
142
+ const pendingTx = await post<PostRequestOptions, TransactionResponse>({
143
+ contentType: MimeType.BCS_SIGNED_TRANSACTION,
144
+ aptosConfig: this.aptosClient.config,
145
+ body: txBytes,
146
+ path: "transactions",
147
+ type: AptosApiType.FULLNODE,
148
+ originMethod: "",
149
+ });
150
+ return pendingTx.data.hash;
151
+ }
152
+
153
+ async getBalance(address: string, token: TokenCurrency): Promise<BigNumber> {
154
+ let balance = new BigNumber(0);
155
+ if (token.tokenType === "coin") {
156
+ balance = await this.getCoinBalance(address, token.contractAddress);
157
+ } else {
158
+ balance = await this.getFABalance(address, token.contractAddress);
159
+ }
160
+ return balance;
161
+ }
162
+
163
+ async getLastBlock(): Promise<BlockInfo> {
164
+ const { block_height } = await this.aptosClient.getLedgerInfo();
165
+ const block = await this.aptosClient.getBlockByHeight({ blockHeight: Number(block_height) });
166
+ return {
167
+ height: Number(block.block_height),
168
+ hash: block.block_hash,
169
+ time: new Date(Number(block.block_timestamp)),
170
+ };
171
+ }
172
+
173
+ async getCoinBalance(address: string, contract_address: string): Promise<BigNumber> {
174
+ try {
175
+ const [balanceStr] = await this.aptosClient.view<[string]>({
176
+ payload: {
177
+ function: "0x1::coin::balance",
178
+ typeArguments: [contract_address],
179
+ functionArguments: [address],
180
+ },
181
+ });
182
+ const balance = parseInt(balanceStr, 10);
183
+ return new BigNumber(balance);
184
+ } catch (_) {
185
+ return new BigNumber(0);
186
+ }
187
+ }
188
+
189
+ async getFABalance(address: string, contract_address: string): Promise<BigNumber> {
190
+ try {
191
+ const [balanceStr] = await this.aptosClient.view<[string]>({
192
+ payload: {
193
+ function: "0x1::primary_fungible_store::balance",
194
+ typeArguments: ["0x1::object::ObjectCore"],
195
+ functionArguments: [address, contract_address],
196
+ },
197
+ });
198
+ const balance = parseInt(balanceStr, 10);
199
+ return new BigNumber(balance);
200
+ } catch (_) {
201
+ return new BigNumber(0);
202
+ }
203
+ }
204
+
205
+ private async fetchTransactions(address: string, gt?: string) {
206
+ if (!address) {
207
+ return [];
208
+ }
209
+
210
+ let query = GetAccountTransactionsData;
211
+ if (gt) {
212
+ query = GetAccountTransactionsDataGt;
213
+ }
214
+
215
+ const queryResponse = await this.apolloClient.query<
216
+ GetAccountTransactionsDataQuery,
217
+ GetAccountTransactionsDataGtQueryVariables
218
+ >({
219
+ query,
220
+ variables: {
221
+ address,
222
+ limit: 1000,
223
+ gt,
224
+ },
225
+ fetchPolicy: "network-only",
226
+ });
227
+
228
+ return Promise.all(
229
+ queryResponse.data.account_transactions.map(({ transaction_version }) => {
230
+ return this.richItemByVersion(transaction_version);
231
+ }),
232
+ );
233
+ }
234
+
235
+ private async richItemByVersion(version: number): Promise<AptosTransaction | null> {
236
+ try {
237
+ const tx: TransactionResponse = await this.aptosClient.getTransactionByVersion({
238
+ ledgerVersion: version,
239
+ });
240
+ const block = await this.getBlock(version);
241
+ return {
242
+ ...tx,
243
+ block,
244
+ } as AptosTransaction;
245
+ } catch (error) {
246
+ return null;
247
+ }
248
+ }
249
+
250
+ private async getHeight(): Promise<number> {
251
+ const { data } = await network<Block>({
252
+ method: "GET",
253
+ url: this.aptosConfig.fullnode || "",
254
+ });
255
+ return parseInt(data.block_height);
256
+ }
257
+
258
+ private async getBlock(version: number) {
259
+ const block = await this.aptosClient.getBlockByVersion({ ledgerVersion: version });
260
+ return {
261
+ height: parseInt(block.block_height),
262
+ hash: block.block_hash,
263
+ };
264
+ }
265
+ }
@@ -9,10 +9,11 @@ import {
9
9
  RawTransaction,
10
10
  SimpleTransaction,
11
11
  } from "@aptos-labs/ts-sdk";
12
- import { SignerContext } from "@ledgerhq/coin-framework/lib/signer";
12
+ import { SignerContext } from "@ledgerhq/coin-framework/signer";
13
13
  import { Account } from "@ledgerhq/types-live";
14
14
  import { AptosSigner } from "../types";
15
15
  import { sha3_256 as sha3Hash } from "@noble/hashes/sha3";
16
+ export * from "./client";
16
17
 
17
18
  export async function signTransaction(
18
19
  signerContext: SignerContext<AptosSigner>,
@@ -0,0 +1,3 @@
1
+ import type { Asset } from "@ledgerhq/coin-framework/api/types";
2
+
3
+ export type AptosAsset = Asset;
@@ -1 +0,0 @@
1
- {"version":3,"file":"queries.d.ts","sourceRoot":"","sources":["../../../src/api/graphql/queries.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,6BAA6B,uCAczC,CAAC;AACF,eAAO,MAAM,0BAA0B,uCAWtC,CAAC;AACF,eAAO,MAAM,4BAA4B,uCAWxC,CAAC;AACF,eAAO,MAAM,4BAA4B,uCAWxC,CAAC"}