@ledgerhq/coin-ton 0.7.0-nightly.3 → 0.7.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/CHANGELOG.md +17 -26
- package/jest.config.js +0 -1
- package/lib/__tests__/fixtures/common.fixtures.d.ts +4 -3
- package/lib/__tests__/fixtures/common.fixtures.d.ts.map +1 -1
- package/lib/__tests__/fixtures/common.fixtures.js +1 -9
- package/lib/__tests__/fixtures/common.fixtures.js.map +1 -1
- package/lib/__tests__/integration/bridge.integration.test.d.ts.map +1 -1
- package/lib/__tests__/integration/bridge.integration.test.js +2 -2
- package/lib/__tests__/integration/bridge.integration.test.js.map +1 -1
- package/lib/__tests__/unit/api.unit.test.js +0 -1
- package/lib/__tests__/unit/api.unit.test.js.map +1 -1
- package/lib/__tests__/unit/deviceTransactionConfig.unit.test.js +3 -12
- package/lib/__tests__/unit/deviceTransactionConfig.unit.test.js.map +1 -1
- package/lib/__tests__/unit/prepareTransaction.unit.test.js +0 -38
- package/lib/__tests__/unit/prepareTransaction.unit.test.js.map +1 -1
- package/lib/__tests__/unit/utils.unit.test.js +1 -43
- package/lib/__tests__/unit/utils.unit.test.js.map +1 -1
- package/lib/bridge/js.d.ts +3 -3
- package/lib/bridge/js.d.ts.map +1 -1
- package/lib/config.d.ts +0 -2
- package/lib/config.d.ts.map +1 -1
- package/lib/config.js.map +1 -1
- package/lib/constants.d.ts +0 -18
- package/lib/constants.d.ts.map +1 -1
- package/lib/constants.js +1 -20
- package/lib/constants.js.map +1 -1
- package/lib/deviceTransactionConfig.d.ts.map +1 -1
- package/lib/deviceTransactionConfig.js +3 -14
- package/lib/deviceTransactionConfig.js.map +1 -1
- package/lib/estimateMaxSpendable.d.ts +3 -3
- package/lib/estimateMaxSpendable.d.ts.map +1 -1
- package/lib/estimateMaxSpendable.js +5 -6
- package/lib/estimateMaxSpendable.js.map +1 -1
- package/lib/getTransactionStatus.d.ts +3 -3
- package/lib/getTransactionStatus.d.ts.map +1 -1
- package/lib/getTransactionStatus.js +2 -2
- package/lib/getTransactionStatus.js.map +1 -1
- package/lib/prepareTransaction.d.ts +3 -3
- package/lib/prepareTransaction.d.ts.map +1 -1
- package/lib/prepareTransaction.js +2 -1
- package/lib/prepareTransaction.js.map +1 -1
- package/lib/signOperation.d.ts +4 -4
- package/lib/signOperation.d.ts.map +1 -1
- package/lib/signOperation.js.map +1 -1
- package/lib/synchronisation.d.ts +3 -3
- package/lib/synchronisation.d.ts.map +1 -1
- package/lib/synchronisation.js +3 -4
- package/lib/synchronisation.js.map +1 -1
- package/lib/types.d.ts +2 -79
- package/lib/types.d.ts.map +1 -1
- package/lib/utils.d.ts +4 -8
- package/lib/utils.d.ts.map +1 -1
- package/lib/utils.js +5 -30
- package/lib/utils.js.map +1 -1
- package/lib-es/__tests__/fixtures/common.fixtures.d.ts +4 -3
- package/lib-es/__tests__/fixtures/common.fixtures.d.ts.map +1 -1
- package/lib-es/__tests__/fixtures/common.fixtures.js +1 -9
- package/lib-es/__tests__/fixtures/common.fixtures.js.map +1 -1
- package/lib-es/__tests__/integration/bridge.integration.test.d.ts.map +1 -1
- package/lib-es/__tests__/integration/bridge.integration.test.js +1 -1
- package/lib-es/__tests__/integration/bridge.integration.test.js.map +1 -1
- package/lib-es/__tests__/unit/api.unit.test.js +0 -1
- package/lib-es/__tests__/unit/api.unit.test.js.map +1 -1
- package/lib-es/__tests__/unit/deviceTransactionConfig.unit.test.js +3 -12
- package/lib-es/__tests__/unit/deviceTransactionConfig.unit.test.js.map +1 -1
- package/lib-es/__tests__/unit/prepareTransaction.unit.test.js +0 -15
- package/lib-es/__tests__/unit/prepareTransaction.unit.test.js.map +1 -1
- package/lib-es/__tests__/unit/utils.unit.test.js +1 -20
- package/lib-es/__tests__/unit/utils.unit.test.js.map +1 -1
- package/lib-es/bridge/js.d.ts +3 -3
- package/lib-es/bridge/js.d.ts.map +1 -1
- package/lib-es/bridge/js.js +1 -1
- package/lib-es/bridge/js.js.map +1 -1
- package/lib-es/config.d.ts +0 -2
- package/lib-es/config.d.ts.map +1 -1
- package/lib-es/config.js.map +1 -1
- package/lib-es/constants.d.ts +0 -18
- package/lib-es/constants.d.ts.map +1 -1
- package/lib-es/constants.js +0 -19
- package/lib-es/constants.js.map +1 -1
- package/lib-es/deviceTransactionConfig.d.ts.map +1 -1
- package/lib-es/deviceTransactionConfig.js +4 -15
- package/lib-es/deviceTransactionConfig.js.map +1 -1
- package/lib-es/estimateMaxSpendable.d.ts +3 -3
- package/lib-es/estimateMaxSpendable.d.ts.map +1 -1
- package/lib-es/estimateMaxSpendable.js +6 -7
- package/lib-es/estimateMaxSpendable.js.map +1 -1
- package/lib-es/getTransactionStatus.d.ts +3 -3
- package/lib-es/getTransactionStatus.d.ts.map +1 -1
- package/lib-es/getTransactionStatus.js +2 -2
- package/lib-es/getTransactionStatus.js.map +1 -1
- package/lib-es/prepareTransaction.d.ts +3 -3
- package/lib-es/prepareTransaction.d.ts.map +1 -1
- package/lib-es/prepareTransaction.js +2 -1
- package/lib-es/prepareTransaction.js.map +1 -1
- package/lib-es/signOperation.d.ts +4 -4
- package/lib-es/signOperation.d.ts.map +1 -1
- package/lib-es/signOperation.js.map +1 -1
- package/lib-es/synchronisation.d.ts +3 -3
- package/lib-es/synchronisation.d.ts.map +1 -1
- package/lib-es/synchronisation.js +3 -4
- package/lib-es/synchronisation.js.map +1 -1
- package/lib-es/types.d.ts +2 -79
- package/lib-es/types.d.ts.map +1 -1
- package/lib-es/utils.d.ts +4 -8
- package/lib-es/utils.d.ts.map +1 -1
- package/lib-es/utils.js +5 -29
- package/lib-es/utils.js.map +1 -1
- package/package.json +9 -9
- package/src/__tests__/fixtures/common.fixtures.ts +5 -12
- package/src/__tests__/integration/bridge.integration.test.ts +3 -3
- package/src/__tests__/unit/api.unit.test.ts +0 -1
- package/src/__tests__/unit/deviceTransactionConfig.unit.test.ts +3 -20
- package/src/__tests__/unit/prepareTransaction.unit.test.ts +0 -17
- package/src/__tests__/unit/utils.unit.test.ts +1 -22
- package/src/bridge/js.ts +3 -3
- package/src/config.ts +0 -2
- package/src/constants.ts +0 -20
- package/src/deviceTransactionConfig.ts +4 -23
- package/src/estimateMaxSpendable.ts +17 -13
- package/src/getTransactionStatus.ts +9 -9
- package/src/prepareTransaction.ts +6 -5
- package/src/signOperation.ts +4 -6
- package/src/synchronisation.ts +12 -17
- package/src/types.ts +1 -103
- package/src/utils.ts +8 -39
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import { estimateFee, fetchAccountInfo } from "../../bridge/bridgeHelpers/api";
|
|
2
|
-
import { setCoinConfig } from "../../config";
|
|
3
2
|
import prepareTransaction from "../../prepareTransaction";
|
|
4
|
-
import mockServer, { API_TON_ENDPOINT } from "../fixtures/api.fixtures";
|
|
5
3
|
import {
|
|
6
4
|
account,
|
|
7
5
|
accountInfo,
|
|
@@ -19,21 +17,6 @@ describe("prepareTransaction", () => {
|
|
|
19
17
|
fetchAccountInfoMock.mockReturnValue(Promise.resolve(accountInfo));
|
|
20
18
|
const fetchEstimateFeeMock = jest.mocked(estimateFee);
|
|
21
19
|
fetchEstimateFeeMock.mockReturnValue(Promise.resolve(fees));
|
|
22
|
-
|
|
23
|
-
setCoinConfig(() => ({
|
|
24
|
-
status: {
|
|
25
|
-
type: "active",
|
|
26
|
-
},
|
|
27
|
-
infra: {
|
|
28
|
-
API_TON_ENDPOINT: API_TON_ENDPOINT,
|
|
29
|
-
KNOWN_JETTONS: [],
|
|
30
|
-
},
|
|
31
|
-
}));
|
|
32
|
-
mockServer.listen();
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
afterAll(() => {
|
|
36
|
-
mockServer.close();
|
|
37
20
|
});
|
|
38
21
|
|
|
39
22
|
describe("Ton Transaction", () => {
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { Address, toNano } from "@ton/core";
|
|
2
|
-
import { setCoinConfig } from "../../config";
|
|
3
2
|
import {
|
|
4
3
|
TOKEN_TRANSFER_FORWARD_AMOUNT,
|
|
5
4
|
TOKEN_TRANSFER_MAX_FEE,
|
|
@@ -14,7 +13,6 @@ import {
|
|
|
14
13
|
getTransferExpirationTime,
|
|
15
14
|
isAddressValid,
|
|
16
15
|
} from "../../utils";
|
|
17
|
-
import mockServer, { API_TON_ENDPOINT } from "../fixtures/api.fixtures";
|
|
18
16
|
import {
|
|
19
17
|
account,
|
|
20
18
|
transaction as baseTransaction,
|
|
@@ -92,7 +90,6 @@ describe("TON transfers", () => {
|
|
|
92
90
|
customPayload: null,
|
|
93
91
|
forwardAmount: BigInt(0),
|
|
94
92
|
forwardPayload: null,
|
|
95
|
-
knownJetton: null,
|
|
96
93
|
};
|
|
97
94
|
|
|
98
95
|
const nftPayload: TonPayloadFormat = {
|
|
@@ -142,23 +139,6 @@ describe("Get TON paths", () => {
|
|
|
142
139
|
});
|
|
143
140
|
|
|
144
141
|
describe("Build TON transaction", () => {
|
|
145
|
-
beforeAll(() => {
|
|
146
|
-
setCoinConfig(() => ({
|
|
147
|
-
status: {
|
|
148
|
-
type: "active",
|
|
149
|
-
},
|
|
150
|
-
infra: {
|
|
151
|
-
API_TON_ENDPOINT: API_TON_ENDPOINT,
|
|
152
|
-
KNOWN_JETTONS: [],
|
|
153
|
-
},
|
|
154
|
-
}));
|
|
155
|
-
mockServer.listen();
|
|
156
|
-
});
|
|
157
|
-
|
|
158
|
-
afterAll(() => {
|
|
159
|
-
mockServer.close();
|
|
160
|
-
});
|
|
161
|
-
|
|
162
142
|
const seqno = 22;
|
|
163
143
|
|
|
164
144
|
test("Build TON transaction with an specific amount", () => {
|
|
@@ -204,7 +184,7 @@ describe("Build TON transaction", () => {
|
|
|
204
184
|
to: jettonTransfer.to.toString(),
|
|
205
185
|
payload: undefined,
|
|
206
186
|
}).toStrictEqual({
|
|
207
|
-
to: Address.parse(account.subAccounts?.[0].
|
|
187
|
+
to: Address.parse(account.subAccounts?.[0].token.contractAddress ?? "").toString(),
|
|
208
188
|
seqno,
|
|
209
189
|
amount: toNano(TOKEN_TRANSFER_MAX_FEE),
|
|
210
190
|
bounce: true,
|
|
@@ -233,7 +213,6 @@ describe("Build TON transaction", () => {
|
|
|
233
213
|
customPayload: null,
|
|
234
214
|
forwardAmount: TOKEN_TRANSFER_FORWARD_AMOUNT.toString(),
|
|
235
215
|
forwardPayload: null,
|
|
236
|
-
knownJetton: null,
|
|
237
216
|
});
|
|
238
217
|
});
|
|
239
218
|
});
|
package/src/bridge/js.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import getAddressWrapper from "@ledgerhq/coin-framework/bridge/getAddressWrapper";
|
|
2
2
|
import {
|
|
3
3
|
getSerializedAddressParameters,
|
|
4
|
+
updateTransaction,
|
|
4
5
|
makeAccountBridgeReceive,
|
|
5
6
|
makeScanAccounts,
|
|
6
|
-
updateTransaction,
|
|
7
7
|
} from "@ledgerhq/coin-framework/bridge/jsHelpers";
|
|
8
8
|
import { SignerContext } from "@ledgerhq/coin-framework/signer";
|
|
9
9
|
|
|
@@ -18,7 +18,7 @@ import prepareTransaction from "../prepareTransaction";
|
|
|
18
18
|
import { buildSignOperation } from "../signOperation";
|
|
19
19
|
import { TonSigner } from "../signer";
|
|
20
20
|
import { getAccountShape, sync } from "../synchronisation";
|
|
21
|
-
import type {
|
|
21
|
+
import type { Transaction } from "../types";
|
|
22
22
|
|
|
23
23
|
export function buildCurrencyBridge(signerContext: SignerContext<TonSigner>): CurrencyBridge {
|
|
24
24
|
const getAddress = resolver(signerContext);
|
|
@@ -37,7 +37,7 @@ export function buildCurrencyBridge(signerContext: SignerContext<TonSigner>): Cu
|
|
|
37
37
|
|
|
38
38
|
export function buildAccountBridge(
|
|
39
39
|
signerContext: SignerContext<TonSigner>,
|
|
40
|
-
): AccountBridge<Transaction
|
|
40
|
+
): AccountBridge<Transaction> {
|
|
41
41
|
const getAddress = resolver(signerContext);
|
|
42
42
|
|
|
43
43
|
const receive = makeAccountBridgeReceive(getAddressWrapper(getAddress));
|
package/src/config.ts
CHANGED
package/src/constants.ts
CHANGED
|
@@ -26,10 +26,6 @@ export const TOKEN_TRANSFER_QUERY_ID = 0;
|
|
|
26
26
|
*/
|
|
27
27
|
export const MAX_COMMENT_BYTES = 120;
|
|
28
28
|
|
|
29
|
-
/**
|
|
30
|
-
* Operation codes for Jetton (TON token standard) transactions.
|
|
31
|
-
* These codes are used to identify different types of token operations.
|
|
32
|
-
*/
|
|
33
29
|
export enum JettonOpCode {
|
|
34
30
|
Transfer = 0xf8a7ea5,
|
|
35
31
|
TransferNotification = 0x7362d09c,
|
|
@@ -38,19 +34,3 @@ export enum JettonOpCode {
|
|
|
38
34
|
Burn = 0x595f07bc,
|
|
39
35
|
BurnNotification = 0x7bdd97de,
|
|
40
36
|
}
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* TON blockchain workchain identifiers.
|
|
44
|
-
* MasterChain (-1) is used for validator operations and governance.
|
|
45
|
-
* BaseChain (0) is the main workchain used for regular accounts and smart contracts.
|
|
46
|
-
*/
|
|
47
|
-
export enum Workchain {
|
|
48
|
-
MasterChain = -1,
|
|
49
|
-
BaseChain = 0,
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Default workchain used for TON addresses.
|
|
54
|
-
* BaseChain (0) is the standard workchain for user accounts and transactions.
|
|
55
|
-
*/
|
|
56
|
-
export const WORKCHAIN = Workchain.BaseChain;
|
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { formatCurrencyUnit } from "@ledgerhq/coin-framework/currencies/index";
|
|
1
|
+
import { isTokenAccount } from "@ledgerhq/coin-framework/account/index";
|
|
3
2
|
import { CommonDeviceTransactionField as DeviceTransactionField } from "@ledgerhq/coin-framework/transaction/common";
|
|
4
3
|
import type { Account, AccountLike } from "@ledgerhq/types-live";
|
|
5
|
-
import { toNano } from "@ton/core";
|
|
6
|
-
import { BigNumber } from "bignumber.js";
|
|
7
4
|
import { TOKEN_TRANSFER_MAX_FEE } from "./constants";
|
|
8
5
|
import type { Transaction, TransactionStatus } from "./types";
|
|
9
6
|
|
|
@@ -25,29 +22,13 @@ function getDeviceTransactionConfig(input: {
|
|
|
25
22
|
if (tokenTransfer) {
|
|
26
23
|
fields.push({
|
|
27
24
|
type: "text",
|
|
28
|
-
label: "Jetton
|
|
29
|
-
value:
|
|
30
|
-
getAccountCurrency(input.account).units[0],
|
|
31
|
-
input.transaction.amount,
|
|
32
|
-
{
|
|
33
|
-
showCode: true,
|
|
34
|
-
disableRounding: true,
|
|
35
|
-
},
|
|
36
|
-
),
|
|
25
|
+
label: "Jetton units",
|
|
26
|
+
value: input.transaction.amount.toString(),
|
|
37
27
|
});
|
|
38
28
|
fields.push({
|
|
39
29
|
type: "text",
|
|
40
30
|
label: "Amount",
|
|
41
|
-
value:
|
|
42
|
-
? formatCurrencyUnit(
|
|
43
|
-
getAccountCurrency(input.parentAccount).units[0],
|
|
44
|
-
BigNumber(toNano(TOKEN_TRANSFER_MAX_FEE).toString()),
|
|
45
|
-
{
|
|
46
|
-
showCode: true,
|
|
47
|
-
disableRounding: true,
|
|
48
|
-
},
|
|
49
|
-
)
|
|
50
|
-
: TOKEN_TRANSFER_MAX_FEE,
|
|
31
|
+
value: TOKEN_TRANSFER_MAX_FEE,
|
|
51
32
|
});
|
|
52
33
|
} else {
|
|
53
34
|
if (input.transaction.useAllAmount) {
|
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
findSubAccountById,
|
|
3
|
+
getMainAccount,
|
|
4
|
+
isTokenAccount,
|
|
5
|
+
} from "@ledgerhq/coin-framework/account/index";
|
|
2
6
|
import type { Account, AccountBridge, AccountLike, TokenAccount } from "@ledgerhq/types-live";
|
|
3
7
|
import { BigNumber } from "bignumber.js";
|
|
4
8
|
import { fetchAccountInfo } from "./bridge/bridgeHelpers/api";
|
|
5
|
-
import type {
|
|
6
|
-
import { buildTonTransaction,
|
|
9
|
+
import type { Transaction } from "./types";
|
|
10
|
+
import { buildTonTransaction, getTonEstimatedFees } from "./utils";
|
|
7
11
|
|
|
8
|
-
const estimateMaxSpendable: AccountBridge<
|
|
9
|
-
Transaction,
|
|
10
|
-
TonAccount
|
|
11
|
-
>["estimateMaxSpendable"] = async ({
|
|
12
|
+
const estimateMaxSpendable: AccountBridge<Transaction, Account>["estimateMaxSpendable"] = async ({
|
|
12
13
|
account,
|
|
13
14
|
parentAccount,
|
|
14
15
|
transaction,
|
|
@@ -17,7 +18,7 @@ const estimateMaxSpendable: AccountBridge<
|
|
|
17
18
|
parentAccount?: Account | null | undefined;
|
|
18
19
|
transaction?: Transaction | null | undefined;
|
|
19
20
|
}): Promise<BigNumber> => {
|
|
20
|
-
const mainAccount = getMainAccount(account, parentAccount)
|
|
21
|
+
const mainAccount = getMainAccount(account, parentAccount);
|
|
21
22
|
let balance = mainAccount.spendableBalance;
|
|
22
23
|
|
|
23
24
|
if (balance.eq(0)) return balance;
|
|
@@ -44,11 +45,14 @@ const estimateMaxSpendable: AccountBridge<
|
|
|
44
45
|
return subAccount.spendableBalance;
|
|
45
46
|
}
|
|
46
47
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
48
|
+
const estimatedFees = transaction
|
|
49
|
+
? transaction.fees ??
|
|
50
|
+
(await getTonEstimatedFees(
|
|
51
|
+
mainAccount,
|
|
52
|
+
accountInfo.status === "uninit",
|
|
53
|
+
buildTonTransaction(transaction, accountInfo.seqno, mainAccount),
|
|
54
|
+
))
|
|
55
|
+
: BigNumber(0);
|
|
52
56
|
|
|
53
57
|
if (balance.lte(estimatedFees)) return new BigNumber(0);
|
|
54
58
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isTokenAccount } from "@ledgerhq/coin-framework/account/index";
|
|
1
|
+
import { findSubAccountById, isTokenAccount } from "@ledgerhq/coin-framework/account/index";
|
|
2
2
|
import {
|
|
3
3
|
AmountRequired,
|
|
4
4
|
InvalidAddress,
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
NotEnoughBalance,
|
|
7
7
|
RecipientRequired,
|
|
8
8
|
} from "@ledgerhq/errors";
|
|
9
|
-
import { AccountBridge } from "@ledgerhq/types-live";
|
|
9
|
+
import { Account, AccountBridge } from "@ledgerhq/types-live";
|
|
10
10
|
import { toNano } from "@ton/core";
|
|
11
11
|
import BigNumber from "bignumber.js";
|
|
12
12
|
import { MINIMUM_REQUIRED_BALANCE, TOKEN_TRANSFER_MAX_FEE } from "./constants";
|
|
@@ -16,8 +16,8 @@ import {
|
|
|
16
16
|
TonMinimumRequired,
|
|
17
17
|
TonNotEnoughBalanceInParentAccount,
|
|
18
18
|
} from "./errors";
|
|
19
|
-
import {
|
|
20
|
-
import { addressesAreEqual, commentIsValid,
|
|
19
|
+
import { Transaction, TransactionStatus } from "./types";
|
|
20
|
+
import { addressesAreEqual, commentIsValid, isAddressValid } from "./utils";
|
|
21
21
|
|
|
22
22
|
type ValidatedTransactionFields = "recipient" | "sender" | "amount" | "transaction";
|
|
23
23
|
type ValidationIssues = Partial<Record<ValidatedTransactionFields, Error>>;
|
|
@@ -25,7 +25,7 @@ type ValidationIssues = Partial<Record<ValidatedTransactionFields, Error>>;
|
|
|
25
25
|
/**
|
|
26
26
|
* Validate an address for account transaction
|
|
27
27
|
*/
|
|
28
|
-
const validateRecipient = (account:
|
|
28
|
+
const validateRecipient = (account: Account, tx: Transaction): Array<ValidationIssues> => {
|
|
29
29
|
const errors: ValidationIssues = {};
|
|
30
30
|
|
|
31
31
|
if (tx.recipient) {
|
|
@@ -52,7 +52,7 @@ const validateRecipient = (account: TonAccount, tx: Transaction): Array<Validati
|
|
|
52
52
|
/**
|
|
53
53
|
* Validate the sender address for account transaction
|
|
54
54
|
*/
|
|
55
|
-
const validateSender = (account:
|
|
55
|
+
const validateSender = (account: Account): Array<ValidationIssues> => {
|
|
56
56
|
const errors: ValidationIssues = {};
|
|
57
57
|
|
|
58
58
|
// Check if sender is matching the format of account valid ton address or not
|
|
@@ -68,7 +68,7 @@ const validateSender = (account: TonAccount): Array<ValidationIssues> => {
|
|
|
68
68
|
};
|
|
69
69
|
|
|
70
70
|
const validateAmount = (
|
|
71
|
-
account:
|
|
71
|
+
account: Account,
|
|
72
72
|
transaction: Transaction,
|
|
73
73
|
totalSpent: BigNumber,
|
|
74
74
|
): Array<ValidationIssues> => {
|
|
@@ -120,10 +120,10 @@ const validateComment = (transaction: Transaction): Array<ValidationIssues> => {
|
|
|
120
120
|
|
|
121
121
|
export const getTransactionStatus: AccountBridge<
|
|
122
122
|
Transaction,
|
|
123
|
-
|
|
123
|
+
Account,
|
|
124
124
|
TransactionStatus
|
|
125
125
|
>["getTransactionStatus"] = async (
|
|
126
|
-
account:
|
|
126
|
+
account: Account,
|
|
127
127
|
transaction: Transaction,
|
|
128
128
|
): Promise<TransactionStatus> => {
|
|
129
129
|
const subAccount = findSubAccountById(account, transaction.subAccountId ?? "");
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
+
import { findSubAccountById } from "@ledgerhq/coin-framework/account/index";
|
|
1
2
|
import { updateTransaction } from "@ledgerhq/coin-framework/bridge/jsHelpers";
|
|
2
|
-
import { AccountBridge } from "@ledgerhq/types-live";
|
|
3
|
+
import { Account, AccountBridge } from "@ledgerhq/types-live";
|
|
3
4
|
import { fetchAccountInfo } from "./bridge/bridgeHelpers/api";
|
|
4
|
-
import type {
|
|
5
|
-
import { buildTonTransaction,
|
|
5
|
+
import type { Transaction } from "./types";
|
|
6
|
+
import { buildTonTransaction, getTonEstimatedFees } from "./utils";
|
|
6
7
|
|
|
7
|
-
const prepareTransaction: AccountBridge<Transaction,
|
|
8
|
-
account:
|
|
8
|
+
const prepareTransaction: AccountBridge<Transaction, Account>["prepareTransaction"] = async (
|
|
9
|
+
account: Account,
|
|
9
10
|
transaction: Transaction,
|
|
10
11
|
): Promise<Transaction> => {
|
|
11
12
|
const accountInfo = await fetchAccountInfo(account.freshAddress);
|
package/src/signOperation.ts
CHANGED
|
@@ -8,7 +8,7 @@ import { Observable } from "rxjs";
|
|
|
8
8
|
import { fetchAccountInfo } from "./bridge/bridgeHelpers/api";
|
|
9
9
|
import { TOKEN_TRANSFER_MAX_FEE } from "./constants";
|
|
10
10
|
import type { TonSigner } from "./signer";
|
|
11
|
-
import type {
|
|
11
|
+
import type { TonCell, TonOperation, Transaction } from "./types";
|
|
12
12
|
import { buildTonTransaction, getLedgerTonPath } from "./utils";
|
|
13
13
|
|
|
14
14
|
const packTransaction = (account: Account, needsInit: boolean, signature: TonCell): string => {
|
|
@@ -30,15 +30,13 @@ const packTransaction = (account: Account, needsInit: boolean, signature: TonCel
|
|
|
30
30
|
* Sign Transaction with Ledger hardware
|
|
31
31
|
*/
|
|
32
32
|
export const buildSignOperation =
|
|
33
|
-
(
|
|
34
|
-
signerContext: SignerContext<TonSigner>,
|
|
35
|
-
): AccountBridge<Transaction, TonAccount>["signOperation"] =>
|
|
33
|
+
(signerContext: SignerContext<TonSigner>): AccountBridge<Transaction>["signOperation"] =>
|
|
36
34
|
({
|
|
37
35
|
account,
|
|
38
36
|
transaction,
|
|
39
37
|
deviceId,
|
|
40
38
|
}: {
|
|
41
|
-
account:
|
|
39
|
+
account: Account;
|
|
42
40
|
transaction: Transaction;
|
|
43
41
|
deviceId: DeviceId;
|
|
44
42
|
}): Observable<SignOperationEvent> =>
|
|
@@ -89,7 +87,7 @@ export const buildSignOperation =
|
|
|
89
87
|
});
|
|
90
88
|
|
|
91
89
|
export const buildOptimisticOperation = (
|
|
92
|
-
account:
|
|
90
|
+
account: Account,
|
|
93
91
|
transaction: Transaction,
|
|
94
92
|
): TonOperation => {
|
|
95
93
|
const { recipient, amount, fees, comment, useAllAmount, subAccountId } = transaction;
|
package/src/synchronisation.ts
CHANGED
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
import { decodeOperationId } from "@ledgerhq/coin-framework/operation";
|
|
15
15
|
import { log } from "@ledgerhq/logs";
|
|
16
16
|
import { TokenCurrency } from "@ledgerhq/types-cryptoassets";
|
|
17
|
+
import { Account, SubAccount } from "@ledgerhq/types-live";
|
|
17
18
|
import BigNumber from "bignumber.js";
|
|
18
19
|
import flatMap from "lodash/flatMap";
|
|
19
20
|
import {
|
|
@@ -29,12 +30,9 @@ import {
|
|
|
29
30
|
mapTxToOps,
|
|
30
31
|
} from "./bridge/bridgeHelpers/txn";
|
|
31
32
|
import { getSyncHash } from "./logic";
|
|
32
|
-
import {
|
|
33
|
+
import { TonOperation } from "./types";
|
|
33
34
|
|
|
34
|
-
export const getAccountShape: GetAccountShape<
|
|
35
|
-
info,
|
|
36
|
-
{ blacklistedTokenIds },
|
|
37
|
-
) => {
|
|
35
|
+
export const getAccountShape: GetAccountShape<Account> = async (info, { blacklistedTokenIds }) => {
|
|
38
36
|
const { address, rest, currency, derivationMode, initialAccount } = info;
|
|
39
37
|
|
|
40
38
|
const publicKey = reconciliatePubkey(rest?.publicKey, initialAccount);
|
|
@@ -87,7 +85,6 @@ export const getAccountShape: GetAccountShape<TonAccount> = async (
|
|
|
87
85
|
mapJettonTxToOps(accountId, address, newTxs.address_book),
|
|
88
86
|
);
|
|
89
87
|
const operations = shouldSyncFromScratch ? newOps : mergeOps(oldOps, newOps);
|
|
90
|
-
|
|
91
88
|
const subAccounts = await getSubAccounts(
|
|
92
89
|
info,
|
|
93
90
|
accountId,
|
|
@@ -106,7 +103,7 @@ export const getAccountShape: GetAccountShape<TonAccount> = async (
|
|
|
106
103
|
blockHeight,
|
|
107
104
|
xpub: publicKey,
|
|
108
105
|
lastSyncDate: new Date(),
|
|
109
|
-
} as Partial<
|
|
106
|
+
} as Partial<Account>;
|
|
110
107
|
return toReturn;
|
|
111
108
|
};
|
|
112
109
|
|
|
@@ -116,15 +113,14 @@ const getSubAccountShape = async (
|
|
|
116
113
|
token: TokenCurrency,
|
|
117
114
|
ops: TonOperation[],
|
|
118
115
|
shouldSyncFromScratch: boolean,
|
|
119
|
-
): Promise<Partial<
|
|
116
|
+
): Promise<Partial<SubAccount>> => {
|
|
117
|
+
const tokenAccountId = encodeTokenAccountId(parentId, token);
|
|
120
118
|
const walletsInfo = await fetchJettonWallets({
|
|
121
119
|
address: info.address,
|
|
122
120
|
jettonMaster: token.contractAddress,
|
|
123
121
|
});
|
|
124
|
-
|
|
125
122
|
if (walletsInfo.length !== 1) throw new Error("[ton] unexpected api response");
|
|
126
|
-
const { balance, address:
|
|
127
|
-
const tokenAccountId = encodeTokenAccountId(parentId, token);
|
|
123
|
+
const { balance, address: jettonWalletAddress } = walletsInfo[0];
|
|
128
124
|
const oldOps = info.initialAccount?.subAccounts?.find(a => a.id === tokenAccountId)?.operations;
|
|
129
125
|
const operations = !oldOps || shouldSyncFromScratch ? ops : mergeOps(oldOps, ops);
|
|
130
126
|
const maybeExistingSubAccount =
|
|
@@ -136,7 +132,7 @@ const getSubAccountShape = async (
|
|
|
136
132
|
type: "TokenAccount",
|
|
137
133
|
id: tokenAccountId,
|
|
138
134
|
parentId,
|
|
139
|
-
token,
|
|
135
|
+
token: { ...token, contractAddress: jettonWalletAddress }, // the contract address is replaced for the jetton wallet address, it will be use for the token transfer
|
|
140
136
|
balance: new BigNumber(balance),
|
|
141
137
|
spendableBalance: new BigNumber(balance),
|
|
142
138
|
operations,
|
|
@@ -145,7 +141,6 @@ const getSubAccountShape = async (
|
|
|
145
141
|
creationDate: operations.length > 0 ? operations[operations.length - 1].date : new Date(),
|
|
146
142
|
balanceHistoryCache: emptyHistoryCache, // calculated in the jsHelpers
|
|
147
143
|
swapHistory: [],
|
|
148
|
-
jettonWallet, // Address of the jetton wallet contract that holds the token balance and handles transfers
|
|
149
144
|
};
|
|
150
145
|
};
|
|
151
146
|
|
|
@@ -155,7 +150,7 @@ async function getSubAccounts(
|
|
|
155
150
|
newOps: TonOperation[],
|
|
156
151
|
blacklistedTokenIds: string[] = [],
|
|
157
152
|
shouldSyncFromScratch: boolean,
|
|
158
|
-
): Promise<Partial<
|
|
153
|
+
): Promise<Partial<SubAccount>[]> {
|
|
159
154
|
const opsPerToken = newOps.reduce((acc, op) => {
|
|
160
155
|
const { accountId: tokenAccountId } = decodeOperationId(op.id);
|
|
161
156
|
const { token } = decodeTokenAccountId(tokenAccountId);
|
|
@@ -164,7 +159,7 @@ async function getSubAccounts(
|
|
|
164
159
|
acc.get(token)?.push(op);
|
|
165
160
|
return acc;
|
|
166
161
|
}, new Map<TokenCurrency, TonOperation[]>());
|
|
167
|
-
const subAccountsPromises: Promise<Partial<
|
|
162
|
+
const subAccountsPromises: Promise<Partial<SubAccount>>[] = [];
|
|
168
163
|
for (const [token, ops] of opsPerToken.entries()) {
|
|
169
164
|
subAccountsPromises.push(
|
|
170
165
|
getSubAccountShape(info, accountId, token, ops, shouldSyncFromScratch),
|
|
@@ -173,7 +168,7 @@ async function getSubAccounts(
|
|
|
173
168
|
return Promise.all(subAccountsPromises);
|
|
174
169
|
}
|
|
175
170
|
|
|
176
|
-
const postSync = (initial:
|
|
171
|
+
const postSync = (initial: Account, synced: Account): Account => {
|
|
177
172
|
// Set of ids from the already existing subAccount from previous sync
|
|
178
173
|
const initialSubAccountsIds = new Set();
|
|
179
174
|
for (const subAccount of initial.subAccounts || []) {
|
|
@@ -211,7 +206,7 @@ const postSync = (initial: TonAccount, synced: TonAccount): TonAccount => {
|
|
|
211
206
|
};
|
|
212
207
|
};
|
|
213
208
|
|
|
214
|
-
function reconciliatePubkey(publicKey?: string, initialAccount?:
|
|
209
|
+
function reconciliatePubkey(publicKey?: string, initialAccount?: Account): string {
|
|
215
210
|
if (publicKey?.length === 64) return publicKey;
|
|
216
211
|
if (initialAccount) {
|
|
217
212
|
if (initialAccount.xpub?.length === 64) return initialAccount.xpub;
|
package/src/types.ts
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
-
Account,
|
|
3
2
|
Operation,
|
|
4
|
-
TokenAccount,
|
|
5
3
|
TransactionCommon,
|
|
6
4
|
TransactionCommonRaw,
|
|
7
5
|
TransactionStatusCommon,
|
|
@@ -45,10 +43,6 @@ export type TonPayloadJettonTransfer = {
|
|
|
45
43
|
customPayload: TonCell | null;
|
|
46
44
|
forwardAmount: bigint;
|
|
47
45
|
forwardPayload: TonCell | null;
|
|
48
|
-
knownJetton: {
|
|
49
|
-
jettonId: number;
|
|
50
|
-
workchain: number;
|
|
51
|
-
} | null;
|
|
52
46
|
};
|
|
53
47
|
|
|
54
48
|
export type TonPayloadNftTransfer = {
|
|
@@ -66,91 +60,7 @@ export type TonPayloadComment = {
|
|
|
66
60
|
text: string;
|
|
67
61
|
};
|
|
68
62
|
|
|
69
|
-
export type
|
|
70
|
-
type: "unsafe";
|
|
71
|
-
message: TonCell;
|
|
72
|
-
};
|
|
73
|
-
|
|
74
|
-
export type TonPayloadJettonBurn = {
|
|
75
|
-
type: "jetton-burn";
|
|
76
|
-
queryId: bigint | null;
|
|
77
|
-
amount: bigint;
|
|
78
|
-
responseDestination: Address;
|
|
79
|
-
customPayload: TonCell | Buffer | null;
|
|
80
|
-
};
|
|
81
|
-
|
|
82
|
-
export type TonPayloadAddWhitelist = {
|
|
83
|
-
type: "add-whitelist";
|
|
84
|
-
queryId: bigint | null;
|
|
85
|
-
address: Address;
|
|
86
|
-
};
|
|
87
|
-
|
|
88
|
-
export type TonPayloadSingleNominatorWithdraw = {
|
|
89
|
-
type: "single-nominator-withdraw";
|
|
90
|
-
queryId: bigint | null;
|
|
91
|
-
amount: bigint;
|
|
92
|
-
};
|
|
93
|
-
|
|
94
|
-
export type TonPayloadSingleNominatorChangeValidator = {
|
|
95
|
-
type: "single-nominator-change-validator";
|
|
96
|
-
queryId: bigint | null;
|
|
97
|
-
address: Address;
|
|
98
|
-
};
|
|
99
|
-
|
|
100
|
-
export type TonPayloadTonStakersDeposit = {
|
|
101
|
-
type: "tonstakers-deposit";
|
|
102
|
-
queryId: bigint | null;
|
|
103
|
-
appId: bigint | null;
|
|
104
|
-
};
|
|
105
|
-
|
|
106
|
-
export type TonPayloadVoteForProposal = {
|
|
107
|
-
type: "vote-for-proposal";
|
|
108
|
-
queryId: bigint | null;
|
|
109
|
-
votingAddress: Address;
|
|
110
|
-
expirationDate: number;
|
|
111
|
-
vote: boolean;
|
|
112
|
-
needConfirmation: boolean;
|
|
113
|
-
};
|
|
114
|
-
|
|
115
|
-
export type TonPayloadChangeDnsRecord = {
|
|
116
|
-
type: "change-dns-record";
|
|
117
|
-
queryId: bigint | null;
|
|
118
|
-
record:
|
|
119
|
-
| {
|
|
120
|
-
type: "wallet";
|
|
121
|
-
value: {
|
|
122
|
-
address: Address;
|
|
123
|
-
capabilities: {
|
|
124
|
-
isWallet: boolean;
|
|
125
|
-
} | null;
|
|
126
|
-
} | null;
|
|
127
|
-
}
|
|
128
|
-
| {
|
|
129
|
-
type: "unknown";
|
|
130
|
-
key: Buffer;
|
|
131
|
-
value: TonCell | null;
|
|
132
|
-
};
|
|
133
|
-
};
|
|
134
|
-
|
|
135
|
-
export type TonPayloadTokenBridgePaySwap = {
|
|
136
|
-
type: "token-bridge-pay-swap";
|
|
137
|
-
queryId: bigint | null;
|
|
138
|
-
swapId: Buffer;
|
|
139
|
-
};
|
|
140
|
-
|
|
141
|
-
export type TonPayloadFormat =
|
|
142
|
-
| TonPayloadComment
|
|
143
|
-
| TonPayloadJettonTransfer
|
|
144
|
-
| TonPayloadNftTransfer
|
|
145
|
-
| TonPayloadUnsafe
|
|
146
|
-
| TonPayloadJettonBurn
|
|
147
|
-
| TonPayloadAddWhitelist
|
|
148
|
-
| TonPayloadSingleNominatorWithdraw
|
|
149
|
-
| TonPayloadSingleNominatorChangeValidator
|
|
150
|
-
| TonPayloadTonStakersDeposit
|
|
151
|
-
| TonPayloadVoteForProposal
|
|
152
|
-
| TonPayloadChangeDnsRecord
|
|
153
|
-
| TonPayloadTokenBridgePaySwap;
|
|
63
|
+
export type TonPayloadFormat = TonPayloadComment | TonPayloadJettonTransfer | TonPayloadNftTransfer;
|
|
154
64
|
|
|
155
65
|
export interface TonTransaction {
|
|
156
66
|
to: Address;
|
|
@@ -170,15 +80,3 @@ export type TonOperationExtra = {
|
|
|
170
80
|
lt: string;
|
|
171
81
|
explorerHash: string;
|
|
172
82
|
};
|
|
173
|
-
|
|
174
|
-
export type KnownJetton = {
|
|
175
|
-
symbol: string;
|
|
176
|
-
masterAddress: Address;
|
|
177
|
-
};
|
|
178
|
-
|
|
179
|
-
export type TonSubAccount = TokenAccount & {
|
|
180
|
-
jettonWallet: string;
|
|
181
|
-
};
|
|
182
|
-
export type TonAccount = Omit<Account, "subAccounts"> & {
|
|
183
|
-
subAccounts?: TonSubAccount[];
|
|
184
|
-
};
|