@ledgerhq/coin-aptos 2.0.0-nightly.5 → 2.0.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.
- package/.turbo/turbo-build.log +1 -1
- package/.unimportedrc.json +18 -6
- package/CHANGELOG.md +152 -34
- package/jest.config.js +2 -1
- package/jest.integ.config.js +8 -0
- package/lib/__tests__/api/index.integ.test.d.ts +2 -0
- package/lib/__tests__/api/index.integ.test.d.ts.map +1 -0
- package/lib/__tests__/api/index.integ.test.js +52 -0
- package/lib/__tests__/api/index.integ.test.js.map +1 -0
- package/lib/__tests__/api/index.test.js +48 -404
- package/lib/__tests__/api/index.test.js.map +1 -1
- package/lib/__tests__/bridge/broadcast.test.js +5 -5
- package/lib/__tests__/bridge/broadcast.test.js.map +1 -1
- package/lib/__tests__/bridge/buildTransaction.test.js +60 -5
- package/lib/__tests__/bridge/buildTransaction.test.js.map +1 -1
- package/lib/__tests__/bridge/createTransaction.test.js +1 -1
- package/lib/__tests__/bridge/createTransaction.test.js.map +1 -1
- package/lib/__tests__/bridge/getFeesForTransaction.test.js +115 -14
- package/lib/__tests__/bridge/getFeesForTransaction.test.js.map +1 -1
- package/lib/__tests__/bridge/getTransactionStatus.test.js +175 -37
- package/lib/__tests__/bridge/getTransactionStatus.test.js.map +1 -1
- package/lib/__tests__/bridge/logic.test.js +889 -115
- package/lib/__tests__/bridge/logic.test.js.map +1 -1
- package/lib/__tests__/bridge/prepareTransaction.test.js +3 -3
- package/lib/__tests__/bridge/prepareTransaction.test.js.map +1 -1
- package/lib/__tests__/bridge/signOperation.test.js +131 -4
- package/lib/__tests__/bridge/signOperation.test.js.map +1 -1
- package/lib/__tests__/bridge/synchronisation.test.js +1215 -68
- package/lib/__tests__/bridge/synchronisation.test.js.map +1 -1
- package/lib/__tests__/network/client.test.d.ts +2 -0
- package/lib/__tests__/network/client.test.d.ts.map +1 -0
- package/lib/__tests__/network/client.test.js +520 -0
- package/lib/__tests__/network/client.test.js.map +1 -0
- package/lib/api/index.d.ts +4 -30
- package/lib/api/index.d.ts.map +1 -1
- package/lib/api/index.js +24 -170
- package/lib/api/index.js.map +1 -1
- package/lib/bridge/bridge.fixture.d.ts +2 -0
- package/lib/bridge/bridge.fixture.d.ts.map +1 -1
- package/lib/bridge/bridge.fixture.js +85 -13
- package/lib/bridge/bridge.fixture.js.map +1 -1
- package/lib/bridge/broadcast.d.ts +3 -2
- package/lib/bridge/broadcast.d.ts.map +1 -1
- package/lib/bridge/broadcast.js +4 -3
- package/lib/bridge/broadcast.js.map +1 -1
- package/lib/bridge/buildTransaction.d.ts +1 -1
- package/lib/bridge/buildTransaction.d.ts.map +1 -1
- package/lib/bridge/buildTransaction.js +29 -3
- package/lib/bridge/buildTransaction.js.map +1 -1
- package/lib/bridge/createTransaction.js +3 -3
- package/lib/bridge/createTransaction.js.map +1 -1
- package/lib/bridge/estimateMaxSpendable.d.ts.map +1 -1
- package/lib/bridge/estimateMaxSpendable.js +6 -5
- package/lib/bridge/estimateMaxSpendable.js.map +1 -1
- package/lib/bridge/getFeesForTransaction.d.ts +1 -1
- package/lib/bridge/getFeesForTransaction.d.ts.map +1 -1
- package/lib/bridge/getFeesForTransaction.js +19 -13
- package/lib/bridge/getFeesForTransaction.js.map +1 -1
- package/lib/bridge/getTransactionStatus.d.ts.map +1 -1
- package/lib/bridge/getTransactionStatus.js +28 -14
- package/lib/bridge/getTransactionStatus.js.map +1 -1
- package/lib/bridge/index.d.ts +1 -1
- package/lib/bridge/index.d.ts.map +1 -1
- package/lib/bridge/logic.d.ts +13 -11
- package/lib/bridge/logic.d.ts.map +1 -1
- package/lib/bridge/logic.js +152 -57
- package/lib/bridge/logic.js.map +1 -1
- package/lib/bridge/prepareTransaction.d.ts.map +1 -1
- package/lib/bridge/prepareTransaction.js +5 -4
- package/lib/bridge/prepareTransaction.js.map +1 -1
- package/lib/bridge/signOperation.d.ts.map +1 -1
- package/lib/bridge/signOperation.js +20 -6
- package/lib/bridge/signOperation.js.map +1 -1
- package/lib/bridge/synchronisation.d.ts +15 -0
- package/lib/bridge/synchronisation.d.ts.map +1 -1
- package/lib/bridge/synchronisation.js +129 -6
- package/lib/bridge/synchronisation.js.map +1 -1
- package/lib/config.d.ts +13 -0
- package/lib/config.d.ts.map +1 -0
- package/lib/config.js +9 -0
- package/lib/config.js.map +1 -0
- package/lib/constants.d.ts +9 -1
- package/lib/constants.d.ts.map +1 -1
- package/lib/constants.js +13 -2
- package/lib/constants.js.map +1 -1
- package/lib/network/client.d.ts +36 -0
- package/lib/network/client.d.ts.map +1 -0
- package/lib/network/client.js +247 -0
- package/lib/network/client.js.map +1 -0
- package/lib/network/graphql/queries.d.ts.map +1 -0
- package/lib/{api → network}/graphql/queries.js +6 -6
- package/lib/network/graphql/queries.js.map +1 -0
- package/lib/{api → network}/graphql/types.d.ts +9 -9
- package/lib/network/graphql/types.d.ts.map +1 -0
- package/lib/{api → network}/graphql/types.js.map +1 -1
- package/lib/network/index.d.ts +2 -1
- package/lib/network/index.d.ts.map +1 -1
- package/lib/network/index.js +15 -0
- package/lib/network/index.js.map +1 -1
- package/lib/test/bot-specs.d.ts.map +1 -1
- package/lib/test/bot-specs.js +40 -1
- package/lib/test/bot-specs.js.map +1 -1
- package/lib/test/bridgeDatasetTest.d.ts.map +1 -1
- package/lib/test/bridgeDatasetTest.js +44 -62
- package/lib/test/bridgeDatasetTest.js.map +1 -1
- package/lib/test/speculos-deviceActions.d.ts +1 -0
- package/lib/test/speculos-deviceActions.d.ts.map +1 -1
- package/lib/test/speculos-deviceActions.js +37 -5
- package/lib/test/speculos-deviceActions.js.map +1 -1
- package/lib/types/assets.d.ts +12 -0
- package/lib/types/assets.d.ts.map +1 -0
- package/lib/types/assets.js +3 -0
- package/lib/types/assets.js.map +1 -0
- package/lib/types/index.d.ts +18 -7
- package/lib/types/index.d.ts.map +1 -1
- package/lib-es/__tests__/api/index.integ.test.d.ts +2 -0
- package/lib-es/__tests__/api/index.integ.test.d.ts.map +1 -0
- package/lib-es/__tests__/api/index.integ.test.js +50 -0
- package/lib-es/__tests__/api/index.integ.test.js.map +1 -0
- package/lib-es/__tests__/api/index.test.js +52 -408
- package/lib-es/__tests__/api/index.test.js.map +1 -1
- package/lib-es/__tests__/bridge/broadcast.test.js +2 -2
- package/lib-es/__tests__/bridge/broadcast.test.js.map +1 -1
- package/lib-es/__tests__/bridge/buildTransaction.test.js +60 -5
- package/lib-es/__tests__/bridge/buildTransaction.test.js.map +1 -1
- package/lib-es/__tests__/bridge/createTransaction.test.js +1 -1
- package/lib-es/__tests__/bridge/createTransaction.test.js.map +1 -1
- package/lib-es/__tests__/bridge/getFeesForTransaction.test.js +112 -11
- package/lib-es/__tests__/bridge/getFeesForTransaction.test.js.map +1 -1
- package/lib-es/__tests__/bridge/getTransactionStatus.test.js +177 -39
- package/lib-es/__tests__/bridge/getTransactionStatus.test.js.map +1 -1
- package/lib-es/__tests__/bridge/logic.test.js +891 -117
- package/lib-es/__tests__/bridge/logic.test.js.map +1 -1
- package/lib-es/__tests__/bridge/prepareTransaction.test.js +2 -2
- package/lib-es/__tests__/bridge/prepareTransaction.test.js.map +1 -1
- package/lib-es/__tests__/bridge/signOperation.test.js +131 -4
- package/lib-es/__tests__/bridge/signOperation.test.js.map +1 -1
- package/lib-es/__tests__/bridge/synchronisation.test.js +1213 -69
- package/lib-es/__tests__/bridge/synchronisation.test.js.map +1 -1
- package/lib-es/__tests__/network/client.test.d.ts +2 -0
- package/lib-es/__tests__/network/client.test.d.ts.map +1 -0
- package/lib-es/__tests__/network/client.test.js +515 -0
- package/lib-es/__tests__/network/client.test.js.map +1 -0
- package/lib-es/api/index.d.ts +4 -30
- package/lib-es/api/index.d.ts.map +1 -1
- package/lib-es/api/index.js +22 -168
- package/lib-es/api/index.js.map +1 -1
- package/lib-es/bridge/bridge.fixture.d.ts +2 -0
- package/lib-es/bridge/bridge.fixture.d.ts.map +1 -1
- package/lib-es/bridge/bridge.fixture.js +82 -12
- package/lib-es/bridge/bridge.fixture.js.map +1 -1
- package/lib-es/bridge/broadcast.d.ts +3 -2
- package/lib-es/bridge/broadcast.d.ts.map +1 -1
- package/lib-es/bridge/broadcast.js +4 -3
- package/lib-es/bridge/broadcast.js.map +1 -1
- package/lib-es/bridge/buildTransaction.d.ts +1 -1
- package/lib-es/bridge/buildTransaction.d.ts.map +1 -1
- package/lib-es/bridge/buildTransaction.js +30 -4
- package/lib-es/bridge/buildTransaction.js.map +1 -1
- package/lib-es/bridge/createTransaction.js +1 -1
- package/lib-es/bridge/createTransaction.js.map +1 -1
- package/lib-es/bridge/estimateMaxSpendable.d.ts.map +1 -1
- package/lib-es/bridge/estimateMaxSpendable.js +4 -3
- package/lib-es/bridge/estimateMaxSpendable.js.map +1 -1
- package/lib-es/bridge/getFeesForTransaction.d.ts +1 -1
- package/lib-es/bridge/getFeesForTransaction.d.ts.map +1 -1
- package/lib-es/bridge/getFeesForTransaction.js +14 -8
- package/lib-es/bridge/getFeesForTransaction.js.map +1 -1
- package/lib-es/bridge/getTransactionStatus.d.ts.map +1 -1
- package/lib-es/bridge/getTransactionStatus.js +28 -14
- package/lib-es/bridge/getTransactionStatus.js.map +1 -1
- package/lib-es/bridge/index.d.ts +1 -1
- package/lib-es/bridge/index.d.ts.map +1 -1
- package/lib-es/bridge/logic.d.ts +13 -11
- package/lib-es/bridge/logic.d.ts.map +1 -1
- package/lib-es/bridge/logic.js +146 -55
- package/lib-es/bridge/logic.js.map +1 -1
- package/lib-es/bridge/prepareTransaction.d.ts.map +1 -1
- package/lib-es/bridge/prepareTransaction.js +5 -4
- package/lib-es/bridge/prepareTransaction.js.map +1 -1
- package/lib-es/bridge/signOperation.d.ts.map +1 -1
- package/lib-es/bridge/signOperation.js +18 -4
- package/lib-es/bridge/signOperation.js.map +1 -1
- package/lib-es/bridge/synchronisation.d.ts +15 -0
- package/lib-es/bridge/synchronisation.d.ts.map +1 -1
- package/lib-es/bridge/synchronisation.js +124 -4
- package/lib-es/bridge/synchronisation.js.map +1 -1
- package/lib-es/config.d.ts +13 -0
- package/lib-es/config.d.ts.map +1 -0
- package/lib-es/config.js +4 -0
- package/lib-es/config.js.map +1 -0
- package/lib-es/constants.d.ts +9 -1
- package/lib-es/constants.d.ts.map +1 -1
- package/lib-es/constants.js +9 -1
- package/lib-es/constants.js.map +1 -1
- package/lib-es/network/client.d.ts +36 -0
- package/lib-es/network/client.d.ts.map +1 -0
- package/lib-es/network/client.js +240 -0
- package/lib-es/network/client.js.map +1 -0
- package/lib-es/network/graphql/queries.d.ts.map +1 -0
- package/lib-es/{api → network}/graphql/queries.js +6 -6
- package/lib-es/network/graphql/queries.js.map +1 -0
- package/lib-es/{api → network}/graphql/types.d.ts +9 -9
- package/lib-es/network/graphql/types.d.ts.map +1 -0
- package/lib-es/{api → network}/graphql/types.js.map +1 -1
- package/lib-es/network/index.d.ts +2 -1
- package/lib-es/network/index.d.ts.map +1 -1
- package/lib-es/network/index.js +1 -0
- package/lib-es/network/index.js.map +1 -1
- package/lib-es/test/bot-specs.d.ts.map +1 -1
- package/lib-es/test/bot-specs.js +41 -2
- package/lib-es/test/bot-specs.js.map +1 -1
- package/lib-es/test/bridgeDatasetTest.d.ts.map +1 -1
- package/lib-es/test/bridgeDatasetTest.js +44 -59
- package/lib-es/test/bridgeDatasetTest.js.map +1 -1
- package/lib-es/test/speculos-deviceActions.d.ts +1 -0
- package/lib-es/test/speculos-deviceActions.d.ts.map +1 -1
- package/lib-es/test/speculos-deviceActions.js +36 -4
- package/lib-es/test/speculos-deviceActions.js.map +1 -1
- package/lib-es/types/assets.d.ts +12 -0
- package/lib-es/types/assets.d.ts.map +1 -0
- package/lib-es/types/assets.js +2 -0
- package/lib-es/types/assets.js.map +1 -0
- package/lib-es/types/index.d.ts +18 -7
- package/lib-es/types/index.d.ts.map +1 -1
- package/package.json +12 -9
- package/src/__tests__/api/index.integ.test.ts +58 -0
- package/src/__tests__/api/index.test.ts +60 -477
- package/src/__tests__/bridge/broadcast.test.ts +2 -2
- package/src/__tests__/bridge/buildTransaction.test.ts +87 -5
- package/src/__tests__/bridge/createTransaction.test.ts +1 -1
- package/src/__tests__/bridge/getFeesForTransaction.test.ts +146 -11
- package/src/__tests__/bridge/getTransactionStatus.test.ts +217 -38
- package/src/__tests__/bridge/logic.test.ts +922 -118
- package/src/__tests__/bridge/prepareTransaction.test.ts +2 -2
- package/src/__tests__/bridge/signOperation.test.ts +147 -5
- package/src/__tests__/bridge/synchronisation.test.ts +1265 -71
- package/src/__tests__/network/client.test.ts +618 -0
- package/src/api/index.ts +31 -223
- package/src/bridge/bridge.fixture.ts +91 -12
- package/src/bridge/broadcast.ts +7 -7
- package/src/bridge/buildTransaction.ts +40 -7
- package/src/bridge/createTransaction.ts +1 -1
- package/src/bridge/estimateMaxSpendable.ts +4 -3
- package/src/bridge/getFeesForTransaction.ts +16 -10
- package/src/bridge/getTransactionStatus.ts +35 -13
- package/src/bridge/index.ts +1 -1
- package/src/bridge/logic.ts +202 -67
- package/src/bridge/prepareTransaction.ts +7 -4
- package/src/bridge/signOperation.ts +20 -4
- package/src/bridge/synchronisation.ts +171 -4
- package/src/config.ts +19 -0
- package/src/constants.ts +17 -1
- package/src/network/client.ts +315 -0
- package/src/{api → network}/graphql/queries.ts +6 -6
- package/src/{api → network}/graphql/types.ts +9 -9
- package/src/network/index.ts +2 -1
- package/src/test/bot-specs.ts +63 -3
- package/src/test/bridgeDatasetTest.ts +46 -59
- package/src/test/speculos-deviceActions.ts +40 -4
- package/src/types/assets.ts +15 -0
- package/src/types/index.ts +15 -1
- package/lib/api/graphql/queries.d.ts.map +0 -1
- package/lib/api/graphql/queries.js.map +0 -1
- package/lib/api/graphql/types.d.ts.map +0 -1
- package/lib-es/api/graphql/queries.d.ts.map +0 -1
- package/lib-es/api/graphql/queries.js.map +0 -1
- package/lib-es/api/graphql/types.d.ts.map +0 -1
- /package/lib/{api → network}/graphql/queries.d.ts +0 -0
- /package/lib/{api → network}/graphql/types.js +0 -0
- /package/lib-es/{api → network}/graphql/queries.d.ts +0 -0
- /package/lib-es/{api → network}/graphql/types.js +0 -0
package/src/bridge/logic.ts
CHANGED
|
@@ -4,24 +4,37 @@ import {
|
|
|
4
4
|
InputEntryFunctionData,
|
|
5
5
|
MoveResource,
|
|
6
6
|
WriteSetChange,
|
|
7
|
+
WriteSetChangeWriteResource,
|
|
7
8
|
} from "@aptos-labs/ts-sdk";
|
|
8
9
|
import { getCryptoCurrencyById } from "@ledgerhq/cryptoassets/currencies";
|
|
9
|
-
import type { Operation, OperationType } from "@ledgerhq/types-live";
|
|
10
|
+
import type { Account, Operation, OperationType, TokenAccount } from "@ledgerhq/types-live";
|
|
11
|
+
import {
|
|
12
|
+
decodeTokenAccountId,
|
|
13
|
+
encodeTokenAccountId,
|
|
14
|
+
findSubAccountById,
|
|
15
|
+
isTokenAccount,
|
|
16
|
+
} from "@ledgerhq/coin-framework/account/index";
|
|
10
17
|
import BigNumber from "bignumber.js";
|
|
11
18
|
import { encodeOperationId } from "@ledgerhq/coin-framework/operation";
|
|
12
19
|
import {
|
|
13
|
-
|
|
20
|
+
APTOS_ASSET_ID,
|
|
21
|
+
APTOS_FUNGIBLE_STORE,
|
|
14
22
|
BATCH_TRANSFER_TYPES,
|
|
15
23
|
DELEGATION_POOL_TYPES,
|
|
16
24
|
DIRECTION,
|
|
17
|
-
|
|
18
|
-
|
|
25
|
+
COIN_TRANSFER_TYPES,
|
|
26
|
+
FA_TRANSFER_TYPES,
|
|
27
|
+
APTOS_OBJECT_CORE,
|
|
19
28
|
} from "../constants";
|
|
20
|
-
import type {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
29
|
+
import type {
|
|
30
|
+
AptosFungibleoObjectCoreResourceData,
|
|
31
|
+
AptosFungibleStoreResourceData,
|
|
32
|
+
AptosMoveResource,
|
|
33
|
+
AptosTransaction,
|
|
34
|
+
Transaction,
|
|
35
|
+
TransactionOptions,
|
|
36
|
+
} from "../types";
|
|
37
|
+
import { findTokenByAddressInCurrency } from "@ledgerhq/cryptoassets";
|
|
25
38
|
|
|
26
39
|
const CLEAN_HEX_REGEXP = /^0x0*|^0+/;
|
|
27
40
|
|
|
@@ -30,13 +43,21 @@ export function isTestnet(currencyId: string): boolean {
|
|
|
30
43
|
}
|
|
31
44
|
|
|
32
45
|
export const getMaxSendBalance = (
|
|
33
|
-
amount: BigNumber,
|
|
34
46
|
gas: BigNumber,
|
|
35
47
|
gasPrice: BigNumber,
|
|
48
|
+
account: Account,
|
|
49
|
+
transaction?: Transaction,
|
|
36
50
|
): BigNumber => {
|
|
51
|
+
const tokenAccount = findSubAccountById(account, transaction?.subAccountId ?? "");
|
|
52
|
+
const fromTokenAccount = tokenAccount && isTokenAccount(tokenAccount);
|
|
53
|
+
|
|
37
54
|
const totalGas = gas.multipliedBy(gasPrice);
|
|
38
55
|
|
|
39
|
-
return
|
|
56
|
+
return fromTokenAccount
|
|
57
|
+
? tokenAccount.spendableBalance
|
|
58
|
+
: account.spendableBalance.gt(totalGas)
|
|
59
|
+
? account.spendableBalance.minus(totalGas)
|
|
60
|
+
: new BigNumber(0);
|
|
40
61
|
};
|
|
41
62
|
|
|
42
63
|
export function normalizeTransactionOptions(options: TransactionOptions): TransactionOptions {
|
|
@@ -88,9 +109,10 @@ export const txsToOps = (
|
|
|
88
109
|
info: { address: string },
|
|
89
110
|
id: string,
|
|
90
111
|
txs: (AptosTransaction | null)[],
|
|
91
|
-
): Operation[] => {
|
|
112
|
+
): [Operation[], Operation[]] => {
|
|
92
113
|
const { address } = info;
|
|
93
114
|
const ops: Operation[] = [];
|
|
115
|
+
const opsTokens: Operation[] = [];
|
|
94
116
|
|
|
95
117
|
txs.forEach(tx => {
|
|
96
118
|
if (tx !== null) {
|
|
@@ -107,10 +129,12 @@ export const txsToOps = (
|
|
|
107
129
|
return; // skip transaction without functions in payload
|
|
108
130
|
}
|
|
109
131
|
|
|
110
|
-
const { amount_in, amount_out } =
|
|
111
|
-
op.value = calculateAmount(tx.sender, address,
|
|
132
|
+
const { coin_id, amount_in, amount_out } = getCoinAndAmounts(tx, address);
|
|
133
|
+
op.value = calculateAmount(tx.sender, address, amount_in, amount_out);
|
|
112
134
|
op.type = compareAddress(tx.sender, address) ? DIRECTION.OUT : DIRECTION.IN;
|
|
113
135
|
op.senders.push(tx.sender);
|
|
136
|
+
op.hasFailed = !tx.success;
|
|
137
|
+
op.id = encodeOperationId(op.accountId, tx.hash, op.type);
|
|
114
138
|
|
|
115
139
|
processRecipients(payload, address, op, function_address);
|
|
116
140
|
|
|
@@ -119,13 +143,30 @@ export const txsToOps = (
|
|
|
119
143
|
op.type = DIRECTION.UNKNOWN;
|
|
120
144
|
}
|
|
121
145
|
|
|
122
|
-
op.
|
|
123
|
-
|
|
124
|
-
|
|
146
|
+
if (op.type !== DIRECTION.UNKNOWN && coin_id !== null) {
|
|
147
|
+
if (coin_id === APTOS_ASSET_ID) {
|
|
148
|
+
ops.push(op);
|
|
149
|
+
} else {
|
|
150
|
+
const token = findTokenByAddressInCurrency(coin_id.toLowerCase(), "aptos");
|
|
151
|
+
if (token !== undefined) {
|
|
152
|
+
op.accountId = encodeTokenAccountId(id, token);
|
|
153
|
+
opsTokens.push(op);
|
|
154
|
+
|
|
155
|
+
if (op.type === DIRECTION.OUT) {
|
|
156
|
+
ops.push({
|
|
157
|
+
...op,
|
|
158
|
+
accountId: decodeTokenAccountId(op.accountId).accountId,
|
|
159
|
+
value: op.fee,
|
|
160
|
+
type: "FEES",
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
125
166
|
}
|
|
126
167
|
});
|
|
127
168
|
|
|
128
|
-
return ops;
|
|
169
|
+
return [ops, opsTokens];
|
|
129
170
|
};
|
|
130
171
|
|
|
131
172
|
export function compareAddress(addressA: string, addressB: string) {
|
|
@@ -151,7 +192,7 @@ export function processRecipients(
|
|
|
151
192
|
): void {
|
|
152
193
|
// get recipients buy 3 groups
|
|
153
194
|
if (
|
|
154
|
-
(
|
|
195
|
+
(COIN_TRANSFER_TYPES.includes(payload.function) ||
|
|
155
196
|
DELEGATION_POOL_TYPES.includes(payload.function)) &&
|
|
156
197
|
payload.functionArguments &&
|
|
157
198
|
payload.functionArguments.length > 0 &&
|
|
@@ -159,6 +200,15 @@ export function processRecipients(
|
|
|
159
200
|
) {
|
|
160
201
|
// 1. Transfer like functions (includes some delegation pool functions)
|
|
161
202
|
op.recipients.push(payload.functionArguments[0].toString());
|
|
203
|
+
} else if (
|
|
204
|
+
FA_TRANSFER_TYPES.includes(payload.function) &&
|
|
205
|
+
payload.functionArguments &&
|
|
206
|
+
payload.functionArguments.length > 1 &&
|
|
207
|
+
typeof payload.functionArguments[0] === "object" &&
|
|
208
|
+
typeof payload.functionArguments[1] === "string"
|
|
209
|
+
) {
|
|
210
|
+
// 1. Transfer like functions (includes some delegation pool functions)
|
|
211
|
+
op.recipients.push(payload.functionArguments[1].toString());
|
|
162
212
|
} else if (
|
|
163
213
|
BATCH_TRANSFER_TYPES.includes(payload.function) &&
|
|
164
214
|
payload.functionArguments &&
|
|
@@ -179,87 +229,172 @@ export function processRecipients(
|
|
|
179
229
|
}
|
|
180
230
|
}
|
|
181
231
|
|
|
182
|
-
function
|
|
183
|
-
|
|
184
|
-
return isChangeOfAptos(change, event, event_name);
|
|
185
|
-
});
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
export function isChangeOfAptos(
|
|
189
|
-
writeSetChange: WriteSetChange,
|
|
232
|
+
export function getEventCoinAddress(
|
|
233
|
+
change: WriteSetChangeWriteResource,
|
|
190
234
|
event: Event,
|
|
191
235
|
event_name: string,
|
|
192
|
-
):
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
236
|
+
): string | null {
|
|
237
|
+
const change_data = change.data;
|
|
238
|
+
|
|
239
|
+
const mr = change_data as MoveResource<AptosMoveResource>; // -> this is data that we want to parse
|
|
240
|
+
|
|
241
|
+
if (!(event_name in mr.data)) {
|
|
242
|
+
return null;
|
|
197
243
|
}
|
|
198
244
|
|
|
199
|
-
|
|
200
|
-
|
|
245
|
+
const change_event_data = mr.data[event_name];
|
|
246
|
+
if (
|
|
247
|
+
change_event_data.guid.id.addr !== event.guid.account_address ||
|
|
248
|
+
change_event_data.guid.id.creation_num !== event.guid.creation_number
|
|
249
|
+
) {
|
|
250
|
+
return null;
|
|
201
251
|
}
|
|
202
252
|
|
|
203
|
-
const
|
|
253
|
+
const address = extractAddress(mr.type);
|
|
204
254
|
|
|
205
|
-
|
|
206
|
-
|
|
255
|
+
return address;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
export function getEventFAAddress(
|
|
259
|
+
change: WriteSetChangeWriteResource,
|
|
260
|
+
event: Event,
|
|
261
|
+
_event_name: string,
|
|
262
|
+
): string | null {
|
|
263
|
+
const change_data = change.data;
|
|
264
|
+
|
|
265
|
+
if (change_data.type !== APTOS_FUNGIBLE_STORE) {
|
|
266
|
+
return null;
|
|
207
267
|
}
|
|
208
268
|
|
|
209
|
-
const mr = change_data as MoveResource<
|
|
269
|
+
const mr = change_data as MoveResource<AptosFungibleStoreResourceData>;
|
|
210
270
|
|
|
211
|
-
if (
|
|
212
|
-
return
|
|
271
|
+
if (change.address !== event.data.store) {
|
|
272
|
+
return null;
|
|
213
273
|
}
|
|
214
274
|
|
|
215
|
-
|
|
275
|
+
return mr.data.metadata.inner;
|
|
276
|
+
}
|
|
216
277
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
278
|
+
export function getResourceAddress(
|
|
279
|
+
tx: AptosTransaction,
|
|
280
|
+
event: Event,
|
|
281
|
+
event_name: string,
|
|
282
|
+
getAddressProcessor: (
|
|
283
|
+
change: WriteSetChangeWriteResource,
|
|
284
|
+
event: Event,
|
|
285
|
+
event_name: string,
|
|
286
|
+
) => string | null,
|
|
287
|
+
): string | null {
|
|
288
|
+
for (const change of tx.changes) {
|
|
289
|
+
if (isWriteSetChangeWriteResource(change)) {
|
|
290
|
+
const address = getAddressProcessor(change, event, event_name);
|
|
291
|
+
if (address !== null) {
|
|
292
|
+
return address;
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
return null;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
function isWriteSetChangeWriteResource(
|
|
300
|
+
change: WriteSetChange,
|
|
301
|
+
): change is WriteSetChangeWriteResource {
|
|
302
|
+
return (change as WriteSetChangeWriteResource).data !== undefined;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
export function checkFAOwner(tx: AptosTransaction, event: Event, user_address: string): boolean {
|
|
306
|
+
for (const change of tx.changes) {
|
|
307
|
+
if (isWriteSetChangeWriteResource(change)) {
|
|
308
|
+
const storeData = change.data as MoveResource<AptosFungibleoObjectCoreResourceData>;
|
|
309
|
+
if (
|
|
310
|
+
change.address == event.data.store &&
|
|
311
|
+
storeData.type == APTOS_OBJECT_CORE &&
|
|
312
|
+
storeData.data.owner == user_address
|
|
313
|
+
) {
|
|
314
|
+
return true;
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
return false;
|
|
221
319
|
}
|
|
222
320
|
|
|
223
|
-
export function
|
|
321
|
+
export function getCoinAndAmounts(
|
|
224
322
|
tx: AptosTransaction,
|
|
225
323
|
address: string,
|
|
226
|
-
): { amount_in: BigNumber; amount_out: BigNumber } {
|
|
227
|
-
let
|
|
228
|
-
let
|
|
324
|
+
): { coin_id: string | null; amount_in: BigNumber; amount_out: BigNumber } {
|
|
325
|
+
let coin_id: string | null = null;
|
|
326
|
+
let amount_in = BigNumber(0);
|
|
327
|
+
let amount_out = BigNumber(0);
|
|
328
|
+
|
|
229
329
|
// collect all events related to the address and calculate the overall amounts
|
|
230
330
|
tx.events.forEach(event => {
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
331
|
+
switch (event.type) {
|
|
332
|
+
case "0x1::coin::WithdrawEvent":
|
|
333
|
+
if (compareAddress(event.guid.account_address, address)) {
|
|
334
|
+
coin_id = getResourceAddress(tx, event, "withdraw_events", getEventCoinAddress);
|
|
335
|
+
amount_out = amount_out.plus(event.data.amount);
|
|
336
|
+
}
|
|
337
|
+
break;
|
|
338
|
+
case "0x1::coin::DepositEvent":
|
|
339
|
+
if (compareAddress(event.guid.account_address, address)) {
|
|
340
|
+
coin_id = getResourceAddress(tx, event, "deposit_events", getEventCoinAddress);
|
|
341
|
+
amount_in = amount_in.plus(event.data.amount);
|
|
342
|
+
}
|
|
343
|
+
break;
|
|
344
|
+
case "0x1::fungible_asset::Withdraw":
|
|
345
|
+
if (checkFAOwner(tx, event, address)) {
|
|
346
|
+
coin_id = getResourceAddress(tx, event, "withdraw_events", getEventFAAddress);
|
|
347
|
+
amount_out = amount_out.plus(event.data.amount);
|
|
348
|
+
}
|
|
349
|
+
break;
|
|
350
|
+
case "0x1::fungible_asset::Deposit":
|
|
351
|
+
if (checkFAOwner(tx, event, address)) {
|
|
352
|
+
coin_id = getResourceAddress(tx, event, "deposit_events", getEventFAAddress);
|
|
353
|
+
amount_in = amount_in.plus(event.data.amount);
|
|
354
|
+
}
|
|
355
|
+
break;
|
|
356
|
+
case "0x1::transaction_fee::FeeStatement":
|
|
357
|
+
if (tx.sender === address) {
|
|
358
|
+
if (coin_id === null) coin_id = APTOS_ASSET_ID;
|
|
359
|
+
if (coin_id === APTOS_ASSET_ID) {
|
|
360
|
+
const fees = BigNumber(tx.gas_unit_price).times(BigNumber(tx.gas_used));
|
|
361
|
+
amount_out = amount_out.plus(fees);
|
|
241
362
|
}
|
|
242
|
-
|
|
243
|
-
|
|
363
|
+
}
|
|
364
|
+
break;
|
|
244
365
|
}
|
|
245
366
|
});
|
|
246
|
-
return { amount_in, amount_out };
|
|
367
|
+
return { coin_id, amount_in, amount_out }; // TODO: manage situation when there are several coinID from the events parsing
|
|
247
368
|
}
|
|
248
369
|
|
|
249
370
|
export function calculateAmount(
|
|
250
371
|
sender: string,
|
|
251
372
|
address: string,
|
|
252
|
-
fee: BigNumber,
|
|
253
373
|
amount_in: BigNumber,
|
|
254
374
|
amount_out: BigNumber,
|
|
255
375
|
): BigNumber {
|
|
256
376
|
const is_sender: boolean = compareAddress(sender, address);
|
|
257
|
-
// Include fees if our address is the sender
|
|
258
|
-
if (is_sender) {
|
|
259
|
-
amount_out = amount_out.plus(fee);
|
|
260
|
-
}
|
|
261
377
|
// LL negates the amount for SEND transactions
|
|
262
378
|
// to show positive amount on the send transaction (ex: in "cancel" tx, when amount will be returned to our account)
|
|
263
379
|
// we need to make it negative
|
|
264
380
|
return is_sender ? amount_out.minus(amount_in) : amount_in.minus(amount_out);
|
|
265
381
|
}
|
|
382
|
+
|
|
383
|
+
/**
|
|
384
|
+
* Extracts the address from a string like "0x1::coin::CoinStore<address::module::type>"
|
|
385
|
+
* @param {string} str - The input string containing the address.
|
|
386
|
+
* @returns {string | null} - The extracted address or null if not found.
|
|
387
|
+
*/
|
|
388
|
+
function extractAddress(str: string): string | null {
|
|
389
|
+
const match = str.match(/<([^<>]+)>{1}$/);
|
|
390
|
+
return match ? match[1] : null;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
export function getTokenAccount(
|
|
394
|
+
account: Account,
|
|
395
|
+
transaction: Transaction,
|
|
396
|
+
): TokenAccount | undefined {
|
|
397
|
+
const tokenAccount = findSubAccountById(account, transaction.subAccountId ?? "");
|
|
398
|
+
const fromTokenAccount = tokenAccount && isTokenAccount(tokenAccount);
|
|
399
|
+
return fromTokenAccount ? tokenAccount : undefined;
|
|
400
|
+
}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import type { Account } from "@ledgerhq/types-live";
|
|
2
2
|
import BigNumber from "bignumber.js";
|
|
3
3
|
|
|
4
|
-
import { AptosAPI } from "../
|
|
4
|
+
import { AptosAPI } from "../network";
|
|
5
5
|
import { getEstimatedGas } from "./getFeesForTransaction";
|
|
6
6
|
import type { Transaction } from "../types";
|
|
7
|
-
import {
|
|
7
|
+
import { getMaxSendBalance } from "./logic";
|
|
8
|
+
import { DEFAULT_GAS, DEFAULT_GAS_PRICE } from "./../constants";
|
|
8
9
|
|
|
9
10
|
const prepareTransaction = async (
|
|
10
11
|
account: Account,
|
|
@@ -28,9 +29,10 @@ const prepareTransaction = async (
|
|
|
28
29
|
if (transaction.useAllAmount) {
|
|
29
30
|
// we will use this amount in simulation, to estimate gas
|
|
30
31
|
transaction.amount = getMaxSendBalance(
|
|
31
|
-
account.spendableBalance,
|
|
32
32
|
new BigNumber(DEFAULT_GAS),
|
|
33
33
|
new BigNumber(DEFAULT_GAS_PRICE),
|
|
34
|
+
account,
|
|
35
|
+
transaction,
|
|
34
36
|
);
|
|
35
37
|
}
|
|
36
38
|
|
|
@@ -39,9 +41,10 @@ const prepareTransaction = async (
|
|
|
39
41
|
if (transaction.useAllAmount) {
|
|
40
42
|
// correct the transaction amount according to estimated fees
|
|
41
43
|
transaction.amount = getMaxSendBalance(
|
|
42
|
-
account.spendableBalance,
|
|
43
44
|
BigNumber(estimate.maxGasAmount),
|
|
44
45
|
BigNumber(estimate.gasUnitPrice),
|
|
46
|
+
account,
|
|
47
|
+
transaction,
|
|
45
48
|
);
|
|
46
49
|
}
|
|
47
50
|
|
|
@@ -4,11 +4,12 @@ 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 "../
|
|
7
|
+
import { AptosAPI } from "../network";
|
|
8
8
|
|
|
9
9
|
import { SignerContext } from "@ledgerhq/coin-framework/signer";
|
|
10
10
|
import { AptosSigner } from "../types";
|
|
11
11
|
import { signTransaction } from "../network";
|
|
12
|
+
import { findSubAccountById } from "@ledgerhq/coin-framework/account/helpers";
|
|
12
13
|
|
|
13
14
|
export const getAddress = (a: Account) => ({
|
|
14
15
|
address: a.freshAddress,
|
|
@@ -45,14 +46,15 @@ const buildSignOperation =
|
|
|
45
46
|
recipients.push(transaction.recipient);
|
|
46
47
|
}
|
|
47
48
|
|
|
49
|
+
const subAccount =
|
|
50
|
+
!!transaction.subAccountId && findSubAccountById(account, transaction.subAccountId);
|
|
51
|
+
|
|
48
52
|
// build optimistic operation
|
|
49
53
|
const operation: Operation = {
|
|
50
54
|
id: encodeOperationId(accountId, hash, type),
|
|
51
55
|
hash,
|
|
52
56
|
type,
|
|
53
|
-
value: transaction.
|
|
54
|
-
? account.balance.minus(fee)
|
|
55
|
-
: transaction.amount.plus(fee),
|
|
57
|
+
value: subAccount ? fee : transaction.amount.plus(fee),
|
|
56
58
|
fee,
|
|
57
59
|
extra,
|
|
58
60
|
blockHash: null,
|
|
@@ -62,6 +64,20 @@ const buildSignOperation =
|
|
|
62
64
|
accountId,
|
|
63
65
|
date: new Date(),
|
|
64
66
|
transactionSequenceNumber: Number(rawTx.sequence_number),
|
|
67
|
+
subOperations: subAccount
|
|
68
|
+
? [
|
|
69
|
+
{
|
|
70
|
+
id: encodeOperationId(subAccount.id, "", "OUT"),
|
|
71
|
+
type: "OUT",
|
|
72
|
+
accountId: transaction.subAccountId,
|
|
73
|
+
senders: [account.freshAddress],
|
|
74
|
+
recipients: [transaction.recipient],
|
|
75
|
+
value: transaction.amount,
|
|
76
|
+
fee,
|
|
77
|
+
date: new Date(),
|
|
78
|
+
} as Operation,
|
|
79
|
+
]
|
|
80
|
+
: [],
|
|
65
81
|
};
|
|
66
82
|
|
|
67
83
|
o.next({
|
|
@@ -1,9 +1,160 @@
|
|
|
1
|
+
import { inferSubOperations } from "@ledgerhq/coin-framework/serialization/index";
|
|
1
2
|
import { decodeAccountId, encodeAccountId } from "@ledgerhq/coin-framework/account";
|
|
2
3
|
import type { GetAccountShape } from "@ledgerhq/coin-framework/bridge/jsHelpers";
|
|
3
4
|
import { mergeOps } from "@ledgerhq/coin-framework/bridge/jsHelpers";
|
|
4
|
-
import { AptosAPI } from "../
|
|
5
|
+
import { AptosAPI } from "../network";
|
|
5
6
|
import { txsToOps } from "./logic";
|
|
6
7
|
import type { AptosAccount } from "../types";
|
|
8
|
+
import { Account, Operation, TokenAccount } from "@ledgerhq/types-live";
|
|
9
|
+
import { CryptoCurrency, TokenCurrency } from "@ledgerhq/types-cryptoassets";
|
|
10
|
+
import {
|
|
11
|
+
decodeTokenAccountId,
|
|
12
|
+
emptyHistoryCache,
|
|
13
|
+
encodeTokenAccountId,
|
|
14
|
+
} from "@ledgerhq/coin-framework/account/index";
|
|
15
|
+
import { AccountShapeInfo } from "@ledgerhq/coin-framework/bridge/jsHelpers";
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* List of properties of a sub account that can be updated when 2 "identical" accounts are found
|
|
19
|
+
*/
|
|
20
|
+
const updatableSubAccountProperties: { name: string; isOps: boolean }[] = [
|
|
21
|
+
{ name: "balance", isOps: false },
|
|
22
|
+
{ name: "spendableBalance", isOps: false },
|
|
23
|
+
{ name: "balanceHistoryCache", isOps: false },
|
|
24
|
+
{ name: "operations", isOps: true },
|
|
25
|
+
{ name: "pendingOperations", isOps: true },
|
|
26
|
+
];
|
|
27
|
+
/**
|
|
28
|
+
* In charge of smartly merging sub accounts while maintaining references as much as possible
|
|
29
|
+
*/
|
|
30
|
+
export const mergeSubAccounts = (
|
|
31
|
+
initialAccount: Account | undefined,
|
|
32
|
+
newSubAccounts: TokenAccount[],
|
|
33
|
+
): Array<TokenAccount> => {
|
|
34
|
+
const oldSubAccounts: Array<TokenAccount> | undefined = initialAccount?.subAccounts;
|
|
35
|
+
if (!oldSubAccounts) {
|
|
36
|
+
return newSubAccounts;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Creating a map of already existing sub accounts by id
|
|
40
|
+
const oldSubAccountsById: { [key: string]: TokenAccount } = {};
|
|
41
|
+
for (const oldSubAccount of oldSubAccounts) {
|
|
42
|
+
oldSubAccountsById[oldSubAccount.id!] = oldSubAccount;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Looping on new sub accounts to compare them with already existing ones
|
|
46
|
+
// Already existing will be updated if necessary (see `updatableSubAccountProperties`)
|
|
47
|
+
// Fresh new sub accounts will be added/pushed after already existing
|
|
48
|
+
const newSubAccountsToAdd: TokenAccount[] = [];
|
|
49
|
+
for (const newSubAccount of newSubAccounts) {
|
|
50
|
+
const duplicatedAccount: TokenAccount | undefined = oldSubAccountsById[newSubAccount.id!];
|
|
51
|
+
|
|
52
|
+
// If this sub account was not already in the initialAccount
|
|
53
|
+
if (!duplicatedAccount) {
|
|
54
|
+
// We'll add it later
|
|
55
|
+
newSubAccountsToAdd.push(newSubAccount);
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const updates: Partial<TokenAccount> & { [key: string]: any } = {};
|
|
60
|
+
for (const { name, isOps } of updatableSubAccountProperties) {
|
|
61
|
+
if (!isOps) {
|
|
62
|
+
if (
|
|
63
|
+
newSubAccount[name as keyof TokenAccount] !==
|
|
64
|
+
duplicatedAccount[name as keyof TokenAccount]
|
|
65
|
+
) {
|
|
66
|
+
updates[name] = newSubAccount[name as keyof TokenAccount];
|
|
67
|
+
}
|
|
68
|
+
} else {
|
|
69
|
+
updates[name] =
|
|
70
|
+
mergeOps(
|
|
71
|
+
duplicatedAccount[name as keyof TokenAccount] as Operation[],
|
|
72
|
+
newSubAccount[name as keyof TokenAccount] as Operation[],
|
|
73
|
+
) || [];
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Updating the operationsCount in case the mergeOps changed it
|
|
78
|
+
updates.operationsCount =
|
|
79
|
+
updates.operations?.length || duplicatedAccount?.operations?.length || 0;
|
|
80
|
+
|
|
81
|
+
// Modifying the Map with the updated sub account with a new ref
|
|
82
|
+
oldSubAccountsById[newSubAccount.id!] = {
|
|
83
|
+
...duplicatedAccount,
|
|
84
|
+
...updates,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
const updatedSubAccounts = Object.values(oldSubAccountsById);
|
|
88
|
+
return [...updatedSubAccounts, ...newSubAccountsToAdd];
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Fetch the balance for a token and creates a TokenAccount based on this and the provided operations
|
|
93
|
+
*/
|
|
94
|
+
export const getSubAccountShape = async (
|
|
95
|
+
currency: CryptoCurrency,
|
|
96
|
+
address: string,
|
|
97
|
+
parentId: string,
|
|
98
|
+
token: TokenCurrency,
|
|
99
|
+
operations: Operation[],
|
|
100
|
+
): Promise<TokenAccount> => {
|
|
101
|
+
const aptosClient = new AptosAPI(currency.id);
|
|
102
|
+
const tokenAccountId = encodeTokenAccountId(parentId, token);
|
|
103
|
+
const balance = await aptosClient.getBalance(address, token);
|
|
104
|
+
const firstOperation = operations
|
|
105
|
+
.sort((a, b) => b.date.getTime() - a.date.getTime())
|
|
106
|
+
.at(operations.length - 1);
|
|
107
|
+
|
|
108
|
+
return {
|
|
109
|
+
type: "TokenAccount",
|
|
110
|
+
id: tokenAccountId,
|
|
111
|
+
parentId,
|
|
112
|
+
token,
|
|
113
|
+
balance,
|
|
114
|
+
spendableBalance: balance,
|
|
115
|
+
creationDate: firstOperation?.date || new Date(0),
|
|
116
|
+
operations,
|
|
117
|
+
operationsCount: operations.length,
|
|
118
|
+
pendingOperations: [],
|
|
119
|
+
balanceHistoryCache: emptyHistoryCache,
|
|
120
|
+
swapHistory: [],
|
|
121
|
+
};
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Getting all token related operations in order to provide TokenAccounts
|
|
126
|
+
*/
|
|
127
|
+
export const getSubAccounts = async (
|
|
128
|
+
infos: AccountShapeInfo<Account>,
|
|
129
|
+
address: string,
|
|
130
|
+
accountId: string,
|
|
131
|
+
lastTokenOperations: Operation[],
|
|
132
|
+
): Promise<TokenAccount[]> => {
|
|
133
|
+
const { currency } = infos;
|
|
134
|
+
|
|
135
|
+
// Creating a Map of Operations by TokenCurrencies in order to know which TokenAccounts should be synced as well
|
|
136
|
+
const operationsByToken = lastTokenOperations.reduce<Map<TokenCurrency, Operation[]>>(
|
|
137
|
+
(acc, operation) => {
|
|
138
|
+
const { token } = decodeTokenAccountId(operation.accountId);
|
|
139
|
+
if (!token) return acc; // TODO: do we need to check blacklistedTokenIds
|
|
140
|
+
|
|
141
|
+
if (!acc.has(token)) {
|
|
142
|
+
acc.set(token, []);
|
|
143
|
+
}
|
|
144
|
+
acc.get(token)?.push(operation);
|
|
145
|
+
return acc;
|
|
146
|
+
},
|
|
147
|
+
new Map<TokenCurrency, Operation[]>(),
|
|
148
|
+
);
|
|
149
|
+
|
|
150
|
+
// Fetching all TokenAccounts possible and providing already filtered operations
|
|
151
|
+
const subAccountsPromises: Promise<TokenAccount>[] = [];
|
|
152
|
+
for (const [token, ops] of operationsByToken.entries()) {
|
|
153
|
+
subAccountsPromises.push(getSubAccountShape(currency, address, accountId, token, ops));
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
return Promise.all(subAccountsPromises);
|
|
157
|
+
};
|
|
7
158
|
|
|
8
159
|
export const getAccountShape: GetAccountShape = async info => {
|
|
9
160
|
const { address, initialAccount, currency, derivationMode, rest } = info;
|
|
@@ -26,14 +177,29 @@ export const getAccountShape: GetAccountShape = async info => {
|
|
|
26
177
|
const xpub = initialAccount?.xpub || publicKey || "";
|
|
27
178
|
|
|
28
179
|
const oldOperations = initialAccount?.operations || [];
|
|
29
|
-
const startAt = (oldOperations[0]?.extra as any)?.version;
|
|
30
180
|
|
|
31
181
|
const aptosClient = new AptosAPI(currency.id);
|
|
32
|
-
const { balance, transactions, blockHeight } = await aptosClient.getAccountInfo(address
|
|
182
|
+
const { balance, transactions, blockHeight } = await aptosClient.getAccountInfo(address);
|
|
33
183
|
|
|
34
|
-
const newOperations = txsToOps(
|
|
184
|
+
const [newOperations, tokenOperations]: [Operation[], Operation[]] = txsToOps(
|
|
185
|
+
info,
|
|
186
|
+
accountId,
|
|
187
|
+
transactions,
|
|
188
|
+
);
|
|
35
189
|
const operations = mergeOps(oldOperations, newOperations);
|
|
36
190
|
|
|
191
|
+
const newSubAccounts = await getSubAccounts(info, address, accountId, tokenOperations);
|
|
192
|
+
const shouldSyncFromScratch = initialAccount === undefined;
|
|
193
|
+
const subAccounts = shouldSyncFromScratch
|
|
194
|
+
? newSubAccounts
|
|
195
|
+
: mergeSubAccounts(initialAccount, newSubAccounts);
|
|
196
|
+
|
|
197
|
+
operations.forEach(op => {
|
|
198
|
+
const subOperations = inferSubOperations(op.hash, subAccounts);
|
|
199
|
+
op.subOperations =
|
|
200
|
+
subOperations.length === 1 ? subOperations : subOperations.filter(op => !!op.blockHash);
|
|
201
|
+
});
|
|
202
|
+
|
|
37
203
|
const shape: Partial<AptosAccount> = {
|
|
38
204
|
type: "Account",
|
|
39
205
|
id: accountId,
|
|
@@ -44,6 +210,7 @@ export const getAccountShape: GetAccountShape = async info => {
|
|
|
44
210
|
operationsCount: operations.length,
|
|
45
211
|
blockHeight,
|
|
46
212
|
lastSyncDate: new Date(),
|
|
213
|
+
subAccounts,
|
|
47
214
|
};
|
|
48
215
|
|
|
49
216
|
return shape;
|
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;
|