koilib 7.1.1 → 8.1.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/README.md +31 -0
- package/dist/koinos.js +76 -93
- package/dist/koinos.min.js +1 -1
- package/lib/Contract.d.ts +3 -3
- package/lib/Provider.d.ts +117 -10
- package/lib/Provider.js +51 -1
- package/lib/Provider.js.map +1 -1
- package/lib/Signer.d.ts +7 -80
- package/lib/Signer.js +2 -88
- package/lib/Signer.js.map +1 -1
- package/lib/Transaction.d.ts +18 -8
- package/lib/Transaction.js +23 -4
- package/lib/Transaction.js.map +1 -1
- package/lib/browser/Contract.d.ts +3 -3
- package/lib/browser/Provider.d.ts +117 -10
- package/lib/browser/Provider.js +51 -1
- package/lib/browser/Provider.js.map +1 -1
- package/lib/browser/Signer.d.ts +7 -80
- package/lib/browser/Signer.js +2 -88
- package/lib/browser/Signer.js.map +1 -1
- package/lib/browser/Transaction.d.ts +18 -8
- package/lib/browser/Transaction.js +23 -4
- package/lib/browser/Transaction.js.map +1 -1
- package/lib/browser/interface.d.ts +13 -29
- package/lib/interface.d.ts +13 -29
- package/package.json +1 -1
- package/src/Contract.ts +3 -3
- package/src/Provider.ts +182 -12
- package/src/Signer.ts +6 -131
- package/src/Transaction.ts +29 -8
- package/src/interface.ts +14 -33
package/src/Provider.ts
CHANGED
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
TransactionJsonWait,
|
|
8
8
|
BlockTopology,
|
|
9
9
|
GetBlockOptions,
|
|
10
|
+
BlockReceipt,
|
|
10
11
|
} from "./interface";
|
|
11
12
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
12
13
|
// @ts-ignore
|
|
@@ -14,6 +15,116 @@ import { koinos } from "./protoModules/protocol-proto.js";
|
|
|
14
15
|
import { decodeBase64url, encodeBase64url } from "./utils";
|
|
15
16
|
import { Serializer } from "./Serializer";
|
|
16
17
|
|
|
18
|
+
export interface ProviderInterface {
|
|
19
|
+
call: <T = unknown>(method: string, params: unknown) => Promise<T>;
|
|
20
|
+
getNonce: (
|
|
21
|
+
account: string,
|
|
22
|
+
deserialize?: boolean
|
|
23
|
+
) => Promise<number | string>;
|
|
24
|
+
getNextNonce: (account: string) => Promise<string>;
|
|
25
|
+
getAccountRc: (account: string) => Promise<string>;
|
|
26
|
+
getTransactionsById: (transactionIds: string[]) => Promise<{
|
|
27
|
+
transactions: {
|
|
28
|
+
transaction: TransactionJson;
|
|
29
|
+
containing_blocks: string[];
|
|
30
|
+
}[];
|
|
31
|
+
}>;
|
|
32
|
+
getBlocksById: (
|
|
33
|
+
blockIds: string[],
|
|
34
|
+
opts?: GetBlockOptions
|
|
35
|
+
) => Promise<{
|
|
36
|
+
block_items: {
|
|
37
|
+
block_id: string;
|
|
38
|
+
block_height: string;
|
|
39
|
+
block: BlockJson;
|
|
40
|
+
receipt: BlockReceipt;
|
|
41
|
+
}[];
|
|
42
|
+
}>;
|
|
43
|
+
getHeadInfo: () => Promise<{
|
|
44
|
+
head_block_time: string;
|
|
45
|
+
head_topology: BlockTopology;
|
|
46
|
+
head_state_merkle_root: string;
|
|
47
|
+
last_irreversible_block: string;
|
|
48
|
+
}>;
|
|
49
|
+
getChainId: () => Promise<string>;
|
|
50
|
+
getBlocks: (
|
|
51
|
+
height: number,
|
|
52
|
+
numBlocks?: number,
|
|
53
|
+
idRef?: string,
|
|
54
|
+
opts?: GetBlockOptions
|
|
55
|
+
) => Promise<
|
|
56
|
+
{
|
|
57
|
+
block_id: string;
|
|
58
|
+
block_height: string;
|
|
59
|
+
block: BlockJson;
|
|
60
|
+
receipt: BlockReceipt;
|
|
61
|
+
}[]
|
|
62
|
+
>;
|
|
63
|
+
getBlock: (
|
|
64
|
+
height: number,
|
|
65
|
+
opts?: GetBlockOptions
|
|
66
|
+
) => Promise<{
|
|
67
|
+
block_id: string;
|
|
68
|
+
block_height: string;
|
|
69
|
+
block: BlockJson;
|
|
70
|
+
receipt: BlockReceipt;
|
|
71
|
+
}>;
|
|
72
|
+
wait: (
|
|
73
|
+
txId: string,
|
|
74
|
+
type?: "byTransactionId" | "byBlock",
|
|
75
|
+
timeout?: number
|
|
76
|
+
) => Promise<{
|
|
77
|
+
blockId: string;
|
|
78
|
+
blockNumber?: number;
|
|
79
|
+
}>;
|
|
80
|
+
sendTransaction: (
|
|
81
|
+
transaction: TransactionJson | TransactionJsonWait,
|
|
82
|
+
broadcast?: boolean
|
|
83
|
+
) => Promise<{
|
|
84
|
+
receipt: TransactionReceipt;
|
|
85
|
+
transaction: TransactionJsonWait;
|
|
86
|
+
}>;
|
|
87
|
+
readContract: (operation: CallContractOperationJson) => Promise<{
|
|
88
|
+
result: string;
|
|
89
|
+
logs: string;
|
|
90
|
+
}>;
|
|
91
|
+
invokeSystemCall: <T = Record<string, unknown>>(
|
|
92
|
+
serializer: Serializer,
|
|
93
|
+
nameOrId: string | number,
|
|
94
|
+
args: Record<string, unknown>,
|
|
95
|
+
callerData?: { caller: string; caller_privilege: number }
|
|
96
|
+
) => Promise<T>;
|
|
97
|
+
|
|
98
|
+
// optional functions
|
|
99
|
+
submitBlock?: (block: BlockJson) => Promise<Record<string, never>>;
|
|
100
|
+
getForkHeads?: () => Promise<{
|
|
101
|
+
last_irreversible_block: BlockTopology;
|
|
102
|
+
fork_heads: BlockTopology[];
|
|
103
|
+
}>;
|
|
104
|
+
getResourceLimits?: () => Promise<{
|
|
105
|
+
resource_limit_data: {
|
|
106
|
+
disk_storage_limit: string;
|
|
107
|
+
disk_storage_cost: string;
|
|
108
|
+
network_bandwidth_limit: string;
|
|
109
|
+
network_bandwidth_cost: string;
|
|
110
|
+
compute_bandwidth_limit: string;
|
|
111
|
+
compute_bandwidth_cost: string;
|
|
112
|
+
};
|
|
113
|
+
}>;
|
|
114
|
+
invokeGetContractMetadata?: (contractId: string) => Promise<{
|
|
115
|
+
value: {
|
|
116
|
+
hash: string;
|
|
117
|
+
system: boolean;
|
|
118
|
+
authorizes_call_contract: boolean;
|
|
119
|
+
authorizes_transaction_application: boolean;
|
|
120
|
+
authorizes_upload_contract: boolean;
|
|
121
|
+
};
|
|
122
|
+
}>;
|
|
123
|
+
invokeGetContractAddress?: (name: string) => Promise<{
|
|
124
|
+
value: { address: string };
|
|
125
|
+
}>;
|
|
126
|
+
}
|
|
127
|
+
|
|
17
128
|
/* eslint-disable @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access */
|
|
18
129
|
|
|
19
130
|
async function sleep(ms: number): Promise<void> {
|
|
@@ -23,7 +134,7 @@ async function sleep(ms: number): Promise<void> {
|
|
|
23
134
|
/**
|
|
24
135
|
* Class to connect with the RPC node
|
|
25
136
|
*/
|
|
26
|
-
export class Provider {
|
|
137
|
+
export class Provider implements ProviderInterface {
|
|
27
138
|
/**
|
|
28
139
|
* Array of URLs of RPC nodes
|
|
29
140
|
*/
|
|
@@ -372,6 +483,7 @@ export class Provider {
|
|
|
372
483
|
block_id: string;
|
|
373
484
|
block_height: string;
|
|
374
485
|
block: BlockJson;
|
|
486
|
+
receipt: BlockReceipt;
|
|
375
487
|
}[];
|
|
376
488
|
}> {
|
|
377
489
|
return this.call("block_store.get_blocks_by_id", {
|
|
@@ -447,9 +559,7 @@ export class Provider {
|
|
|
447
559
|
block_id: string;
|
|
448
560
|
block_height: string;
|
|
449
561
|
block: BlockJson;
|
|
450
|
-
|
|
451
|
-
[x: string]: unknown;
|
|
452
|
-
};
|
|
562
|
+
receipt: BlockReceipt;
|
|
453
563
|
}[]
|
|
454
564
|
> {
|
|
455
565
|
let blockIdRef = idRef;
|
|
@@ -463,9 +573,7 @@ export class Provider {
|
|
|
463
573
|
block_id: string;
|
|
464
574
|
block_height: string;
|
|
465
575
|
block: BlockJson;
|
|
466
|
-
|
|
467
|
-
[x: string]: unknown;
|
|
468
|
-
};
|
|
576
|
+
receipt: BlockReceipt;
|
|
469
577
|
}[];
|
|
470
578
|
}>("block_store.get_blocks_by_height", {
|
|
471
579
|
head_block_id: blockIdRef,
|
|
@@ -555,9 +663,7 @@ export class Provider {
|
|
|
555
663
|
block_id: string;
|
|
556
664
|
block_height: string;
|
|
557
665
|
block: BlockJson;
|
|
558
|
-
|
|
559
|
-
[x: string]: unknown;
|
|
560
|
-
};
|
|
666
|
+
receipt: BlockReceipt;
|
|
561
667
|
}> {
|
|
562
668
|
return (await this.getBlocks(height, 1, undefined, opts))[0];
|
|
563
669
|
}
|
|
@@ -835,7 +941,7 @@ export class Provider {
|
|
|
835
941
|
|
|
836
942
|
/**
|
|
837
943
|
* Function to get the contract metadata of a specific contract.
|
|
838
|
-
* @param contractId contract ID
|
|
944
|
+
* @param contractId - contract ID
|
|
839
945
|
*
|
|
840
946
|
* @example
|
|
841
947
|
* ```ts
|
|
@@ -912,10 +1018,74 @@ export class Provider {
|
|
|
912
1018
|
returnTypeName: "get_contract_metadata_result",
|
|
913
1019
|
}
|
|
914
1020
|
);
|
|
915
|
-
return this.invokeSystemCall
|
|
1021
|
+
return this.invokeSystemCall<{
|
|
1022
|
+
value: {
|
|
1023
|
+
hash: string;
|
|
1024
|
+
system: boolean;
|
|
1025
|
+
authorizes_call_contract: boolean;
|
|
1026
|
+
authorizes_transaction_application: boolean;
|
|
1027
|
+
authorizes_upload_contract: boolean;
|
|
1028
|
+
};
|
|
1029
|
+
}>(serializer, "get_contract_metadata", {
|
|
916
1030
|
contract_id: contractId,
|
|
917
1031
|
});
|
|
918
1032
|
}
|
|
1033
|
+
|
|
1034
|
+
/**
|
|
1035
|
+
* Function to get the address of a system contract
|
|
1036
|
+
* @param name - contract name
|
|
1037
|
+
*
|
|
1038
|
+
* @example
|
|
1039
|
+
* * ```ts
|
|
1040
|
+
* const provider = new Provider("https://api.koinos.io");
|
|
1041
|
+
* const result = await provider.invokeGetContractAddress("koin");
|
|
1042
|
+
* console.log(result);
|
|
1043
|
+
*
|
|
1044
|
+
* // { value: { address: '15DJN4a8SgrbGhhGksSBASiSYjGnMU8dGL' } }
|
|
1045
|
+
* ```
|
|
1046
|
+
*/
|
|
1047
|
+
async invokeGetContractAddress(name: string) {
|
|
1048
|
+
const serializer = new Serializer(
|
|
1049
|
+
{
|
|
1050
|
+
nested: {
|
|
1051
|
+
get_address_arguments: {
|
|
1052
|
+
fields: {
|
|
1053
|
+
name: {
|
|
1054
|
+
type: "string",
|
|
1055
|
+
id: 1,
|
|
1056
|
+
},
|
|
1057
|
+
},
|
|
1058
|
+
},
|
|
1059
|
+
get_address_result: {
|
|
1060
|
+
fields: {
|
|
1061
|
+
value: {
|
|
1062
|
+
type: "address_record",
|
|
1063
|
+
id: 1,
|
|
1064
|
+
},
|
|
1065
|
+
},
|
|
1066
|
+
},
|
|
1067
|
+
address_record: {
|
|
1068
|
+
fields: {
|
|
1069
|
+
address: {
|
|
1070
|
+
type: "bytes",
|
|
1071
|
+
id: 1,
|
|
1072
|
+
options: {
|
|
1073
|
+
"(koinos.btype)": "ADDRESS",
|
|
1074
|
+
},
|
|
1075
|
+
},
|
|
1076
|
+
},
|
|
1077
|
+
},
|
|
1078
|
+
},
|
|
1079
|
+
},
|
|
1080
|
+
{
|
|
1081
|
+
argumentsTypeName: "get_address_arguments",
|
|
1082
|
+
returnTypeName: "get_address_result",
|
|
1083
|
+
}
|
|
1084
|
+
);
|
|
1085
|
+
return this.invokeSystemCall<{
|
|
1086
|
+
value: { address: string };
|
|
1087
|
+
}>(serializer, "get_contract_address", { name });
|
|
1088
|
+
}
|
|
919
1089
|
}
|
|
920
1090
|
|
|
921
1091
|
export default Provider;
|
package/src/Signer.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
/* eslint-disable no-param-reassign, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment */
|
|
2
2
|
import { sha256 } from "@noble/hashes/sha256";
|
|
3
3
|
import * as secp from "@noble/secp256k1";
|
|
4
|
-
import {
|
|
5
|
-
import { Transaction } from "./Transaction";
|
|
4
|
+
import { ProviderInterface } from "./Provider";
|
|
6
5
|
import {
|
|
7
6
|
TransactionJson,
|
|
8
7
|
TransactionJsonWait,
|
|
@@ -12,7 +11,6 @@ import {
|
|
|
12
11
|
TypeField,
|
|
13
12
|
TransactionReceipt,
|
|
14
13
|
SendTransactionOptions,
|
|
15
|
-
ResourceCreditsOptions,
|
|
16
14
|
} from "./interface";
|
|
17
15
|
import {
|
|
18
16
|
bitcoinAddress,
|
|
@@ -30,7 +28,7 @@ import {
|
|
|
30
28
|
import { koinos } from "./protoModules/protocol-proto.js";
|
|
31
29
|
|
|
32
30
|
export interface SignerInterface {
|
|
33
|
-
provider?:
|
|
31
|
+
provider?: ProviderInterface;
|
|
34
32
|
getAddress: (compressed?: boolean) => string;
|
|
35
33
|
signHash: (hash: Uint8Array) => Promise<Uint8Array>;
|
|
36
34
|
signMessage: (message: string | Uint8Array) => Promise<Uint8Array>;
|
|
@@ -144,7 +142,7 @@ export class Signer implements SignerInterface {
|
|
|
144
142
|
/**
|
|
145
143
|
* Provider to connect with the blockchain
|
|
146
144
|
*/
|
|
147
|
-
provider?:
|
|
145
|
+
provider?: ProviderInterface;
|
|
148
146
|
|
|
149
147
|
/**
|
|
150
148
|
* Options to apply when sending a transaction.
|
|
@@ -153,33 +151,6 @@ export class Signer implements SignerInterface {
|
|
|
153
151
|
*/
|
|
154
152
|
sendOptions?: SendTransactionOptions;
|
|
155
153
|
|
|
156
|
-
/**
|
|
157
|
-
* Options related to the estimation of the rcLimit.
|
|
158
|
-
* By default the estimation is enabled and increased
|
|
159
|
-
* by 10%.
|
|
160
|
-
*
|
|
161
|
-
* @example
|
|
162
|
-
* This code estimates the mana by multiplying the rc_used
|
|
163
|
-
* by 2.
|
|
164
|
-
* ```ts
|
|
165
|
-
* const signer = new Signer({
|
|
166
|
-
* privateKey,
|
|
167
|
-
* provider,
|
|
168
|
-
* rcOptions: {
|
|
169
|
-
* estimateRc: true,
|
|
170
|
-
* adjustRcLimit: (receipt) => 2 * Number(receipt.rc_used),
|
|
171
|
-
* },
|
|
172
|
-
* });
|
|
173
|
-
*
|
|
174
|
-
* // you can also update rcOptions
|
|
175
|
-
* signer.rcOptions = {
|
|
176
|
-
* estimateRc: true,
|
|
177
|
-
* adjustRcLimit: (receipt) => 2 * Number(receipt.rc_used),
|
|
178
|
-
* }
|
|
179
|
-
* ```
|
|
180
|
-
*/
|
|
181
|
-
rcOptions: ResourceCreditsOptions;
|
|
182
|
-
|
|
183
154
|
/**
|
|
184
155
|
* The constructor receives de private key as hexstring, bigint or Uint8Array.
|
|
185
156
|
* See also the functions [[Signer.fromWif]] and [[Signer.fromSeed]]
|
|
@@ -189,7 +160,6 @@ export class Signer implements SignerInterface {
|
|
|
189
160
|
* @param compressed - compressed format is true by default
|
|
190
161
|
* @param provider - provider to connect with the blockchain
|
|
191
162
|
* @param sendOptions - Send options
|
|
192
|
-
* @param rcOptions - options for mana estimation
|
|
193
163
|
* @example
|
|
194
164
|
* ```ts
|
|
195
165
|
* const privateKey = "ec8601a24f81decd57f4b611b5ac6eb801cb3780bb02c0f9cdfe9d09daaddf9c";
|
|
@@ -197,46 +167,12 @@ export class Signer implements SignerInterface {
|
|
|
197
167
|
* console.log(signer.getAddress());
|
|
198
168
|
* // 1MbL6mG8ASAvSYdoMnGUfG3ZXkmQ2dpL5b
|
|
199
169
|
* ```
|
|
200
|
-
*
|
|
201
|
-
* By default the mana is estimated as 110% the mana used. This
|
|
202
|
-
* estimation is computed using the "broadcast:false" option.
|
|
203
|
-
* For instance, if the transaction consumes 1 mana, the rc_limit
|
|
204
|
-
* will be set to 1.1 mana.
|
|
205
|
-
*
|
|
206
|
-
* You can also adjust the rc limit.
|
|
207
|
-
* @example
|
|
208
|
-
* ```ts
|
|
209
|
-
* const privateKey = "ec8601a24f81decd57f4b611b5ac6eb801cb3780bb02c0f9cdfe9d09daaddf9c";
|
|
210
|
-
* cons signer = new Signer({
|
|
211
|
-
* privateKey,
|
|
212
|
-
* provider,
|
|
213
|
-
* rcOptions: {
|
|
214
|
-
* estimateRc: true,
|
|
215
|
-
* // use 2 times rc_used as rc_limit
|
|
216
|
-
* adjustRcLimit: (r) => 2 * Number(r.rc_used),
|
|
217
|
-
* },
|
|
218
|
-
* });
|
|
219
|
-
* ```
|
|
220
|
-
*
|
|
221
|
-
* The rpc node must be highly trusted because the transaction
|
|
222
|
-
* is signed during the estimation of the mana. You can also
|
|
223
|
-
* disable the mana estimation:
|
|
224
|
-
* @example
|
|
225
|
-
* ```ts
|
|
226
|
-
* const privateKey = "ec8601a24f81decd57f4b611b5ac6eb801cb3780bb02c0f9cdfe9d09daaddf9c";
|
|
227
|
-
* cons signer = new Signer({
|
|
228
|
-
* privateKey,
|
|
229
|
-
* provider,
|
|
230
|
-
* rcOptions: { estimateRc: false },
|
|
231
|
-
* });
|
|
232
|
-
* ```
|
|
233
170
|
*/
|
|
234
171
|
constructor(c: {
|
|
235
172
|
privateKey: string | number | bigint | Uint8Array;
|
|
236
173
|
compressed?: boolean;
|
|
237
|
-
provider?:
|
|
174
|
+
provider?: ProviderInterface;
|
|
238
175
|
sendOptions?: SendTransactionOptions;
|
|
239
|
-
rcOptions?: ResourceCreditsOptions;
|
|
240
176
|
}) {
|
|
241
177
|
this.compressed = typeof c.compressed === "undefined" ? true : c.compressed;
|
|
242
178
|
this.privateKey = c.privateKey;
|
|
@@ -252,16 +188,6 @@ export class Signer implements SignerInterface {
|
|
|
252
188
|
broadcast: true,
|
|
253
189
|
...c.sendOptions,
|
|
254
190
|
};
|
|
255
|
-
this.rcOptions = c.rcOptions ?? {
|
|
256
|
-
estimateRc: true,
|
|
257
|
-
adjustRcLimit: (receipt) =>
|
|
258
|
-
Promise.resolve(
|
|
259
|
-
Math.min(
|
|
260
|
-
Number(receipt.max_payer_rc),
|
|
261
|
-
Math.floor(1.1 * Number(receipt.rc_used))
|
|
262
|
-
)
|
|
263
|
-
),
|
|
264
|
-
};
|
|
265
191
|
}
|
|
266
192
|
|
|
267
193
|
/**
|
|
@@ -392,18 +318,6 @@ export class Signer implements SignerInterface {
|
|
|
392
318
|
): Promise<TransactionJson> {
|
|
393
319
|
if (!tx.id) throw new Error("Missing transaction id");
|
|
394
320
|
|
|
395
|
-
// estimation of rcLimit
|
|
396
|
-
if (
|
|
397
|
-
this.rcOptions.estimateRc &&
|
|
398
|
-
(!tx.signatures || tx.signatures.length === 0)
|
|
399
|
-
) {
|
|
400
|
-
const receipt = await this.estimateReceipt(tx);
|
|
401
|
-
tx.header!.rc_limit = this.rcOptions.adjustRcLimit
|
|
402
|
-
? await this.rcOptions.adjustRcLimit(receipt)
|
|
403
|
-
: receipt.rc_used;
|
|
404
|
-
tx.id = Transaction.computeTransactionId(tx.header!);
|
|
405
|
-
}
|
|
406
|
-
|
|
407
321
|
// multihash 0x1220. 12: code sha2-256. 20: length (32 bytes)
|
|
408
322
|
// tx id is a stringified multihash, need to extract the hash digest only
|
|
409
323
|
const hash = toUint8Array(tx.id.slice(6));
|
|
@@ -466,45 +380,6 @@ export class Signer implements SignerInterface {
|
|
|
466
380
|
return this.provider.sendTransaction(transaction, opts.broadcast);
|
|
467
381
|
}
|
|
468
382
|
|
|
469
|
-
/**
|
|
470
|
-
* Estimate the receipt associated to the transaction if
|
|
471
|
-
* it sent to the blockchain. It is useful to estimate the
|
|
472
|
-
* consumption of mana.
|
|
473
|
-
* The transaction is signed during this process and sent
|
|
474
|
-
* to the rpc node with the "broadcast:false" option to
|
|
475
|
-
* just compute the transaction without broadcasting it to
|
|
476
|
-
* the network.
|
|
477
|
-
* After that, the initial signatures are restored (if any)
|
|
478
|
-
* and the ones used for the estimation will be removed.
|
|
479
|
-
*/
|
|
480
|
-
async estimateReceipt(
|
|
481
|
-
tx: TransactionJson | TransactionJsonWait
|
|
482
|
-
): Promise<TransactionReceipt> {
|
|
483
|
-
if (!tx.id) throw new Error("Missing transaction id");
|
|
484
|
-
if (!tx.signatures) tx.signatures = [];
|
|
485
|
-
const signaturesCopy = [...tx.signatures];
|
|
486
|
-
|
|
487
|
-
// sign if there are no signatures
|
|
488
|
-
if (tx.signatures.length === 0) {
|
|
489
|
-
const hash = toUint8Array(tx.id.slice(6));
|
|
490
|
-
const signature = await this.signHash(hash);
|
|
491
|
-
tx.signatures.push(encodeBase64url(signature));
|
|
492
|
-
}
|
|
493
|
-
|
|
494
|
-
try {
|
|
495
|
-
const { receipt } = await this.sendTransaction(tx, {
|
|
496
|
-
broadcast: false,
|
|
497
|
-
});
|
|
498
|
-
// restore signatures
|
|
499
|
-
tx.signatures = signaturesCopy;
|
|
500
|
-
return receipt;
|
|
501
|
-
} catch (error) {
|
|
502
|
-
// restore signatures
|
|
503
|
-
tx.signatures = signaturesCopy;
|
|
504
|
-
throw error;
|
|
505
|
-
}
|
|
506
|
-
}
|
|
507
|
-
|
|
508
383
|
/**
|
|
509
384
|
* Function to recover the public key from hash and signature
|
|
510
385
|
* @param hash - hash sha256
|
|
@@ -596,7 +471,7 @@ export class Signer implements SignerInterface {
|
|
|
596
471
|
* });
|
|
597
472
|
* ```
|
|
598
473
|
*/
|
|
599
|
-
async recoverPublicKeys(
|
|
474
|
+
static async recoverPublicKeys(
|
|
600
475
|
txOrBlock: TransactionJson | BlockJson,
|
|
601
476
|
opts?: RecoverPublicKeyOptions
|
|
602
477
|
): Promise<string[]> {
|
|
@@ -696,7 +571,7 @@ export class Signer implements SignerInterface {
|
|
|
696
571
|
* });
|
|
697
572
|
* ```
|
|
698
573
|
*/
|
|
699
|
-
async recoverAddresses(
|
|
574
|
+
static async recoverAddresses(
|
|
700
575
|
txOrBlock: TransactionJson | BlockJson,
|
|
701
576
|
opts?: RecoverPublicKeyOptions
|
|
702
577
|
): Promise<string[]> {
|
package/src/Transaction.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/* eslint-disable no-param-reassign, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment */
|
|
2
2
|
import { sha256 } from "@noble/hashes/sha256";
|
|
3
3
|
import { Contract } from "./Contract";
|
|
4
|
-
import {
|
|
4
|
+
import { ProviderInterface } from "./Provider";
|
|
5
5
|
import { SignerInterface } from "./Signer";
|
|
6
6
|
import {
|
|
7
7
|
Abi,
|
|
@@ -90,7 +90,7 @@ export class Transaction {
|
|
|
90
90
|
/**
|
|
91
91
|
* Provider to connect with the blockchain
|
|
92
92
|
*/
|
|
93
|
-
provider?:
|
|
93
|
+
provider?: ProviderInterface;
|
|
94
94
|
|
|
95
95
|
/**
|
|
96
96
|
* Transaction
|
|
@@ -109,7 +109,8 @@ export class Transaction {
|
|
|
109
109
|
|
|
110
110
|
constructor(c?: {
|
|
111
111
|
signer?: SignerInterface;
|
|
112
|
-
provider?:
|
|
112
|
+
provider?: ProviderInterface;
|
|
113
|
+
transaction?: TransactionJson;
|
|
113
114
|
options?: TransactionOptions;
|
|
114
115
|
}) {
|
|
115
116
|
this.signer = c?.signer;
|
|
@@ -128,6 +129,7 @@ export class Transaction {
|
|
|
128
129
|
...(c?.options?.payee && { payee: c.options.payee }),
|
|
129
130
|
},
|
|
130
131
|
operations: [],
|
|
132
|
+
...c?.transaction,
|
|
131
133
|
};
|
|
132
134
|
}
|
|
133
135
|
|
|
@@ -146,14 +148,17 @@ export class Transaction {
|
|
|
146
148
|
* signer.provider = provider;
|
|
147
149
|
* const tx = new Transaction({ signer });
|
|
148
150
|
*
|
|
149
|
-
* //
|
|
151
|
+
* // Method 1 (using 2 arguments)
|
|
152
|
+
* // note that with 2 arguments it is not necessary to
|
|
153
|
+
* // set "onlyOperation: true". For the rest of the
|
|
154
|
+
* // methods it's necessary to do that.
|
|
150
155
|
* await tx.pushOperation(koin.transfer, {
|
|
151
156
|
* from: "1NRYHBYr9qxYQAeVqfdSvyjJemRQ4qD3Mt",
|
|
152
157
|
* to: "13UdKjYuzfBYbB6bGLQkUN9DJRFPCmG1mU",
|
|
153
158
|
* value: "1000",
|
|
154
159
|
* });
|
|
155
160
|
*
|
|
156
|
-
* //
|
|
161
|
+
* // Method 2
|
|
157
162
|
* await tx.pushOperation(
|
|
158
163
|
* koin.transfer({
|
|
159
164
|
* from: "1NRYHBYr9qxYQAeVqfdSvyjJemRQ4qD3Mt",
|
|
@@ -164,7 +169,7 @@ export class Transaction {
|
|
|
164
169
|
* })
|
|
165
170
|
* );
|
|
166
171
|
*
|
|
167
|
-
* //
|
|
172
|
+
* // Method 3
|
|
168
173
|
* await tx.pushOperation(
|
|
169
174
|
* await koin.transfer({
|
|
170
175
|
* from: "1NRYHBYr9qxYQAeVqfdSvyjJemRQ4qD3Mt",
|
|
@@ -175,7 +180,7 @@ export class Transaction {
|
|
|
175
180
|
* })
|
|
176
181
|
* );
|
|
177
182
|
*
|
|
178
|
-
* //
|
|
183
|
+
* // Method 4
|
|
179
184
|
* const { operation } = await koin.transfer({
|
|
180
185
|
* from: "1NRYHBYr9qxYQAeVqfdSvyjJemRQ4qD3Mt",
|
|
181
186
|
* to: "13UdKjYuzfBYbB6bGLQkUN9DJRFPCmG1mU",
|
|
@@ -240,7 +245,7 @@ export class Transaction {
|
|
|
240
245
|
*/
|
|
241
246
|
static async prepareTransaction(
|
|
242
247
|
tx: TransactionJson,
|
|
243
|
-
provider?:
|
|
248
|
+
provider?: ProviderInterface,
|
|
244
249
|
payer?: string
|
|
245
250
|
): Promise<TransactionJson> {
|
|
246
251
|
if (!tx.header) {
|
|
@@ -347,6 +352,22 @@ export class Transaction {
|
|
|
347
352
|
return this.transaction;
|
|
348
353
|
}
|
|
349
354
|
|
|
355
|
+
/**
|
|
356
|
+
* Update the rc limit with a new value and update the
|
|
357
|
+
* transaction ID accordingly. The signatures will be removed
|
|
358
|
+
* if the transaction ID changed
|
|
359
|
+
*/
|
|
360
|
+
adjustRcLimit(newRcLimit: string | number): void {
|
|
361
|
+
if (!this.transaction.header)
|
|
362
|
+
throw new Error("transaction header not defined");
|
|
363
|
+
this.transaction.header.rc_limit = newRcLimit;
|
|
364
|
+
const newTxId = Transaction.computeTransactionId(this.transaction.header);
|
|
365
|
+
if (this.transaction.id !== newTxId) {
|
|
366
|
+
this.transaction.signatures = [];
|
|
367
|
+
}
|
|
368
|
+
this.transaction.id = newTxId;
|
|
369
|
+
}
|
|
370
|
+
|
|
350
371
|
/**
|
|
351
372
|
* Function to sign the transaction
|
|
352
373
|
*/
|
package/src/interface.ts
CHANGED
|
@@ -231,39 +231,6 @@ export interface DecodedOperationJson {
|
|
|
231
231
|
args?: Record<string, unknown>;
|
|
232
232
|
}
|
|
233
233
|
|
|
234
|
-
export interface ResourceCreditsOptions {
|
|
235
|
-
/**
|
|
236
|
-
* Boolean to define if the mana should be estimated
|
|
237
|
-
* and the rcLimit be updated before signing the transaction.
|
|
238
|
-
* It is true by default
|
|
239
|
-
*/
|
|
240
|
-
estimateRc?: boolean;
|
|
241
|
-
|
|
242
|
-
/**
|
|
243
|
-
* Function to adjust the rc limit after the estimation.
|
|
244
|
-
* It is useful to give an extra margin to the rc limit.
|
|
245
|
-
* By default the Signer will use a function that increases
|
|
246
|
-
* the rcLimit by 10% with respect to the estimation.
|
|
247
|
-
*
|
|
248
|
-
* @example
|
|
249
|
-
* ```ts
|
|
250
|
-
* const signer = Signer.fromWif("Kab...");
|
|
251
|
-
* signer.rcOptions = {
|
|
252
|
-
* estimateRc: true,
|
|
253
|
-
* adjustRcLimit: async (receipt) => {
|
|
254
|
-
* return Math.min(
|
|
255
|
-
* Number(receipt.max_payer_rc),
|
|
256
|
-
* Math.floor(1.1 * Number(receipt.rc_used))
|
|
257
|
-
* );
|
|
258
|
-
* },
|
|
259
|
-
* }
|
|
260
|
-
* ```
|
|
261
|
-
*/
|
|
262
|
-
adjustRcLimit?: (
|
|
263
|
-
receipt: TransactionReceipt
|
|
264
|
-
) => Promise<string | number> | string | number;
|
|
265
|
-
}
|
|
266
|
-
|
|
267
234
|
export interface SendTransactionOptions {
|
|
268
235
|
/**
|
|
269
236
|
* Broadcast
|
|
@@ -821,3 +788,17 @@ export interface TransactionReceipt {
|
|
|
821
788
|
logs: string[];
|
|
822
789
|
rpc_error?: unknown;
|
|
823
790
|
}
|
|
791
|
+
|
|
792
|
+
export interface BlockReceipt {
|
|
793
|
+
id: string;
|
|
794
|
+
height: string;
|
|
795
|
+
disk_storage_used: string;
|
|
796
|
+
network_bandwidth_used: string;
|
|
797
|
+
compute_bandwidth_used: string;
|
|
798
|
+
disk_storage_charged: string;
|
|
799
|
+
network_bandwidth_charged: string;
|
|
800
|
+
compute_bandwidth_charged: string;
|
|
801
|
+
events: EventData[];
|
|
802
|
+
transaction_receipts: TransactionReceipt[];
|
|
803
|
+
state_delta_entries: StateDeltaEntry[];
|
|
804
|
+
}
|