@ledgerhq/coin-sui 0.15.0-nightly.3 → 0.15.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 +23 -16
- package/index.d.ts +0 -0
- package/lib/api/index.js +2 -7
- package/lib/api/index.js.map +1 -1
- package/lib/api/index.test.js +1 -1
- package/lib/api/index.test.js.map +1 -1
- package/lib/logic/craftTransaction.d.ts +1 -1
- package/lib/logic/craftTransaction.d.ts.map +1 -1
- package/lib/logic/craftTransaction.integration.test.js +0 -38
- package/lib/logic/craftTransaction.integration.test.js.map +1 -1
- package/lib/logic/craftTransaction.js +4 -3
- package/lib/logic/craftTransaction.js.map +1 -1
- package/lib/logic/craftTransaction.test.js +5 -5
- package/lib/logic/craftTransaction.test.js.map +1 -1
- package/lib/logic/estimateFees.integration.test.js +1 -1
- package/lib/network/index.d.ts +1 -1
- package/lib/network/sdk.d.ts +3 -7
- package/lib/network/sdk.d.ts.map +1 -1
- package/lib/network/sdk.integration.test.js +2 -2
- package/lib/network/sdk.integration.test.js.map +1 -1
- package/lib/network/sdk.js +21 -47
- package/lib/network/sdk.js.map +1 -1
- package/lib/network/sdk.test.js +43 -44
- package/lib/network/sdk.test.js.map +1 -1
- package/lib/types/model.d.ts +0 -3
- package/lib/types/model.d.ts.map +1 -1
- package/lib-es/api/index.js +2 -7
- package/lib-es/api/index.js.map +1 -1
- package/lib-es/api/index.test.js +1 -1
- package/lib-es/api/index.test.js.map +1 -1
- package/lib-es/logic/craftTransaction.d.ts +1 -1
- package/lib-es/logic/craftTransaction.d.ts.map +1 -1
- package/lib-es/logic/craftTransaction.integration.test.js +0 -38
- package/lib-es/logic/craftTransaction.integration.test.js.map +1 -1
- package/lib-es/logic/craftTransaction.js +4 -3
- package/lib-es/logic/craftTransaction.js.map +1 -1
- package/lib-es/logic/craftTransaction.test.js +5 -5
- package/lib-es/logic/craftTransaction.test.js.map +1 -1
- package/lib-es/logic/estimateFees.integration.test.js +1 -1
- package/lib-es/network/index.d.ts +1 -1
- package/lib-es/network/sdk.d.ts +3 -7
- package/lib-es/network/sdk.d.ts.map +1 -1
- package/lib-es/network/sdk.integration.test.js +2 -2
- package/lib-es/network/sdk.integration.test.js.map +1 -1
- package/lib-es/network/sdk.js +19 -44
- package/lib-es/network/sdk.js.map +1 -1
- package/lib-es/network/sdk.test.js +43 -44
- package/lib-es/network/sdk.test.js.map +1 -1
- package/lib-es/types/model.d.ts +0 -3
- package/lib-es/types/model.d.ts.map +1 -1
- package/package.json +10 -10
- package/src/api/index.test.ts +1 -1
- package/src/api/index.ts +2 -7
- package/src/logic/craftTransaction.integration.test.ts +0 -48
- package/src/logic/craftTransaction.test.ts +25 -41
- package/src/logic/craftTransaction.ts +20 -25
- package/src/logic/estimateFees.integration.test.ts +1 -1
- package/src/network/sdk.integration.test.ts +2 -2
- package/src/network/sdk.test.ts +71 -81
- package/src/network/sdk.ts +26 -80
- package/src/types/model.ts +0 -4
|
@@ -10,7 +10,7 @@ describe("craftTransaction", () => {
|
|
|
10
10
|
|
|
11
11
|
beforeEach(() => {
|
|
12
12
|
jest.clearAllMocks();
|
|
13
|
-
mockCreateTransaction.mockResolvedValue(
|
|
13
|
+
mockCreateTransaction.mockResolvedValue(mockUnsignedTx);
|
|
14
14
|
});
|
|
15
15
|
|
|
16
16
|
it("should create a transaction with correct parameters", async () => {
|
|
@@ -27,16 +27,12 @@ describe("craftTransaction", () => {
|
|
|
27
27
|
asset: { type: "native" },
|
|
28
28
|
});
|
|
29
29
|
|
|
30
|
-
expect(mockCreateTransaction).toHaveBeenCalledWith(
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
coinType: "0x2::sui::SUI",
|
|
37
|
-
},
|
|
38
|
-
false,
|
|
39
|
-
);
|
|
30
|
+
expect(mockCreateTransaction).toHaveBeenCalledWith(sender, {
|
|
31
|
+
amount: new BigNumber(amount.toString()),
|
|
32
|
+
recipient,
|
|
33
|
+
mode: type,
|
|
34
|
+
coinType: "0x2::sui::SUI",
|
|
35
|
+
});
|
|
40
36
|
expect(result).toEqual({ unsigned: mockUnsignedTx });
|
|
41
37
|
});
|
|
42
38
|
|
|
@@ -54,16 +50,12 @@ describe("craftTransaction", () => {
|
|
|
54
50
|
asset: { type: "native" },
|
|
55
51
|
});
|
|
56
52
|
|
|
57
|
-
expect(mockCreateTransaction).toHaveBeenCalledWith(
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
coinType: "0x2::sui::SUI",
|
|
64
|
-
},
|
|
65
|
-
false,
|
|
66
|
-
);
|
|
53
|
+
expect(mockCreateTransaction).toHaveBeenCalledWith(sender, {
|
|
54
|
+
amount: new BigNumber(amount.toString()),
|
|
55
|
+
recipient,
|
|
56
|
+
mode: type,
|
|
57
|
+
coinType: "0x2::sui::SUI",
|
|
58
|
+
});
|
|
67
59
|
expect(result).toEqual({ unsigned: mockUnsignedTx });
|
|
68
60
|
});
|
|
69
61
|
|
|
@@ -81,16 +73,12 @@ describe("craftTransaction", () => {
|
|
|
81
73
|
asset: { type: "native" },
|
|
82
74
|
});
|
|
83
75
|
|
|
84
|
-
expect(mockCreateTransaction).toHaveBeenCalledWith(
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
coinType: "0x2::sui::SUI",
|
|
91
|
-
},
|
|
92
|
-
false,
|
|
93
|
-
);
|
|
76
|
+
expect(mockCreateTransaction).toHaveBeenCalledWith(sender, {
|
|
77
|
+
amount: new BigNumber(amount.toString()),
|
|
78
|
+
recipient,
|
|
79
|
+
mode: type,
|
|
80
|
+
coinType: "0x2::sui::SUI",
|
|
81
|
+
});
|
|
94
82
|
expect(result).toEqual({ unsigned: mockUnsignedTx });
|
|
95
83
|
});
|
|
96
84
|
|
|
@@ -108,16 +96,12 @@ describe("craftTransaction", () => {
|
|
|
108
96
|
asset: { type: "native" },
|
|
109
97
|
});
|
|
110
98
|
|
|
111
|
-
expect(mockCreateTransaction).toHaveBeenCalledWith(
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
coinType: "0x2::sui::SUI",
|
|
118
|
-
},
|
|
119
|
-
false,
|
|
120
|
-
);
|
|
99
|
+
expect(mockCreateTransaction).toHaveBeenCalledWith(sender, {
|
|
100
|
+
amount: new BigNumber(amount.toString()),
|
|
101
|
+
recipient,
|
|
102
|
+
mode: type,
|
|
103
|
+
coinType: "0x2::sui::SUI",
|
|
104
|
+
});
|
|
121
105
|
expect(result).toEqual({ unsigned: mockUnsignedTx });
|
|
122
106
|
});
|
|
123
107
|
|
|
@@ -4,33 +4,28 @@ import type { SuiTransactionMode, CoreTransaction } from "../types";
|
|
|
4
4
|
import suiAPI from "../network";
|
|
5
5
|
import { DEFAULT_COIN_TYPE } from "../network/sdk";
|
|
6
6
|
|
|
7
|
-
export async function craftTransaction(
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
},
|
|
19
|
-
withObjects: boolean = false,
|
|
20
|
-
): Promise<CoreTransaction> {
|
|
7
|
+
export async function craftTransaction({
|
|
8
|
+
amount,
|
|
9
|
+
asset,
|
|
10
|
+
recipient,
|
|
11
|
+
sender,
|
|
12
|
+
type,
|
|
13
|
+
...extra
|
|
14
|
+
}: TransactionIntent & {
|
|
15
|
+
useAllAmount?: boolean;
|
|
16
|
+
stakedSuiId?: string;
|
|
17
|
+
}): Promise<CoreTransaction> {
|
|
21
18
|
let coinType = DEFAULT_COIN_TYPE;
|
|
22
19
|
if (asset.type === "token" && asset.assetReference) {
|
|
23
20
|
coinType = asset.assetReference;
|
|
24
21
|
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
withObjects,
|
|
35
|
-
);
|
|
22
|
+
const unsigned = await suiAPI.createTransaction(sender, {
|
|
23
|
+
amount: BigNumber(amount.toString()),
|
|
24
|
+
coinType,
|
|
25
|
+
mode: type as SuiTransactionMode,
|
|
26
|
+
recipient,
|
|
27
|
+
...extra,
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
return { unsigned };
|
|
36
31
|
}
|
|
@@ -3,7 +3,7 @@ import { getFullnodeUrl } from "@mysten/sui/client";
|
|
|
3
3
|
import coinConfig from "../config";
|
|
4
4
|
import { estimateFees } from "./estimateFees";
|
|
5
5
|
|
|
6
|
-
const SENDER = "
|
|
6
|
+
const SENDER = "0x6e143fe0a8ca010a86580dafac44298e5b1b7d73efc345356a59a15f0d7824f0";
|
|
7
7
|
const RECIPIENT = "0x33444cf803c690db96527cec67e3c9ab512596f4ba2d4eace43f0b4f716e0164";
|
|
8
8
|
|
|
9
9
|
describe("estimateFees", () => {
|
|
@@ -155,14 +155,14 @@ describe("SUI SDK Integration tests", () => {
|
|
|
155
155
|
recipient: "0x33444cf803c690db96527cec67e3c9ab512596f4ba2d4eace43f0b4f716e0164",
|
|
156
156
|
errors: {},
|
|
157
157
|
};
|
|
158
|
-
const
|
|
158
|
+
const tx = await createTransaction(address, transaction);
|
|
159
159
|
expect(tx).toBeInstanceOf(Uint8Array);
|
|
160
160
|
});
|
|
161
161
|
});
|
|
162
162
|
|
|
163
163
|
describe("paymentInfo", () => {
|
|
164
164
|
test("paymentInfo should return gas budget and fees", async () => {
|
|
165
|
-
const sender = "
|
|
165
|
+
const sender = "0x6e143fe0a8ca010a86580dafac44298e5b1b7d73efc345356a59a15f0d7824f0";
|
|
166
166
|
const fakeTransaction = {
|
|
167
167
|
mode: "send" as const,
|
|
168
168
|
family: "sui" as const,
|
package/src/network/sdk.test.ts
CHANGED
|
@@ -185,7 +185,7 @@ const mockTransaction = {
|
|
|
185
185
|
],
|
|
186
186
|
timestampMs: "1742294454878",
|
|
187
187
|
checkpoint: "313024",
|
|
188
|
-
}
|
|
188
|
+
};
|
|
189
189
|
|
|
190
190
|
const mockApi = new SuiClient({ url: "mock" }) as jest.Mocked<SuiClient>;
|
|
191
191
|
|
|
@@ -254,12 +254,16 @@ describe("SDK Functions", () => {
|
|
|
254
254
|
|
|
255
255
|
test("getOperationType should return IN for incoming tx", () => {
|
|
256
256
|
const address = "0x33444cf803c690db96527cec67e3c9ab512596f4ba2d4eace43f0b4f716e0164";
|
|
257
|
-
expect(sdk.getOperationType(address, mockTransaction)).toBe(
|
|
257
|
+
expect(sdk.getOperationType(address, mockTransaction as SuiTransactionBlockResponse)).toBe(
|
|
258
|
+
"IN",
|
|
259
|
+
);
|
|
258
260
|
});
|
|
259
261
|
|
|
260
262
|
test("getOperationType should return OUT for outgoing tx", () => {
|
|
261
263
|
const address = "0x65449f57946938c84c512732f1d69405d1fce417d9c9894696ddf4522f479e24";
|
|
262
|
-
expect(sdk.getOperationType(address, mockTransaction)).toBe(
|
|
264
|
+
expect(sdk.getOperationType(address, mockTransaction as SuiTransactionBlockResponse)).toBe(
|
|
265
|
+
"OUT",
|
|
266
|
+
);
|
|
263
267
|
});
|
|
264
268
|
|
|
265
269
|
test("getOperationSenders should return sender address", () => {
|
|
@@ -274,12 +278,36 @@ describe("SDK Functions", () => {
|
|
|
274
278
|
).toEqual(["0x6e143fe0a8ca010a86580dafac44298e5b1b7d73efc345356a59a15f0d7824f0"]);
|
|
275
279
|
});
|
|
276
280
|
|
|
281
|
+
test("getOperationAmount should calculate amount correctly for SUI", () => {
|
|
282
|
+
const address = "0x6e143fe0a8ca010a86580dafac44298e5b1b7d73efc345356a59a15f0d7824f0";
|
|
283
|
+
expect(
|
|
284
|
+
sdk.getOperationAmount(
|
|
285
|
+
address,
|
|
286
|
+
mockTransaction as SuiTransactionBlockResponse,
|
|
287
|
+
sdk.DEFAULT_COIN_TYPE,
|
|
288
|
+
),
|
|
289
|
+
).toEqual(new BigNumber("9998990120"));
|
|
290
|
+
});
|
|
291
|
+
|
|
292
|
+
test("getOperationAmount should calculate amount correctly for tokens", () => {
|
|
293
|
+
const address = "0x6e143fe0a8ca010a86580dafac44298e5b1b7d73efc345356a59a15f0d7824f0";
|
|
294
|
+
expect(
|
|
295
|
+
sdk.getOperationAmount(
|
|
296
|
+
address,
|
|
297
|
+
mockTransaction as SuiTransactionBlockResponse,
|
|
298
|
+
"0x123::test::TOKEN",
|
|
299
|
+
),
|
|
300
|
+
).toEqual(new BigNumber("500000"));
|
|
301
|
+
});
|
|
302
|
+
|
|
277
303
|
test("getOperationFee should calculate fee correctly", () => {
|
|
278
|
-
expect(sdk.getOperationFee(mockTransaction)).toEqual(
|
|
304
|
+
expect(sdk.getOperationFee(mockTransaction as SuiTransactionBlockResponse)).toEqual(
|
|
305
|
+
new BigNumber(1009880),
|
|
306
|
+
);
|
|
279
307
|
});
|
|
280
308
|
|
|
281
309
|
test("getOperationDate should return correct date", () => {
|
|
282
|
-
const date = sdk.getOperationDate(mockTransaction);
|
|
310
|
+
const date = sdk.getOperationDate(mockTransaction as SuiTransactionBlockResponse);
|
|
283
311
|
expect(date).toBeDefined();
|
|
284
312
|
expect(date).toBeInstanceOf(Date);
|
|
285
313
|
});
|
|
@@ -449,7 +477,7 @@ describe("SDK Functions", () => {
|
|
|
449
477
|
],
|
|
450
478
|
};
|
|
451
479
|
|
|
452
|
-
const operation = sdk.
|
|
480
|
+
const operation = sdk.transactionToOp(address, tokenTx as SuiTransactionBlockResponse);
|
|
453
481
|
expect(operation.id).toEqual("DhKLpX5kwuKuyRa71RGqpX5EY2M8Efw535ZVXYXsRiDt");
|
|
454
482
|
expect(operation.type).toEqual("IN");
|
|
455
483
|
expect(operation.senders).toEqual([
|
|
@@ -615,34 +643,41 @@ describe("Staking Operations", () => {
|
|
|
615
643
|
});
|
|
616
644
|
|
|
617
645
|
describe("Operation Amount Calculation", () => {
|
|
618
|
-
|
|
646
|
+
test("getOperationAmount should calculate staking amount correctly", () => {
|
|
647
|
+
const address = "0x65449f57946938c84c512732f1d69405d1fce417d9c9894696ddf4522f479e24";
|
|
619
648
|
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
649
|
+
const mockStakingTx = {
|
|
650
|
+
transaction: {
|
|
651
|
+
data: {
|
|
652
|
+
transaction: {
|
|
653
|
+
kind: "ProgrammableTransaction",
|
|
654
|
+
transactions: [
|
|
655
|
+
{
|
|
656
|
+
MoveCall: {
|
|
657
|
+
function: "request_add_stake",
|
|
658
|
+
},
|
|
629
659
|
},
|
|
630
|
-
|
|
631
|
-
|
|
660
|
+
],
|
|
661
|
+
},
|
|
632
662
|
},
|
|
633
663
|
},
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
} as SuiTransactionBlockResponse;
|
|
664
|
+
balanceChanges: [
|
|
665
|
+
{
|
|
666
|
+
owner: { AddressOwner: address },
|
|
667
|
+
coinType: "0x2::sui::SUI",
|
|
668
|
+
amount: "-1000000000",
|
|
669
|
+
},
|
|
670
|
+
],
|
|
671
|
+
} as unknown as SuiTransactionBlockResponse;
|
|
643
672
|
|
|
644
|
-
|
|
645
|
-
|
|
673
|
+
const amount = sdk.getOperationAmount(address, mockStakingTx, sdk.DEFAULT_COIN_TYPE);
|
|
674
|
+
expect(amount).toEqual(new BigNumber("1000000000")); // The function returns minus of the balance change
|
|
675
|
+
});
|
|
676
|
+
|
|
677
|
+
test("getOperationAmount should calculate unstaking amount correctly", () => {
|
|
678
|
+
const address = "0x65449f57946938c84c512732f1d69405d1fce417d9c9894696ddf4522f479e24";
|
|
679
|
+
|
|
680
|
+
const mockUnstakingTx = {
|
|
646
681
|
transaction: {
|
|
647
682
|
data: {
|
|
648
683
|
transaction: {
|
|
@@ -661,59 +696,14 @@ describe("Staking Operations", () => {
|
|
|
661
696
|
{
|
|
662
697
|
owner: { AddressOwner: address },
|
|
663
698
|
coinType: "0x2::sui::SUI",
|
|
664
|
-
amount:
|
|
699
|
+
amount: "0",
|
|
665
700
|
},
|
|
666
701
|
],
|
|
667
|
-
} as SuiTransactionBlockResponse;
|
|
668
|
-
}
|
|
669
|
-
|
|
670
|
-
function bridgeOperationAmount(
|
|
671
|
-
mock: SuiTransactionBlockResponse,
|
|
672
|
-
coinType: string = sdk.DEFAULT_COIN_TYPE,
|
|
673
|
-
) {
|
|
674
|
-
return sdk.getOperationAmount(address, mock, coinType);
|
|
675
|
-
}
|
|
676
|
-
|
|
677
|
-
test("getOperationAmount should calculate staking amount", () =>
|
|
678
|
-
expect(bridgeOperationAmount(mockStakingTx)).toEqual(new BigNumber("1000000000")));
|
|
679
|
-
|
|
680
|
-
test("getOperationAmount should calculate unstaking amount of 1000", () =>
|
|
681
|
-
expect(bridgeOperationAmount(mockUnstakingTx("1000"))).toEqual(new BigNumber("-1000")));
|
|
682
|
-
|
|
683
|
-
test("getOperationAmount should calculate unstaking amount of 0", () =>
|
|
684
|
-
expect(bridgeOperationAmount(mockUnstakingTx("0"))).toEqual(new BigNumber("0")));
|
|
685
|
-
|
|
686
|
-
test("getOperationAmount should calculate amount correctly for SUI", () =>
|
|
687
|
-
expect(bridgeOperationAmount(mockTransaction)).toEqual(new BigNumber("9998990120")));
|
|
688
|
-
|
|
689
|
-
test("getOperationAmount should calculate amount correctly for tokens", () =>
|
|
690
|
-
expect(bridgeOperationAmount(mockTransaction, "0x123::test::TOKEN")).toEqual(
|
|
691
|
-
new BigNumber("500000"),
|
|
692
|
-
));
|
|
693
|
-
|
|
694
|
-
function alpacaOperationAmount(
|
|
695
|
-
mock: SuiTransactionBlockResponse,
|
|
696
|
-
coinType: string = sdk.DEFAULT_COIN_TYPE,
|
|
697
|
-
) {
|
|
698
|
-
return sdk.alpacaGetOperationAmount(address, mock, coinType);
|
|
699
|
-
}
|
|
700
|
-
|
|
701
|
-
test("alpaca getOperationAmount should calculate staking amount", () =>
|
|
702
|
-
expect(alpacaOperationAmount(mockStakingTx)).toEqual(new BigNumber("1000000000")));
|
|
703
|
-
|
|
704
|
-
test("alpaca getOperationAmount should calculate unstaking amount of 1000", () =>
|
|
705
|
-
expect(alpacaOperationAmount(mockUnstakingTx("1000"))).toEqual(new BigNumber("1000")));
|
|
706
|
-
|
|
707
|
-
test("alpaca getOperationAmount should calculate unstaking amount of 0", () =>
|
|
708
|
-
expect(alpacaOperationAmount(mockUnstakingTx("0"))).toEqual(new BigNumber("0")));
|
|
709
|
-
|
|
710
|
-
test("alpaca getOperationAmount should calculate amount correctly for SUI", () =>
|
|
711
|
-
expect(alpacaOperationAmount(mockTransaction)).toEqual(new BigNumber("9998990120")));
|
|
702
|
+
} as unknown as SuiTransactionBlockResponse;
|
|
712
703
|
|
|
713
|
-
|
|
714
|
-
expect(
|
|
715
|
-
|
|
716
|
-
));
|
|
704
|
+
const amount = sdk.getOperationAmount(address, mockUnstakingTx, sdk.DEFAULT_COIN_TYPE);
|
|
705
|
+
expect(amount).toEqual(new BigNumber("0"));
|
|
706
|
+
});
|
|
717
707
|
});
|
|
718
708
|
|
|
719
709
|
describe("Operation Recipients", () => {
|
|
@@ -994,7 +984,7 @@ describe("Staking Operations", () => {
|
|
|
994
984
|
checkpoint: "313024",
|
|
995
985
|
} as unknown as SuiTransactionBlockResponse;
|
|
996
986
|
|
|
997
|
-
const operation = sdk.
|
|
987
|
+
const operation = sdk.transactionToOp(address, mockStakingTx);
|
|
998
988
|
|
|
999
989
|
expect(operation.id).toEqual("delegate_tx_digest_123");
|
|
1000
990
|
expect(operation.type).toEqual("DELEGATE");
|
|
@@ -1045,7 +1035,7 @@ describe("Staking Operations", () => {
|
|
|
1045
1035
|
checkpoint: "313024",
|
|
1046
1036
|
} as unknown as SuiTransactionBlockResponse;
|
|
1047
1037
|
|
|
1048
|
-
const operation = sdk.
|
|
1038
|
+
const operation = sdk.transactionToOp(address, mockUnstakingTx);
|
|
1049
1039
|
|
|
1050
1040
|
expect(operation.id).toEqual("undelegate_tx_digest_456");
|
|
1051
1041
|
expect(operation.type).toEqual("UNDELEGATE");
|
package/src/network/sdk.ts
CHANGED
|
@@ -34,19 +34,13 @@ import uniqBy from "lodash/unionBy";
|
|
|
34
34
|
import { encodeOperationId } from "@ledgerhq/coin-framework/operation";
|
|
35
35
|
import { log } from "@ledgerhq/logs";
|
|
36
36
|
import { makeLRUCache, minutes } from "@ledgerhq/live-network/cache";
|
|
37
|
-
import type {
|
|
38
|
-
Transaction as TransactionType,
|
|
39
|
-
SuiValidator,
|
|
40
|
-
CreateExtrinsicArg,
|
|
41
|
-
CoreTransaction,
|
|
42
|
-
} from "../types";
|
|
37
|
+
import type { Transaction as TransactionType, SuiValidator, CreateExtrinsicArg } from "../types";
|
|
43
38
|
import { ensureAddressFormat } from "../utils";
|
|
44
39
|
import coinConfig from "../config";
|
|
45
40
|
import { getEnv } from "@ledgerhq/live-env";
|
|
46
41
|
import { SUI_SYSTEM_STATE_OBJECT_ID } from "@mysten/sui/utils";
|
|
47
42
|
import { getCurrentSuiPreloadData } from "../bridge/preload";
|
|
48
43
|
import { ONE_SUI } from "../constants";
|
|
49
|
-
import { getInputObjects } from "@mysten/signers/ledger";
|
|
50
44
|
|
|
51
45
|
const apiMap: Record<string, SuiClient> = {};
|
|
52
46
|
type AsyncApiFunction<T> = (api: SuiClient) => Promise<T>;
|
|
@@ -108,31 +102,32 @@ export const getAllBalancesCached = makeLRUCache(
|
|
|
108
102
|
(owner: string) => owner,
|
|
109
103
|
minutes(1),
|
|
110
104
|
);
|
|
111
|
-
|
|
112
|
-
type ProgrammableTransaction = {
|
|
105
|
+
function isStaking(block?: SuiTransactionBlockKind): block is {
|
|
113
106
|
inputs: SuiCallArg[];
|
|
114
107
|
kind: "ProgrammableTransaction";
|
|
115
108
|
transactions: SuiTransaction[];
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
functionName: string,
|
|
120
|
-
block?: SuiTransactionBlockKind,
|
|
121
|
-
): block is ProgrammableTransaction {
|
|
122
|
-
if (block?.kind === "ProgrammableTransaction") {
|
|
109
|
+
} {
|
|
110
|
+
if (!block) return false;
|
|
111
|
+
if (block.kind === "ProgrammableTransaction") {
|
|
123
112
|
const move = block.transactions.find(item => "MoveCall" in item) as any;
|
|
124
|
-
return move?.MoveCall.function ===
|
|
125
|
-
} else {
|
|
126
|
-
return false;
|
|
113
|
+
return move?.MoveCall.function === "request_add_stake";
|
|
127
114
|
}
|
|
115
|
+
return false;
|
|
128
116
|
}
|
|
129
117
|
|
|
130
|
-
function
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
118
|
+
function isUnstaking(block?: SuiTransactionBlockKind): block is {
|
|
119
|
+
inputs: SuiCallArg[];
|
|
120
|
+
kind: "ProgrammableTransaction";
|
|
121
|
+
transactions: SuiTransaction[];
|
|
122
|
+
} {
|
|
123
|
+
if (!block) return false;
|
|
124
|
+
if (block.kind === "ProgrammableTransaction") {
|
|
125
|
+
const move = block.transactions.find(
|
|
126
|
+
item => "MoveCall" in item && item["MoveCall"].function === "request_withdraw_stake",
|
|
127
|
+
) as any;
|
|
128
|
+
return Boolean(move);
|
|
129
|
+
}
|
|
130
|
+
return false;
|
|
136
131
|
}
|
|
137
132
|
|
|
138
133
|
/**
|
|
@@ -341,48 +336,11 @@ export function transactionToOperation(
|
|
|
341
336
|
};
|
|
342
337
|
}
|
|
343
338
|
|
|
344
|
-
// This function is only used by alpaca code path
|
|
345
|
-
// Logic is similar to getOperationAmount, but we guarantee to return a positive amount in any case
|
|
346
|
-
// If there is need to display negative amount for staking or unstaking, the view can handle it based on the type of the operation
|
|
347
|
-
export const alpacaGetOperationAmount = (
|
|
348
|
-
address: string,
|
|
349
|
-
transaction: SuiTransactionBlockResponse,
|
|
350
|
-
coinType: string,
|
|
351
|
-
): BigNumber => {
|
|
352
|
-
const absoluteAmount = (balanceChange: BalanceChange | undefined) =>
|
|
353
|
-
new BigNumber(balanceChange?.amount || 0).abs();
|
|
354
|
-
|
|
355
|
-
const zero = BigNumber(0);
|
|
356
|
-
|
|
357
|
-
const tx = transaction.transaction?.data.transaction;
|
|
358
|
-
|
|
359
|
-
if (isStaking(tx) || isUnstaking(tx)) return absoluteAmount(transaction.balanceChanges?.[0]);
|
|
360
|
-
else {
|
|
361
|
-
return (
|
|
362
|
-
transaction.balanceChanges
|
|
363
|
-
?.filter(
|
|
364
|
-
balanceChange =>
|
|
365
|
-
typeof balanceChange.owner !== "string" &&
|
|
366
|
-
"AddressOwner" in balanceChange.owner &&
|
|
367
|
-
balanceChange.owner.AddressOwner === address &&
|
|
368
|
-
balanceChange.coinType === coinType,
|
|
369
|
-
)
|
|
370
|
-
.map(absoluteAmount)
|
|
371
|
-
.reduce((acc, curr) => acc.plus(curr), zero) || zero
|
|
372
|
-
);
|
|
373
|
-
}
|
|
374
|
-
};
|
|
375
|
-
|
|
376
339
|
/**
|
|
377
|
-
* This function is only used by alpaca code path
|
|
378
|
-
*
|
|
379
340
|
* @returns the operation converted. Note that if param `transaction` was retrieved as an "IN" operations, the type may be converted to "OUT".
|
|
380
341
|
* It happens for most "OUT" operations because the sender receive a new version of the coin objects.
|
|
381
342
|
*/
|
|
382
|
-
export function
|
|
383
|
-
address: string,
|
|
384
|
-
transaction: SuiTransactionBlockResponse,
|
|
385
|
-
): Op {
|
|
343
|
+
export function transactionToOp(address: string, transaction: SuiTransactionBlockResponse): Op {
|
|
386
344
|
const type = getOperationType(address, transaction);
|
|
387
345
|
const coinType = getOperationCoinType(transaction);
|
|
388
346
|
const hash = transaction.digest;
|
|
@@ -401,7 +359,7 @@ export function alpacaTransactionToOp(
|
|
|
401
359
|
recipients: getOperationRecipients(transaction.transaction?.data),
|
|
402
360
|
senders: getOperationSenders(transaction.transaction?.data),
|
|
403
361
|
type,
|
|
404
|
-
value: BigInt(
|
|
362
|
+
value: BigInt(getOperationAmount(address, transaction, coinType).toString()),
|
|
405
363
|
};
|
|
406
364
|
}
|
|
407
365
|
|
|
@@ -612,7 +570,7 @@ export const getListOperations = async (
|
|
|
612
570
|
|
|
613
571
|
const operations = ops.operations
|
|
614
572
|
.sort((a, b) => Number(b.timestampMs) - Number(a.timestampMs))
|
|
615
|
-
.map(t =>
|
|
573
|
+
.map(t => transactionToOp(addr, t));
|
|
616
574
|
|
|
617
575
|
return {
|
|
618
576
|
items: operations,
|
|
@@ -774,15 +732,10 @@ export const getCoinsForAmount = async (
|
|
|
774
732
|
*
|
|
775
733
|
* @param address - The sender's address
|
|
776
734
|
* @param transaction - The transaction details including recipient, amount, and coin type
|
|
777
|
-
* @param withObjects - Return serialized input objects used in the transaction
|
|
778
735
|
* @returns Promise<TransactionBlock> - A built transaction block ready for execution
|
|
779
736
|
*
|
|
780
737
|
*/
|
|
781
|
-
export const createTransaction = async (
|
|
782
|
-
address: string,
|
|
783
|
-
transaction: CreateExtrinsicArg,
|
|
784
|
-
withObjects: boolean = false,
|
|
785
|
-
): Promise<CoreTransaction> =>
|
|
738
|
+
export const createTransaction = async (address: string, transaction: CreateExtrinsicArg) =>
|
|
786
739
|
withApi(async api => {
|
|
787
740
|
const tx = new Transaction();
|
|
788
741
|
tx.setSender(ensureAddressFormat(address));
|
|
@@ -847,14 +800,7 @@ export const createTransaction = async (
|
|
|
847
800
|
}
|
|
848
801
|
}
|
|
849
802
|
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
if (withObjects) {
|
|
853
|
-
const { bcsObjects } = await getInputObjects(tx, api);
|
|
854
|
-
return { unsigned: serialized, objects: bcsObjects as Uint8Array[] };
|
|
855
|
-
}
|
|
856
|
-
|
|
857
|
-
return { unsigned: serialized };
|
|
803
|
+
return tx.build({ client: api });
|
|
858
804
|
});
|
|
859
805
|
|
|
860
806
|
/**
|
|
@@ -862,7 +808,7 @@ export const createTransaction = async (
|
|
|
862
808
|
*/
|
|
863
809
|
export const paymentInfo = async (sender: string, fakeTransaction: TransactionType) =>
|
|
864
810
|
withApi(async api => {
|
|
865
|
-
const
|
|
811
|
+
const txb = await createTransaction(sender, fakeTransaction);
|
|
866
812
|
const dryRunTxResponse = await api.dryRunTransactionBlock({ transactionBlock: txb });
|
|
867
813
|
const fees = getTotalGasUsed(dryRunTxResponse.effects);
|
|
868
814
|
|
package/src/types/model.ts
CHANGED
|
@@ -3,9 +3,5 @@ export type SuiOperationMode = "send";
|
|
|
3
3
|
export type AccountInfoResponse = Record<string, string>;
|
|
4
4
|
|
|
5
5
|
export type CoreTransaction = {
|
|
6
|
-
/** The transaction in a serialized format, ready to be signed. */
|
|
7
6
|
unsigned: Uint8Array;
|
|
8
|
-
|
|
9
|
-
/** The input objects referenced in the transaction, in serialized form.. */
|
|
10
|
-
objects?: Uint8Array[];
|
|
11
7
|
};
|