koilib 5.5.6 → 5.6.1
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/dist/koinos.js +656 -365
- package/dist/koinos.min.js +1 -1
- package/lib/Contract.js +7 -4
- package/lib/Contract.js.map +1 -1
- package/lib/Signer.d.ts +2 -1
- package/lib/Signer.js +2 -1
- package/lib/Signer.js.map +1 -1
- package/lib/Transaction.d.ts +9 -0
- package/lib/Transaction.js +148 -19
- package/lib/Transaction.js.map +1 -1
- package/lib/browser/Contract.js +7 -4
- package/lib/browser/Contract.js.map +1 -1
- package/lib/browser/Signer.d.ts +2 -1
- package/lib/browser/Signer.js +2 -1
- package/lib/browser/Signer.js.map +1 -1
- package/lib/browser/Transaction.d.ts +9 -0
- package/lib/browser/Transaction.js +148 -19
- package/lib/browser/Transaction.js.map +1 -1
- package/package.json +6 -6
- package/src/Contract.ts +35 -26
- package/src/Signer.ts +2 -1
- package/src/Transaction.ts +179 -12
package/src/Transaction.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
/* eslint-disable no-param-reassign, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment */
|
|
2
|
+
import { sha256 } from "@noble/hashes/sha256";
|
|
1
3
|
import { Contract } from "./Contract";
|
|
2
4
|
import { Provider } from "./Provider";
|
|
3
5
|
import { Signer } from "./Signer";
|
|
@@ -8,8 +10,75 @@ import {
|
|
|
8
10
|
TransactionJson,
|
|
9
11
|
TransactionOptions,
|
|
10
12
|
TransactionReceipt,
|
|
13
|
+
TypeField,
|
|
11
14
|
WaitFunction,
|
|
12
15
|
} from "./interface";
|
|
16
|
+
import {
|
|
17
|
+
btypeDecode,
|
|
18
|
+
calculateMerkleRoot,
|
|
19
|
+
encodeBase64url,
|
|
20
|
+
toHexString,
|
|
21
|
+
} from "./utils";
|
|
22
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
23
|
+
// @ts-ignore
|
|
24
|
+
import { koinos } from "./protoModules/protocol-proto.js";
|
|
25
|
+
|
|
26
|
+
const btypeTransactionHeader: TypeField["subtypes"] = {
|
|
27
|
+
chain_id: { type: "bytes" },
|
|
28
|
+
rc_limit: { type: "uint64" },
|
|
29
|
+
nonce: { type: "bytes" },
|
|
30
|
+
operation_merkle_root: { type: "bytes" },
|
|
31
|
+
payer: { type: "bytes", btype: "ADDRESS" },
|
|
32
|
+
payee: { type: "bytes", btype: "ADDRESS" },
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const btypesOperation: TypeField["subtypes"] = {
|
|
36
|
+
upload_contract: {
|
|
37
|
+
type: "object",
|
|
38
|
+
subtypes: {
|
|
39
|
+
contract_id: { type: "bytes", btype: "CONTRACT_ID" },
|
|
40
|
+
bytecode: { type: "bytes" },
|
|
41
|
+
abi: { type: "string" },
|
|
42
|
+
authorizes_call_contract: { type: "bool" },
|
|
43
|
+
authorizes_transaction_application: { type: "bool" },
|
|
44
|
+
authorizes_upload_contract: { type: "bool" },
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
call_contract: {
|
|
48
|
+
type: "object",
|
|
49
|
+
subtypes: {
|
|
50
|
+
contract_id: { type: "bytes", btype: "CONTRACT_ID" },
|
|
51
|
+
entry_point: { type: "uint32" },
|
|
52
|
+
args: { type: "bytes" },
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
set_system_call: {
|
|
56
|
+
type: "object",
|
|
57
|
+
subtypes: {
|
|
58
|
+
call_id: { type: "uint32" },
|
|
59
|
+
target: {
|
|
60
|
+
type: "object",
|
|
61
|
+
subtypes: {
|
|
62
|
+
thunk_id: { type: "uint32" },
|
|
63
|
+
system_call_bundle: {
|
|
64
|
+
type: "object",
|
|
65
|
+
subtypes: {
|
|
66
|
+
contract_id: { type: "bytes", btype: "CONTRACT_ID" },
|
|
67
|
+
entry_point: { type: "uint32" },
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
set_system_contract: {
|
|
75
|
+
type: "object",
|
|
76
|
+
subtypes: {
|
|
77
|
+
contract_id: { type: "bytes", btype: "CONTRACT_ID" },
|
|
78
|
+
system_contract: { type: "bool" },
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
};
|
|
13
82
|
|
|
14
83
|
export class Transaction {
|
|
15
84
|
/**
|
|
@@ -43,7 +112,7 @@ export class Transaction {
|
|
|
43
112
|
options?: TransactionOptions;
|
|
44
113
|
}) {
|
|
45
114
|
this.signer = c?.signer;
|
|
46
|
-
this.provider = c?.provider;
|
|
115
|
+
this.provider = c?.provider || c?.signer?.provider;
|
|
47
116
|
this.options = {
|
|
48
117
|
broadcast: true,
|
|
49
118
|
sendAbis: true,
|
|
@@ -147,6 +216,110 @@ export class Transaction {
|
|
|
147
216
|
this.transaction.operations.push(operation);
|
|
148
217
|
}
|
|
149
218
|
|
|
219
|
+
/**
|
|
220
|
+
* Function to prepare a transaction
|
|
221
|
+
* @param tx - Do not set the nonce to get it from the blockchain
|
|
222
|
+
* using the provider. The rc_limit is 1e8 by default.
|
|
223
|
+
* @param provider - Provider
|
|
224
|
+
* @param payer - payer to be used in case it is not defined in the transaction
|
|
225
|
+
* @returns A prepared transaction.
|
|
226
|
+
*/
|
|
227
|
+
static async prepareTransaction(
|
|
228
|
+
tx: TransactionJson,
|
|
229
|
+
provider?: Provider,
|
|
230
|
+
payer?: string
|
|
231
|
+
): Promise<TransactionJson> {
|
|
232
|
+
if (!tx.header) {
|
|
233
|
+
tx.header = {};
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
const { payer: payerHeader, payee } = tx.header;
|
|
237
|
+
if (!payerHeader) tx.header.payer = payer;
|
|
238
|
+
payer = tx.header.payer;
|
|
239
|
+
if (!payer) throw new Error("payer is undefined");
|
|
240
|
+
|
|
241
|
+
let nonce: string;
|
|
242
|
+
if (tx.header.nonce === undefined) {
|
|
243
|
+
if (!provider)
|
|
244
|
+
throw new Error(
|
|
245
|
+
"Cannot get the nonce because provider is undefined. To skip this call set a nonce in the transaction header"
|
|
246
|
+
);
|
|
247
|
+
nonce = await provider.getNextNonce(payee || payer);
|
|
248
|
+
} else {
|
|
249
|
+
nonce = tx.header.nonce;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
let rcLimit: string;
|
|
253
|
+
if (tx.header.rc_limit === undefined) {
|
|
254
|
+
if (!provider)
|
|
255
|
+
throw new Error(
|
|
256
|
+
"Cannot get the rc_limit because provider is undefined. To skip this call set a rc_limit in the transaction header"
|
|
257
|
+
);
|
|
258
|
+
rcLimit = await provider.getAccountRc(payer);
|
|
259
|
+
} else {
|
|
260
|
+
rcLimit = tx.header.rc_limit;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
if (!tx.header.chain_id) {
|
|
264
|
+
if (!provider)
|
|
265
|
+
throw new Error(
|
|
266
|
+
"Cannot get the chain_id because provider is undefined. To skip this call set a chain_id"
|
|
267
|
+
);
|
|
268
|
+
tx.header.chain_id = await provider.getChainId();
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
const operationsHashes: Uint8Array[] = [];
|
|
272
|
+
|
|
273
|
+
if (tx.operations) {
|
|
274
|
+
for (let index = 0; index < tx.operations?.length; index += 1) {
|
|
275
|
+
const operationDecoded = btypeDecode(
|
|
276
|
+
tx.operations[index],
|
|
277
|
+
btypesOperation!,
|
|
278
|
+
false
|
|
279
|
+
);
|
|
280
|
+
const message = koinos.protocol.operation.create(operationDecoded);
|
|
281
|
+
const operationEncoded = koinos.protocol.operation
|
|
282
|
+
.encode(message)
|
|
283
|
+
.finish() as Uint8Array;
|
|
284
|
+
operationsHashes.push(sha256(operationEncoded));
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
const operationMerkleRoot = encodeBase64url(
|
|
288
|
+
new Uint8Array([
|
|
289
|
+
// multihash sha256: 18, 32
|
|
290
|
+
18,
|
|
291
|
+
32,
|
|
292
|
+
...calculateMerkleRoot(operationsHashes),
|
|
293
|
+
])
|
|
294
|
+
);
|
|
295
|
+
|
|
296
|
+
tx.header = {
|
|
297
|
+
chain_id: tx.header.chain_id,
|
|
298
|
+
rc_limit: rcLimit,
|
|
299
|
+
nonce,
|
|
300
|
+
operation_merkle_root: operationMerkleRoot,
|
|
301
|
+
payer,
|
|
302
|
+
...(payee && { payee }),
|
|
303
|
+
// TODO: Option to resolve names (payer, payee)
|
|
304
|
+
};
|
|
305
|
+
|
|
306
|
+
const headerDecoded = btypeDecode(
|
|
307
|
+
tx.header,
|
|
308
|
+
btypeTransactionHeader!,
|
|
309
|
+
false
|
|
310
|
+
);
|
|
311
|
+
const message = koinos.protocol.transaction_header.create(headerDecoded);
|
|
312
|
+
const headerBytes = koinos.protocol.transaction_header
|
|
313
|
+
.encode(message)
|
|
314
|
+
.finish() as Uint8Array;
|
|
315
|
+
|
|
316
|
+
const hash = sha256(headerBytes);
|
|
317
|
+
|
|
318
|
+
// multihash 0x1220. 12: code sha2-256. 20: length (32 bytes)
|
|
319
|
+
tx.id = `0x1220${toHexString(hash)}`;
|
|
320
|
+
return tx;
|
|
321
|
+
}
|
|
322
|
+
|
|
150
323
|
/**
|
|
151
324
|
* Functon to prepare the transaction (set headers, merkle
|
|
152
325
|
* root, etc)
|
|
@@ -165,17 +338,11 @@ export class Transaction {
|
|
|
165
338
|
...header,
|
|
166
339
|
};
|
|
167
340
|
}
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
this.
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
throw new Error("no payer defined");
|
|
174
|
-
}
|
|
175
|
-
const signer = Signer.fromSeed("0");
|
|
176
|
-
signer.provider = this.provider;
|
|
177
|
-
this.transaction = await signer.prepareTransaction(this.transaction);
|
|
178
|
-
}
|
|
341
|
+
this.transaction = await Transaction.prepareTransaction(
|
|
342
|
+
this.transaction,
|
|
343
|
+
this.provider,
|
|
344
|
+
this.signer?.getAddress()
|
|
345
|
+
);
|
|
179
346
|
return this.transaction;
|
|
180
347
|
}
|
|
181
348
|
|