koilib 5.0.0 → 5.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 +74 -11
- package/dist/koinos.js +71 -49
- package/dist/koinos.min.js +1 -1
- package/lib/Contract.js +34 -30
- package/lib/Contract.js.map +1 -1
- package/lib/Provider.d.ts +4 -1
- package/lib/Provider.js +19 -8
- package/lib/Provider.js.map +1 -1
- package/lib/Signer.d.ts +14 -11
- package/lib/Signer.js +18 -11
- package/lib/Signer.js.map +1 -1
- package/lib/browser/Contract.js +34 -30
- package/lib/browser/Contract.js.map +1 -1
- package/lib/browser/Provider.d.ts +4 -1
- package/lib/browser/Provider.js +19 -8
- package/lib/browser/Provider.js.map +1 -1
- package/lib/browser/Signer.d.ts +14 -11
- package/lib/browser/Signer.js +18 -11
- package/lib/browser/Signer.js.map +1 -1
- package/lib/browser/interface.d.ts +56 -1
- package/lib/interface.d.ts +56 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -123,7 +123,7 @@ a transaction, and read contracts.
|
|
|
123
123
|
}
|
|
124
124
|
|
|
125
125
|
// wait to be mined
|
|
126
|
-
const blockNumber = await transaction.wait();
|
|
126
|
+
const { blockNumber } = await transaction.wait();
|
|
127
127
|
console.log(`Transaction mined. Block number: ${blockNumber}`);
|
|
128
128
|
|
|
129
129
|
// read the balance
|
|
@@ -150,13 +150,56 @@ It's also possible to upload contracts. First, follow the instructions in [koino
|
|
|
150
150
|
console.log("Transaction submitted. Receipt:");
|
|
151
151
|
console.log(receipt);
|
|
152
152
|
// wait to be mined
|
|
153
|
-
const blockNumber = await transaction.wait();
|
|
153
|
+
const { blockNumber } = await transaction.wait();
|
|
154
154
|
console.log(`Contract uploaded in block number ${blockNumber}`);
|
|
155
155
|
})();
|
|
156
156
|
```
|
|
157
157
|
|
|
158
158
|
You can also upload a contract in a new address. It is not required that this new address has funds, you just have to set your principal wallet as payer.
|
|
159
159
|
|
|
160
|
+
```typescript
|
|
161
|
+
(async () => {
|
|
162
|
+
// define signer, provider and bytecode
|
|
163
|
+
const provider = new Provider(["http://api.koinos.io:8080"]);
|
|
164
|
+
const accountWithFunds = Signer.fromSeed("this account has funds");
|
|
165
|
+
const newAccount = Signer.fromSeed("new account without funds");
|
|
166
|
+
accountWithFunds.provider = provider;
|
|
167
|
+
newAccount.provider = provider;
|
|
168
|
+
|
|
169
|
+
const bytecode = fs.readFileSync("my_contract.wasm");
|
|
170
|
+
|
|
171
|
+
// create contract. Set newAccount as signer
|
|
172
|
+
const contract = new Contract({
|
|
173
|
+
signer: newAccount,
|
|
174
|
+
provider,
|
|
175
|
+
bytecode,
|
|
176
|
+
options: {
|
|
177
|
+
// transaction options
|
|
178
|
+
// set payer
|
|
179
|
+
payer: accountWithFunds.address,
|
|
180
|
+
|
|
181
|
+
// use "beforeSend" function to sign
|
|
182
|
+
// the transaction with the payer
|
|
183
|
+
beforeSend: async (tx) => {
|
|
184
|
+
accountWithFunds.signTransaction(tx);
|
|
185
|
+
},
|
|
186
|
+
},
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
// call deploy()
|
|
190
|
+
// By default it is signed by "newAccount". But, as
|
|
191
|
+
// in beforeSend it is signed by the payer then it
|
|
192
|
+
// will have 2 signatures
|
|
193
|
+
const { receipt } = await contract.deploy();
|
|
194
|
+
console.log("Transaction submitted. Receipt: ");
|
|
195
|
+
console.log(receipt);
|
|
196
|
+
const { blockNumber } = await transaction.wait();
|
|
197
|
+
console.log(`Contract uploaded in block number ${blockNumber}`);
|
|
198
|
+
})();
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
In fact, there are several ways to set a different payer and use it to upload a contract. This is another example:
|
|
202
|
+
|
|
160
203
|
```typescript
|
|
161
204
|
(async () => {
|
|
162
205
|
// define signer, provider and bytecode
|
|
@@ -193,11 +236,37 @@ You can also upload a contract in a new address. It is not required that this ne
|
|
|
193
236
|
const { receipt } = await newAccount.sendTransaction(transaction);
|
|
194
237
|
console.log("Transaction submitted. Receipt: ");
|
|
195
238
|
console.log(receipt);
|
|
196
|
-
const blockNumber = await transaction.wait();
|
|
239
|
+
const { blockNumber } = await transaction.wait();
|
|
197
240
|
console.log(`Contract uploaded in block number ${blockNumber}`);
|
|
198
241
|
})();
|
|
199
242
|
```
|
|
200
243
|
|
|
244
|
+
### Multisignatures
|
|
245
|
+
|
|
246
|
+
It can be configured to sign a single transaction with multiple accounts. Here is an example:
|
|
247
|
+
|
|
248
|
+
```ts
|
|
249
|
+
const signer2 = Signer.fromSeed("signer2");
|
|
250
|
+
const signer3 = Signer.fromSeed("signer3");
|
|
251
|
+
|
|
252
|
+
const addMoreSignatures = async (tx) => {
|
|
253
|
+
await signer2.signTransaction(tx);
|
|
254
|
+
await signer3.signTransaction(tx);
|
|
255
|
+
};
|
|
256
|
+
|
|
257
|
+
const { transaction } = await koin.transfer(
|
|
258
|
+
{
|
|
259
|
+
from: "16MT1VQFgsVxEfJrSGinrA5buiqBsN5ViJ",
|
|
260
|
+
to: "1Gvqdo9if6v6tFomEuTuMWP1D7H7U9yksb",
|
|
261
|
+
value: "1000000",
|
|
262
|
+
},
|
|
263
|
+
{
|
|
264
|
+
payer: signer2.getAddress(),
|
|
265
|
+
beforeSend: addMoreSignatures,
|
|
266
|
+
}
|
|
267
|
+
);
|
|
268
|
+
```
|
|
269
|
+
|
|
201
270
|
### Create ABIs
|
|
202
271
|
|
|
203
272
|
ABIs are composed of 2 elements: methods and types.
|
|
@@ -209,7 +278,7 @@ To generate the types is necessary to use the dependency protobufjs. The followi
|
|
|
209
278
|
|
|
210
279
|
```js
|
|
211
280
|
const fs = require("fs");
|
|
212
|
-
const pbjs = require("protobufjs
|
|
281
|
+
const pbjs = require("protobufjs-cli/pbjs");
|
|
213
282
|
|
|
214
283
|
pbjs.main(["--target", "json", "./token.proto"], (err, output) => {
|
|
215
284
|
if (err) throw err;
|
|
@@ -245,12 +314,6 @@ const abiToken = {
|
|
|
245
314
|
};
|
|
246
315
|
```
|
|
247
316
|
|
|
248
|
-
Note that this example uses "default_output" for the method
|
|
249
|
-
"balanceOf". This is used when the smart contract returns an
|
|
250
|
-
empty response (for instance when there are no balance records
|
|
251
|
-
for a specific address) and you require a default output in
|
|
252
|
-
such cases.
|
|
253
|
-
|
|
254
317
|
## FAQ
|
|
255
318
|
|
|
256
319
|
1. Can this library be used to create smart contracts?
|
|
@@ -269,7 +332,7 @@ such cases.
|
|
|
269
332
|
For the ABI you need the .proto file and the library
|
|
270
333
|
[protobufjs](https://www.npmjs.com/package/protobufjs). Then follow the format
|
|
271
334
|
for the ABI as described in the previous section. It's important to note that
|
|
272
|
-
this ABI has a
|
|
335
|
+
this ABI has a difference with respect to the ABI used in [koinos-cli](https://docs.koinos.io/architecture/contract-abi.html).
|
|
273
336
|
In particular, koilib takes the descriptor from `koilib_types`, which is a
|
|
274
337
|
descriptor in json format, while the ABI in koinos-cli takes the descriptor from
|
|
275
338
|
`types`, which is a descriptor in binary format.
|
package/dist/koinos.js
CHANGED
|
@@ -10007,11 +10007,7 @@ class Contract {
|
|
|
10007
10007
|
...c.options,
|
|
10008
10008
|
};
|
|
10009
10009
|
this.functions = {};
|
|
10010
|
-
if (this.
|
|
10011
|
-
this.provider &&
|
|
10012
|
-
this.abi &&
|
|
10013
|
-
this.abi.methods &&
|
|
10014
|
-
this.serializer) {
|
|
10010
|
+
if (this.abi && this.abi.methods) {
|
|
10015
10011
|
Object.keys(this.abi.methods).forEach((name) => {
|
|
10016
10012
|
this.functions[name] = async (argu = {}, options) => {
|
|
10017
10013
|
if (!this.provider)
|
|
@@ -10052,29 +10048,33 @@ class Contract {
|
|
|
10052
10048
|
throw new Error("signer not found");
|
|
10053
10049
|
let tx = await this.signer.prepareTransaction({
|
|
10054
10050
|
header: {
|
|
10055
|
-
...(
|
|
10056
|
-
...(
|
|
10057
|
-
...(
|
|
10058
|
-
...(
|
|
10059
|
-
...(
|
|
10051
|
+
...(opts.chainId && { chain_id: opts.chainId }),
|
|
10052
|
+
...(opts.rcLimit && { rc_limit: opts.rcLimit }),
|
|
10053
|
+
...(opts.nonce && { nonce: opts.nonce }),
|
|
10054
|
+
...(opts.payer && { payer: opts.payer }),
|
|
10055
|
+
...(opts.payee && { payee: opts.payee }),
|
|
10060
10056
|
},
|
|
10061
10057
|
operations: [operation],
|
|
10062
10058
|
});
|
|
10063
|
-
const
|
|
10064
|
-
|
|
10059
|
+
const optsSend = {
|
|
10060
|
+
broadcast: opts.broadcast,
|
|
10061
|
+
beforeSend: opts.beforeSend,
|
|
10062
|
+
};
|
|
10063
|
+
if (opts.sendAbis) {
|
|
10064
|
+
optsSend.abis = {};
|
|
10065
10065
|
const contractId = (0, utils_1.encodeBase58)(this.id);
|
|
10066
|
-
abis[contractId] = this.abi;
|
|
10066
|
+
optsSend.abis[contractId] = this.abi;
|
|
10067
10067
|
}
|
|
10068
10068
|
// return result if the transaction will not be broadcasted
|
|
10069
|
-
if (!
|
|
10069
|
+
if (!opts.sendTransaction) {
|
|
10070
10070
|
const noWait = () => {
|
|
10071
10071
|
throw new Error("This transaction was not broadcasted");
|
|
10072
10072
|
};
|
|
10073
10073
|
if (opts.signTransaction)
|
|
10074
|
-
tx = await this.signer.signTransaction(tx, abis);
|
|
10074
|
+
tx = await this.signer.signTransaction(tx, optsSend.abis);
|
|
10075
10075
|
return { operation, transaction: { ...tx, wait: noWait } };
|
|
10076
10076
|
}
|
|
10077
|
-
const { transaction, receipt } = await this.signer.sendTransaction(tx,
|
|
10077
|
+
const { transaction, receipt } = await this.signer.sendTransaction(tx, optsSend);
|
|
10078
10078
|
return { operation, transaction, receipt };
|
|
10079
10079
|
};
|
|
10080
10080
|
});
|
|
@@ -10148,30 +10148,34 @@ class Contract {
|
|
|
10148
10148
|
upload_contract: {
|
|
10149
10149
|
contract_id: contractId,
|
|
10150
10150
|
bytecode: (0, utils_1.encodeBase64url)(this.bytecode),
|
|
10151
|
-
...(
|
|
10152
|
-
...(
|
|
10153
|
-
authorizes_call_contract: opts
|
|
10151
|
+
...(opts.abi && { abi: opts.abi }),
|
|
10152
|
+
...(opts.authorizesCallContract && {
|
|
10153
|
+
authorizes_call_contract: opts.authorizesCallContract,
|
|
10154
10154
|
}),
|
|
10155
|
-
...(
|
|
10156
|
-
authorizes_transaction_application: opts
|
|
10155
|
+
...(opts.authorizesTransactionApplication && {
|
|
10156
|
+
authorizes_transaction_application: opts.authorizesTransactionApplication,
|
|
10157
10157
|
}),
|
|
10158
|
-
...(
|
|
10159
|
-
authorizes_upload_contract: opts
|
|
10158
|
+
...(opts.authorizesUploadContract && {
|
|
10159
|
+
authorizes_upload_contract: opts.authorizesUploadContract,
|
|
10160
10160
|
}),
|
|
10161
10161
|
},
|
|
10162
10162
|
};
|
|
10163
10163
|
let tx = await this.signer.prepareTransaction({
|
|
10164
10164
|
header: {
|
|
10165
|
-
...(
|
|
10166
|
-
...(
|
|
10167
|
-
...(
|
|
10168
|
-
...(
|
|
10169
|
-
...(
|
|
10165
|
+
...(opts.chainId && { chain_id: opts.chainId }),
|
|
10166
|
+
...(opts.rcLimit && { rc_limit: opts.rcLimit }),
|
|
10167
|
+
...(opts.nonce && { nonce: opts.nonce }),
|
|
10168
|
+
...(opts.payer && { payer: opts.payer }),
|
|
10169
|
+
...(opts.payee && { payee: opts.payee }),
|
|
10170
10170
|
},
|
|
10171
10171
|
operations: [operation],
|
|
10172
10172
|
});
|
|
10173
|
+
const optsSend = {
|
|
10174
|
+
broadcast: opts.broadcast,
|
|
10175
|
+
beforeSend: opts.beforeSend,
|
|
10176
|
+
};
|
|
10173
10177
|
// return result if the transaction will not be broadcasted
|
|
10174
|
-
if (!
|
|
10178
|
+
if (!opts.sendTransaction) {
|
|
10175
10179
|
const noWait = () => {
|
|
10176
10180
|
throw new Error("This transaction was not broadcasted");
|
|
10177
10181
|
};
|
|
@@ -10179,7 +10183,7 @@ class Contract {
|
|
|
10179
10183
|
tx = await this.signer.signTransaction(tx);
|
|
10180
10184
|
return { operation, transaction: { ...tx, wait: noWait } };
|
|
10181
10185
|
}
|
|
10182
|
-
const { transaction, receipt } = await this.signer.sendTransaction(tx,
|
|
10186
|
+
const { transaction, receipt } = await this.signer.sendTransaction(tx, optsSend);
|
|
10183
10187
|
return { operation, transaction, receipt };
|
|
10184
10188
|
}
|
|
10185
10189
|
/**
|
|
@@ -10495,14 +10499,17 @@ class Provider {
|
|
|
10495
10499
|
if (transactions &&
|
|
10496
10500
|
transactions[0] &&
|
|
10497
10501
|
transactions[0].containing_blocks)
|
|
10498
|
-
return
|
|
10502
|
+
return {
|
|
10503
|
+
blockId: transactions[0].containing_blocks[0],
|
|
10504
|
+
};
|
|
10499
10505
|
}
|
|
10500
10506
|
throw new Error(`Transaction not mined after ${timeout} ms`);
|
|
10501
10507
|
}
|
|
10502
10508
|
// byBlock
|
|
10503
10509
|
const findTxInBlocks = async (ini, numBlocks, idRef) => {
|
|
10504
10510
|
const blocks = await this.getBlocks(ini, numBlocks, idRef);
|
|
10505
|
-
let bNum = 0;
|
|
10511
|
+
let bNum = 0;
|
|
10512
|
+
let bId = "";
|
|
10506
10513
|
blocks.forEach((block) => {
|
|
10507
10514
|
if (!block ||
|
|
10508
10515
|
!block.block ||
|
|
@@ -10510,11 +10517,13 @@ class Provider {
|
|
|
10510
10517
|
!block.block.transactions)
|
|
10511
10518
|
return;
|
|
10512
10519
|
const tx = block.block.transactions.find((t) => t.id === txId);
|
|
10513
|
-
if (tx)
|
|
10520
|
+
if (tx) {
|
|
10514
10521
|
bNum = Number(block.block_height);
|
|
10522
|
+
bId = block.block_id;
|
|
10523
|
+
}
|
|
10515
10524
|
});
|
|
10516
10525
|
const lastId = blocks[blocks.length - 1].block_id;
|
|
10517
|
-
return [bNum, lastId];
|
|
10526
|
+
return [bNum, bId, lastId];
|
|
10518
10527
|
};
|
|
10519
10528
|
let blockNumber = 0;
|
|
10520
10529
|
let iniBlock = 0;
|
|
@@ -10529,18 +10538,24 @@ class Provider {
|
|
|
10529
10538
|
if (Number(headTopology.height) === blockNumber - 1 &&
|
|
10530
10539
|
previousId &&
|
|
10531
10540
|
previousId !== headTopology.id) {
|
|
10532
|
-
const [bNum, lastId] = await findTxInBlocks(iniBlock, Number(headTopology.height) - iniBlock + 1, headTopology.id);
|
|
10541
|
+
const [bNum, bId, lastId] = await findTxInBlocks(iniBlock, Number(headTopology.height) - iniBlock + 1, headTopology.id);
|
|
10533
10542
|
if (bNum)
|
|
10534
|
-
return
|
|
10543
|
+
return {
|
|
10544
|
+
blockId: bId,
|
|
10545
|
+
blockNumber: bNum,
|
|
10546
|
+
};
|
|
10535
10547
|
previousId = lastId;
|
|
10536
10548
|
blockNumber = Number(headTopology.height) + 1;
|
|
10537
10549
|
}
|
|
10538
10550
|
// eslint-disable-next-line no-continue
|
|
10539
10551
|
if (blockNumber > Number(headTopology.height))
|
|
10540
10552
|
continue;
|
|
10541
|
-
const [bNum, lastId] = await findTxInBlocks(blockNumber, 1, headTopology.id);
|
|
10553
|
+
const [bNum, bId, lastId] = await findTxInBlocks(blockNumber, 1, headTopology.id);
|
|
10542
10554
|
if (bNum)
|
|
10543
|
-
return
|
|
10555
|
+
return {
|
|
10556
|
+
blockId: bId,
|
|
10557
|
+
blockNumber: bNum,
|
|
10558
|
+
};
|
|
10544
10559
|
if (!previousId)
|
|
10545
10560
|
previousId = lastId;
|
|
10546
10561
|
blockNumber += 1;
|
|
@@ -10976,6 +10991,10 @@ class Signer {
|
|
|
10976
10991
|
}
|
|
10977
10992
|
if (c.chainId)
|
|
10978
10993
|
this.chainId = c.chainId;
|
|
10994
|
+
this.sendOptions = {
|
|
10995
|
+
broadcast: true,
|
|
10996
|
+
...c.sendOptions,
|
|
10997
|
+
};
|
|
10979
10998
|
}
|
|
10980
10999
|
/**
|
|
10981
11000
|
* Function to import a private key from the WIF
|
|
@@ -11124,21 +11143,24 @@ class Signer {
|
|
|
11124
11143
|
/**
|
|
11125
11144
|
* Function to sign and send a transaction. It internally uses
|
|
11126
11145
|
* [[Provider.sendTransaction]]
|
|
11127
|
-
* @param
|
|
11128
|
-
* if it is not signed yet
|
|
11129
|
-
* @param
|
|
11130
|
-
* different nodes in the network
|
|
11131
|
-
* @param _abis - Collection of Abis to parse the operations in the
|
|
11132
|
-
* transaction. This parameter is optional.
|
|
11133
|
-
* @returns
|
|
11146
|
+
* @param transaction - Transaction to send. It will be signed inside this
|
|
11147
|
+
* function if it is not signed yet
|
|
11148
|
+
* @param options - Options for sending the transaction
|
|
11134
11149
|
*/
|
|
11135
|
-
async sendTransaction(
|
|
11150
|
+
async sendTransaction(transaction, options) {
|
|
11136
11151
|
var _a;
|
|
11137
|
-
if (!
|
|
11138
|
-
|
|
11152
|
+
if (!transaction.signatures || !((_a = transaction.signatures) === null || _a === void 0 ? void 0 : _a.length))
|
|
11153
|
+
transaction = await this.signTransaction(transaction);
|
|
11139
11154
|
if (!this.provider)
|
|
11140
11155
|
throw new Error("provider is undefined");
|
|
11141
|
-
|
|
11156
|
+
const opts = {
|
|
11157
|
+
...this.sendOptions,
|
|
11158
|
+
...options,
|
|
11159
|
+
};
|
|
11160
|
+
if (opts.beforeSend) {
|
|
11161
|
+
await opts.beforeSend(transaction);
|
|
11162
|
+
}
|
|
11163
|
+
return this.provider.sendTransaction(transaction, opts.broadcast);
|
|
11142
11164
|
}
|
|
11143
11165
|
/**
|
|
11144
11166
|
* Function to recover the public key from hash and signature
|