@ledgerhq/coin-aptos 1.9.6-next.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 (259) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/.unimportedrc.json +18 -6
  3. package/CHANGELOG.md +19 -4
  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 -404
  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 +60 -5
  14. package/lib/__tests__/bridge/buildTransaction.test.js.map +1 -1
  15. package/lib/__tests__/bridge/getFeesForTransaction.test.js +115 -14
  16. package/lib/__tests__/bridge/getFeesForTransaction.test.js.map +1 -1
  17. package/lib/__tests__/bridge/getTransactionStatus.test.js +175 -37
  18. package/lib/__tests__/bridge/getTransactionStatus.test.js.map +1 -1
  19. package/lib/__tests__/bridge/logic.test.js +889 -115
  20. package/lib/__tests__/bridge/logic.test.js.map +1 -1
  21. package/lib/__tests__/bridge/prepareTransaction.test.js +3 -3
  22. package/lib/__tests__/bridge/prepareTransaction.test.js.map +1 -1
  23. package/lib/__tests__/bridge/signOperation.test.js +131 -4
  24. package/lib/__tests__/bridge/signOperation.test.js.map +1 -1
  25. package/lib/__tests__/bridge/synchronisation.test.js +1215 -68
  26. package/lib/__tests__/bridge/synchronisation.test.js.map +1 -1
  27. package/lib/__tests__/network/client.test.d.ts +2 -0
  28. package/lib/__tests__/network/client.test.d.ts.map +1 -0
  29. package/lib/__tests__/network/client.test.js +478 -0
  30. package/lib/__tests__/network/client.test.js.map +1 -0
  31. package/lib/api/index.d.ts +4 -30
  32. package/lib/api/index.d.ts.map +1 -1
  33. package/lib/api/index.js +26 -170
  34. package/lib/api/index.js.map +1 -1
  35. package/lib/bridge/bridge.fixture.d.ts +2 -0
  36. package/lib/bridge/bridge.fixture.d.ts.map +1 -1
  37. package/lib/bridge/bridge.fixture.js +85 -13
  38. package/lib/bridge/bridge.fixture.js.map +1 -1
  39. package/lib/bridge/broadcast.d.ts +3 -2
  40. package/lib/bridge/broadcast.d.ts.map +1 -1
  41. package/lib/bridge/broadcast.js +4 -3
  42. package/lib/bridge/broadcast.js.map +1 -1
  43. package/lib/bridge/buildTransaction.d.ts +1 -1
  44. package/lib/bridge/buildTransaction.d.ts.map +1 -1
  45. package/lib/bridge/buildTransaction.js +29 -3
  46. package/lib/bridge/buildTransaction.js.map +1 -1
  47. package/lib/bridge/estimateMaxSpendable.js +3 -3
  48. package/lib/bridge/estimateMaxSpendable.js.map +1 -1
  49. package/lib/bridge/getFeesForTransaction.d.ts +1 -1
  50. package/lib/bridge/getFeesForTransaction.d.ts.map +1 -1
  51. package/lib/bridge/getFeesForTransaction.js +12 -7
  52. package/lib/bridge/getFeesForTransaction.js.map +1 -1
  53. package/lib/bridge/getTransactionStatus.d.ts.map +1 -1
  54. package/lib/bridge/getTransactionStatus.js +28 -14
  55. package/lib/bridge/getTransactionStatus.js.map +1 -1
  56. package/lib/bridge/index.d.ts +1 -1
  57. package/lib/bridge/index.d.ts.map +1 -1
  58. package/lib/bridge/logic.d.ts +13 -8
  59. package/lib/bridge/logic.d.ts.map +1 -1
  60. package/lib/bridge/logic.js +152 -54
  61. package/lib/bridge/logic.js.map +1 -1
  62. package/lib/bridge/prepareTransaction.d.ts.map +1 -1
  63. package/lib/bridge/prepareTransaction.js +4 -4
  64. package/lib/bridge/prepareTransaction.js.map +1 -1
  65. package/lib/bridge/signOperation.d.ts.map +1 -1
  66. package/lib/bridge/signOperation.js +20 -6
  67. package/lib/bridge/signOperation.js.map +1 -1
  68. package/lib/bridge/synchronisation.d.ts +15 -0
  69. package/lib/bridge/synchronisation.d.ts.map +1 -1
  70. package/lib/bridge/synchronisation.js +129 -6
  71. package/lib/bridge/synchronisation.js.map +1 -1
  72. package/lib/config.d.ts +13 -0
  73. package/lib/config.d.ts.map +1 -0
  74. package/lib/config.js +9 -0
  75. package/lib/config.js.map +1 -0
  76. package/lib/constants.d.ts +5 -1
  77. package/lib/constants.d.ts.map +1 -1
  78. package/lib/constants.js +6 -2
  79. package/lib/constants.js.map +1 -1
  80. package/lib/network/client.d.ts +34 -0
  81. package/lib/network/client.d.ts.map +1 -0
  82. package/lib/network/client.js +213 -0
  83. package/lib/network/client.js.map +1 -0
  84. package/lib/network/graphql/queries.d.ts.map +1 -0
  85. package/lib/{api → network}/graphql/queries.js +6 -6
  86. package/lib/network/graphql/queries.js.map +1 -0
  87. package/lib/{api → network}/graphql/types.d.ts +9 -9
  88. package/lib/network/graphql/types.d.ts.map +1 -0
  89. package/lib/{api → network}/graphql/types.js.map +1 -1
  90. package/lib/network/index.d.ts +2 -1
  91. package/lib/network/index.d.ts.map +1 -1
  92. package/lib/network/index.js +15 -0
  93. package/lib/network/index.js.map +1 -1
  94. package/lib/test/bot-specs.d.ts.map +1 -1
  95. package/lib/test/bot-specs.js +40 -1
  96. package/lib/test/bot-specs.js.map +1 -1
  97. package/lib/test/bridgeDatasetTest.d.ts.map +1 -1
  98. package/lib/test/bridgeDatasetTest.js +44 -62
  99. package/lib/test/bridgeDatasetTest.js.map +1 -1
  100. package/lib/test/speculos-deviceActions.d.ts +1 -0
  101. package/lib/test/speculos-deviceActions.d.ts.map +1 -1
  102. package/lib/test/speculos-deviceActions.js +37 -5
  103. package/lib/test/speculos-deviceActions.js.map +1 -1
  104. package/lib/types/assets.d.ts +3 -0
  105. package/lib/types/assets.d.ts.map +1 -0
  106. package/lib/types/assets.js +3 -0
  107. package/lib/types/assets.js.map +1 -0
  108. package/lib/types/index.d.ts +18 -7
  109. package/lib/types/index.d.ts.map +1 -1
  110. package/lib-es/__tests__/api/index.integ.test.d.ts +2 -0
  111. package/lib-es/__tests__/api/index.integ.test.d.ts.map +1 -0
  112. package/lib-es/__tests__/api/index.integ.test.js +20 -0
  113. package/lib-es/__tests__/api/index.integ.test.js.map +1 -0
  114. package/lib-es/__tests__/api/index.test.js +52 -408
  115. package/lib-es/__tests__/api/index.test.js.map +1 -1
  116. package/lib-es/__tests__/bridge/broadcast.test.js +2 -2
  117. package/lib-es/__tests__/bridge/broadcast.test.js.map +1 -1
  118. package/lib-es/__tests__/bridge/buildTransaction.test.js +60 -5
  119. package/lib-es/__tests__/bridge/buildTransaction.test.js.map +1 -1
  120. package/lib-es/__tests__/bridge/getFeesForTransaction.test.js +112 -11
  121. package/lib-es/__tests__/bridge/getFeesForTransaction.test.js.map +1 -1
  122. package/lib-es/__tests__/bridge/getTransactionStatus.test.js +177 -39
  123. package/lib-es/__tests__/bridge/getTransactionStatus.test.js.map +1 -1
  124. package/lib-es/__tests__/bridge/logic.test.js +891 -117
  125. package/lib-es/__tests__/bridge/logic.test.js.map +1 -1
  126. package/lib-es/__tests__/bridge/prepareTransaction.test.js +2 -2
  127. package/lib-es/__tests__/bridge/prepareTransaction.test.js.map +1 -1
  128. package/lib-es/__tests__/bridge/signOperation.test.js +131 -4
  129. package/lib-es/__tests__/bridge/signOperation.test.js.map +1 -1
  130. package/lib-es/__tests__/bridge/synchronisation.test.js +1213 -69
  131. package/lib-es/__tests__/bridge/synchronisation.test.js.map +1 -1
  132. package/lib-es/__tests__/network/client.test.d.ts +2 -0
  133. package/lib-es/__tests__/network/client.test.d.ts.map +1 -0
  134. package/lib-es/__tests__/network/client.test.js +473 -0
  135. package/lib-es/__tests__/network/client.test.js.map +1 -0
  136. package/lib-es/api/index.d.ts +4 -30
  137. package/lib-es/api/index.d.ts.map +1 -1
  138. package/lib-es/api/index.js +24 -168
  139. package/lib-es/api/index.js.map +1 -1
  140. package/lib-es/bridge/bridge.fixture.d.ts +2 -0
  141. package/lib-es/bridge/bridge.fixture.d.ts.map +1 -1
  142. package/lib-es/bridge/bridge.fixture.js +82 -12
  143. package/lib-es/bridge/bridge.fixture.js.map +1 -1
  144. package/lib-es/bridge/broadcast.d.ts +3 -2
  145. package/lib-es/bridge/broadcast.d.ts.map +1 -1
  146. package/lib-es/bridge/broadcast.js +4 -3
  147. package/lib-es/bridge/broadcast.js.map +1 -1
  148. package/lib-es/bridge/buildTransaction.d.ts +1 -1
  149. package/lib-es/bridge/buildTransaction.d.ts.map +1 -1
  150. package/lib-es/bridge/buildTransaction.js +30 -4
  151. package/lib-es/bridge/buildTransaction.js.map +1 -1
  152. package/lib-es/bridge/estimateMaxSpendable.js +2 -2
  153. package/lib-es/bridge/estimateMaxSpendable.js.map +1 -1
  154. package/lib-es/bridge/getFeesForTransaction.d.ts +1 -1
  155. package/lib-es/bridge/getFeesForTransaction.d.ts.map +1 -1
  156. package/lib-es/bridge/getFeesForTransaction.js +13 -8
  157. package/lib-es/bridge/getFeesForTransaction.js.map +1 -1
  158. package/lib-es/bridge/getTransactionStatus.d.ts.map +1 -1
  159. package/lib-es/bridge/getTransactionStatus.js +28 -14
  160. package/lib-es/bridge/getTransactionStatus.js.map +1 -1
  161. package/lib-es/bridge/index.d.ts +1 -1
  162. package/lib-es/bridge/index.d.ts.map +1 -1
  163. package/lib-es/bridge/logic.d.ts +13 -8
  164. package/lib-es/bridge/logic.d.ts.map +1 -1
  165. package/lib-es/bridge/logic.js +146 -52
  166. package/lib-es/bridge/logic.js.map +1 -1
  167. package/lib-es/bridge/prepareTransaction.d.ts.map +1 -1
  168. package/lib-es/bridge/prepareTransaction.js +3 -3
  169. package/lib-es/bridge/prepareTransaction.js.map +1 -1
  170. package/lib-es/bridge/signOperation.d.ts.map +1 -1
  171. package/lib-es/bridge/signOperation.js +18 -4
  172. package/lib-es/bridge/signOperation.js.map +1 -1
  173. package/lib-es/bridge/synchronisation.d.ts +15 -0
  174. package/lib-es/bridge/synchronisation.d.ts.map +1 -1
  175. package/lib-es/bridge/synchronisation.js +124 -4
  176. package/lib-es/bridge/synchronisation.js.map +1 -1
  177. package/lib-es/config.d.ts +13 -0
  178. package/lib-es/config.d.ts.map +1 -0
  179. package/lib-es/config.js +4 -0
  180. package/lib-es/config.js.map +1 -0
  181. package/lib-es/constants.d.ts +5 -1
  182. package/lib-es/constants.d.ts.map +1 -1
  183. package/lib-es/constants.js +5 -1
  184. package/lib-es/constants.js.map +1 -1
  185. package/lib-es/network/client.d.ts +34 -0
  186. package/lib-es/network/client.d.ts.map +1 -0
  187. package/lib-es/network/client.js +206 -0
  188. package/lib-es/network/client.js.map +1 -0
  189. package/lib-es/network/graphql/queries.d.ts.map +1 -0
  190. package/lib-es/{api → network}/graphql/queries.js +6 -6
  191. package/lib-es/network/graphql/queries.js.map +1 -0
  192. package/lib-es/{api → network}/graphql/types.d.ts +9 -9
  193. package/lib-es/network/graphql/types.d.ts.map +1 -0
  194. package/lib-es/{api → network}/graphql/types.js.map +1 -1
  195. package/lib-es/network/index.d.ts +2 -1
  196. package/lib-es/network/index.d.ts.map +1 -1
  197. package/lib-es/network/index.js +1 -0
  198. package/lib-es/network/index.js.map +1 -1
  199. package/lib-es/test/bot-specs.d.ts.map +1 -1
  200. package/lib-es/test/bot-specs.js +41 -2
  201. package/lib-es/test/bot-specs.js.map +1 -1
  202. package/lib-es/test/bridgeDatasetTest.d.ts.map +1 -1
  203. package/lib-es/test/bridgeDatasetTest.js +44 -59
  204. package/lib-es/test/bridgeDatasetTest.js.map +1 -1
  205. package/lib-es/test/speculos-deviceActions.d.ts +1 -0
  206. package/lib-es/test/speculos-deviceActions.d.ts.map +1 -1
  207. package/lib-es/test/speculos-deviceActions.js +36 -4
  208. package/lib-es/test/speculos-deviceActions.js.map +1 -1
  209. package/lib-es/types/assets.d.ts +3 -0
  210. package/lib-es/types/assets.d.ts.map +1 -0
  211. package/lib-es/types/assets.js +2 -0
  212. package/lib-es/types/assets.js.map +1 -0
  213. package/lib-es/types/index.d.ts +18 -7
  214. package/lib-es/types/index.d.ts.map +1 -1
  215. package/package.json +10 -8
  216. package/src/__tests__/api/index.integ.test.ts +24 -0
  217. package/src/__tests__/api/index.test.ts +58 -477
  218. package/src/__tests__/bridge/broadcast.test.ts +2 -2
  219. package/src/__tests__/bridge/buildTransaction.test.ts +87 -5
  220. package/src/__tests__/bridge/getFeesForTransaction.test.ts +146 -11
  221. package/src/__tests__/bridge/getTransactionStatus.test.ts +217 -38
  222. package/src/__tests__/bridge/logic.test.ts +922 -118
  223. package/src/__tests__/bridge/prepareTransaction.test.ts +2 -2
  224. package/src/__tests__/bridge/signOperation.test.ts +147 -5
  225. package/src/__tests__/bridge/synchronisation.test.ts +1265 -71
  226. package/src/__tests__/network/client.test.ts +569 -0
  227. package/src/api/index.ts +30 -223
  228. package/src/bridge/bridge.fixture.ts +91 -12
  229. package/src/bridge/broadcast.ts +7 -7
  230. package/src/bridge/buildTransaction.ts +40 -7
  231. package/src/bridge/estimateMaxSpendable.ts +2 -2
  232. package/src/bridge/getFeesForTransaction.ts +15 -10
  233. package/src/bridge/getTransactionStatus.ts +35 -13
  234. package/src/bridge/index.ts +1 -1
  235. package/src/bridge/logic.ts +202 -63
  236. package/src/bridge/prepareTransaction.ts +5 -3
  237. package/src/bridge/signOperation.ts +20 -4
  238. package/src/bridge/synchronisation.ts +171 -4
  239. package/src/config.ts +19 -0
  240. package/src/constants.ts +12 -1
  241. package/src/network/client.ts +265 -0
  242. package/src/{api → network}/graphql/queries.ts +6 -6
  243. package/src/{api → network}/graphql/types.ts +9 -9
  244. package/src/network/index.ts +2 -1
  245. package/src/test/bot-specs.ts +63 -3
  246. package/src/test/bridgeDatasetTest.ts +46 -59
  247. package/src/test/speculos-deviceActions.ts +40 -4
  248. package/src/types/assets.ts +3 -0
  249. package/src/types/index.ts +15 -1
  250. package/lib/api/graphql/queries.d.ts.map +0 -1
  251. package/lib/api/graphql/queries.js.map +0 -1
  252. package/lib/api/graphql/types.d.ts.map +0 -1
  253. package/lib-es/api/graphql/queries.d.ts.map +0 -1
  254. package/lib-es/api/graphql/queries.js.map +0 -1
  255. package/lib-es/api/graphql/types.d.ts.map +0 -1
  256. /package/lib/{api → network}/graphql/queries.d.ts +0 -0
  257. /package/lib/{api → network}/graphql/types.js +0 -0
  258. /package/lib-es/{api → network}/graphql/queries.d.ts +0 -0
  259. /package/lib-es/{api → network}/graphql/types.js +0 -0
package/src/constants.ts CHANGED
@@ -10,25 +10,36 @@ export enum TX_STATUS {
10
10
 
11
11
  export const WRITE_RESOURCE = "write_resource";
12
12
 
13
- export const TRANSFER_TYPES: MoveStructId[] = [
13
+ export const COIN_TRANSFER_TYPES: MoveStructId[] = [
14
14
  "0x1::aptos_account::transfer",
15
15
  "0x1::aptos_account::transfer_coins",
16
16
  "0x1::coin::transfer",
17
17
  ];
18
+
19
+ export const FA_TRANSFER_TYPES: MoveStructId[] = ["0x1::primary_fungible_store::transfer"];
20
+
18
21
  export const BATCH_TRANSFER_TYPES: MoveStructId[] = [
19
22
  "0x1::aptos_account::batch_transfer",
20
23
  "0x1::aptos_account::batch_transfer_coins",
21
24
  ];
25
+
22
26
  export const DELEGATION_POOL_TYPES: MoveStructId[] = [
23
27
  "0x1::delegation_pool::add_stake",
24
28
  "0x1::delegation_pool::withdraw",
25
29
  ];
26
30
 
27
31
  export const APTOS_ASSET_ID: MoveStructId = "0x1::aptos_coin::AptosCoin";
32
+
28
33
  export const APTOS_COIN_CHANGE: MoveStructId = `0x1::coin::CoinStore<${APTOS_ASSET_ID}>`;
29
34
 
35
+ export const APTOS_FUNGIBLE_STORE: MoveStructId = "0x1::fungible_asset::FungibleStore";
36
+
37
+ export const APTOS_OBJECT_CORE: MoveStructId = "0x1::object::ObjectCore";
38
+
30
39
  export enum DIRECTION {
31
40
  IN = "IN",
32
41
  OUT = "OUT",
33
42
  UNKNOWN = "UNKNOWN",
34
43
  }
44
+
45
+ export const SUPPORTED_TOKEN_TYPES = ["coin", "fungible_asset"];
@@ -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
+ }
@@ -18,8 +18,8 @@ export const GetDelegatedStakingActivities = gql`
18
18
  `;
19
19
  export const GetAccountTransactionsData = gql`
20
20
  query GetAccountTransactionsData($address: String, $limit: Int) {
21
- address_version_from_move_resources(
22
- where: { address: { _eq: $address } }
21
+ account_transactions(
22
+ where: { account_address: { _eq: $address } }
23
23
  order_by: { transaction_version: desc }
24
24
  limit: $limit
25
25
  ) {
@@ -30,8 +30,8 @@ export const GetAccountTransactionsData = gql`
30
30
  `;
31
31
  export const GetAccountTransactionsDataGt = gql`
32
32
  query GetAccountTransactionsDataGt($address: String, $limit: Int, $gt: bigint) {
33
- address_version_from_move_resources(
34
- where: { address: { _eq: $address }, transaction_version: { _gt: $gt } }
33
+ account_transactions(
34
+ where: { account_address: { _eq: $address }, transaction_version: { _gt: $gt } }
35
35
  order_by: { transaction_version: desc }
36
36
  limit: $limit
37
37
  ) {
@@ -42,8 +42,8 @@ export const GetAccountTransactionsDataGt = gql`
42
42
  `;
43
43
  export const GetAccountTransactionsDataLt = gql`
44
44
  query GetAccountTransactionsDataLt($address: String, $limit: Int, $lt: bigint) {
45
- address_version_from_move_resources(
46
- where: { address: { _eq: $address }, transaction_version: { _lt: $lt } }
45
+ account_transactions(
46
+ where: { account_address: { _eq: $address }, transaction_version: { _lt: $lt } }
47
47
  order_by: { transaction_version: desc }
48
48
  limit: $limit
49
49
  ) {
@@ -22,9 +22,9 @@ export type GetAccountTransactionsDataQueryVariables = Exact<{
22
22
 
23
23
  export type GetAccountTransactionsDataQuery = {
24
24
  __typename?: "query_root";
25
- address_version_from_move_resources: Array<{
26
- __typename: "address_version_from_move_resources";
27
- transaction_version?: any | null;
25
+ account_transactions: Array<{
26
+ __typename?: "account_transactions";
27
+ transaction_version: number;
28
28
  }>;
29
29
  };
30
30
 
@@ -36,9 +36,9 @@ export type GetAccountTransactionsDataGtQueryVariables = Exact<{
36
36
 
37
37
  export type GetAccountTransactionsDataGtQuery = {
38
38
  __typename?: "query_root";
39
- address_version_from_move_resources: Array<{
40
- __typename: "address_version_from_move_resources";
41
- transaction_version?: any | null;
39
+ account_transactions: Array<{
40
+ __typename?: "account_transactions";
41
+ transaction_version: number;
42
42
  }>;
43
43
  };
44
44
 
@@ -50,9 +50,9 @@ export type GetAccountTransactionsDataLtQueryVariables = Exact<{
50
50
 
51
51
  export type GetAccountTransactionsDataLtQuery = {
52
52
  __typename?: "query_root";
53
- address_version_from_move_resources: Array<{
54
- __typename: "address_version_from_move_resources";
55
- transaction_version?: any | null;
53
+ account_transactions: Array<{
54
+ __typename?: "account_transactions";
55
+ transaction_version: number;
56
56
  }>;
57
57
  };
58
58
 
@@ -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>,
@@ -5,8 +5,9 @@ import BigNumber from "bignumber.js";
5
5
  import type { Transaction } from "../types";
6
6
  import { getCryptoCurrencyById } from "@ledgerhq/cryptoassets/currencies";
7
7
  import { genericTestDestination, pickSiblings, botTest } from "@ledgerhq/coin-framework/bot/specs";
8
- import type { AppSpec } from "@ledgerhq/coin-framework/bot/types";
9
- import { acceptTransaction } from "./speculos-deviceActions";
8
+ import type { AppSpec, TransactionTestInput } from "@ledgerhq/coin-framework/bot/types";
9
+ import { acceptTokenTransaction, acceptTransaction } from "./speculos-deviceActions";
10
+ import { Account, TokenAccount } from "@ledgerhq/types-live";
10
11
 
11
12
  const MIN_SAFE = new BigNumber(0.0001);
12
13
  const maxAccount = 6;
@@ -19,7 +20,7 @@ const aptosSpecs: AppSpec<Transaction> = {
19
20
  appName: "Aptos",
20
21
  },
21
22
  genericDeviceAction: acceptTransaction,
22
- testTimeout: 6 * 60 * 1000,
23
+ testTimeout: 2 * 60 * 1000,
23
24
  minViableAmount: MIN_SAFE,
24
25
  transactionCheck: ({ maxSpendable }) => {
25
26
  invariant(maxSpendable.gt(MIN_SAFE), "balance is too low");
@@ -84,9 +85,68 @@ const aptosSpecs: AppSpec<Transaction> = {
84
85
  );
85
86
  },
86
87
  },
88
+ {
89
+ name: "Send ~50% of token amount",
90
+ feature: "tokens",
91
+ maxRun: 1,
92
+ deviceAction: acceptTokenTransaction,
93
+ transaction: ({ account, bridge, siblings, maxSpendable }) => {
94
+ invariant(maxSpendable.gt(MIN_SAFE), "Balance is too low");
95
+
96
+ const senderTokenAcc = findTokenSubAccountWithBalance(account);
97
+ invariant(senderTokenAcc, "Sender token account with available balance not found");
98
+
99
+ const sibling = pickSiblings(siblings, maxAccount);
100
+
101
+ const recipientTokenAcc = findTokenSubAccountWithBalance(sibling);
102
+ invariant(recipientTokenAcc, "Receiver token account with available balance not found");
103
+
104
+ const amount = senderTokenAcc.spendableBalance.div(2).integerValue();
105
+ const recipient = sibling.freshAddress;
106
+ const transaction = bridge.createTransaction(account);
107
+ const subAccountId = senderTokenAcc.id;
108
+
109
+ return {
110
+ transaction,
111
+ updates: [{ subAccountId }, { recipient }, { amount }],
112
+ };
113
+ },
114
+ test: input => {
115
+ expectTokenAccountCorrectBalanceChange(input);
116
+ },
117
+ },
87
118
  ],
88
119
  };
89
120
 
121
+ function findTokenSubAccountWithBalance(account: Account) {
122
+ return account.subAccounts?.find(acc => acc.type === "TokenAccount" && acc.balance.gt(0)) as
123
+ | TokenAccount
124
+ | undefined;
125
+ }
126
+
127
+ function expectTokenAccountCorrectBalanceChange({
128
+ account,
129
+ accountBeforeTransaction,
130
+ status,
131
+ transaction,
132
+ }: TransactionTestInput<Transaction>) {
133
+ const tokenAccId = transaction.subAccountId;
134
+ if (!tokenAccId) throw new Error("Wrong subAccountId");
135
+
136
+ const tokenAccAfterTx = account.subAccounts?.find(acc => acc.id === tokenAccId);
137
+ const tokenAccBeforeTx = accountBeforeTransaction.subAccounts?.find(acc => acc.id === tokenAccId);
138
+
139
+ if (!tokenAccAfterTx || !tokenAccBeforeTx) {
140
+ throw new Error("Token sub accounts not found!");
141
+ }
142
+
143
+ botTest("Token balance decreased with operation", () =>
144
+ expect(tokenAccAfterTx.balance.toString()).toBe(
145
+ tokenAccBeforeTx.balance.minus(status.amount).toString(),
146
+ ),
147
+ );
148
+ }
149
+
90
150
  export default {
91
151
  aptosSpecs,
92
152
  };
@@ -1,6 +1,4 @@
1
1
  import { CurrenciesData, DatasetTest } from "@ledgerhq/types-live";
2
- import BigNumber from "bignumber.js";
3
- import { fromTransactionRaw } from "../bridge/transaction";
4
2
  import { Transaction } from "../types";
5
3
 
6
4
  const aptos: CurrenciesData<Transaction> = {
@@ -21,86 +19,75 @@ const aptos: CurrenciesData<Transaction> = {
21
19
  ],
22
20
  accounts: [
23
21
  {
22
+ FIXME_tests: ["balance is sum of ops"],
24
23
  raw: {
25
- id: "js:2:aptos:d1a8c6a1cdd52dd40c7ea61ee4571fb51fcae440a594c1eca18636928f1d3956:",
24
+ id: "js:2:aptos:d1a8c6a1cdd52dd40c7ea61ee4571fb51fcae440a594c1eca18636928f1d3956:aptos",
26
25
  seedIdentifier: "d6816f4f22f867b56cf9304b776f452a16d107835d73ee8a33c4ced210300583",
27
26
  used: true,
28
- derivationMode: "",
27
+ derivationMode: "aptos",
29
28
  index: 0,
30
29
  freshAddress: "0x445fa0013887abd1a0c14acdec6e48090e0ad3fed3e08202aac15ca14f3be26b",
31
30
  freshAddressPath: "44'/637'/0'/0'/0'",
32
- blockHeight: 286066372,
31
+ blockHeight: 302459501,
33
32
  creationDate: "2024-12-18T12:26:31.070Z",
34
- operationsCount: 5,
33
+ operationsCount: 6,
35
34
  operations: [],
36
35
  pendingOperations: [],
37
36
  currencyId: "aptos",
38
- lastSyncDate: "2025-02-04T14:00:46.693Z",
39
- balance: "30100",
40
- spendableBalance: "30100",
37
+ lastSyncDate: "2025-03-12T10:42:53.570Z",
38
+ balance: "19949100",
39
+ spendableBalance: "19949100",
41
40
  balanceHistoryCache: {
42
41
  HOUR: {
43
42
  balances: [
44
- 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100,
45
- 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100,
46
- 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100,
47
- 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100,
48
- 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100,
49
- 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100,
50
- 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100,
51
- 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100,
52
- 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100,
53
- 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100,
54
- 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100,
55
- 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100,
56
- 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100,
57
- 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100,
58
- 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100,
59
- 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100,
60
- 30100,
43
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
44
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
45
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
46
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
47
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
48
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
49
+ 0, 19949100, 19949100, 19949100, 19949100, 19949100, 19949100, 19949100, 19949100,
50
+ 19949100, 19949100, 19949100, 19949100, 19949100, 19949100, 19949100, 19949100,
51
+ 19949100, 19949100,
61
52
  ],
62
- latestDate: 1738677600000,
53
+ latestDate: 1741773600000,
63
54
  },
64
55
  DAY: {
65
56
  balances: [
66
- 0, 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100,
67
- 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100,
68
- 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100,
69
- 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100, 30100,
57
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
58
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
59
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
60
+ 19949100,
70
61
  ],
71
- latestDate: 1738627200000,
72
- },
73
- WEEK: {
74
- balances: [0, 30100, 30100, 30100, 30100, 30100, 30100, 30100],
75
- latestDate: 1738454400000,
62
+ latestDate: 1741737600000,
76
63
  },
64
+ WEEK: { balances: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], latestDate: 1741478400000 },
77
65
  },
78
66
  xpub: "d1a8c6a1cdd52dd40c7ea61ee4571fb51fcae440a594c1eca18636928f1d3956",
67
+ subAccounts: [
68
+ {
69
+ type: "TokenAccountRaw",
70
+ id: "js:2:aptos:d1a8c6a1cdd52dd40c7ea61ee4571fb51fcae440a594c1eca18636928f1d3956:aptos+aptos%2Fcoin%2Fdstapt~!underscore!~0xd11107bdf0d6d7040c6c0bfbdecb6545191fdf13e8d8d259952f53e1713f61b5%3A%3Astaked~!underscore!~coin%3A%3Astakedaptos",
71
+ parentId:
72
+ "js:2:aptos:d1a8c6a1cdd52dd40c7ea61ee4571fb51fcae440a594c1eca18636928f1d3956:aptos",
73
+ tokenId:
74
+ "aptos/coin/dstapt_0xd11107bdf0d6d7040c6c0bfbdecb6545191fdf13e8d8d259952f53e1713f61b5::staked_coin::stakedaptos",
75
+ balance: "30000000",
76
+ spendableBalance: "30000000",
77
+ balanceHistoryCache: {
78
+ HOUR: { latestDate: null, balances: [] },
79
+ DAY: { latestDate: null, balances: [] },
80
+ WEEK: { latestDate: null, balances: [] },
81
+ },
82
+ creationDate: "2025-03-12T10:42:53.570Z",
83
+ operationsCount: 2,
84
+ operations: [],
85
+ pendingOperations: [],
86
+ swapHistory: [],
87
+ },
88
+ ],
79
89
  swapHistory: [],
80
90
  },
81
- transactions: [
82
- {
83
- name: "NO_NAME",
84
- transaction: fromTransactionRaw({
85
- amount: "1000",
86
- recipient: "0xd20fa44192f94ba086ab16bfdf57e43ff118ada69b4c66fa9b9a9223cbc068c1",
87
- useAllAmount: false,
88
- subAccountId: null,
89
- family: "aptos",
90
- mode: "send",
91
- fees: "900",
92
- options: '{"maxGasAmount":"9","gasUnitPrice":"100"}',
93
- errors: "{}",
94
- }),
95
- expectedStatus: () =>
96
- // you can use account and transaction for smart logic. drop the =>fn otherwise
97
- ({
98
- errors: {},
99
- warnings: {},
100
- amount: BigNumber("1000"),
101
- }),
102
- },
103
- ],
104
91
  },
105
92
  ],
106
93
  };