@ledgerhq/coin-stacks 0.1.1-next.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/.eslintrc.js +20 -0
- package/.turbo/turbo-build.log +4 -0
- package/.unimportedrc.json +31 -0
- package/CHANGELOG.md +11 -0
- package/LICENSE.txt +21 -0
- package/jest.config.js +8 -0
- package/lib/bridge/broadcast.d.ts +4 -0
- package/lib/bridge/broadcast.d.ts.map +1 -0
- package/lib/bridge/broadcast.js +28 -0
- package/lib/bridge/broadcast.js.map +1 -0
- package/lib/bridge/buildOptimisticOperation.d.ts +4 -0
- package/lib/bridge/buildOptimisticOperation.d.ts.map +1 -0
- package/lib/bridge/buildOptimisticOperation.js +34 -0
- package/lib/bridge/buildOptimisticOperation.js.map +1 -0
- package/lib/bridge/createTransaction.d.ts +4 -0
- package/lib/bridge/createTransaction.d.ts.map +1 -0
- package/lib/bridge/createTransaction.js +18 -0
- package/lib/bridge/createTransaction.js.map +1 -0
- package/lib/bridge/deviceTransactionConfig.d.ts +22 -0
- package/lib/bridge/deviceTransactionConfig.d.ts.map +1 -0
- package/lib/bridge/deviceTransactionConfig.js +34 -0
- package/lib/bridge/deviceTransactionConfig.js.map +1 -0
- package/lib/bridge/estimateMaxSpendable.d.ts +4 -0
- package/lib/bridge/estimateMaxSpendable.d.ts.map +1 -0
- package/lib/bridge/estimateMaxSpendable.js +46 -0
- package/lib/bridge/estimateMaxSpendable.js.map +1 -0
- package/lib/bridge/getTransactionStatus.d.ts +4 -0
- package/lib/bridge/getTransactionStatus.d.ts.map +1 -0
- package/lib/bridge/getTransactionStatus.js +60 -0
- package/lib/bridge/getTransactionStatus.js.map +1 -0
- package/lib/bridge/index.d.ts +11 -0
- package/lib/bridge/index.d.ts.map +1 -0
- package/lib/bridge/index.js +56 -0
- package/lib/bridge/index.js.map +1 -0
- package/lib/bridge/prepareTransaction.d.ts +4 -0
- package/lib/bridge/prepareTransaction.d.ts.map +1 -0
- package/lib/bridge/prepareTransaction.js +56 -0
- package/lib/bridge/prepareTransaction.js.map +1 -0
- package/lib/bridge/signOperation.d.ts +5 -0
- package/lib/bridge/signOperation.d.ts.map +1 -0
- package/lib/bridge/signOperation.js +85 -0
- package/lib/bridge/signOperation.js.map +1 -0
- package/lib/bridge/synchronization.d.ts +5 -0
- package/lib/bridge/synchronization.d.ts.map +1 -0
- package/lib/bridge/synchronization.js +62 -0
- package/lib/bridge/synchronization.js.map +1 -0
- package/lib/bridge/transaction.d.ts +14 -0
- package/lib/bridge/transaction.d.ts.map +1 -0
- package/lib/bridge/transaction.js +46 -0
- package/lib/bridge/transaction.js.map +1 -0
- package/lib/bridge/utils/addresses.d.ts +13 -0
- package/lib/bridge/utils/addresses.d.ts.map +1 -0
- package/lib/bridge/utils/addresses.js +15 -0
- package/lib/bridge/utils/addresses.js.map +1 -0
- package/lib/bridge/utils/misc.d.ts +15 -0
- package/lib/bridge/utils/misc.d.ts.map +1 -0
- package/lib/bridge/utils/misc.js +186 -0
- package/lib/bridge/utils/misc.js.map +1 -0
- package/lib/bridge/utils/misc.unit.test.d.ts +2 -0
- package/lib/bridge/utils/misc.unit.test.d.ts.map +1 -0
- package/lib/bridge/utils/misc.unit.test.js +230 -0
- package/lib/bridge/utils/misc.unit.test.js.map +1 -0
- package/lib/config.d.ts +14 -0
- package/lib/config.d.ts.map +1 -0
- package/lib/config.js +16 -0
- package/lib/config.js.map +1 -0
- package/lib/errors.d.ts +4 -0
- package/lib/errors.d.ts.map +1 -0
- package/lib/errors.js +6 -0
- package/lib/errors.js.map +1 -0
- package/lib/index.d.ts +4 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +21 -0
- package/lib/index.js.map +1 -0
- package/lib/network/api.d.ts +11 -0
- package/lib/network/api.d.ts.map +1 -0
- package/lib/network/api.js +139 -0
- package/lib/network/api.js.map +1 -0
- package/lib/network/api.types.d.ts +168 -0
- package/lib/network/api.types.d.ts.map +1 -0
- package/lib/network/api.types.js +9 -0
- package/lib/network/api.types.js.map +1 -0
- package/lib/network/index.d.ts +3 -0
- package/lib/network/index.d.ts.map +1 -0
- package/lib/network/index.js +19 -0
- package/lib/network/index.js.map +1 -0
- package/lib/signer/getAddress.d.ts +6 -0
- package/lib/signer/getAddress.d.ts.map +1 -0
- package/lib/signer/getAddress.js +31 -0
- package/lib/signer/getAddress.js.map +1 -0
- package/lib/signer/index.d.ts +4 -0
- package/lib/signer/index.d.ts.map +1 -0
- package/lib/signer/index.js +23 -0
- package/lib/signer/index.js.map +1 -0
- package/lib/signer/signMessage.d.ts +12 -0
- package/lib/signer/signMessage.d.ts.map +1 -0
- package/lib/signer/signMessage.js +31 -0
- package/lib/signer/signMessage.js.map +1 -0
- package/lib/test/bot-deviceActions.d.ts +4 -0
- package/lib/test/bot-deviceActions.d.ts.map +1 -0
- package/lib/test/bot-deviceActions.js +48 -0
- package/lib/test/bot-deviceActions.js.map +1 -0
- package/lib/test/bot-specs.d.ts +7 -0
- package/lib/test/bot-specs.d.ts.map +1 -0
- package/lib/test/bot-specs.js +73 -0
- package/lib/test/bot-specs.js.map +1 -0
- package/lib/test/bridgeDatasetTest.d.ts +4 -0
- package/lib/test/bridgeDatasetTest.d.ts.map +1 -0
- package/lib/test/bridgeDatasetTest.js +129 -0
- package/lib/test/bridgeDatasetTest.js.map +1 -0
- package/lib/test/cli.d.ts +15 -0
- package/lib/test/cli.d.ts.map +1 -0
- package/lib/test/cli.js +27 -0
- package/lib/test/cli.js.map +1 -0
- package/lib/test/index.d.ts +6 -0
- package/lib/test/index.d.ts.map +1 -0
- package/lib/test/index.js +26 -0
- package/lib/test/index.js.map +1 -0
- package/lib/types/bridge.d.ts +35 -0
- package/lib/types/bridge.d.ts.map +1 -0
- package/lib/types/bridge.js +3 -0
- package/lib/types/bridge.js.map +1 -0
- package/lib/types/index.d.ts +3 -0
- package/lib/types/index.d.ts.map +1 -0
- package/lib/types/index.js +19 -0
- package/lib/types/index.js.map +1 -0
- package/lib/types/signer.d.ts +14 -0
- package/lib/types/signer.d.ts.map +1 -0
- package/lib/types/signer.js +3 -0
- package/lib/types/signer.js.map +1 -0
- package/lib/utils.d.ts +8 -0
- package/lib/utils.d.ts.map +1 -0
- package/lib/utils.js +26 -0
- package/lib/utils.js.map +1 -0
- package/lib-es/bridge/broadcast.d.ts +4 -0
- package/lib-es/bridge/broadcast.d.ts.map +1 -0
- package/lib-es/bridge/broadcast.js +21 -0
- package/lib-es/bridge/broadcast.js.map +1 -0
- package/lib-es/bridge/buildOptimisticOperation.d.ts +4 -0
- package/lib-es/bridge/buildOptimisticOperation.d.ts.map +1 -0
- package/lib-es/bridge/buildOptimisticOperation.js +27 -0
- package/lib-es/bridge/buildOptimisticOperation.js.map +1 -0
- package/lib-es/bridge/createTransaction.d.ts +4 -0
- package/lib-es/bridge/createTransaction.d.ts.map +1 -0
- package/lib-es/bridge/createTransaction.js +11 -0
- package/lib-es/bridge/createTransaction.js.map +1 -0
- package/lib-es/bridge/deviceTransactionConfig.d.ts +22 -0
- package/lib-es/bridge/deviceTransactionConfig.d.ts.map +1 -0
- package/lib-es/bridge/deviceTransactionConfig.js +32 -0
- package/lib-es/bridge/deviceTransactionConfig.js.map +1 -0
- package/lib-es/bridge/estimateMaxSpendable.d.ts +4 -0
- package/lib-es/bridge/estimateMaxSpendable.d.ts.map +1 -0
- package/lib-es/bridge/estimateMaxSpendable.js +39 -0
- package/lib-es/bridge/estimateMaxSpendable.js.map +1 -0
- package/lib-es/bridge/getTransactionStatus.d.ts +4 -0
- package/lib-es/bridge/getTransactionStatus.d.ts.map +1 -0
- package/lib-es/bridge/getTransactionStatus.js +53 -0
- package/lib-es/bridge/getTransactionStatus.js.map +1 -0
- package/lib-es/bridge/index.d.ts +11 -0
- package/lib-es/bridge/index.d.ts.map +1 -0
- package/lib-es/bridge/index.js +48 -0
- package/lib-es/bridge/index.js.map +1 -0
- package/lib-es/bridge/prepareTransaction.d.ts +4 -0
- package/lib-es/bridge/prepareTransaction.d.ts.map +1 -0
- package/lib-es/bridge/prepareTransaction.js +49 -0
- package/lib-es/bridge/prepareTransaction.js.map +1 -0
- package/lib-es/bridge/signOperation.d.ts +5 -0
- package/lib-es/bridge/signOperation.d.ts.map +1 -0
- package/lib-es/bridge/signOperation.js +78 -0
- package/lib-es/bridge/signOperation.js.map +1 -0
- package/lib-es/bridge/synchronization.d.ts +5 -0
- package/lib-es/bridge/synchronization.d.ts.map +1 -0
- package/lib-es/bridge/synchronization.js +55 -0
- package/lib-es/bridge/synchronization.js.map +1 -0
- package/lib-es/bridge/transaction.d.ts +14 -0
- package/lib-es/bridge/transaction.d.ts.map +1 -0
- package/lib-es/bridge/transaction.js +38 -0
- package/lib-es/bridge/transaction.js.map +1 -0
- package/lib-es/bridge/utils/addresses.d.ts +13 -0
- package/lib-es/bridge/utils/addresses.d.ts.map +1 -0
- package/lib-es/bridge/utils/addresses.js +11 -0
- package/lib-es/bridge/utils/addresses.js.map +1 -0
- package/lib-es/bridge/utils/misc.d.ts +15 -0
- package/lib-es/bridge/utils/misc.d.ts.map +1 -0
- package/lib-es/bridge/utils/misc.js +176 -0
- package/lib-es/bridge/utils/misc.js.map +1 -0
- package/lib-es/bridge/utils/misc.unit.test.d.ts +2 -0
- package/lib-es/bridge/utils/misc.unit.test.d.ts.map +1 -0
- package/lib-es/bridge/utils/misc.unit.test.js +228 -0
- package/lib-es/bridge/utils/misc.unit.test.js.map +1 -0
- package/lib-es/config.d.ts +14 -0
- package/lib-es/config.d.ts.map +1 -0
- package/lib-es/config.js +11 -0
- package/lib-es/config.js.map +1 -0
- package/lib-es/errors.d.ts +4 -0
- package/lib-es/errors.d.ts.map +1 -0
- package/lib-es/errors.js +3 -0
- package/lib-es/errors.js.map +1 -0
- package/lib-es/index.d.ts +4 -0
- package/lib-es/index.d.ts.map +1 -0
- package/lib-es/index.js +3 -0
- package/lib-es/index.js.map +1 -0
- package/lib-es/network/api.d.ts +11 -0
- package/lib-es/network/api.d.ts.map +1 -0
- package/lib-es/network/api.js +124 -0
- package/lib-es/network/api.js.map +1 -0
- package/lib-es/network/api.types.d.ts +168 -0
- package/lib-es/network/api.types.d.ts.map +1 -0
- package/lib-es/network/api.types.js +6 -0
- package/lib-es/network/api.types.js.map +1 -0
- package/lib-es/network/index.d.ts +3 -0
- package/lib-es/network/index.d.ts.map +1 -0
- package/lib-es/network/index.js +3 -0
- package/lib-es/network/index.js.map +1 -0
- package/lib-es/signer/getAddress.d.ts +6 -0
- package/lib-es/signer/getAddress.d.ts.map +1 -0
- package/lib-es/signer/getAddress.js +29 -0
- package/lib-es/signer/getAddress.js.map +1 -0
- package/lib-es/signer/index.d.ts +4 -0
- package/lib-es/signer/index.d.ts.map +1 -0
- package/lib-es/signer/index.js +4 -0
- package/lib-es/signer/index.js.map +1 -0
- package/lib-es/signer/signMessage.d.ts +12 -0
- package/lib-es/signer/signMessage.d.ts.map +1 -0
- package/lib-es/signer/signMessage.js +27 -0
- package/lib-es/signer/signMessage.js.map +1 -0
- package/lib-es/test/bot-deviceActions.d.ts +4 -0
- package/lib-es/test/bot-deviceActions.d.ts.map +1 -0
- package/lib-es/test/bot-deviceActions.js +45 -0
- package/lib-es/test/bot-deviceActions.js.map +1 -0
- package/lib-es/test/bot-specs.d.ts +7 -0
- package/lib-es/test/bot-specs.d.ts.map +1 -0
- package/lib-es/test/bot-specs.js +68 -0
- package/lib-es/test/bot-specs.js.map +1 -0
- package/lib-es/test/bridgeDatasetTest.d.ts +4 -0
- package/lib-es/test/bridgeDatasetTest.d.ts.map +1 -0
- package/lib-es/test/bridgeDatasetTest.js +126 -0
- package/lib-es/test/bridgeDatasetTest.js.map +1 -0
- package/lib-es/test/cli.d.ts +15 -0
- package/lib-es/test/cli.d.ts.map +1 -0
- package/lib-es/test/cli.js +21 -0
- package/lib-es/test/cli.js.map +1 -0
- package/lib-es/test/index.d.ts +6 -0
- package/lib-es/test/index.d.ts.map +1 -0
- package/lib-es/test/index.js +6 -0
- package/lib-es/test/index.js.map +1 -0
- package/lib-es/types/bridge.d.ts +35 -0
- package/lib-es/types/bridge.d.ts.map +1 -0
- package/lib-es/types/bridge.js +2 -0
- package/lib-es/types/bridge.js.map +1 -0
- package/lib-es/types/index.d.ts +3 -0
- package/lib-es/types/index.d.ts.map +1 -0
- package/lib-es/types/index.js +3 -0
- package/lib-es/types/index.js.map +1 -0
- package/lib-es/types/signer.d.ts +14 -0
- package/lib-es/types/signer.d.ts.map +1 -0
- package/lib-es/types/signer.js +2 -0
- package/lib-es/types/signer.js.map +1 -0
- package/lib-es/utils.d.ts +8 -0
- package/lib-es/utils.d.ts.map +1 -0
- package/lib-es/utils.js +17 -0
- package/lib-es/utils.js.map +1 -0
- package/package.json +136 -0
- package/src/bridge/broadcast.ts +18 -0
- package/src/bridge/buildOptimisticOperation.ts +34 -0
- package/src/bridge/createTransaction.ts +13 -0
- package/src/bridge/deviceTransactionConfig.ts +57 -0
- package/src/bridge/estimateMaxSpendable.ts +50 -0
- package/src/bridge/getTransactionStatus.ts +56 -0
- package/src/bridge/index.ts +64 -0
- package/src/bridge/prepareTransaction.ts +60 -0
- package/src/bridge/signOperation.ts +91 -0
- package/src/bridge/synchronization.ts +55 -0
- package/src/bridge/transaction.ts +75 -0
- package/src/bridge/utils/addresses.ts +23 -0
- package/src/bridge/utils/misc.ts +274 -0
- package/src/bridge/utils/misc.unit.test.ts +237 -0
- package/src/config.ts +26 -0
- package/src/errors.ts +3 -0
- package/src/index.ts +4 -0
- package/src/network/api.ts +173 -0
- package/src/network/api.types.ts +180 -0
- package/src/network/index.ts +2 -0
- package/src/signer/getAddress.ts +27 -0
- package/src/signer/index.ts +4 -0
- package/src/signer/signMessage.ts +26 -0
- package/src/test/bot-deviceActions.ts +47 -0
- package/src/test/bot-specs.ts +82 -0
- package/src/test/bridgeDatasetTest.ts +134 -0
- package/src/test/cli.ts +38 -0
- package/src/test/index.ts +5 -0
- package/src/types/bridge.ts +49 -0
- package/src/types/index.ts +2 -0
- package/src/types/signer.ts +16 -0
- package/src/utils.ts +24 -0
- package/tsconfig.json +14 -0
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
import { mapPendingTxToOps, mapTxToOps } from "./misc";
|
|
2
|
+
import { encodeAccountId } from "@ledgerhq/coin-framework/account/index";
|
|
3
|
+
import { TransactionResponse, fetchFullTxs } from "../../network/index";
|
|
4
|
+
import { Operation } from "@ledgerhq/types-live";
|
|
5
|
+
|
|
6
|
+
const Address = "SP26AZ1JSFZQ82VH5W2NJSB2QW15EW5YKT6WMD69J";
|
|
7
|
+
|
|
8
|
+
const mempoolTransfer = {
|
|
9
|
+
tx_id: "0x628369d2c9b49f0ec95531fe1e6a39141573117f3dd047fca65ff5e4058fbc55",
|
|
10
|
+
nonce: 32,
|
|
11
|
+
fee_rate: "487",
|
|
12
|
+
sender_address: "SPNX9YY3T4GR4XDSNRVWB2MDQVCTJMP3BGT7VCZA",
|
|
13
|
+
sponsored: false,
|
|
14
|
+
post_condition_mode: "deny",
|
|
15
|
+
post_conditions: [],
|
|
16
|
+
anchor_mode: "any",
|
|
17
|
+
tx_status: "pending",
|
|
18
|
+
receipt_time: 1714554733,
|
|
19
|
+
receipt_time_iso: "2024-05-01T09:12:13.000Z",
|
|
20
|
+
tx_type: "token_transfer",
|
|
21
|
+
token_transfer: {
|
|
22
|
+
recipient_address: "SP26AZ1JSFZQ82VH5W2NJSB2QW15EW5YKT6WMD69J",
|
|
23
|
+
amount: "9523",
|
|
24
|
+
memo: "0x00000000000000000000000000000000000000000000000000000000000000000000",
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const sendManyTransfer = {
|
|
29
|
+
tx: {
|
|
30
|
+
tx_id: "0x68bdba90cdbd4e2e112fd008c8c396bd4ca365e482dc68fe25c7aeb5d8eb4c3f",
|
|
31
|
+
nonce: 18,
|
|
32
|
+
fee_rate: "500000",
|
|
33
|
+
sender_address: "SP26AZ1JSFZQ82VH5W2NJSB2QW15EW5YKT6WMD69J",
|
|
34
|
+
sponsored: false,
|
|
35
|
+
post_condition_mode: "deny",
|
|
36
|
+
post_conditions: [
|
|
37
|
+
{
|
|
38
|
+
type: "stx",
|
|
39
|
+
condition_code: "sent_equal_to",
|
|
40
|
+
amount: "345000",
|
|
41
|
+
principal: {
|
|
42
|
+
type_id: "principal_standard",
|
|
43
|
+
address: "SP26AZ1JSFZQ82VH5W2NJSB2QW15EW5YKT6WMD69J",
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
],
|
|
47
|
+
anchor_mode: "any",
|
|
48
|
+
is_unanchored: false,
|
|
49
|
+
block_hash: "0xc8dd294972d86b09d4226fe99f8bfcdf2c55a7280ca87b7dc8b0fd119a7059f1",
|
|
50
|
+
parent_block_hash: "0xc8f2c105e37544ce27a3a470651d950c6e8fe5f6c072aef653e7ea1fbd97a429",
|
|
51
|
+
block_height: 137791,
|
|
52
|
+
block_time: 1706802438,
|
|
53
|
+
block_time_iso: "2024-02-01T15:47:18.000Z",
|
|
54
|
+
burn_block_time: 1706802438,
|
|
55
|
+
burn_block_time_iso: "2024-02-01T15:47:18.000Z",
|
|
56
|
+
parent_burn_block_time: 1706801557,
|
|
57
|
+
parent_burn_block_time_iso: "2024-02-01T15:32:37.000Z",
|
|
58
|
+
canonical: true,
|
|
59
|
+
tx_index: 121,
|
|
60
|
+
tx_status: "success",
|
|
61
|
+
tx_result: {
|
|
62
|
+
hex: "0x0703",
|
|
63
|
+
repr: "(ok true)",
|
|
64
|
+
},
|
|
65
|
+
microblock_hash: "0x",
|
|
66
|
+
microblock_sequence: 2147483647,
|
|
67
|
+
microblock_canonical: true,
|
|
68
|
+
event_count: 6,
|
|
69
|
+
events: [],
|
|
70
|
+
execution_cost_read_count: 6,
|
|
71
|
+
execution_cost_read_length: 737,
|
|
72
|
+
execution_cost_runtime: 151010,
|
|
73
|
+
execution_cost_write_count: 3,
|
|
74
|
+
execution_cost_write_length: 3,
|
|
75
|
+
tx_type: "contract_call",
|
|
76
|
+
contract_call: {
|
|
77
|
+
contract_id: "SP3FBR2AGK5H9QBDH3EEN6DF8EK8JY7RX8QJ5SVTE.send-many-memo",
|
|
78
|
+
function_name: "send-many",
|
|
79
|
+
function_signature: "",
|
|
80
|
+
function_args: [
|
|
81
|
+
{
|
|
82
|
+
hex: "0x0b000000030c00000003046d656d6f020000000333333302746f05162bd4fbc3d1218275b9ae37c58a8dbed9a952c35c047573747801000000000000000000000000000027100c00000003046d656d6f020000000334343402746f051601a0369ffa2faa8fe74faada53e2e3d215b4d42a047573747801000000000000000000000000000088b80c00000003046d656d6f020000000335353502746f051660cc6b74d6d317918d0a7717069da56d775d817e047573747801000000000000000000000000000493e0",
|
|
83
|
+
repr: "(list (tuple (memo 0x333333) (to 'SPNX9YY3T4GR4XDSNRVWB2MDQVCTJMP3BGT7VCZA) (ustx u10000)) (tuple (memo 0x343434) (to 'SPT0DMZZ8QTN3Z79YNDMMZ2WF91BD6M59S9Z10Y) (ustx u35000)) (tuple (memo 0x353535) (to 'SP1GCRTVMTV9HF4CD19VHE1MXMNPQEQC1FT6YWF5Y) (ustx u300000)))",
|
|
84
|
+
name: "",
|
|
85
|
+
type: "(list 3 (tuple (memo (buff 3)) (to principal) (ustx uint)))",
|
|
86
|
+
},
|
|
87
|
+
],
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
stx_sent: "845000",
|
|
91
|
+
stx_received: "0",
|
|
92
|
+
events: {
|
|
93
|
+
stx: {
|
|
94
|
+
transfer: 3,
|
|
95
|
+
mint: 0,
|
|
96
|
+
burn: 0,
|
|
97
|
+
},
|
|
98
|
+
ft: {
|
|
99
|
+
transfer: 0,
|
|
100
|
+
mint: 0,
|
|
101
|
+
burn: 0,
|
|
102
|
+
},
|
|
103
|
+
nft: {
|
|
104
|
+
transfer: 0,
|
|
105
|
+
mint: 0,
|
|
106
|
+
burn: 0,
|
|
107
|
+
},
|
|
108
|
+
},
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
const basicTransfer = {
|
|
112
|
+
tx: {
|
|
113
|
+
tx_id: "0x84254bb1e50b9e4f1dd48161ba5e87dff4ba8718117e8c364769067614dfb99a",
|
|
114
|
+
nonce: 22,
|
|
115
|
+
fee_rate: "125250",
|
|
116
|
+
sender_address: "SP26AZ1JSFZQ82VH5W2NJSB2QW15EW5YKT6WMD69J",
|
|
117
|
+
sponsored: false,
|
|
118
|
+
post_condition_mode: "deny",
|
|
119
|
+
post_conditions: [],
|
|
120
|
+
anchor_mode: "any",
|
|
121
|
+
is_unanchored: false,
|
|
122
|
+
block_hash: "0xd3272fbbc264eec8f8b7857541d7a5e6c043b54dd799274544a72d185dc34f1d",
|
|
123
|
+
parent_block_hash: "0x7bc3a3adae166f4a876697ad4c4f924d29dcea2c84607fc7765c0ed0855c3e90",
|
|
124
|
+
block_height: 151738,
|
|
125
|
+
block_time: 1716831904,
|
|
126
|
+
block_time_iso: "2024-05-27T17:45:04.000Z",
|
|
127
|
+
burn_block_time: 1716831849,
|
|
128
|
+
burn_block_time_iso: "2024-05-27T17:44:09.000Z",
|
|
129
|
+
parent_burn_block_time: 1716831377,
|
|
130
|
+
parent_burn_block_time_iso: "2024-05-27T17:36:17.000Z",
|
|
131
|
+
canonical: true,
|
|
132
|
+
tx_index: 29,
|
|
133
|
+
tx_status: "success",
|
|
134
|
+
tx_result: {
|
|
135
|
+
hex: "0x0703",
|
|
136
|
+
repr: "(ok true)",
|
|
137
|
+
},
|
|
138
|
+
microblock_hash: "0x",
|
|
139
|
+
microblock_sequence: 2147483647,
|
|
140
|
+
microblock_canonical: true,
|
|
141
|
+
event_count: 1,
|
|
142
|
+
events: [],
|
|
143
|
+
execution_cost_read_count: 0,
|
|
144
|
+
execution_cost_read_length: 0,
|
|
145
|
+
execution_cost_runtime: 0,
|
|
146
|
+
execution_cost_write_count: 0,
|
|
147
|
+
execution_cost_write_length: 0,
|
|
148
|
+
tx_type: "token_transfer",
|
|
149
|
+
token_transfer: {
|
|
150
|
+
recipient_address: "SPNX9YY3T4GR4XDSNRVWB2MDQVCTJMP3BGT7VCZA",
|
|
151
|
+
amount: "827695",
|
|
152
|
+
memo: "0x31323333333334000000000000000000000000000000000000000000000000000000",
|
|
153
|
+
},
|
|
154
|
+
},
|
|
155
|
+
stx_sent: "952945",
|
|
156
|
+
stx_received: "0",
|
|
157
|
+
events: {
|
|
158
|
+
stx: {
|
|
159
|
+
transfer: 1,
|
|
160
|
+
mint: 0,
|
|
161
|
+
burn: 0,
|
|
162
|
+
},
|
|
163
|
+
ft: {
|
|
164
|
+
transfer: 0,
|
|
165
|
+
mint: 0,
|
|
166
|
+
burn: 0,
|
|
167
|
+
},
|
|
168
|
+
nft: {
|
|
169
|
+
transfer: 0,
|
|
170
|
+
mint: 0,
|
|
171
|
+
burn: 0,
|
|
172
|
+
},
|
|
173
|
+
},
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
describe("operation building from raw", () => {
|
|
177
|
+
test("map raw transaction to op", async () => {
|
|
178
|
+
const accountId = encodeAccountId({
|
|
179
|
+
type: "js",
|
|
180
|
+
version: "2",
|
|
181
|
+
currencyId: "stacks",
|
|
182
|
+
xpubOrAddress: "",
|
|
183
|
+
derivationMode: "stacks_wallet",
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
// Contains operations for txn of type token_transfer
|
|
187
|
+
const operations = ([sendManyTransfer, basicTransfer] as any).flatMap(
|
|
188
|
+
mapTxToOps(accountId, Address),
|
|
189
|
+
);
|
|
190
|
+
|
|
191
|
+
expect(operations.length).toBe(2);
|
|
192
|
+
|
|
193
|
+
const opSenMany = operations[0];
|
|
194
|
+
const opBasic = operations[1];
|
|
195
|
+
|
|
196
|
+
expect(opSenMany.type).toBe("OUT");
|
|
197
|
+
expect(opSenMany.internalOperations).toHaveLength(3);
|
|
198
|
+
expect(opSenMany.senders).toHaveLength(1);
|
|
199
|
+
expect(opSenMany.recipients).toHaveLength(0);
|
|
200
|
+
|
|
201
|
+
expect(opBasic.type).toBe("OUT");
|
|
202
|
+
expect(opBasic.internalOperations).toBeUndefined();
|
|
203
|
+
expect(opBasic.senders).toHaveLength(1);
|
|
204
|
+
expect(opBasic.recipients).toHaveLength(1);
|
|
205
|
+
});
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
test("convert raw transactions to live operations", async () => {
|
|
209
|
+
const rawTxs: TransactionResponse[] = await fetchFullTxs(Address);
|
|
210
|
+
const operations: Operation[] = rawTxs.flatMap(mapTxToOps("dummyAccountID", Address));
|
|
211
|
+
|
|
212
|
+
expect(operations).toBeDefined();
|
|
213
|
+
expect(operations.length).toBeGreaterThan(0);
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
describe("operation building from mempool raw", () => {
|
|
217
|
+
test("map raw mempool transaction to op", async () => {
|
|
218
|
+
const accountId = encodeAccountId({
|
|
219
|
+
type: "js",
|
|
220
|
+
version: "2",
|
|
221
|
+
currencyId: "stacks",
|
|
222
|
+
xpubOrAddress: "",
|
|
223
|
+
derivationMode: "stacks_wallet",
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
const address = "SPNX9YY3T4GR4XDSNRVWB2MDQVCTJMP3BGT7VCZA";
|
|
227
|
+
|
|
228
|
+
// Contains operations for txn of type token_transfer
|
|
229
|
+
const operations = [mempoolTransfer].map(mapPendingTxToOps(accountId, address)).flat();
|
|
230
|
+
|
|
231
|
+
expect(operations.length).toBe(1);
|
|
232
|
+
expect(operations[0].type).toBe("OUT");
|
|
233
|
+
expect(operations[0].internalOperations).toBeUndefined();
|
|
234
|
+
expect(operations[0].senders).toHaveLength(1);
|
|
235
|
+
expect(operations[0].recipients).toHaveLength(1);
|
|
236
|
+
});
|
|
237
|
+
});
|
package/src/config.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { CurrencyConfig } from "@ledgerhq/coin-framework/config";
|
|
2
|
+
|
|
3
|
+
export type StacksCoinConfig = () => CurrencyConfig & {
|
|
4
|
+
config_currency_stacks: {
|
|
5
|
+
type: "object";
|
|
6
|
+
default: {
|
|
7
|
+
status: {
|
|
8
|
+
type: "active";
|
|
9
|
+
};
|
|
10
|
+
};
|
|
11
|
+
};
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
let coinConfig: StacksCoinConfig | undefined;
|
|
15
|
+
|
|
16
|
+
export const setCoinConfig = (config: StacksCoinConfig): void => {
|
|
17
|
+
coinConfig = config;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export const getCoinConfig = (): ReturnType<StacksCoinConfig> => {
|
|
21
|
+
if (!coinConfig?.()) {
|
|
22
|
+
throw new Error("Stacks module config not set");
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return coinConfig();
|
|
26
|
+
};
|
package/src/errors.ts
ADDED
package/src/index.ts
ADDED
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import { AxiosRequestConfig, AxiosResponse } from "axios";
|
|
2
|
+
|
|
3
|
+
import { getEnv } from "@ledgerhq/live-env";
|
|
4
|
+
import network from "@ledgerhq/live-network/network";
|
|
5
|
+
import {
|
|
6
|
+
BalanceResponse,
|
|
7
|
+
BroadcastTransactionRequest,
|
|
8
|
+
BroadcastTransactionResponse,
|
|
9
|
+
EstimatedFeesRequest,
|
|
10
|
+
EstimatedFeesResponse,
|
|
11
|
+
GetNonceResponse,
|
|
12
|
+
MempoolResponse,
|
|
13
|
+
MempoolTransaction,
|
|
14
|
+
NetworkStatusResponse,
|
|
15
|
+
TransactionResponse,
|
|
16
|
+
TransactionsResponse,
|
|
17
|
+
} from "./api.types";
|
|
18
|
+
|
|
19
|
+
const getStacksURL = (path?: string): string => {
|
|
20
|
+
const baseUrl = getEnv("API_STACKS_ENDPOINT");
|
|
21
|
+
if (!baseUrl) throw new Error("API base URL not available");
|
|
22
|
+
|
|
23
|
+
return `${baseUrl}${path ? path : ""}`;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const fetch = async <T>(path: string) => {
|
|
27
|
+
const url = getStacksURL(path);
|
|
28
|
+
|
|
29
|
+
// We force data to this way as network func is not using the correct param type. Changing that func will generate errors in other implementations
|
|
30
|
+
const opts: AxiosRequestConfig = {
|
|
31
|
+
method: "GET",
|
|
32
|
+
url,
|
|
33
|
+
};
|
|
34
|
+
const rawResponse = await network(opts);
|
|
35
|
+
|
|
36
|
+
// We force data to this way as network func is not using the correct param type. Changing that func will generate errors in other implementations
|
|
37
|
+
const { data } = rawResponse as AxiosResponse<T>;
|
|
38
|
+
|
|
39
|
+
return data;
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
const send = async <T>(path: string, data: Record<string, any>) => {
|
|
43
|
+
const url = getStacksURL(path);
|
|
44
|
+
|
|
45
|
+
const opts: AxiosRequestConfig = {
|
|
46
|
+
method: "POST",
|
|
47
|
+
url,
|
|
48
|
+
data: JSON.stringify(data),
|
|
49
|
+
headers: { "Content-Type": "application/json" },
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const rawResponse = await network(opts);
|
|
53
|
+
|
|
54
|
+
// We force data to this way as network func is not using generics. Changing that func will generate errors in other implementations
|
|
55
|
+
const { data: responseData } = rawResponse as AxiosResponse<T>;
|
|
56
|
+
|
|
57
|
+
return responseData;
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const sendRaw = async <T>(path: string, data: Buffer) => {
|
|
61
|
+
const url = getStacksURL(path);
|
|
62
|
+
|
|
63
|
+
const opts: AxiosRequestConfig = {
|
|
64
|
+
method: "POST",
|
|
65
|
+
url,
|
|
66
|
+
data,
|
|
67
|
+
headers: { "Content-Type": "application/octet-stream" },
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
const rawResponse = await network(opts);
|
|
71
|
+
|
|
72
|
+
// We force data to this way as network func is not using generics. Changing that func will generate errors in other implementations
|
|
73
|
+
const { data: responseData } = rawResponse as AxiosResponse<T>;
|
|
74
|
+
|
|
75
|
+
return responseData;
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
export const fetchBalances = async (addr: string): Promise<BalanceResponse> => {
|
|
79
|
+
const data = await fetch<BalanceResponse>(`/extended/v1/address/${addr}/stx`);
|
|
80
|
+
return data; // TODO Validate if the response fits this interface
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
export const fetchEstimatedFees = async (
|
|
84
|
+
request: EstimatedFeesRequest,
|
|
85
|
+
): Promise<EstimatedFeesResponse> => {
|
|
86
|
+
const feeRate = await send<EstimatedFeesResponse>(`/v2/fees/transfer`, request);
|
|
87
|
+
return feeRate; // TODO Validate if the response fits this interface
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
export const fetchBlockHeight = async (): Promise<NetworkStatusResponse> => {
|
|
91
|
+
const data = await fetch<NetworkStatusResponse>("/extended");
|
|
92
|
+
return data as NetworkStatusResponse; // TODO Validate if the response fits this interface
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
export const fetchTxs = async (addr: string, offset = 0): Promise<TransactionsResponse> => {
|
|
96
|
+
const limit = 50;
|
|
97
|
+
try {
|
|
98
|
+
const response = await fetch<TransactionsResponse>(
|
|
99
|
+
`/extended/v2/addresses/${addr}/transactions?offset=${offset}&limit=${limit}`,
|
|
100
|
+
);
|
|
101
|
+
return response; // TODO Validate if the response fits this interface
|
|
102
|
+
} catch (e) {
|
|
103
|
+
return { limit, offset, total: 0, results: [] };
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
export const fetchFullTxs = async (addr: string): Promise<TransactionResponse[]> => {
|
|
108
|
+
let qty,
|
|
109
|
+
offset = 0;
|
|
110
|
+
let txs: TransactionResponse[] = [];
|
|
111
|
+
|
|
112
|
+
do {
|
|
113
|
+
const { results, total, limit } = await fetchTxs(addr, offset);
|
|
114
|
+
txs = txs.concat(
|
|
115
|
+
results.filter(t => {
|
|
116
|
+
if (t.tx?.tx_type === "token_transfer") {
|
|
117
|
+
return true;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if (
|
|
121
|
+
t.tx?.tx_type === "contract_call" &&
|
|
122
|
+
t.tx?.contract_call?.function_name === "send-many"
|
|
123
|
+
) {
|
|
124
|
+
return true;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return false;
|
|
128
|
+
}),
|
|
129
|
+
);
|
|
130
|
+
|
|
131
|
+
offset += limit;
|
|
132
|
+
qty = total;
|
|
133
|
+
} while (offset < qty);
|
|
134
|
+
|
|
135
|
+
return txs; // TODO Validate if the response fits this interface
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
export const broadcastTx = async (
|
|
139
|
+
message: BroadcastTransactionRequest,
|
|
140
|
+
): Promise<BroadcastTransactionResponse> => {
|
|
141
|
+
let response = await sendRaw<BroadcastTransactionResponse>(`/v2/transactions`, message);
|
|
142
|
+
|
|
143
|
+
if (response != "") response = `0x${response}`;
|
|
144
|
+
return response; // TODO Validate if the response fits this interface
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
export const fetchMempoolTxs = async (addr: string, offset = 0): Promise<MempoolResponse> => {
|
|
148
|
+
const response = await fetch<MempoolResponse>(
|
|
149
|
+
`/extended/v1/tx/mempool?sender_address=${addr}&offset=${offset}`,
|
|
150
|
+
);
|
|
151
|
+
return response; // TODO Validate if the response fits this interface
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
export const fetchFullMempoolTxs = async (addr: string): Promise<MempoolTransaction[]> => {
|
|
155
|
+
let qty,
|
|
156
|
+
offset = 0;
|
|
157
|
+
let txs: MempoolTransaction[] = [];
|
|
158
|
+
|
|
159
|
+
do {
|
|
160
|
+
const { results, total, limit } = await fetchMempoolTxs(addr, offset);
|
|
161
|
+
txs = txs.concat(results);
|
|
162
|
+
|
|
163
|
+
offset += limit;
|
|
164
|
+
qty = total;
|
|
165
|
+
} while (offset < qty);
|
|
166
|
+
|
|
167
|
+
return txs; // TODO Validate if the response fits this interface
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
export const fetchNonce = async (addr: string): Promise<GetNonceResponse> => {
|
|
171
|
+
const response = await fetch<GetNonceResponse>(`/extended/v1/address/${addr}/nonces`);
|
|
172
|
+
return response; // TODO Validate if the response fits this interface
|
|
173
|
+
};
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import { StacksMainnet, StacksTestnet } from "@stacks/network";
|
|
2
|
+
|
|
3
|
+
export const StacksNetwork = {
|
|
4
|
+
mainnet: new StacksMainnet(),
|
|
5
|
+
testnet: new StacksTestnet(),
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export interface EstimatedFeesRequest {
|
|
9
|
+
to: string;
|
|
10
|
+
from: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export type EstimatedFeesResponse = number;
|
|
14
|
+
|
|
15
|
+
export interface TransactionsResponse {
|
|
16
|
+
limit: number;
|
|
17
|
+
offset: number;
|
|
18
|
+
total: number;
|
|
19
|
+
results: TransactionResponse[];
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface TransactionResponse {
|
|
23
|
+
tx: {
|
|
24
|
+
tx_id: string;
|
|
25
|
+
nonce: number;
|
|
26
|
+
fee_rate: string;
|
|
27
|
+
sender_address: string;
|
|
28
|
+
sponsored: boolean;
|
|
29
|
+
post_condition_mode: string;
|
|
30
|
+
post_conditions: Array<{
|
|
31
|
+
type: string;
|
|
32
|
+
condition_code: string;
|
|
33
|
+
amount: string;
|
|
34
|
+
principal: {
|
|
35
|
+
type_id: string;
|
|
36
|
+
address: string;
|
|
37
|
+
};
|
|
38
|
+
}>;
|
|
39
|
+
anchor_mode: string;
|
|
40
|
+
is_unanchored: boolean;
|
|
41
|
+
block_hash: string;
|
|
42
|
+
parent_block_hash: string;
|
|
43
|
+
block_height: number;
|
|
44
|
+
block_time: number;
|
|
45
|
+
block_time_iso: string;
|
|
46
|
+
burn_block_time: number;
|
|
47
|
+
burn_block_time_iso: string;
|
|
48
|
+
parent_burn_block_time: number;
|
|
49
|
+
parent_burn_block_time_iso: string;
|
|
50
|
+
canonical: boolean;
|
|
51
|
+
tx_index: number;
|
|
52
|
+
tx_status: string;
|
|
53
|
+
tx_result: {
|
|
54
|
+
hex: string;
|
|
55
|
+
repr: string;
|
|
56
|
+
};
|
|
57
|
+
microblock_hash: string;
|
|
58
|
+
microblock_sequence: number;
|
|
59
|
+
microblock_canonical: boolean;
|
|
60
|
+
event_count: number;
|
|
61
|
+
events: Array<any>;
|
|
62
|
+
execution_cost_read_count: number;
|
|
63
|
+
execution_cost_read_length: number;
|
|
64
|
+
execution_cost_runtime: number;
|
|
65
|
+
execution_cost_write_count: number;
|
|
66
|
+
execution_cost_write_length: number;
|
|
67
|
+
tx_type: "token_transfer" | "contract_call";
|
|
68
|
+
token_transfer?: {
|
|
69
|
+
recipient_address: string;
|
|
70
|
+
amount: string;
|
|
71
|
+
memo: string;
|
|
72
|
+
};
|
|
73
|
+
smart_contract?: {
|
|
74
|
+
clarity_version: number;
|
|
75
|
+
contract_id: string;
|
|
76
|
+
source_code: string;
|
|
77
|
+
};
|
|
78
|
+
contract_call?: {
|
|
79
|
+
contract_id: string;
|
|
80
|
+
function_name: string;
|
|
81
|
+
function_signature: string;
|
|
82
|
+
function_args: Array<{
|
|
83
|
+
hex: string;
|
|
84
|
+
repr: string;
|
|
85
|
+
name: string;
|
|
86
|
+
type: string;
|
|
87
|
+
}>;
|
|
88
|
+
};
|
|
89
|
+
};
|
|
90
|
+
stx_sent: string;
|
|
91
|
+
stx_received: string;
|
|
92
|
+
events: {
|
|
93
|
+
stx: {
|
|
94
|
+
transfer: number;
|
|
95
|
+
mint: number;
|
|
96
|
+
burn: number;
|
|
97
|
+
};
|
|
98
|
+
ft: {
|
|
99
|
+
transfer: number;
|
|
100
|
+
mint: number;
|
|
101
|
+
burn: number;
|
|
102
|
+
};
|
|
103
|
+
nft: {
|
|
104
|
+
transfer: number;
|
|
105
|
+
mint: number;
|
|
106
|
+
burn: number;
|
|
107
|
+
};
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export interface DecodedSendManyFunctionArgsCV {
|
|
112
|
+
type: string;
|
|
113
|
+
value: Array<{
|
|
114
|
+
type: string;
|
|
115
|
+
value: {
|
|
116
|
+
memo?: {
|
|
117
|
+
type: string;
|
|
118
|
+
value: string;
|
|
119
|
+
};
|
|
120
|
+
to: {
|
|
121
|
+
type: string;
|
|
122
|
+
value: string;
|
|
123
|
+
};
|
|
124
|
+
ustx: {
|
|
125
|
+
type: string;
|
|
126
|
+
value: string;
|
|
127
|
+
};
|
|
128
|
+
};
|
|
129
|
+
}>;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export interface MempoolTransaction {
|
|
133
|
+
tx_id: string;
|
|
134
|
+
nonce: number;
|
|
135
|
+
tx_status: string;
|
|
136
|
+
tx_type: string;
|
|
137
|
+
receipt_time: number;
|
|
138
|
+
receipt_time_iso: string;
|
|
139
|
+
fee_rate: string;
|
|
140
|
+
sender_address: string;
|
|
141
|
+
sponsored: boolean;
|
|
142
|
+
token_transfer: {
|
|
143
|
+
recipient_address: string;
|
|
144
|
+
amount: string;
|
|
145
|
+
memo: string;
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
export interface MempoolResponse {
|
|
150
|
+
limit: number;
|
|
151
|
+
offset: number;
|
|
152
|
+
total: number;
|
|
153
|
+
results: MempoolTransaction[];
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
export interface GetNonceResponse {
|
|
157
|
+
last_mempool_tx_nonce: number;
|
|
158
|
+
last_executed_tx_nonce: number;
|
|
159
|
+
possible_next_nonce: number;
|
|
160
|
+
detected_missing_nonces: number[];
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
export interface BalanceResponse {
|
|
164
|
+
balance: string;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
export interface NetworkStatusResponse {
|
|
168
|
+
server_version: string;
|
|
169
|
+
status: string;
|
|
170
|
+
chain_tip: BlockIdentifier;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
export type BroadcastTransactionRequest = Buffer;
|
|
174
|
+
|
|
175
|
+
export type BroadcastTransactionResponse = string;
|
|
176
|
+
|
|
177
|
+
interface BlockIdentifier {
|
|
178
|
+
block_height: number;
|
|
179
|
+
block_hash: string;
|
|
180
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { GetAddressFn } from "@ledgerhq/coin-framework/bridge/getAddressWrapper";
|
|
2
|
+
import { GetAddressOptions } from "@ledgerhq/coin-framework/derivation";
|
|
3
|
+
import { SignerContext } from "@ledgerhq/coin-framework/signer";
|
|
4
|
+
import { AddressVersion } from "@stacks/transactions/dist";
|
|
5
|
+
import { StacksSigner } from "../types";
|
|
6
|
+
import { getPath, throwIfError } from "../utils";
|
|
7
|
+
|
|
8
|
+
const resolver = (signerContext: SignerContext<StacksSigner>): GetAddressFn => {
|
|
9
|
+
return async (deviceId: string, { path, verify }: GetAddressOptions) => {
|
|
10
|
+
const r = await signerContext(deviceId, async signer => {
|
|
11
|
+
const r = verify
|
|
12
|
+
? await signer.showAddressAndPubKey(getPath(path), AddressVersion.MainnetSingleSig)
|
|
13
|
+
: await signer.getAddressAndPubKey(getPath(path), AddressVersion.MainnetSingleSig);
|
|
14
|
+
return r;
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
throwIfError(r);
|
|
18
|
+
|
|
19
|
+
return {
|
|
20
|
+
path,
|
|
21
|
+
address: r.address,
|
|
22
|
+
publicKey: r.publicKey.toString("hex"),
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export default resolver;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { getBufferFromString, getPath, throwIfError } from "../utils";
|
|
2
|
+
|
|
3
|
+
import { SignerContext } from "@ledgerhq/coin-framework/signer";
|
|
4
|
+
import { Account, AnyMessage } from "@ledgerhq/types-live";
|
|
5
|
+
import { StacksSigner } from "../types";
|
|
6
|
+
|
|
7
|
+
export const signMessage =
|
|
8
|
+
(signerContext: SignerContext<StacksSigner>) =>
|
|
9
|
+
async (deviceId: string, account: Account, { message }: AnyMessage) => {
|
|
10
|
+
if (!message) throw new Error(`Message cannot be empty`);
|
|
11
|
+
if (typeof message !== "string") throw new Error(`Message must be string`);
|
|
12
|
+
|
|
13
|
+
const r = await signerContext(deviceId, signer =>
|
|
14
|
+
signer.sign(getPath(account.freshAddressPath), getBufferFromString(message)),
|
|
15
|
+
);
|
|
16
|
+
throwIfError(r);
|
|
17
|
+
|
|
18
|
+
return {
|
|
19
|
+
rsv: {
|
|
20
|
+
r: r.signatureCompact.slice(0, 32).toString("hex"),
|
|
21
|
+
s: r.signatureCompact.slice(32, 64).toString("hex"),
|
|
22
|
+
v: parseInt(r.signatureCompact.slice(64, 65).toString("hex"), 16),
|
|
23
|
+
},
|
|
24
|
+
signature: `0x${r.signatureVRS.toString("hex")}`,
|
|
25
|
+
};
|
|
26
|
+
};
|