diff --git a/docs/increase_paid_storage.md b/docs/increase_paid_storage.md index c6ce4a9959..b15a75c085 100644 --- a/docs/increase_paid_storage.md +++ b/docs/increase_paid_storage.md @@ -9,9 +9,11 @@ This helps resolve an issue where several operations on the same contract would For more information on this change, refer to this [MR](https://gitlab.com/tezos/tezos/-/merge_requests/5605) in the Tezos codebase. ## Examples -Similar to other operations, the Increase Paid Storage operation will be available in the Contract API (and later, the wallet API). +Similar to other operations, the Increase Paid Storage operation is available in the Contract and Wallet API -### Simple Usage +### Contract API + +#### Simple Usage ```js const op = await Tezos.contract.increasePaidStorage({ amount: 2, @@ -25,8 +27,8 @@ await op.confirmation(); After waiting for the operation confirmation, you will also have access to various getters of the operation such as `status`, `amount`, `destination`, `fee`, `gasLimit`, `errors`, `storageLimit`, `consumedMilligas`. -### Usage in Batches -```js +#### Usage in Batches +```typescript const op = await Tezos.contract .batch() .withOrigination({ @@ -45,12 +47,12 @@ const op = await Tezos.contract destination: 'SMART_CONTRACT_ADDRESS' }) .send(); - + await op.confirmation(); ``` or -```js +```typescript const op = await Tezos.contract.batch([ { kind: 'origination', @@ -69,4 +71,38 @@ const op = await Tezos.contract.batch([ await op.confirmation(); ``` -Both syntax will work fine for batching any operations, including `increase_paid_storage`. \ No newline at end of file +Both syntax will work fine for batching any operations, including `increase_paid_storage`. + +### Wallet API + +#### Usage Example +```typescript +const op = await Tezos.wallet.increasePaidStorage({ + amount: 1, + destination: simpleContractAddress +}).send(); +``` + +#### Usage in Batches +```typescript +const batch = await Tezos.wallet + .batch() + .withOrigination({ + balance: "1", + code: `parameter string; + storage string; + code {CAR; + PUSH string "Hello "; + CONCAT; + NIL operation; PAIR}; + `, + init: `"test"` + }) + .withIncreasePaidStorage({ + amount: 1, + destination: simpleContractAddress + }); + +const op = await batch.send(); +await op.confirmation(); +``` \ No newline at end of file diff --git a/docs/version.md b/docs/version.md index 6b9329f0f8..5a94fa1921 100644 --- a/docs/version.md +++ b/docs/version.md @@ -2,6 +2,68 @@ title: Versions author: Jev Bjorsell --- +# Taquito v15.1.0 +## Summary + +### New Features +- `@taquito/taquito` New provider support `PrepareProvider` to facilitate preparation of operations in Taquito. #2020 +- `@taquito/taquito` Support new operation `increase_paid_storage` on the wallet API #1768 + +### Bug Fixes +- Fixed a bug where `axios-fetch-adapter` was not returning the response body from errors, causing the wrong error to be captured by the calling method #2187 + +### Documentation +- Update Taquito website live code examples to use Ghostnet endpoint. #2224 + +### Internals +- Updated Beacon version to v3.3.1 [PR](https://github.com/ecadlabs/taquito/pull/2266) +- Updated Taquito Github Workflows to use Node LTS/Gallium (v16) [PR](https://github.com/ecadlabs/taquito/pull/2301) + +## `@taquito/taquito` - Added new provider `PrepareProvider` to facilitate operation preparation + +`PrepareProvider` now extends more control to the user to give them the ability to 'prepare' Tezos operations before forging and injection. The preparation step now can be done through the `TezosToolkit` class as such: + +```typescript +// example of a transaction operation preparation +const prepare = await Tezos.prepare.transaction({ + to: 'tz1KvJCU5cNdz5RAS3diEtdRvS9wfhRC7Cwj', + amount: 5 +}); +``` + +The expected output will look something like this: +```typescript +{ + opOb: { + branch: 'BLOCK_HASH', + contents: [ + { + kind: 'transaction', + fee: '391', + gas_limit: '101', + storage_limit: '1000', + amount: '5000000', + destination: 'tz1KvJCU5cNdz5RAS3diEtdRvS9wfhRC7Cwj', + source: 'PUBLIC_KEY_HASH', + counter: '1', + }, + ], + protocol: 'PROTOCOL_HASH', + }, + counter: 0, + } +``` + +## `@taquito/taquito` - Increase paid storage operation support in the wallet API +Taquito now supports `increase_paid_storage` operation in the Wallet API (previously only available in the Contract API). + +```typescript +const op = await Tezos.wallet.increasePaidStorage({ + amount: 1, + destination: simpleContractAddress +}).send(); +``` + # Taquito v15.0.1 ## Hotfix - Fixed a bug where the `local-forging` package was using an outdated version of the codec when it's instantiated without passing in a protocol hash. Updated so that the default value uses the current protocol hash. #2242 diff --git a/website/sidebars.js b/website/sidebars.js index 1cc97fd7dc..68435643b9 100644 --- a/website/sidebars.js +++ b/website/sidebars.js @@ -45,6 +45,7 @@ const sidebars = { 'multisig_doc', 'on_chain_views', 'originate', + 'prepare', 'rpc_nodes', 'rpc_package', 'signing', diff --git a/website/sidebars.json b/website/sidebars.json index d26973d456..d2dfd3dd89 100644 --- a/website/sidebars.json +++ b/website/sidebars.json @@ -24,6 +24,7 @@ "multisig_doc", "originate", "global_constant", + "prepare", "rpc_nodes", "rpc_package", "signing", diff --git a/website/versioned_docs/version-13.0.0/boilerplate.md b/website/versioned_docs/version-13.0.0/boilerplate.md deleted file mode 100644 index 2506a66e2b..0000000000 --- a/website/versioned_docs/version-13.0.0/boilerplate.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -title: Taquito boilerplate -author: Maksym Bykovskyy ---- - -### Framework agnostic demo - -Taquito boilerplate is a framework-agnostic starter kit for developing web-based applications running on the Tezos network. - -To get started with the Taquito boilerplate, please refer to the [Getting Started][get-started] section in the README found in the [taquito-boilerplate][repo] repository in Github. - -[get-started]: https://github.com/ecadlabs/taquito-boilerplate#getting-started -[repo]: https://github.com/ecadlabs/taquito-boilerplate - -### React demo - -You can also download a demo app written in React to try Taquito. The app's template is available in the [Taquito React template repo][taquito-react-template] and only requires a few commands to be up and running. - -[taquito-react-template]: https://github.com/ecadlabs/taquito-react-template diff --git a/website/versioned_docs/version-13.0.0/rpc_nodes.md b/website/versioned_docs/version-13.0.0/rpc_nodes.md deleted file mode 100644 index 1f2dc558e3..0000000000 --- a/website/versioned_docs/version-13.0.0/rpc_nodes.md +++ /dev/null @@ -1,42 +0,0 @@ ---- -title: RPC nodes -author: Roxane Letourneau ---- - -## What to consider when choosing a node - -- **Trust**: Choose a node that you can trust the people who operate it. - - It should not alter your requests, for example, changing the operation data before forging it. - - It should not censor your operations; you want to know that your operations will reach the network. -- **Reliability**: Consider your requirements for uptime, and choose your node option accordingly. If node availability is critical for your user-case, consider self-hosting a node or contracting someone to operate a node specifically for you. -- ** End-points support**: Public nodes have different policies on the end-points that they expose. Your use case may require specific end-points to be available to your app. We have made a suite of [integration tests](rpc_nodes_integration_test.md) for the Taquito RPC package. These tests show what RPC end-points are available on a given node. These tests are available here: integration-tests/rpc-nodes.spec.ts. - -## List of community-run nodes - -*If you are aware of a public node missing from our list or our information is inaccurate, please help us by submitting an issue or pull request on our GitHub page.* - -| Provider | Net | URL | Header | -|------------------|-------------|------------------------------------|-------| -| ECAD Labs | Mainnet | https://mainnet.api.tez.ie | [Check](https://mainnet.api.tez.ie/chains/main/blocks/head/header) | -| ECAD Labs | Ithacanet | https://ithacanet.ecadinfra.com | [Check](https://ithacanet.ecadinfra.com/chains/main/blocks/head/header) | -| ECAD Labs | Jakartanet | https://jakartanet.ecadinfra.com | [Check](https://jakartanet.ecadinfra.com/chains/main/blocks/head/header) | -| SmartPy | Mainnet | https://mainnet.smartpy.io | [Check](https://mainnet.smartpy.io/chains/main/blocks/head/header) | -| SmartPy | Ithacanet | https://ithacanet.smartpy.io/ | [Check](https://ithacanet.smartpy.io/chains/main/blocks/head/header) | -| Tezos Foundation | Mainnet | https://rpc.tzbeta.net/ | [Check](https://rpc.tzbeta.net/chains/main/blocks/head/header) | -| Tezos Foundation | Jakartanet | https://rpczero.tzbeta.net/ | [Check](https://rpczero.tzbeta.net/chains/main/blocks/head/header) | -| GigaNode | Mainnet | https://mainnet-tezos.giganode.io | [Check](https://mainnet-tezos.giganode.io/chains/main/blocks/head/header) | -| GigaNode | Ithacanet | https://testnet-tezos.giganode.io/ | [Check](https://testnet-tezos.giganode.io/chains/main/blocks/head/header) | -| Marigold | Mainnet | https://mainnet.tezos.marigold.dev/ | [Check](https://mainnet.tezos.marigold.dev/chains/main/blocks/head/header) | -| Marigold | Ithacanet | https://ithacanet.tezos.marigold.dev/ | [Check](https://ithacanet.tezos.marigold.dev/chains/main/blocks/head/header) | -| Marigold | Jakartanet | https://jakartanet.tezos.marigold.dev/ | [Check](https://jakartanet.tezos.marigold.dev/chains/main/blocks/head/header) | - -## How to run a node - -Running a node is a good way of contributing to Tezos by increasing the decentralization of the network. - -There are many ways to set up a node. Here are some links providing general instructions: - -- [Use docker images](https://tezos.gitlab.io/introduction/howtoget.html#docker-images) -- [Build from sources](https://tezos.gitlab.io/introduction/howtoget.html#docker-images) -- [Use Ansible Role](https://github.com/ecadlabs/ansible-role-tezos-node/blob/master/README.md) - diff --git a/website/versioned_docs/version-15.1.0/amendment_and_voting.md b/website/versioned_docs/version-15.1.0/amendment_and_voting.md new file mode 100644 index 0000000000..04ce697a79 --- /dev/null +++ b/website/versioned_docs/version-15.1.0/amendment_and_voting.md @@ -0,0 +1,46 @@ +--- +title: Amendment and Voting +id: amendment_and_voting +author: Davis Sawali +--- + +In Tezos, the economic protocol can be amended by proposing and voting for changes. The protocol change will happen depending on the result of the votes. + +## Proposals +A `Proposals` operation can be injected during a **Proposal Period**. It allows a delegate to submit a proposal identified by a protocol hash. Submitting a proposal also upvotes said proposal during the **Proposal Period**, not to be confused with *Ballot* votes in the section below. + +The proposal with the most support is selected and will move on to the **Exploration Period**. + +:::info +Note: Each delegate can submit a maximum of 20 proposals +::: + +### Example +The `Proposals` operation is currently available in the Contract API, and can be used as such: +```typescript +const op = await Tezos.contract.proposals({ + proposals: ['PROTOCOL_HASH1', 'PROTOCOL_HASH2'] +}); + +await op.confirmation(); +``` +- `proposals` parameter takes in a list of Protocol hash(es) you would like to submit. + +## Ballot +The `Ballot` operation allows delegates to cast one `Yay`, `Nay`, or `Pass` ballot on a selected proposal. Delegates are only able to cast their votes during the **Exploration period** and the **Promotion period**. + +### Example +The `Ballot` operation is currently available in the Contract API, and can be used as such: +```typescript +const op = await Tezos.contract.ballot({ + proposal: 'PROTOCOL_HASH', + ballot: 'BALLOT_VOTE_STRING' +}); + +await op.confirmation(); +``` +- `proposal` is the string that you (a delegate) would like to point your ballot towards. Information on the current proposal can be obtained by calling [this RPC endpoint](https://tezos.gitlab.io/alpha/rpc.html#get-block-id-votes-current-proposal). Alternatively, you could also get the protocol hash by using Taquito's RPC Client method `RpcClient.getCurrentProposal`. For more information on the `RpcClient` refer to [this document](https://tezostaquito.io/docs/rpc_package/) +- `ballot` is your ballot vote (`yay`, `nay`, or `pass`) + + +For more information in regards to the Amendment & Voting Process, refer to [this document](https://tezos.gitlab.io/alpha/voting.html) diff --git a/website/versioned_docs/version-15.1.0/ballot.md b/website/versioned_docs/version-15.1.0/ballot.md new file mode 100644 index 0000000000..4e0af62414 --- /dev/null +++ b/website/versioned_docs/version-15.1.0/ballot.md @@ -0,0 +1,23 @@ +--- +title: Ballot Operation +id: ballot +author: Davis Sawali +--- + +The `Ballot` operation allows delegates to cast one `Yay`, `Nay`, or `Pass` ballot on a selected proposal. Delegates are only able to cast their votes during the **Exploration period** and the **Promotion period** + +## Examples +The `Ballot` operation is currently available in the Contract API, and can be used as such: +```typescript +const op = await Tezos.contract.ballot({ + proposal: 'PROPOSAL_HASH', + ballot: 'BALLOT_VOTE_STRING' +}); + +await op.confirmation(); +``` +- `proposal` is the proposal hash string that you (a delegate) would like to point your ballot towards. Information on the current proposal can be obtained by calling [this RPC endpoint](https://tezos.gitlab.io/alpha/rpc.html#get-block-id-votes-current-proposal). Alternatively, you could also get the proposal hash by using Taquito's RPC Client method `RpcClient.getCurrentProposal`. For more information on the `RpcClient` refer to [this document](https://tezostaquito.io/docs/rpc_package/) +- `ballot` is your ballot vote (`yay`, `nay`, or `pass`) + + +For more information in regards to the Amendment (and Voting) Process refer to [this document](https://tezos.gitlab.io/alpha/voting.html) diff --git a/website/versioned_docs/version-13.0.0/batch-api.md b/website/versioned_docs/version-15.1.0/batch-api.md similarity index 96% rename from website/versioned_docs/version-13.0.0/batch-api.md rename to website/versioned_docs/version-15.1.0/batch-api.md index fa8dc02212..e031e70a02 100644 --- a/website/versioned_docs/version-13.0.0/batch-api.md +++ b/website/versioned_docs/version-15.1.0/batch-api.md @@ -20,7 +20,11 @@ await op1.confirmation(); await op2.confirmation(); /* - * Error Message returned by the node: + * Error Message returned by the node (since Kathmandu): + * Error while applying operation opHash: + * Only one manager operation per manager per block allowed (found opHash2 with Xtez fee). + * + * Error Message that was returned by the node (before Kathmandu): * "Error while applying operation opWH2nEcmmzUwK4T6agHg3bn9GDR7fW1ynqWL58AVRAb7aZFciD: * branch refused (Error: * Counter 1122148 already used for contract tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb (expected 1122149))" diff --git a/website/versioned_docs/version-13.0.0/beaconwallet-singleton.md b/website/versioned_docs/version-15.1.0/beaconwallet-singleton.md similarity index 96% rename from website/versioned_docs/version-13.0.0/beaconwallet-singleton.md rename to website/versioned_docs/version-15.1.0/beaconwallet-singleton.md index e21efe561f..427793ad7e 100644 --- a/website/versioned_docs/version-13.0.0/beaconwallet-singleton.md +++ b/website/versioned_docs/version-15.1.0/beaconwallet-singleton.md @@ -3,6 +3,10 @@ title: BeaconWallet singleton author: Claude Barde --- +:::caution Outdated documentation +Since version 14, Taquito uses the beacon-dapp's `getDAppClientInstance` method instead of the `new DAppClient`. This new method ensures that only one instance is created. The same cached instance is returned if called multiple times. +::: + # How to use a single instance of the BeaconWallet? > TL;DR: in order to avoid unexpected problems with the Beacon wallet instance, there should be only one __new BeaconWallet(options)__ in your whole app. diff --git a/website/versioned_docs/version-13.0.0/cancel_http_requests.md b/website/versioned_docs/version-15.1.0/cancel_http_requests.md similarity index 100% rename from website/versioned_docs/version-13.0.0/cancel_http_requests.md rename to website/versioned_docs/version-15.1.0/cancel_http_requests.md diff --git a/website/versioned_docs/version-13.0.0/complex_parameters.md b/website/versioned_docs/version-15.1.0/complex_parameters.md similarity index 88% rename from website/versioned_docs/version-13.0.0/complex_parameters.md rename to website/versioned_docs/version-15.1.0/complex_parameters.md index d875181675..a85f187f87 100644 --- a/website/versioned_docs/version-13.0.0/complex_parameters.md +++ b/website/versioned_docs/version-15.1.0/complex_parameters.md @@ -8,8 +8,6 @@ This section shows how Taquito can be used to : - Call a contract function with a complex object as a parameter - Pass null value to some optional arguments -The source code of the contract used in the following examples is available [here](https://better-call.dev/carthagenet/KT1TRHzT3HdLe3whe35q6rNxavGx8WVFHSpH/code). - ## Origination of a contract with complex storage Here we have the storage of the contract defined in Michelson. @@ -54,7 +52,7 @@ An annotation identifies every argument. Therefore we can ignore optional values ```js live noInline // import { TezosToolkit, MichelsonMap } from '@taquito/taquito'; // import { importKey } from '@taquito/signer'; -// const Tezos = new TezosToolkit('https://ithacanet.ecadinfra.com'); +// const Tezos = new TezosToolkit('https://ghostnet.ecadinfra.com'); //%data const dataMap = new MichelsonMap(); @@ -85,7 +83,7 @@ const validatorsMap = new MichelsonMap(); //key is a nat, value is an address validatorsMap.set('1', 'tz1btkXVkVFWLgXa66sbRJa8eeUSwvQFX4kP') -importKey(Tezos, emailExample, passwordExample, mnemonicExample, secretExample) +importKey(Tezos, secretKey) .then(() => { return Tezos.contract.originate({ code : contractJson, @@ -131,12 +129,12 @@ The way to write the parameter when calling the function of a contract with Taqu ```js live noInline // import { TezosToolkit, MichelsonMap } from '@taquito/taquito'; -// const Tezos = new TezosToolkit('https://ithacanet.ecadinfra.com') +// const Tezos = new TezosToolkit('https://ghostnet.ecadinfra.com') // import { importKey } from '@taquito/signer'; -importKey(Tezos, emailExample, passwordExample, mnemonicExample, secretExample) +importKey(Tezos, secretKey) .then(signer => { - return Tezos.contract.at('KT1Rf9znRBHPW4BW8NbFuYeHKdykrAyb21si') + return Tezos.contract.at('KT1B2exfRrGMjfZqWK1bDemr3nBFhHsUWQuN') }).then(myContract => { const dataMap = new MichelsonMap(); dataMap.set("Hello World", { bool : true }) @@ -149,12 +147,12 @@ importKey(Tezos, emailExample, passwordExample, mnemonicExample, secretExample) ```js live noInline // import { TezosToolkit, MichelsonMap } from '@taquito/taquito'; -// const Tezos = new TezosToolkit('https://ithacanet.ecadinfra.com') +// const Tezos = new TezosToolkit('https://ghostnet.ecadinfra.com') // import { importKey } from '@taquito/signer'; -importKey(Tezos, emailExample, passwordExample, mnemonicExample, secretExample) +importKey(Tezos, secretKey) .then(signer => { - return Tezos.contract.at('KT1Rf9znRBHPW4BW8NbFuYeHKdykrAyb21si') + return Tezos.contract.at('KT1B2exfRrGMjfZqWK1bDemr3nBFhHsUWQuN') }).then(myContract => { const dataMap = new MichelsonMap(); dataMap.set("Hello World", { bool : true }) @@ -171,7 +169,7 @@ importKey(Tezos, emailExample, passwordExample, mnemonicExample, secretExample) println(`Waiting for ${op.hash} to be confirmed...`); return op.confirmation(1).then(() => op.hash); }).then(hash => { - println(`Operation injected: https://better-call.dev/ithacanet/KT1Rf9znRBHPW4BW8NbFuYeHKdykrAyb21si/operations`); + println(`Operation injected: https://better-call.dev/ghostnet/KT1B2exfRrGMjfZqWK1bDemr3nBFhHsUWQuN/operations`); }).catch(error => println(`Error: ${JSON.stringify(error, null, 2)}`)); ``` #### Call the set_child_record function when optional arguments are null @@ -180,12 +178,12 @@ The `address %address` and the `nat %ttl` of the `set_child_record` function are ```js live noInline // import { TezosToolkit, MichelsonMap } from '@taquito/taquito'; -// const Tezos = new TezosToolkit('https://ithacanet.ecadinfra.com') +// const Tezos = new TezosToolkit('https://jakartanet.ecadinfra.com') // import { importKey } from '@taquito/signer'; -importKey(Tezos, emailExample, passwordExample, mnemonicExample, secretExample) +importKey(Tezos, secretKey) .then(signer => { - return Tezos.contract.at('KT1Rf9znRBHPW4BW8NbFuYeHKdykrAyb21si') + return Tezos.contract.at('KT1B2exfRrGMjfZqWK1bDemr3nBFhHsUWQuN') }).then(myContract => { const dataMap = new MichelsonMap(); dataMap.set("Hello World", { nat : '3' }) @@ -202,6 +200,6 @@ importKey(Tezos, emailExample, passwordExample, mnemonicExample, secretExample) println(`Waiting for ${op.hash} to be confirmed...`); return op.confirmation(1).then(() => op.hash); }).then(hash => { - println(`Operation injected: https://better-call.dev/ithacanet/KT1Rf9znRBHPW4BW8NbFuYeHKdykrAyb21si/operations`); + println(`Operation injected: https://better-call.dev/ghostnet/KT1B2exfRrGMjfZqWK1bDemr3nBFhHsUWQuN/operations`); }).catch(error => println(`Error: ${JSON.stringify(error, null, 2)}`)); ``` \ No newline at end of file diff --git a/website/versioned_docs/version-13.0.0/confirmation_event_stream.md b/website/versioned_docs/version-15.1.0/confirmation_event_stream.md similarity index 100% rename from website/versioned_docs/version-13.0.0/confirmation_event_stream.md rename to website/versioned_docs/version-15.1.0/confirmation_event_stream.md diff --git a/website/versioned_docs/version-15.1.0/consensus_key.md b/website/versioned_docs/version-15.1.0/consensus_key.md new file mode 100644 index 0000000000..7b9b84b478 --- /dev/null +++ b/website/versioned_docs/version-15.1.0/consensus_key.md @@ -0,0 +1,39 @@ +--- +title: Consensus Keys +author: Davis Sawali & Hui-An Yang +--- + +The "consensus key" feature allows bakers to use a different key, called the consensus key. It will allow for baking and signing consensus operations (i.e. pre-endorsements and endorsements). For more detailed information on consensus keys, refer to [this documentation](https://tezos.gitlab.io/protocols/015_lima.html?highlight=update%20consensus%20key#consensus-key) + +Starting from Lima protocol, these 2 new operations will be available: + +## Update Consensus Key +This is a manager operation that must be signed by the manager key of the baker. This operation updates the consensus key of the baker to `PUBLIC_KEY` starting from the current cycle plus `PRESERVED_CYCLES + 1`. A consensus key can only be used by a single baker, the operation will fail otherwise. + +### Examples +```typescript +const op = await Tezos.contract.updateConsensusKey({ + pk: 'PUBLIC_KEY' +}); + +await op.confirmation(); +``` +- `pk` is the public key you want the consensus key to point to + + +## Drain Delegate +This is an operation that must be signed by the active consensus key `consensus_pkh` of the baker `baker_pkh`. This operation immediately transfers all the spendable balance of the `baker_pkh`’s implicit account into the `destination_pkh` implicit account. It has no effect on the frozen balance. This operation is included in pass 2 (anonymous operations). So drain operations don’t compete with regular manager operations for gas and block size quota; the 1M restriction (one-operation-per-manager-per-block) applies to drain operations as well, meaning that a drain for a baker and a transfer operation from the same baker are in conflict. As an incentive for bakers to include drain operations, a fixed fraction of the drained baker’s spendable balance is transferred as fees to the baker that includes the operation, i.e. the maximum between 1tz or 1% of the spendable balance. + +### Examples +```typescript +const drain = await Tezos.contract.drainDelegate({ + consensus_key: 'CONSENSUS_PKH', + delegate: 'BAKER_PKH', + destination: 'DESTINATION_PKH', +}); +await drain.confirmation(); +``` + +- `consensus_key` is the public key hash of the updated consensus key +- `delegate` is the public key hash of the baker/delegate +- `destination` is the public key hash of the destination account diff --git a/website/versioned_docs/version-13.0.0/contract-test-collection.md b/website/versioned_docs/version-15.1.0/contract-test-collection.md similarity index 92% rename from website/versioned_docs/version-13.0.0/contract-test-collection.md rename to website/versioned_docs/version-15.1.0/contract-test-collection.md index d1b45a703f..b98e49308e 100644 --- a/website/versioned_docs/version-13.0.0/contract-test-collection.md +++ b/website/versioned_docs/version-15.1.0/contract-test-collection.md @@ -1,5 +1,5 @@ --- -title: Taquito Smart Contract Collection +title: Smart contract collection id: contracts_collection author: Michael Kernaghan --- @@ -49,7 +49,7 @@ Each contract description will include the storage in Michelson and the storage ## IncrementContract -[KT1A3dyvS4pWd9b9yLLMBKLxc6S6G5b58BsK](https://better-call.dev/ithacanet/KT1A3dyvS4pWd9b9yLLMBKLxc6S6G5b58BsK/code) +[KT1Hn49LVCTemdbkPpZEZnzXGm1rqtQs2HH2](https://better-call.dev/jakartanet/KT1Hn49LVCTemdbkPpZEZnzXGm1rqtQs2HH2/code) This contract serves as the default introductory example on the [Ligo-WEB-IDE](https://ide.ligolang.org/p/CelcoaDRK5mLFDmr5rSWug) It has two endpoints, %decrement and %increment. The contract is used to demo addition and subtraction by a smart contract. This contract has neither an FA1.2 nor an FA2 interface. @@ -83,7 +83,7 @@ storage: 1; ## MichelsonMapContract -[KT1NzbR52g8TBAKzDH5TXEtxiARFuwzvC4hi](https://better-call.dev/ithacanet/KT1NzbR52g8TBAKzDH5TXEtxiARFuwzvC4hi/code) +[KT1NASCf1Dr3SZu4RewZSRjd4mHvh8uADxf2](https://better-call.dev/jakartanet/KT1NASCf1Dr3SZu4RewZSRjd4mHvh8uADxf2/code) The contract supports a [Michelson Tutorial](https://tezostaquito.io/docs/michelsonmap). It has a default endpoint that takes a pair of an address and an amount of tez. @@ -117,7 +117,7 @@ storage: MichelsonMap ## GenericMultisigContract -[KT19oXBkAz1njVaTEypSzxGorWAFy6wnLLe1](https://better-call.dev/ithacanet/KT19oXBkAz1njVaTEypSzxGorWAFy6wnLLe1/code) +[KT1L3hwPB7M5GrvXW7CY3DV65JYBcTSyWVv4](https://better-call.dev/jakartanet/KT1L3hwPB7M5GrvXW7CY3DV65JYBcTSyWVv4/code) This contact has a stored counter. The contract is used in some Taquito Integration Tests for generic tests of such features as transfers. @@ -154,13 +154,13 @@ storage (pair (nat %stored_counter) (pair (nat %threshold) (list %keys key))); # Lambda Contracts -Taquito internally contains a list of lambda contracts. Thus, there is no need to deploy a lambda contract if you are using Mainnet, Ithacanet, or Hangzhounet. Taquito will detect the current network and use the appropriate lambda contract. +Taquito internally contains a list of lambda contracts. Thus, there is no need to deploy a lambda contract if you are using Mainnet, jakartanet, or Hangzhounet. Taquito will detect the current network and use the appropriate lambda contract. Lambda views are introduced in [Tzip4](https://gitlab.com/tezos/tzip/-/blob/master/proposals/tzip-4/tzip-4.md#view-entrypoints). ## LambdaViewContract -[KT1D2eQBuuaH4rv8HuoRdv2tgDdS3DoqPepN](https://better-call.dev/ithacanet/KT1D2eQBuuaH4rv8HuoRdv2tgDdS3DoqPepN/code) +[KT1Kmu8xRvMsJs3zMvgoCdv7Da2twfZ2qTEg](https://better-call.dev/jakartanet/KT1Kmu8xRvMsJs3zMvgoCdv7Da2twfZ2qTEg/code) Not a supported FA1.2 contract. Almost an Fa2 interface but it is missing update_operators. @@ -212,7 +212,7 @@ const allowances = new MichelsonMap(); ## LambdaViewWithTokenContract -[KT1RviHjggYhesZAxxMsi8dwibm4maHqCcf4](https://better-call.dev/ithacanet/KT1RviHjggYhesZAxxMsi8dwibm4maHqCcf4/code) +[KT1Ff5pAQ9PT8kBgcDuKU6daRbEhnfWb9TY7](https://better-call.dev/jakartanet/KT1Ff5pAQ9PT8kBgcDuKU6daRbEhnfWb9TY7/code) This contact is another example of a Lambda contract, this time involving a token. It is not a supported FA1.2 contract. The contract does have the three entry points that define an FA2 interface - . @@ -292,7 +292,7 @@ const op = await tezos.contract.originate({ ## MapWithPairasMapContract -[KT1NoACbTF2wh2Zrz3aZLC5rr2nAqsBFa9gc](https://better-call.dev/ithacanet/KT1NoACbTF2wh2Zrz3aZLC5rr2nAqsBFa9gc/code) +[KT1ASaoLYgdJBz3mWUic6e6n6f3RFn5u9uAP](https://better-call.dev/jakartanet/KT1ASaoLYgdJBz3mWUic6e6n6f3RFn5u9uAP/code) A simple contract with a default entrypoint that takes unit. Not a supported FA1.2 contract. @@ -359,7 +359,7 @@ const op = await tezos.contract.originate({ ## MapWithComplexKeysContract -[KT1HpDxVK67YxzAUs7Ubp7R7KzV3i1X1nZtD](https://better-call.dev/ithacanet/KT1HpDxVK67YxzAUs7Ubp7R7KzV3i1X1nZtD/code) +[KT1G9UQsSbBej2PKpPHcs9su4ywCe3jcX7ED](https://better-call.dev/jakartanet/KT1G9UQsSbBej2PKpPHcs9su4ywCe3jcX7ED/code) This contract has a single default entrypoint that takes unit and produces a map: @@ -441,7 +441,7 @@ Note the lack of annotations in the Michelson for the storage. If the storage do ## MapWithInitialStorageContract -[KT1DXCqq3suQKEUoC4UtzNi1c6jNcunGynas](https://better-call.dev/ithacanet/KT1DXCqq3suQKEUoC4UtzNi1c6jNcunGynas/code) +[KT1Na57o4VNiX1dFP2ookfRBFnQLboLwV4u5](https://better-call.dev/jakartanet/KT1Na57o4VNiX1dFP2ookfRBFnQLboLwV4u5/code) Taquito provides a get method of the MichelsonMap on storage of type Map. We can only change contract storage by calling the function provided by the contract. The main function on this Smart Contract is decreasing the value of the current_stock associated with the key 1. @@ -476,7 +476,7 @@ storageMap.set('3', { current_stock: '50', max_price: '60' }); ## MapWithMapandBigmapContract -[KT1JmL7j8CY371kRF2oZoJmzi7EUWbLPjEqZ](https://better-call.dev/ithacanet/KT1JmL7j8CY371kRF2oZoJmzi7EUWbLPjEqZ/code) +[KT1Na57o4VNiX1dFP2ookfRBFnQLboLwV4u5](https://better-call.dev/jakartanet/KT1Na57o4VNiX1dFP2ookfRBFnQLboLwV4u5/code) The get method of the MichelsonMap class accesses the values of the map and values of the bigMap. The difference is that the value gets returned directly for a map while the get method on a bigMap returns a promise. @@ -502,7 +502,7 @@ storage (pair (big_map %thebigmap (pair nat address) int) ```js Tezos.contract - .at('KT1JmL7j8CY371kRF2oZoJmzi7EUWbLPjEqZ') + .at('KT1RBE127YSA96FwCYrA8sazvr8pt1TYaThS') .then((myContract) => { return myContract .storage() @@ -537,7 +537,7 @@ Tezos.contract ## BigMapsMultipleValuesContract -[KT1MMfuLrpBufDyxrLFkxBNE73Lp3AWkHivG](https://better-call.dev/ithacanet/KT1MMfuLrpBufDyxrLFkxBNE73Lp3AWkHivG/code) +[KT1CcxnvcSm1SdSHUv2KptECfJ97ZMNbTPu6](https://better-call.dev/jakartanet/KT1CcxnvcSm1SdSHUv2KptECfJ97ZMNbTPu6/code) This contract has an FA1.2 interface. @@ -595,7 +595,7 @@ const op = await tezos.contract.originate({ ## BigMapsComplexStorageContract -[KT1Rf9znRBHPW4BW8NbFuYeHKdykrAyb21si](https://better-call.dev/ithacanet/KT1Rf9znRBHPW4BW8NbFuYeHKdykrAyb21si/code) +[KT1GhkZzKSBjMxY4kKURNhhYiSVuTyBaGspe](https://better-call.dev/jakartanet/KT1GhkZzKSBjMxY4kKURNhhYiSVuTyBaGspe/code) This contract is used in many Taquito documentation Live Code Examples to demonstrate how to get data from a complex storage. Not a supported FA1.2 contract. @@ -681,7 +681,7 @@ const op = await tezos.contract.originate({ ## BigMapsWithLedgerContract -[KT1GxL96iix8MCTsCA1DBVfnZ4Gdk7EZW4Eq](https://better-call.dev/ithacanet/KT1GxL96iix8MCTsCA1DBVfnZ4Gdk7EZW4Eq/code) +[KT1AbzoXYgGXjCD3Msi3spuqa5r5MP3rkvM9](https://better-call.dev/jakartanet/KT1AbzoXYgGXjCD3Msi3spuqa5r5MP3rkvM9/code) This contract is used in Taquito integration tests. It is not a FA1.2 contract, since Entrypoint "transfer" has type (pair (pair (address %0) (address %1)) (nat %2)), but should have type (pair address address nat). Also not an FA2 contract as it does not have an entrypoint for update_operators. @@ -737,7 +737,7 @@ const opknownBigMapContract = await tezos.contract.originate({ ## BigMapPackContract -[KT1N5Z6hh8SuJgQGoh7QQfUAeofNV4NzKpbn](https://better-call.dev/ithacanet/KT1N5Z6hh8SuJgQGoh7QQfUAeofNV4NzKpbn/code) +[KT1Hrp5i3P5BUATvkP7scdqY5PHBmYyz3CNA](https://better-call.dev/jakartanet/KT1Hrp5i3P5BUATvkP7scdqY5PHBmYyz3CNA/code) By default, a call to an RPC node is used to pack data when fetching values from a big map. Big map keys need to be serialized or packed and Taquito relies on the PACK functionality of a Tezos RPC node to pack the big map keys. This may be considered inefficient as it adds a request to a remote node to fetch data. @@ -792,7 +792,7 @@ Views are meant to be called by a contract using the Michelson Instruction View This contract is used to demonstrate On Chain views. It calls the view 'fib' in another contract called contractTopLevelViews. -[KT1EcJTojUXgbMj2s7VowWTxs9ca4qSUqW4s](https://better-call.dev/ithacanet/KT1EcJTojUXgbMj2s7VowWTxs9ca4qSUqW4s/code) +[KT1VzRnJRGx6uuvKur9AejKZmiY2eTDrTwVy](https://better-call.dev/jakartanet/KT1VzRnJRGx6uuvKur9AejKZmiY2eTDrTwVy/code) #### Entrypoints @@ -830,7 +830,7 @@ view "add" nat nat { UNPAIR ; ADD } ; which can be called by other contracts to calculate and return some value. -[KT1H7Bg7r7Aa9sci2hoJtmTdS7W64aq4vev8](https://better-call.dev/ithacanet/KT1H7Bg7r7Aa9sci2hoJtmTdS7W64aq4vev8/code) +[KT1CpgZcWr45Arc2p6q4axM2f23N3Aujyv1D](https://better-call.dev/jakartanet/KT1CpgZcWr45Arc2p6q4axM2f23N3Aujyv1D/code) #### Entrypoints @@ -864,7 +864,7 @@ Tzip-7 introduced the approvable ledger: [Tzip-7](https://gitlab.com/tezos/tzip/ ## TokenContract -[KT1ERpZEpgtXni64q87VQd6MxgSMrt6Ek65o](https://better-call.dev/ithacanet/KT1ERpZEpgtXni64q87VQd6MxgSMrt6Ek65o/code) +[KT1AhKTHfwKvEQeJ13X9M1TSF6pGJnZZCCau](https://better-call.dev/jakartanet/KT1AhKTHfwKvEQeJ13X9M1TSF6pGJnZZCCau/code) - [A Beginner's Guide to Tezos Tzip-7 Proposal](https://claudebarde.medium.com/a-beginners-guide-to-tezos-tzip-7-proposal-90a8b816af7e) @@ -930,7 +930,7 @@ A contract has an FA2 interface if it has entrypoints: transfer, balance_of, and ## Tzip12BigMapOffChainContract -[KT1PVTW2QkkSsMsnW5GzNweGbsxWbGuBYFmo](https://better-call.dev/ithacanet/KT1PVTW2QkkSsMsnW5GzNweGbsxWbGuBYFmo/code) +[KT1MPzoNmHvDfGpUupVyKVhPkz5iasdT7tZA](https://better-call.dev/jakartanet/KT1MPzoNmHvDfGpUupVyKVhPkz5iasdT7tZA/code) This contract has an FA2 interface. @@ -1061,7 +1061,7 @@ Each of the following contracts is used to demonstrate an aspect of getMetadata. In this example the storage holds the metadata in a bigmap. -[KT1GL5WBtKc6PgFAk4cSGp5Dg8RSXQPk4zkR](https://better-call.dev/ithacanet/KT1GL5WBtKc6PgFAk4cSGp5Dg8RSXQPk4zkR/code) +[KT1UCrgZ3xpuMQaHGgZv5FmYVL1ST6sACSsa](https://better-call.dev/jakartanet/KT1UCrgZ3xpuMQaHGgZv5FmYVL1ST6sACSsa/code) #### Entrypoints: @@ -1126,7 +1126,7 @@ homepage: https://tezostaquito.io/ ## Tzip16HTTPSContract -[KT1Qrn8qpdZAFwuzh6qrnA3uA2bQJkVdMLRr](https://better-call.dev/ithacanet/KT1Qrn8qpdZAFwuzh6qrnA3uA2bQJkVdMLRr/code) +[KT1C1EJh8zizUjEyRJ1BunqL58w2u4Zwv6o7](https://better-call.dev/jakartanet/KT1C1EJh8zizUjEyRJ1BunqL58w2u4Zwv6o7/code) In this example the storage holds a URL that refers to the metadata. @@ -1186,7 +1186,7 @@ homepage: https://github.com/ecadlabs/taquito ## Tzip16SHA256Contract -[KT1FYBzqkMQ5g4XRiHenHbN43xVgFEEEoPHu](https://better-call.dev/ithacanet/KT1FYBzqkMQ5g4XRiHenHbN43xVgFEEEoPHu/code) +[KT1TUufULv5wbZeTRxEzdR7eBzGu6kXBMinS](https://better-call.dev/jakartanet/KT1TUufULv5wbZeTRxEzdR7eBzGu6kXBMinS/code) In this example the storage holds a URL encrypted with SHA 256 that refers to the metadata. @@ -1250,7 +1250,7 @@ homepage: https://github.com/ecadlabs/taquito ## Tzip16IPFSContract -[KT1PT8xPJZovECeVwAxuSSzAAoKok9EYmy2w](https://better-call.dev/ithacanet/KT1PT8xPJZovECeVwAxuSSzAAoKok9EYmy2w/code) +[KT1BJLSSAzTBMVWKbTnGE3UYWMopW2VZ8Mb3](https://better-call.dev/jakartanet/KT1BJLSSAzTBMVWKbTnGE3UYWMopW2VZ8Mb3/code) In this example the storage holds an IPFS location that refers to the metadata. @@ -1309,7 +1309,7 @@ homepage: https://github.com/ecadlabs/taquitoj ## Tzip16OffChainContractJSON -[KT1TzUzfjd8cZsFD3YfuFxKRgCnireksh8M7](https://better-call.dev/ithacanet/KT1TzUzfjd8cZsFD3YfuFxKRgCnireksh8M7/code) +[KT1JJm8dr4JzCMZRN31ccoWL2K49q1oQAd1Q](https://better-call.dev/jakartanet/KT1JJm8dr4JzCMZRN31ccoWL2K49q1oQAd1Q/code) This contract has a view named `someJson` that can be found in the metadata. When we inspect those metadata, we can see that this view takes no parameter and has a returnType of bytes. @@ -1360,7 +1360,7 @@ license: MIT ## Tzip16OffChainContractMultiply -[KT1Q1PFYduhRqWohspCcWdZ7j6mDg5xrgqJG](https://better-call.dev/ithacanet/KT1Q1PFYduhRqWohspCcWdZ7j6mDg5xrgqJG/code) +[KT1H3ZyFYochQdjZ29ed3yBfPRy6ga4WdZXR](https://better-call.dev/jakartanet/KT1H3ZyFYochQdjZ29ed3yBfPRy6ga4WdZXR/code) This contract has a view named `multiply-the-nat-in-storage` that can be found in the metadata. When we inspect those metadata, we can see that this view takes a `nat` has a parameter, has a returnType of `nat` and has the following instructions: `DUP, CDR, CAR, SWAP, CAR, MUL`. @@ -1411,7 +1411,7 @@ license: MIT ## WalletContract -[KT1KgtEEbDuw1b7QEFKh3VW6wzvQGYjawDwa](https://better-call.dev/ithacanet/KT1KgtEEbDuw1b7QEFKh3VW6wzvQGYjawDwa/code) +[KT1T1KsEcVvsVGoHYrzjCzuJjviUDM3uyGmh](https://better-call.dev/jakartanet/KT1T1KsEcVvsVGoHYrzjCzuJjviUDM3uyGmh/code) Transactions to smart contracts operate in the same fashion as transactions to an implicit account, the only difference being the `KT1...` address. You will also receive a transaction hash and have to wait for the transaction to be confirmed. Once confirmed, it can be the right time to update the user's/contract's balance, for example. @@ -1455,7 +1455,7 @@ storage: 1; ## WalletAreYouThereContract -[KT1HiLoD3TnPcWwcK51Bbpy4eAVbTuhdB6hf](https://better-call.dev/ithacanet/KT1HiLoD3TnPcWwcK51Bbpy4eAVbTuhdB6hf/code) +[KT1C9Vjt3p3whEst9h1ykmNMFiQ36QfkYdDW](https://better-call.dev/jakartanet/KT1C9Vjt3p3whEst9h1ykmNMFiQ36QfkYdDW/code) This is a simple smart contract with two methods: `areYouThere` expects a value of type `boolean` to update the `areYouThere` value in the storage of the same type, and `addName` expects a value of type `string` to add it to the map in the contract. @@ -1495,7 +1495,7 @@ storage (pair (pair (bool %areyouthere) (int %integer)) ## SaplingContract -[KT1CDenBWcgWjNZULc9GbJRTnQZQXYWrVT7k](https://better-call.dev/ithacanet/KT1CDenBWcgWjNZULc9GbJRTnQZQXYWrVT7k/code) +[KT1G2kvdfPoavgR6Fjdd68M2vaPk14qJ8bhC](https://better-call.dev/jakartanet/KT1G2kvdfPoavgR6Fjdd68M2vaPk14qJ8bhC/code) Sapling is a protocol enabling privacy-preserving transactions of fungible tokens in a decentralised environment. The example contract used in Taquito Integration Tests is a single-state sapling contract. It features the Michelson instruction "SAPLING_VERIFY_UPDATE". diff --git a/website/versioned_docs/version-13.0.0/contracts-library.md b/website/versioned_docs/version-15.1.0/contracts-library.md similarity index 100% rename from website/versioned_docs/version-13.0.0/contracts-library.md rename to website/versioned_docs/version-15.1.0/contracts-library.md diff --git a/website/versioned_docs/version-13.0.0/dapp_prelaunch.md b/website/versioned_docs/version-15.1.0/dapp_prelaunch.md similarity index 100% rename from website/versioned_docs/version-13.0.0/dapp_prelaunch.md rename to website/versioned_docs/version-15.1.0/dapp_prelaunch.md diff --git a/website/versioned_docs/version-13.0.0/drain_account.md b/website/versioned_docs/version-15.1.0/drain_account.md similarity index 98% rename from website/versioned_docs/version-13.0.0/drain_account.md rename to website/versioned_docs/version-15.1.0/drain_account.md index be9a86e85d..92000886cb 100644 --- a/website/versioned_docs/version-13.0.0/drain_account.md +++ b/website/versioned_docs/version-15.1.0/drain_account.md @@ -22,7 +22,7 @@ In the following example, we have not revealed the account that we want to empty ::: ```js live noInline -// const Tezos = new TezosToolkit('https://ithacanet.ecadinfra.com'); +// const Tezos = new TezosToolkit('https://jakartanet.ecadinfra.com'); // import { DEFAULT_FEE } from "@taquito/taquito"; Tezos.signer @@ -87,7 +87,7 @@ The contract we originate is a `manager contract.` It has a `do` method taking a In the example, we estimate the transfer operation before doing it. The associated fees are deducted from the manager's address when draining the account. Thus, for the operation to be successful, the manager's address for that account must contain funds to cover the gas. ```js live noInline -// const Tezos = new TezosToolkit('https://ithacanet.ecadinfra.com'); +// const Tezos = new TezosToolkit('https://jakartanet.ecadinfra.com'); function transferImplicit(key, mutez) { return [ diff --git a/website/versioned_docs/version-13.0.0/estimate.md b/website/versioned_docs/version-15.1.0/estimate.md similarity index 90% rename from website/versioned_docs/version-13.0.0/estimate.md rename to website/versioned_docs/version-15.1.0/estimate.md index 9ed24d8045..b0768c28ac 100644 --- a/website/versioned_docs/version-13.0.0/estimate.md +++ b/website/versioned_docs/version-15.1.0/estimate.md @@ -37,7 +37,7 @@ values={[ ```js live noInline // import { TezosToolkit } from '@taquito/taquito'; -// const Tezos = new TezosToolkit('https://ithacanet.ecadinfra.com'); +// const Tezos = new TezosToolkit('https://ghostnet.ecadinfra.com'); const amount = 2; const address = 'tz1h3rQ8wBxFd8L9B3d7Jhaawu6Z568XU3xY'; @@ -62,7 +62,7 @@ Tezos.estimate ```js live noInline wallet // import { TezosToolkit } from '@taquito/taquito'; -// const Tezos = new TezosToolkit('https://hangzhounet.api.tez.ie'); +// const Tezos = new TezosToolkit('https://ghostnet.ecadinfra.com'); const amount = 2; const address = 'tz1h3rQ8wBxFd8L9B3d7Jhaawu6Z568XU3xY'; @@ -88,7 +88,7 @@ Tezos.estimate ### Estimate a smart contract call -This example will demonstrate how to estimate the fees related to calling a smart contract. The Ligo source code for the smart contract used in this example is at [Ligo Web IDE](https://ide.ligolang.org/p/N2QTykOAXBkXmiKcRCyg3Q). +This example will demonstrate how to estimate the fees related to calling a smart contract. { const i = 7; return contract.methods.increment(i).toTransferParams({}); @@ -130,10 +130,10 @@ Tezos.contract ```js live noInline wallet // import { TezosToolkit } from '@taquito/taquito'; -// const Tezos = new TezosToolkit('https://hangzhounet.api.tez.ie'); +// const Tezos = new TezosToolkit('https://ghostnet.api.tez.ie'); Tezos.wallet - .at('KT1NcdpzokZQY4sLmCBUwLnMHQCCQ6rRXYwS') + .at('KT1BJadpDyLCACMH7Tt9xtpx4dQZVKw9cDF7') .then((contract) => { const i = 7; return contract.methods.increment(i).toTransferParams({}); @@ -172,7 +172,7 @@ values={[ ```js live noInline // import { TezosToolkit } from '@taquito/taquito'; -// const Tezos = new TezosToolkit('https://ithacanet.ecadinfra.com'); +// const Tezos = new TezosToolkit('https://ghostnet.ecadinfra.com'); println(`Estimating the contract origination : `); Tezos.estimate @@ -202,7 +202,7 @@ Tezos.estimate ```js live noInline wallet // import { TezosToolkit } from '@taquito/taquito'; -// const Tezos = new TezosToolkit('https://hangzhounet.api.tez.ie'); +// const Tezos = new TezosToolkit('https://ghostnet.ecadinfra.com'); println(`Estimating the contract origination : `); Tezos.estimate @@ -227,4 +227,4 @@ Tezos.estimate ``` - \ No newline at end of file + diff --git a/website/versioned_docs/version-15.1.0/events.md b/website/versioned_docs/version-15.1.0/events.md new file mode 100644 index 0000000000..8f1a04801a --- /dev/null +++ b/website/versioned_docs/version-15.1.0/events.md @@ -0,0 +1,85 @@ +--- +title: Event subscription +id: subscribe_event +author: Davis Sawali +--- + +# Contract Event Logging + +## Introduction +Contract events is a way for contracts to deliver event-like information to third-party (off-chain) applications. It can be emitted by using the EMIT instruction in Michelson. + +For more details and examples of how the EMIT instruction works, refer to [this article](https://tezos.gitlab.io/kathmandu/event.html). + +## Subscribing to Events in Taquito +Taquito provides a simple way for users to subscribe to certain events on the blockchain via the `PollingSubscribeProvider`. + +### Example +#### Usage +```typescript +const Tezos = new TezosToolkit(RPC_URL); + +Tezos.setStreamProvider( + Tezos.getFactory(PollingSubscribeProvider)({ + shouldObservableSubscriptionRetry: true, + pollingIntervalMilliseconds: 1500 + }) +); + +try { + const sub = Tezos.stream.subscribeEvent({ + tag: 'tagName', + address: 'KT1_CONTRACT_ADDRESS' + }); + + sub.on('data', console.log); + +} catch (e) { + console.log(e); +} +``` + + +- `tag` is the tag string that was defined in the smart contract with the EMIT instruction +- `address` is the address of the smart contract that was called + +:::info +If you would like to subscribe to **_any_** event that goes through, you can call `subscribeEvent()` as is without any parameters +::: + +#### Output +The output of the `subscribeEvent` method will look something like this: +```json +{ + "opHash": "oopRTC5iNxssoC5dAz54u7uthUz6xBayaSPcLXhkLwHGjuS7Bos", + "blockHash": "BLCTEDjZDtuUcYxmSPXHn3XrKruub4NF4mzTgR2EbpPRFN7JzDV", + "level": 313647, + "kind": "event", + "source": "KT1ACmSCoRsA69zHnv5mMBC4vdcxbFJpHRoo", + "nonce": 0, + "type": { + "prim": "or", + "args": [ + { + "prim": "nat" + }, + { + "prim": "string" + } + ] + }, + "tag": "first", + "payload": { + "prim": "Left", + "args": [ + { + "int": "10" + } + ] + }, + "result": { + "status": "applied", + "consumed_milligas": "1000000" + } +} +``` \ No newline at end of file diff --git a/website/versioned_docs/version-13.0.0/fa2_parameters.md b/website/versioned_docs/version-15.1.0/fa2_parameters.md similarity index 100% rename from website/versioned_docs/version-13.0.0/fa2_parameters.md rename to website/versioned_docs/version-15.1.0/fa2_parameters.md diff --git a/website/versioned_docs/version-13.0.0/failwith_errors.md b/website/versioned_docs/version-15.1.0/failwith_errors.md similarity index 100% rename from website/versioned_docs/version-13.0.0/failwith_errors.md rename to website/versioned_docs/version-15.1.0/failwith_errors.md diff --git a/website/versioned_docs/version-13.0.0/forger.md b/website/versioned_docs/version-15.1.0/forger.md similarity index 100% rename from website/versioned_docs/version-13.0.0/forger.md rename to website/versioned_docs/version-15.1.0/forger.md diff --git a/website/versioned_docs/version-13.0.0/global_constant.md b/website/versioned_docs/version-15.1.0/global_constant.md similarity index 100% rename from website/versioned_docs/version-13.0.0/global_constant.md rename to website/versioned_docs/version-15.1.0/global_constant.md diff --git a/website/versioned_docs/version-13.0.0/images/Tzip16ExecuteView.png b/website/versioned_docs/version-15.1.0/images/Tzip16ExecuteView.png similarity index 100% rename from website/versioned_docs/version-13.0.0/images/Tzip16ExecuteView.png rename to website/versioned_docs/version-15.1.0/images/Tzip16ExecuteView.png diff --git a/website/versioned_docs/version-13.0.0/images/diagramTzip16Metadata.png b/website/versioned_docs/version-15.1.0/images/diagramTzip16Metadata.png similarity index 100% rename from website/versioned_docs/version-13.0.0/images/diagramTzip16Metadata.png rename to website/versioned_docs/version-15.1.0/images/diagramTzip16Metadata.png diff --git a/website/versioned_docs/version-13.0.0/images/github.png b/website/versioned_docs/version-15.1.0/images/github.png similarity index 100% rename from website/versioned_docs/version-13.0.0/images/github.png rename to website/versioned_docs/version-15.1.0/images/github.png diff --git a/website/versioned_docs/version-13.0.0/images/gitlab.png b/website/versioned_docs/version-15.1.0/images/gitlab.png similarity index 100% rename from website/versioned_docs/version-13.0.0/images/gitlab.png rename to website/versioned_docs/version-15.1.0/images/gitlab.png diff --git a/website/versioned_docs/version-15.1.0/increase_paid_storage.md b/website/versioned_docs/version-15.1.0/increase_paid_storage.md new file mode 100644 index 0000000000..b15a75c085 --- /dev/null +++ b/website/versioned_docs/version-15.1.0/increase_paid_storage.md @@ -0,0 +1,108 @@ +--- +title: Increase Paid Storage +author: Davis Sawali +--- + +Increase Paid Storage is a new operation available for use starting from Protocol 14 (Kathmandu). It is a new operation that enables a payer to increase the paid storage of a smart contract by a certain byte amount. + +This helps resolve an issue where several operations on the same contract would fail when they are added at the same level due to the storage limit being lower than the `paid_storage_size_diff`. + +For more information on this change, refer to this [MR](https://gitlab.com/tezos/tezos/-/merge_requests/5605) in the Tezos codebase. +## Examples +Similar to other operations, the Increase Paid Storage operation is available in the Contract and Wallet API + +### Contract API + +#### Simple Usage +```js +const op = await Tezos.contract.increasePaidStorage({ + amount: 2, + destination: 'SMART_CONTRACT_ADDRESS' +}); + +await op.confirmation(); +``` +- `amount` is the the number of `bytes` you want to increase the paid storage by +- `destination` is the `KT1` address of the smart contract which storage you would like to increase + +After waiting for the operation confirmation, you will also have access to various getters of the operation such as `status`, `amount`, `destination`, `fee`, `gasLimit`, `errors`, `storageLimit`, `consumedMilligas`. + +#### Usage in Batches +```typescript +const op = await Tezos.contract + .batch() + .withOrigination({ + balance: "1", + code: `parameter string; + storage string; + code {CAR; + PUSH string "Hello "; + CONCAT; + NIL operation; PAIR}; + `, + init: `"test"` + }) + .withIncreasePaidStorage({ + amount: 1, + destination: 'SMART_CONTRACT_ADDRESS' + }) + .send(); + + await op.confirmation(); +``` + +or +```typescript +const op = await Tezos.contract.batch([ + { + kind: 'origination', + balance: '1', + code: SAMPLE_CODE, + storage: 0 + }, + { + kind: 'increase_paid_storage', + amount: 1, + destination: 'SMART_CONTRACT_ADDRESS' + } + ]) + .send(); + +await op.confirmation(); +``` + +Both syntax will work fine for batching any operations, including `increase_paid_storage`. + +### Wallet API + +#### Usage Example +```typescript +const op = await Tezos.wallet.increasePaidStorage({ + amount: 1, + destination: simpleContractAddress +}).send(); +``` + +#### Usage in Batches +```typescript +const batch = await Tezos.wallet + .batch() + .withOrigination({ + balance: "1", + code: `parameter string; + storage string; + code {CAR; + PUSH string "Hello "; + CONCAT; + NIL operation; PAIR}; + `, + init: `"test"` + }) + .withIncreasePaidStorage({ + amount: 1, + destination: simpleContractAddress + }); + +const op = await batch.send(); +await op.confirmation(); +``` \ No newline at end of file diff --git a/website/versioned_docs/version-13.0.0/inmemory_signer.md b/website/versioned_docs/version-15.1.0/inmemory_signer.md similarity index 71% rename from website/versioned_docs/version-13.0.0/inmemory_signer.md rename to website/versioned_docs/version-15.1.0/inmemory_signer.md index a67a99e28d..cd67a19951 100644 --- a/website/versioned_docs/version-13.0.0/inmemory_signer.md +++ b/website/versioned_docs/version-15.1.0/inmemory_signer.md @@ -40,7 +40,7 @@ The `fromSecretKey` method takes a secret that is base58 encoded as a parameter. ```js live noInline // import { TezosToolkit } from '@taquito/taquito' // import { InMemorySigner } from '@taquito/signer' -// const Tezos = new TezosToolkit('https://ithacanet.ecadinfra.com'); +// const Tezos = new TezosToolkit('https://limanet.ecadinfra.com'); InMemorySigner.fromSecretKey('edsk2rKA8YEExg9Zo2qNPiQnnYheF1DhqjLVmfKdxiFfu5GyGRZRnb') .then((theSigner) => { @@ -57,7 +57,7 @@ InMemorySigner.fromSecretKey('edsk2rKA8YEExg9Zo2qNPiQnnYheF1DhqjLVmfKdxiFfu5GyGR ```js live noInline // import { TezosToolkit } from '@taquito/taquito' // import { InMemorySigner } from '@taquito/signer' -// const Tezos = new TezosToolkit('https://ithacanet.ecadinfra.com'); +// const Tezos = new TezosToolkit('https://limanet.ecadinfra.com'); InMemorySigner.fromSecretKey('spsk2Fiz7sGP5fNMJrokp6ynTa4bcFbsRhw58FHXbNf5ProDNFJ5Xq') .then((theSigner) => { @@ -77,7 +77,7 @@ When required, Taquito offers the `b58cencode` function allowing to encode the s // import { b58cencode, prefix, Prefix } from '@taquito/utils'; // import { TezosToolkit } from '@taquito/taquito' // import { InMemorySigner } from '@taquito/signer' -// const Tezos = new TezosToolkit('https://ithacanet.ecadinfra.com'); +// const Tezos = new TezosToolkit('https://limanet.ecadinfra.com'); const b58encodedSecret = b58cencode( '7c842c15c8b0c8fd228e6cb5302a50201f41642dd36b699003fb3c857920bc9d', @@ -118,7 +118,7 @@ Here are three examples with encrypted private keys where the passphrase used is ```js live noInline // import { TezosToolkit } from '@taquito/taquito' // import { InMemorySigner } from '@taquito/signer' -// const Tezos = new TezosToolkit('https://ithacanet.ecadinfra.com'); +// const Tezos = new TezosToolkit('https://limanet.ecadinfra.com'); InMemorySigner.fromSecretKey( 'edesk1GXwWmGjXiLHBKxGBxwmNvG21vKBh6FBxc4CyJ8adQQE2avP5vBB57ZUZ93Anm7i4k8RmsHaPzVAvpnHkFF', @@ -138,7 +138,7 @@ InMemorySigner.fromSecretKey( ```js live noInline // import { TezosToolkit } from '@taquito/taquito' // import { InMemorySigner } from '@taquito/signer' -// const Tezos = new TezosToolkit('https://ithacanet.ecadinfra.com'); +// const Tezos = new TezosToolkit('https://limanet.ecadinfra.com'); InMemorySigner.fromSecretKey( 'spesk24UQkAiJk8X6AufNtRv1WWPp2BAssEgmijCTQPMgUXweSKPmLdbyAjPmCG1pR2dC9P5UZZVeZcb7zVodUHZ', @@ -158,7 +158,7 @@ InMemorySigner.fromSecretKey( ```js live noInline // import { TezosToolkit } from '@taquito/taquito' // import { InMemorySigner } from '@taquito/signer' -// const Tezos = new TezosToolkit('https://ithacanet.ecadinfra.com'); +// const Tezos = new TezosToolkit('https://limanet.ecadinfra.com'); InMemorySigner.fromSecretKey( 'p2esk28hoUE2J88QNFj2aDX2pjzL7wcVh2g8tkEwtWWguby9M3FHUgSbzvF2Sd7wQ4Kd8crFwvto6gF3otcBuo4T', @@ -175,57 +175,65 @@ InMemorySigner.fromSecretKey( .catch((error) => println(`Error: ${error} ${JSON.stringify(error, null, 2)}`)); ``` -### Using a testnet faucet key -To load a faucet key (available from https://faucet.tzalpha.net/) for working a public testnet use the `importKey` function. -can do so as follows: +### Loading a mnemonic -```js -import { TezosToolkit } from '@taquito/taquito'; -import { importKey } from '@taquito/taquito-signer'; - -const Tezos = new TezosToolkit('https://YOUR_PREFERRED_TESTNET_RPC_URL'); - -// A key faucet, similar to what is available from https://faucet.tzalpha.net/ -const FAUCET_KEY = { - mnemonic: [ - 'cart', - 'will', - 'page', - 'bench', - 'notice', - 'leisure', - 'penalty', - 'medal', - 'define', - 'odor', - 'ride', - 'devote', - 'cannon', - 'setup', - 'rescue', - ], - secret: '35f266fbf0fca752da1342fdfc745a9c608e7b20', - amount: '4219352756', - pkh: 'tz1YBMFg1nLAPxBE6djnCPbMRH5PLXQWt8Mg', - password: 'Fa26j580dQ', - email: 'jxmjvauo.guddusns@tezos.example.org', -}; +The `fromMnemonic` method takes the mnemonic, password, derivationPath, and curve as parameters. Here is an example of an instantiation of an `InMemorySigner.fromMnemonic` -importKey( - Tezos, - FAUCET_KEY.email, - FAUCET_KEY.password, - FAUCET_KEY.mnemonic.join(' '), - FAUCET_KEY.secret -); -// Your Tezos instance is now operably configured for signing with the faucet key. +derivation path MUST start with "44'/1729'/" + +With ed25519 default derivation path (Reminder Must be hardened with either h or ') + +```js live noInline + // import { TezosToolkit } from '@taquito/taquito + // import { InMemorySigner } from '@taquito/signer' + // const Tezos = new TezosToolkit('https://limanet.ecadinfra.com'); + + // ed25519 must have all hardened paths + + // using all default values password = '' curve = 'ed25519' and derivationPath "44'/1729'/0'/0'" + const params = { + mnemonic: 'author crumble medal dose ribbon permit ankle sport final hood shadow vessel horn hawk enter zebra prefer devote captain during fly found despair business' + } + + + const signer = InMemorySigner.fromMnemonic(params); + Tezos.setSignerProvider(signer) + Tezos.signer.publicKeyHash() + .then((publicKeyHash) => { + println(`The public key hash associated is: ${publicKeyHash}`) + }) + .catch(err => println(err)) ``` -If you configure Taquito this way, you will now be able to use every function that needs signing support. +With a non-default derivation path non-hardened with a tz2 address + +```js live noInline + // import { TezosToolkit } from '@taquito/taquito + // import { InMemorySigner } from '@taquito/signer' + // const Tezos = new TezosToolkit('https://limanet.ecadinfra.com'); + + const params = { + mnemonic: 'author crumble medal dose ribbon permit ankle sport final hood shadow vessel horn hawk enter zebra prefer devote captain during fly found despair business', + password: '', + derivationPath: '44h/1729h/1/0', // h or ' specify hardened derivation path) + curve: 'secp256k1' + } + + const signer = InMemorySigner.fromMnemonic(params); + Tezos.setSignerProvider(signer) + Tezos.signer.publicKeyHash() + .then((publicKeyHash) => { + println(`The public key hash associated is: ${publicKeyHash}`) + }) + .catch(err => println(err)) +``` +### Using a testnet faucet key + +~~To load a faucet key (available from https://faucet.tzalpha.net/) for working a public testnet use the `importKey` function.~~ :::note -The operation will be signed automatically using the signer (no prompt) +Since August 2022, the JSON faucets we used to import with the `importKey` function are no longer available. You can use the following link to fund an address on the different testnets: https://teztnets.xyz/. ::: ### A simple factory multiple keys/wallets @@ -248,4 +256,4 @@ const alice = await signerFactory('alices_secret_key'); ``` [0]: https://signatory.io -[1]: https://github.com/tacoinfra/remote-signer \ No newline at end of file +[1]: https://github.com/tacoinfra/remote-signer diff --git a/website/versioned_docs/version-13.0.0/lambda_view.md b/website/versioned_docs/version-15.1.0/lambda_view.md similarity index 89% rename from website/versioned_docs/version-13.0.0/lambda_view.md rename to website/versioned_docs/version-15.1.0/lambda_view.md index e43deae39b..6bdd35cfe7 100644 --- a/website/versioned_docs/version-13.0.0/lambda_view.md +++ b/website/versioned_docs/version-15.1.0/lambda_view.md @@ -57,7 +57,7 @@ Parameters must not include the callback parameter Then we call the `read()` method. (Note that we have no longer need a lambda contract) ```js live noInline Tezos.contract - .at('KT1D2eQBuuaH4rv8HuoRdv2tgDdS3DoqPepN') + .at('KT1MhfAnNbg2oACFBP4VDU5bNY5MZUXdeDWs') .then((contract) => { return contract.views.getTotalSupply([['Unit']]).read(); }) @@ -67,23 +67,23 @@ Tezos.contract .catch((error) => println(`Error: ${error} ${JSON.stringify(error, null, 2)}`)); ``` -```js live noInline + **More examples:** ```js live noInline Tezos.contract - .at('KT1RueqfMN7aWHLzgHPphdmipNgopkk8okqX') + .at('KT1Ccr6ZMeB1mp9yJAqJTHK7F4xoFV9uc11T') .then((contract) => { return contract.views .balance_of([{ owner: 'tz1c1X8vD4pKV9TgV1cyosR7qdnkc8FTEyM1', token_id: '0' }]) @@ -95,14 +95,14 @@ Tezos.contract .catch((error) => println(`Error: ${error} ${JSON.stringify(error, null, 2)}`)); ``` -```js live noInline + diff --git a/website/versioned_docs/version-13.0.0/ledger_integration_test.md b/website/versioned_docs/version-15.1.0/ledger_integration_test.md similarity index 100% rename from website/versioned_docs/version-13.0.0/ledger_integration_test.md rename to website/versioned_docs/version-15.1.0/ledger_integration_test.md diff --git a/website/versioned_docs/version-13.0.0/ledger_signer.md b/website/versioned_docs/version-15.1.0/ledger_signer.md similarity index 95% rename from website/versioned_docs/version-13.0.0/ledger_signer.md rename to website/versioned_docs/version-15.1.0/ledger_signer.md index 2860be0f85..c5d0f6c4de 100644 --- a/website/versioned_docs/version-13.0.0/ledger_signer.md +++ b/website/versioned_docs/version-15.1.0/ledger_signer.md @@ -63,7 +63,7 @@ The constructor of the `LedgerSigner` class can take three other parameters. If - prompt: **default is true** If true, you will be asked on your Ledger device to send your public key for validation. - derivationType: **default is DerivationType.ED25519** - It can be DerivationType.ED25519 (tz1), DerivationType.SECP256K1 (tz2) or DerivationType.P256 (tz3). + It can be DerivationType.ED25519 | DerivationType.BIP32_ED25519 (tz1), DerivationType.SECP256K1 (tz2) or DerivationType.P256 (tz3). ```js import { LedgerSigner, DerivationType, HDPathTemplate } from '@taquito/ledger-signer'; @@ -116,7 +116,7 @@ Tezos.contract console.log(`Waiting for ${op.hash} to be confirmed...`); return op.confirmation(1).then(() => op.hash); }) - .then((hash) => console.log(`Operation injected: https://ithaca.tzstats.com/${hash}`)) + .then((hash) => console.log(`Operation injected: https://jakarta.tzstats.com/${hash}`)) .catch((error) => console.log(`Error: ${error} ${JSON.stringify(error, null, 2)}`)); ``` @@ -135,7 +135,7 @@ Tezos.wallet console.log(`Waiting for ${op.opHash} to be confirmed...`); return op.confirmation(1).then(() => op.opHash); }) - .then((hash) => console.log(`Operation injected: https://ithaca.tzstats.com/${hash}`)) + .then((hash) => console.log(`Operation injected: https://jakarta.tzstats.com/${hash}`)) .catch((error) => console.log(`Error: ${error} ${JSON.stringify(error, null, 2)}`)); ``` @@ -190,16 +190,16 @@ https://github.com/MyCryptoHQ/MyCrypto/issues/2070 https://medium.com/mycrypto/wtf-is-a-derivation-path-c3493ca2eb52 -## Live example that iterate from path `44'/1729'/0'/0'` to `44'/1729'/9'/0'` +## Live example that iterates from the path `44'/1729'/0'/0'` to `44'/1729'/9'/0'` Having your Ledger device connected to your computer and the `Tezos Wallet App` opened, you can run the following code example. It will scan your Ledger from path `44'/1729'/0'/0'` to `44'/1729'/9'/0'` to get public key hashes and the balance for revealed accounts. Confirmations will be asked on your Ledger to send the public keys. -_Note that this example is not intended to be a complete example of paths scanning but only a rough outline of what is possible to do._ +_Note that this example is not intended to be a complete example of paths scanning but only a rough outline of what it is possible to do._ ```js live noInline //import { LedgerSigner, DerivationType, HDPathTemplate } from '@taquito/ledger-signer'; //import { TezosToolkit } from '@taquito/taquito'; // import TransportWebHID from "@ledgerhq/hw-transport-webhid"; -//const Tezos = new TezosToolkit('https://ithacanet.ecadinfra.com'); +//const Tezos = new TezosToolkit('https://jakartanet.ecadinfra.com'); TransportWebHID.create().then((transport) => { for (let index = 0, p = Promise.resolve(); index < 10; index++) { diff --git a/website/versioned_docs/version-13.0.0/liquidity_baking.md b/website/versioned_docs/version-15.1.0/liquidity_baking.md similarity index 99% rename from website/versioned_docs/version-13.0.0/liquidity_baking.md rename to website/versioned_docs/version-15.1.0/liquidity_baking.md index 2572c953ec..b1f7feaa0e 100644 --- a/website/versioned_docs/version-13.0.0/liquidity_baking.md +++ b/website/versioned_docs/version-15.1.0/liquidity_baking.md @@ -193,7 +193,7 @@ const minTokensBought = xtzToTokenTokenOutput({ const op = await lbContract.methods.xtzToToken( USER_ADDRESS, minTokensBought, deadline -) +).send(); await op.confirmation(); ``` diff --git a/website/versioned_docs/version-13.0.0/making_transfers.md b/website/versioned_docs/version-15.1.0/making_transfers.md similarity index 96% rename from website/versioned_docs/version-13.0.0/making_transfers.md rename to website/versioned_docs/version-15.1.0/making_transfers.md index b447f2ece4..f8a5cc3a64 100644 --- a/website/versioned_docs/version-13.0.0/making_transfers.md +++ b/website/versioned_docs/version-15.1.0/making_transfers.md @@ -23,10 +23,10 @@ In the following example, we transfer 0.5ꜩ from a `tz1aaYoabvj2DQtpHz74Z83fSNj ```js live noInline // import { TezosToolkit } from '@taquito/taquito'; -// const Tezos = new TezosToolkit('https://hangzhounet.api.tez.ie'); +// const Tezos = new TezosToolkit('https://ghostnet.ecadinfra.com'); render(`Fetching a private key...`); -fetch('https://api.tez.ie/keys/ithacanet/', { +fetch('https://api.tez.ie/keys/ghostnet/', { method: 'POST', headers: { Authorization: 'Bearer taquito-example' }, }) @@ -46,7 +46,7 @@ fetch('https://api.tez.ie/keys/ithacanet/', { render(`Waiting for ${op.hash} to be confirmed...`); return op.confirmation(1).then(() => op.hash); }) - .then((hash) => render(`Operation injected: https://ithaca.tzstats.com/${hash}`)) + .then((hash) => render(`Operation injected: https://ghost.tzstats.com/${hash}`)) .catch((error) => render(`Error: ${JSON.stringify(error, null, 2)}`)); ``` diff --git a/website/versioned_docs/version-13.0.0/maps_bigmaps.md b/website/versioned_docs/version-15.1.0/maps_bigmaps.md similarity index 93% rename from website/versioned_docs/version-13.0.0/maps_bigmaps.md rename to website/versioned_docs/version-15.1.0/maps_bigmaps.md index 5f93c1d213..d1c79d808f 100644 --- a/website/versioned_docs/version-13.0.0/maps_bigmaps.md +++ b/website/versioned_docs/version-15.1.0/maps_bigmaps.md @@ -1,961 +1,967 @@ ---- -title: Maps and BigMaps -author: Roxane Letourneau ---- - -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; -import { MichelsonMap } from '@taquito/taquito'; - -Learn how to: - -- Fetch data from a `Map` datatype on a Tezos Smart Contract -- Fetch data from a `BigMap` datatype on a Tezos Smart Contract -- Initialize `Map` data while originating a new contract to the Tezos Blockchain -- Use Pairs as a key to access `Map` and `BigMap` values -- Why Michelson `Map` and `BigMap` don't look like a Javascript `Map` - -Taquito provides `MichelsonMap` to make it easy for developers to work with the native Michelson map datatypes. `MichelsonMap` supports initialization, get and set methods to `Maps` using primitive datatypes and pairs as keys. - -Michelson offers two variants of `Maps` that are semantically the same but have different implementations and trade-offs in terms of `gas` and `storage` costs on a contract. A `Map` uses more storage but costs less gas, whereas a `BigMap` consumes less storage but has higher gas costs during the Smart Contract's execution. - -- [Michelson documentation for Map][michelson_map] -- [Michelson documentation for BigMap][michelson_bigmap] - -## A Contract with a single Map for storage - -### Origination of the contract with an initial storage - -This example builds on the Ligo Lang Taco Shop learning resources. - -The storage of the contract used in the following example is a map where a key is a natural number (a `nat`), and a value is a pair composed of two values representing the quantity of stock and `tez` tokens, respectively. The contract's source code is available [here](https://ligolang.org/docs/tutorials/get-started/tezos-taco-shop-smart-contract#making-sure-we-get-paid-for-our-tacos). In the example, the contract is originated with initial values using the `MichelsonMap` class' `set` method. - - - - -```js live noInline -import { MichelsonMap } from '@taquito/taquito'; -// import { TezosToolkit } from '@taquito/taquito'; -// const Tezos = new TezosToolkit('https://YOUR_PREFERRED_RPC_URL'); - -const storageMap = new MichelsonMap(); -storageMap.set('1', { current_stock: '10000', max_price: '50' }); -storageMap.set('2', { current_stock: '120', max_price: '20' }); -storageMap.set('3', { current_stock: '50', max_price: '60' }); - -// contractMapTacoShop variable contains the Michelson Smart Contract source code, and is not shown for brevity -Tezos.contract - .originate({ - code: contractMapTacoShop, - storage: storageMap, - }) - .then((contractOriginated) => { - println(`Waiting for confirmation of origination for ${contractOriginated.contractAddress}...`); - return contractOriginated.contract(); - }) - .then((contract) => { - println(`Origination completed.`); - }) - .catch((error) => println(`Error: ${JSON.stringify(error, null, 2)}`)); -``` - - - - -```js live noInline wallet -import { MichelsonMap } from '@taquito/taquito'; -// import { TezosToolkit } from '@taquito/taquito'; -// const Tezos = new TezosToolkit('https://YOUR_PREFERRED_RPC_URL'); - -const storageMap = new MichelsonMap(); -storageMap.set('1', { current_stock: '10000', max_price: '50' }); -storageMap.set('2', { current_stock: '120', max_price: '20' }); -storageMap.set('3', { current_stock: '50', max_price: '60' }); - -// contractMapTacoShop variable contains the Michelson Smart Contract source code, and is not shown for brevity -Tezos.wallet - .originate({ - code: contractMapTacoShop, - storage: storageMap, - }) - .send() - .then((originationOp) => { - println(`Waiting for confirmation of origination...`); - return originationOp.contract(); - }) - .then((contract) => { - println(`Origination completed for ${contract.address}.`); - }) - .catch((error) => println(`Error: ${JSON.stringify(error, null, 2)}`)); -``` - - - - -The `fromLiteral` convenience method can be used instead of using `set` for each element. Here is the same `origination` operation but using `fromLiteral` to create our `MichelsonMap`. - - - - -```js live noInline -import { MichelsonMap } from '@taquito/taquito'; - -Tezos.contract - .originate({ - code: contractMapTacoShop, - storage: MichelsonMap.fromLiteral({ - 1: { current_stock: '10000', max_price: '50' }, - 2: { current_stock: '120', max_price: '20' }, - 3: { current_stock: '50', max_price: '60' }, - }), - }) - .then((contractOriginated) => { - println(`Waiting for confirmation of origination for ${contractOriginated.contractAddress}...`); - return contractOriginated.contract(); - }) - .then((contract) => { - println(`Origination completed.`); - }) - .catch((error) => println(`Error: ${JSON.stringify(error, null, 2)}`)); -``` - - - - -```js live noInline wallet -import { MichelsonMap } from '@taquito/taquito'; - -Tezos.wallet - .originate({ - code: contractMapTacoShop, - storage: MichelsonMap.fromLiteral({ - 1: { current_stock: '10000', max_price: '50' }, - 2: { current_stock: '120', max_price: '20' }, - 3: { current_stock: '50', max_price: '60' }, - }), - }) - .send() - .then((originationOp) => { - println(`Waiting for confirmation of origination...`); - return originationOp.contract(); - }) - .then((contract) => { - println(`Origination completed for ${contract.address}.`); - }) - .catch((error) => println(`Error: ${JSON.stringify(error, null, 2)}`)); -``` - - - - -### Accessing the values of the map - -This example loads the same type of Taco Shop contract (we created this one earlier). Taquito provides a `get` method of the `MichelsonMap` on storage of type `Map`, and in this case, we access the value stored with a key of `1`. - -The example calls the Contracts `main` function of the contract using the key `1` as its parameter. Remember, we can only change contract storage by calling the function provided by the contract. The `main` function on this Smart Contract is decreasing the value of the `current_stock` associated with the key `1`. We use the `get` method of the `MichelsonMap` class to see the difference in storage after the method call. - - - - -```js live noInline -Tezos.contract - .at('KT1ALm5dUKi47p8WRfX1AYzFG7A8YwE4LhRv') - .then((myContract) => { - return myContract - .storage() - .then((myStorage) => { - //We want to see the value of the key "1" - const value = myStorage.get('1'); - println( - `The key "1" of the map has a current_stock of ${ - value[Object.keys(value)[0]] - } and a max_price of ${value[Object.keys(value)[1]]}.` - ); - - //Calling the main method of the contract will modify the storage - return myContract.methods.default('1').send(); - }) - .then((op) => { - println(`Waiting for ${op.hash} to be confirmed...`); - return op.confirmation(1).then(() => op.hash); - }) - .then((hash) => { - println(`Operation injected.`); - - //Use the get method to see the change in storage - return myContract.storage(); - }) - .then((myStorage) => { - const value = myStorage.get('1'); - println( - `The key "1" of the map has now a current_stock of ${ - value[Object.keys(value)[0]] - } and a max_price of ${value[Object.keys(value)[1]]}.` - ); - }); - }) - .catch((error) => println(`Error: ${JSON.stringify(error, null, 2)}`)); -``` - - - - -```js live noInline wallet -Tezos.wallet - .at('KT1ALm5dUKi47p8WRfX1AYzFG7A8YwE4LhRv') - .then((myContract) => { - return myContract - .storage() - .then((myStorage) => { - //We want to see the value of the key "1" - const value = myStorage.get('1'); - println( - `The key "1" of the map has a current_stock of ${ - value[Object.keys(value)[0]] - } and a max_price of ${value[Object.keys(value)[1]]}.` - ); - - //Calling the main method of the contract will modify the storage - return myContract.methods.default('1').send(); - }) - .then((op) => { - println(`Waiting for ${op.opHash} to be confirmed...`); - return op.confirmation(1).then(() => op.opHash); - }) - .then((hash) => { - println(`Operation injected.`); - - //Use the get method to see the change in storage - return myContract.storage(); - }) - .then((myStorage) => { - const value = myStorage.get('1'); - println( - `The key "1" of the map has now a current_stock of ${ - value[Object.keys(value)[0]] - } and a max_price of ${value[Object.keys(value)[1]]}.` - ); - }); - }) - .catch((error) => println(`Error: ${JSON.stringify(error, null, 2)}`)); -``` - - - - -## A Contract with a Map using an unannotated pair/tuple as a key - -Here we have the storage of our contract defined in Michelson. - -It has a `Map` with the annotated name `%theMap`. This `Map` uses a pair consisting of a natural number and an address as its key `(1, tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx)`. Its value is also a pair of values, consisting of an `int` (annotated as `%quantity`) and `mutez` (annotated as `%amount`). - -``` -(pair (pair (address %theAddress) - (map %theMap (pair nat address) (pair (mutez %amount) (int %quantity)))) - (int %theNumber)) -``` - -### Origination of the contract with Pair as Map keys - -Since the key of the map has no annotations, MichelsonMap requires that we use an index value starting at `0` to initialize its elements. - - - - -```js live noInline -import { MichelsonMap } from '@taquito/taquito'; - -const storageMap = new MichelsonMap(); -//First entry of the map -storageMap.set( - { - // Pair as Key - 0: '1', //nat - 1: 'tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx', //address - }, - { quantity: '10', amount: '100' } -); - -//Second entry of the map -storageMap.set( - { - // Pair as Key - 0: '2', //nat - 1: 'tz1h3rQ8wBxFd8L9B3d7Jhaawu6Z568XU3xY', //address - }, - { quantity: '20', amount: '200' } -); - -//Third entry of the map -storageMap.set( - { - 0: '3', //nat - 1: 'tz1eY5Aqa1kXDFoiebL28emyXFoneAoVg1zh', //address - }, - { quantity: '30', amount: '300' } -); - -// contractMapPairKey variable contains the Michelson Smart Contract -Tezos.contract - .originate({ - code: contractMapPairKey, - storage: { - theAddress: 'tz1NAozDvi5e7frVq9cUaC3uXQQannemB8Jw', - theMap: storageMap, - theNumber: 10, - }, - }) - .then((contractOriginated) => { - println(`Waiting for the contract origination of ${contractOriginated.contractAddress}...`); - return contractOriginated.contract(); - }) - .then((contract) => { - println(`Origination completed.`); - }) - .catch((error) => println(`Error: ${JSON.stringify(error, null, 2)}`)); -``` - - - - -```js live noInline wallet -import { MichelsonMap } from '@taquito/taquito'; - -const storageMap = new MichelsonMap(); -//First entry of the map -storageMap.set( - { - // Pair as Key - 0: '1', //nat - 1: 'tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx', //address - }, - { quantity: '10', amount: '100' } -); - -//Second entry of the map -storageMap.set( - { - // Pair as Key - 0: '2', //nat - 1: 'tz1h3rQ8wBxFd8L9B3d7Jhaawu6Z568XU3xY', //address - }, - { quantity: '20', amount: '200' } -); - -//Third entry of the map -storageMap.set( - { - 0: '3', //nat - 1: 'tz1eY5Aqa1kXDFoiebL28emyXFoneAoVg1zh', //address - }, - { quantity: '30', amount: '300' } -); - -// contractMapPairKey variable contains the Michelson Smart Contract -Tezos.wallet - .originate({ - code: contractMapPairKey, - storage: { - theAddress: 'tz1NAozDvi5e7frVq9cUaC3uXQQannemB8Jw', - theMap: storageMap, - theNumber: 10, - }, - }) - .send() - .then((originationOp) => { - println(`Waiting for confirmation of origination...`); - return originationOp.contract(); - }) - .then((contract) => { - println(`Origination completed for ${contract.address}.`); - }) - .catch((error) => println(`Error: ${JSON.stringify(error, null, 2)}`)); -``` - - - - -### Accessing Map values using Pairs - -The `get` method of the `MichelsonMap` class accesses values of the map for a specified key. - -This example accesses the map using its `theMap` annotation. If the storage does not annotate its properties, the caller must use numeric indexes instead. - -Recall that this contract does not annotate the pairs of the key pair either. We use numeric indexes for this also. - - - - -```js live noInline -Tezos.contract - .at('KT1NoACbTF2wh2Zrz3aZLC5rr2nAqsBFa9gc') - .then((myContract) => { - return myContract.storage(); - }) - .then((myStorage) => { - const value = myStorage['theMap'].get({ - 0: '2', //nat - 1: 'tz1h3rQ8wBxFd8L9B3d7Jhaawu6Z568XU3xY', //address - }); - println(`Values associated with this key : amount : ${value[Object.keys(value)[0]]}, quantity : - ${value[Object.keys(value)[1]]}`); - }) - .catch((error) => println(`Error: ${JSON.stringify(error, null, 2)}`)); -``` - - - - -```js live noInline wallet -Tezos.wallet - .at('KT1NoACbTF2wh2Zrz3aZLC5rr2nAqsBFa9gc') - .then((myContract) => { - return myContract.storage(); - }) - .then((myStorage) => { - const value = myStorage['theMap'].get({ - 0: '2', //nat - 1: 'tz1h3rQ8wBxFd8L9B3d7Jhaawu6Z568XU3xY', //address - }); - println(`Values associated with this key : amount : ${value[Object.keys(value)[0]]}, quantity : - ${value[Object.keys(value)[1]]}`); - }) - .catch((error) => println(`Error: ${JSON.stringify(error, null, 2)}`)); -``` - - - - -## A Map with nested Pairs as keys - -This contract schema has a key with eight nested pairs and the value of an int. This example type of key is impractical, but we offer it as an example to illustrate how to work with complex keys. - -The Michelson storage schema with a map using eight pairs as a key: - -``` -(map (pair int - (pair nat - (pair string - (pair bytes - (pair mutez - (pair bool - (pair key_hash - (pair timestamp address)))))))) int) -``` - -### Origination of a contract with complex keys - -In this example, the contract schema does not have map annotations, which means that each value needs to have an index as a property name. - - - - -```js live noInline -const storageMap = new MichelsonMap(); -storageMap.set( - { - 0: '1', // int - 1: '2', // nat - 2: 'test', // string - 3: 'cafe', // bytes - 4: '10', // mutez - 5: true, // bool - 6: 'tz3WXYtyDUNL91qfiCJtVUX746QpNv5i5ve5', // key_hash - 7: '2019-09-06T15:08:29.000Z', // timestamp - 8: 'tz3WXYtyDUNL91qfiCJtVUX746QpNv5i5ve5', // address - }, - 100 -); - -storageMap.set( - { - 0: '10', // int - 1: '20', // nat - 2: 'Hello', // string - 3: 'ffff', // bytes - 4: '100', // mutez - 5: false, // bool - 6: 'tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx', // key_hash - 7: '2019-10-06T15:08:29.000Z', // timestamp - 8: 'tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx', // address - }, - 1000 -); - -// contractMap8pairs variable contains the Michelson Smart Contract -Tezos.contract - .originate({ - code: contractMap8pairs, - storage: storageMap, - }) - .then((contractOriginated) => { - println(`Waiting for the contract origination of ${contractOriginated.contractAddress}...`); - return contractOriginated.contract(); - }) - .then((contract) => { - println(`Origination completed.`); - }) - .catch((error) => println(`Error: ${JSON.stringify(error, null, 2)}`)); -``` - - - - -```js live noInline wallet -const storageMap = new MichelsonMap(); -storageMap.set( - { - 0: '1', // int - 1: '2', // nat - 2: 'test', // string - 3: 'cafe', // bytes - 4: '10', // mutez - 5: true, // bool - 6: 'tz3WXYtyDUNL91qfiCJtVUX746QpNv5i5ve5', // key_hash - 7: '2019-09-06T15:08:29.000Z', // timestamp - 8: 'tz3WXYtyDUNL91qfiCJtVUX746QpNv5i5ve5', // address - }, - 100 -); - -storageMap.set( - { - 0: '10', // int - 1: '20', // nat - 2: 'Hello', // string - 3: 'ffff', // bytes - 4: '100', // mutez - 5: false, // bool - 6: 'tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx', // key_hash - 7: '2019-10-06T15:08:29.000Z', // timestamp - 8: 'tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx', // address - }, - 1000 -); - -// contractMap8pairs variable contains the Michelson Smart Contract -Tezos.wallet - .originate({ - code: contractMap8pairs, - storage: storageMap, - }) - .send() - .then((originationOp) => { - println(`Waiting for confirmation of origination...`); - return originationOp.contract(); - }) - .then((contract) => { - println(`Origination completed for ${contract.address}.`); - }) - .catch((error) => println(`Error: ${JSON.stringify(error, null, 2)}`)); -``` - - - - -### Accessing Map values with complex keys - -The `get` method of the `MichelsonMap` class accesses values of the map for a specified key. - - - - -```js live noInline -Tezos.contract - .at('KT1HpDxVK67YxzAUs7Ubp7R7KzV3i1X1nZtD') - .then((myContract) => { - return myContract.storage(); - }) - .then((myStorage) => { - const value = myStorage.get({ - 0: '1', // int - 1: '2', // nat - 2: 'test', // string - 3: 'cafe', // bytes - 4: '10', // mutez - 5: true, // bool - 6: 'tz3WXYtyDUNL91qfiCJtVUX746QpNv5i5ve5', // key_hash - 7: '2019-09-06T15:08:29.000Z', // timestamp - 8: 'tz3WXYtyDUNL91qfiCJtVUX746QpNv5i5ve5', // address - }); - println(`The value associated to this key is ${value}.`); - }) - .catch((error) => println(`Error: ${JSON.stringify(error, null, 2)}`)); -``` - - - - -```js live noInline wallet -Tezos.wallet - .at('KT1HpDxVK67YxzAUs7Ubp7R7KzV3i1X1nZtD') - .then((myContract) => { - return myContract.storage(); - }) - .then((myStorage) => { - const value = myStorage.get({ - 0: '1', // int - 1: '2', // nat - 2: 'test', // string - 3: 'cafe', // bytes - 4: '10', // mutez - 5: true, // bool - 6: 'tz3WXYtyDUNL91qfiCJtVUX746QpNv5i5ve5', // key_hash - 7: '2019-09-06T15:08:29.000Z', // timestamp - 8: 'tz3WXYtyDUNL91qfiCJtVUX746QpNv5i5ve5', // address - }); - println(`The value associated to this key is ${value}.`); - }) - .catch((error) => println(`Error: ${JSON.stringify(error, null, 2)}`)); -``` - - - - -## BigMaps - -Map and BigMap are semantically the same except for everything you learned about Maps applies to working with BigMaps. The only difference is that when calling `get` on a bigMap will return a Javascript Promise, whereas get on a Map returns directly. In this example, the contract schema does not have map annotations, which means that each value needs to have an index as a property name. - -### Contract storage containing a map and a bigMap - -The `MichelsonMap` class also supports the `bigMap` type. The following example uses a contract containing both a map and a bigMap in its storage. Here is the Michelson definition of storage for this example: - -``` -(pair (big_map %thebigmap (pair nat address) int) (map %themap (pair nat address) int)) -``` - -#### Origination of the contract with an initial storage - - - - -```js live noInline -import { MichelsonMap } from '@taquito/taquito'; - -const storageMap = new MichelsonMap(); -storageMap.set( - { - 0: '1', //nat - 1: 'tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx', //address - }, - 10 -); -storageMap.set( - { - 0: '2', //nat - 1: 'tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx', //address - }, - 20 -); - -const storageBigMap = new MichelsonMap(); -storageBigMap.set( - { - 0: '10', //nat - 1: 'tz3WXYtyDUNL91qfiCJtVUX746QpNv5i5ve5', //address - }, - 100 -); -storageBigMap.set( - { - 0: '20', //nat - 1: 'tz3WXYtyDUNL91qfiCJtVUX746QpNv5i5ve5', //address - }, - 200 -); -// contractMapBigMap variable contains the Michelson Smart Contract -Tezos.contract - .originate({ - code: contractMapBigMap, - storage: { - themap: storageMap, - thebigmap: storageBigMap, - }, - }) - .then((originationOp) => { - println(`Waiting for confirmation of origination...`); - return originationOp.contract(); - }) - .then((contract) => { - println(`Origination completed for ${contract.address}.`); - }) - .catch((error) => println(`Error: ${JSON.stringify(error, null, 2)}`)); -``` - - - - -```js live noInline wallet -import { MichelsonMap } from '@taquito/taquito'; - -const storageMap = new MichelsonMap(); -storageMap.set( - { - 0: '1', //nat - 1: 'tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx', //address - }, - 10 -); -storageMap.set( - { - 0: '2', //nat - 1: 'tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx', //address - }, - 20 -); - -const storageBigMap = new MichelsonMap(); -storageBigMap.set( - { - 0: '10', //nat - 1: 'tz3WXYtyDUNL91qfiCJtVUX746QpNv5i5ve5', //address - }, - 100 -); -storageBigMap.set( - { - 0: '20', //nat - 1: 'tz3WXYtyDUNL91qfiCJtVUX746QpNv5i5ve5', //address - }, - 200 -); -// contractMapBigMap variable contains the Michelson Smart Contract -Tezos.wallet - .originate({ - code: contractMapBigMap, - storage: { - themap: storageMap, - thebigmap: storageBigMap, - }, - }) - .send() - .then((originationOp) => { - println(`Waiting for confirmation of origination...`); - return originationOp.contract(); - }) - .then((contract) => { - println(`Origination completed for ${contract.address}.`); - }) - .catch((error) => println(`Error: ${JSON.stringify(error, null, 2)}`)); -``` - - - - -#### Accessing the values of the map and the bigMap - -The `get` method of the `MichelsonMap` class accesses the values of the map and values of the bigMap. The difference is that the value gets returned directly for a map while the get method on a bigMap returns a promise. - - - - -```js live noInline -Tezos.contract - .at('KT1DXCqq3suQKEUoC4UtzNi1c6jNcunGynas') - .then((myContract) => { - return myContract - .storage() - .then((myStorage) => { - //When called on a map, the get method returns the value directly - const valueMap = myStorage['themap'].get({ - 0: '1', //nat - 1: 'tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx', //address - }); - println(`The value associated with the specified key of the map is ${valueMap}.`); - return myContract.storage(); - }) - - .then((myStorage) => { - //When called on a bigMap, the get method returns a promise - return myStorage['thebigmap'].get({ - 0: '10', //nat - 1: 'tz3WXYtyDUNL91qfiCJtVUX746QpNv5i5ve5', //address - }); - }) - .then((valueBigMap) => { - println(`The value associated with the specified key of the bigMap is ${valueBigMap}.`); - }); - }) - .catch((error) => println(`Error: ${JSON.stringify(error, null, 2)}`)); -``` - - - - -```js live noInline wallet -Tezos.wallet - .at('KT1DXCqq3suQKEUoC4UtzNi1c6jNcunGynas') - .then((myContract) => { - return myContract - .storage() - .then((myStorage) => { - //When called on a map, the get method returns the value directly - const valueMap = myStorage['themap'].get({ - 0: '1', //nat - 1: 'tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx', //address - }); - println(`The value associated with the specified key of the map is ${valueMap}.`); - return myContract.storage(); - }) - - .then((myStorage) => { - //When called on a bigMap, the get method returns a promise - return myStorage['thebigmap'].get({ - 0: '10', //nat - 1: 'tz3WXYtyDUNL91qfiCJtVUX746QpNv5i5ve5', //address - }); - }) - .then((valueBigMap) => { - println(`The value associated with the specified key of the bigMap is ${valueBigMap}.`); - }); - }) - .catch((error) => println(`Error: ${JSON.stringify(error, null, 2)}`)); -``` - - - - -## Local packing for big maps - -By default, a call to an RPC node is used to pack data when fetching values from a big map. Big map keys need to be serialized or packed and Taquito relies on the PACK functionality of a Tezos RPC node to pack the big map keys. This may be considered inefficient as it adds a request to a remote node to fetch data. - -Now, Taquito allows you to pack the required data locally to fetch values from a big map. By relying on the local pack implementation, Taquito eliminates one RPC roundtrip when fetching big map values. This feature makes fetching big map values **50% faster**. - -Implementing this feature is a very easy 2 step process: - -1. Importing the `MichelCodecPacker` class from `@taquito/taquito` -2. Creating an instance of the `MichelCodecPacker` class and passing it to the `setPackerProvider` method of the `TezosToolkit` instance. - -Here is an example: - -```js -import { MichelCodecPacker } from '@taquito/taquito'; -const Tezos = new TezosToolkit(RPC_URL); -Tezos.setPackerProvider(new MichelCodecPacker()); -``` - -After that, Taquito will automatically pack the keys locally when you want to fetch the values of a big map. - -## Fetch multiple big map values at once - -It is possible to fetch multiple big map values using Taquito with one call using the `getMultipleValues` method of the `BigMapAbstraction` class. Taquito will ensure that all fetched big maps come from the same block to ensure a consistent state. - -The method takes an `array` of keys to query as a parameter and an optional block level and returns a `MichelsonMap` containing the keys and their value in a well-formatted JSON object format. The accepted types for the keys are `string`, `number` or `object` (the last one is used when the type of the keys in the big map is a Michelson `pair`). - -In the following example, we will fetch 4 big map values at once. The Michelson type of the big map key is an `address` and the type of its value is a `pair` made of a `nat` and a `map`. We see in the example that the address `tz1QZ6KY7d3BuZDT1d19dUxoQrtFPN2QJ3hn` is not a key of the big map, so its value is set to `undefined` in the returned MichelsonMap. - - - - -```js live noInline -// import { TezosToolkit } from '@taquito/taquito'; -// const Tezos = new TezosToolkit('https://ithacanet.ecadinfra.com'); - -Tezos.contract - .at('KT1MMfuLrpBufDyxrLFkxBNE73Lp3AWkHivG') - .then((contract) => { - println('Fetching the storage of the contract...'); - return contract.storage(); - }) - .then((storage) => { - println('Fetching the big map values...\n'); - return storage['0'].getMultipleValues([ - 'tz3PNdfg3Fc8hH4m9iSs7bHgDgugsufJnBZ1', - 'tz2Ch1abG7FNiibmV26Uzgdsnfni9XGrk5wD', - 'tz3YjfexGakCDeCseXFUpcXPSAN9xHxE9TH2', - ]); - }) - .then((values) => { - values.forEach((value, key) => { - println(`The value of the key ${key} is:\n${JSON.stringify(value, null, 2)}.\n`); - }); - }) - .catch((error) => println(JSON.stringify(error))); -``` - - - - -```js live noInline wallet -// import { TezosToolkit } from '@taquito/taquito'; -// const Tezos = new TezosToolkit('https://ithacanet.ecadinfra.com'); - -Tezos.wallet - .at('KT1MMfuLrpBufDyxrLFkxBNE73Lp3AWkHivG') - .then((contract) => { - println('Fetching the storage of the contract...'); - return contract.storage(); - }) - .then((storage) => { - println('Fetching the big map values...\n'); - return storage['0'].getMultipleValues([ - 'tz3PNdfg3Fc8hH4m9iSs7bHgDgugsufJnBZ1', - 'tz2Ch1abG7FNiibmV26Uzgdsnfni9XGrk5wD', - 'tz3YjfexGakCDeCseXFUpcXPSAN9xHxE9TH2', - ]); - }) - .then((values) => { - values.forEach((value, key) => { - println(`The value of the key ${key} is:\n${JSON.stringify(value, null, 2)}.\n`); - }); - }) - .catch((error) => println(JSON.stringify(error))); -``` - - - - ---- - -[michelson_map]: https://michelson.nomadic-labs.com/#type-big_map -[michelson_bigmap]: https://michelson.nomadic-labs.com/#type-big_map +--- +title: Maps and BigMaps +author: Roxane Letourneau +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; +import { MichelsonMap } from '@taquito/taquito'; + +Learn how to: + +- Fetch data from a `Map` datatype on a Tezos Smart Contract +- Fetch data from a `BigMap` datatype on a Tezos Smart Contract +- Initialize `Map` data while originating a new contract to the Tezos Blockchain +- Use Pairs as a key to access `Map` and `BigMap` values +- Why Michelson `Map` and `BigMap` don't look like a Javascript `Map` + +Taquito provides `MichelsonMap` to make it easy for developers to work with the native Michelson map datatypes. `MichelsonMap` supports initialization, get and set methods to `Maps` using primitive datatypes and pairs as keys. + +Michelson offers two variants of `Maps` that are semantically the same but have different implementations and trade-offs in terms of `gas` and `storage` costs on a contract. A `Map` uses more storage but costs less gas, whereas a `BigMap` consumes less storage but has higher gas costs during the Smart Contract's execution. + +- [Michelson documentation for Map][michelson_map] +- [Michelson documentation for BigMap][michelson_bigmap] + +## A Contract with a single Map for storage + +### Origination of the contract with an initial storage + +This example builds on the Ligo Lang Taco Shop learning resources. + +The storage of the contract used in the following example is a map where a key is a natural number (a `nat`), and a value is a pair composed of two values representing the quantity of stock and `tez` tokens, respectively. The contract's source code is available [here](https://ligolang.org/docs/tutorials/get-started/tezos-taco-shop-smart-contract#making-sure-we-get-paid-for-our-tacos). In the example, the contract is originated with initial values using the `MichelsonMap` class' `set` method. + + + + +```js live noInline +import { MichelsonMap } from '@taquito/taquito'; +// import { TezosToolkit } from '@taquito/taquito'; +// const Tezos = new TezosToolkit('https://YOUR_PREFERRED_RPC_URL'); + +const storageMap = new MichelsonMap(); +storageMap.set('1', { current_stock: '10000', max_price: '50' }); +storageMap.set('2', { current_stock: '120', max_price: '20' }); +storageMap.set('3', { current_stock: '50', max_price: '60' }); + +// contractMapTacoShop variable contains the Michelson Smart Contract source code, and is not shown for brevity +Tezos.contract + .originate({ + code: contractMapTacoShop, + storage: storageMap, + }) + .then((contractOriginated) => { + println(`Waiting for confirmation of origination for ${contractOriginated.contractAddress}...`); + return contractOriginated.contract(); + }) + .then((contract) => { + println(`Origination completed.`); + }) + .catch((error) => println(`Error: ${JSON.stringify(error, null, 2)}`)); +``` + + + + +```js live noInline wallet +import { MichelsonMap } from '@taquito/taquito'; +// import { TezosToolkit } from '@taquito/taquito'; +// const Tezos = new TezosToolkit('https://YOUR_PREFERRED_RPC_URL'); + +const storageMap = new MichelsonMap(); +storageMap.set('1', { current_stock: '10000', max_price: '50' }); +storageMap.set('2', { current_stock: '120', max_price: '20' }); +storageMap.set('3', { current_stock: '50', max_price: '60' }); + +// contractMapTacoShop variable contains the Michelson Smart Contract source code, and is not shown for brevity +Tezos.wallet + .originate({ + code: contractMapTacoShop, + storage: storageMap, + }) + .send() + .then((originationOp) => { + println(`Waiting for confirmation of origination...`); + return originationOp.contract(); + }) + .then((contract) => { + println(`Origination completed for ${contract.address}.`); + }) + .catch((error) => println(`Error: ${JSON.stringify(error, null, 2)}`)); +``` + + + + +The `fromLiteral` convenience method can be used instead of using `set` for each element. Here is the same `origination` operation but using `fromLiteral` to create our `MichelsonMap`. + + + + +```js live noInline +import { MichelsonMap } from '@taquito/taquito'; + +Tezos.contract + .originate({ + code: contractMapTacoShop, + storage: MichelsonMap.fromLiteral({ + 1: { current_stock: '10000', max_price: '50' }, + 2: { current_stock: '120', max_price: '20' }, + 3: { current_stock: '50', max_price: '60' }, + }), + }) + .then((contractOriginated) => { + println(`Waiting for confirmation of origination for ${contractOriginated.contractAddress}...`); + return contractOriginated.contract(); + }) + .then((contract) => { + println(`Origination completed.`); + }) + .catch((error) => println(`Error: ${JSON.stringify(error, null, 2)}`)); +``` + + + + +```js live noInline wallet +import { MichelsonMap } from '@taquito/taquito'; + +Tezos.wallet + .originate({ + code: contractMapTacoShop, + storage: MichelsonMap.fromLiteral({ + 1: { current_stock: '10000', max_price: '50' }, + 2: { current_stock: '120', max_price: '20' }, + 3: { current_stock: '50', max_price: '60' }, + }), + }) + .send() + .then((originationOp) => { + println(`Waiting for confirmation of origination...`); + return originationOp.contract(); + }) + .then((contract) => { + println(`Origination completed for ${contract.address}.`); + }) + .catch((error) => println(`Error: ${JSON.stringify(error, null, 2)}`)); +``` + + + + +### Accessing the values of the map + +This example loads the same type of Taco Shop contract (we created this one earlier). Taquito provides a `get` method of the `MichelsonMap` on storage of type `Map`, and in this case, we access the value stored with a key of `1`. + +The example calls the Contracts `main` function of the contract using the key `1` as its parameter. Remember, we can only change contract storage by calling the function provided by the contract. The `main` function on this Smart Contract is decreasing the value of the `current_stock` associated with the key `1`. We use the `get` method of the `MichelsonMap` class to see the difference in storage after the method call. + + + + +```js live noInline +Tezos.contract + .at('KT1B3SpFJ1iHagwdkd1utVYP18RyYgZXeGio') + .then((myContract) => { + return myContract + .storage() + .then((myStorage) => { + //We want to see the value of the key "1" + const value = myStorage.get('1'); + println( + `The key "1" of the map has a current_stock of ${ + value[Object.keys(value)[0]] + } and a max_price of ${value[Object.keys(value)[1]]}.` + ); + + //Calling the main method of the contract will modify the storage + return myContract.methods.default('1').send(); + }) + .then((op) => { + println(`Waiting for ${op.hash} to be confirmed...`); + return op.confirmation(1).then(() => op.hash); + }) + .then((hash) => { + println(`Operation injected.`); + + //Use the get method to see the change in storage + return myContract.storage(); + }) + .then((myStorage) => { + const value = myStorage.get('1'); + println( + `The key "1" of the map has now a current_stock of ${ + value[Object.keys(value)[0]] + } and a max_price of ${value[Object.keys(value)[1]]}.` + ); + }); + }) + .catch((error) => println(`Error: ${JSON.stringify(error, null, 2)}`)); +``` + + + + +```js live noInline wallet +Tezos.wallet + .at('KT1B3SpFJ1iHagwdkd1utVYP18RyYgZXeGio') + .then((myContract) => { + return myContract + .storage() + .then((myStorage) => { + //We want to see the value of the key "1" + const value = myStorage.get('1'); + println( + `The key "1" of the map has a current_stock of ${ + value[Object.keys(value)[0]] + } and a max_price of ${value[Object.keys(value)[1]]}.` + ); + + //Calling the main method of the contract will modify the storage + return myContract.methods.default('1').send(); + }) + .then((op) => { + println(`Waiting for ${op.opHash} to be confirmed...`); + return op.confirmation(1).then(() => op.opHash); + }) + .then((hash) => { + println(`Operation injected.`); + + //Use the get method to see the change in storage + return myContract.storage(); + }) + .then((myStorage) => { + const value = myStorage.get('1'); + println( + `The key "1" of the map has now a current_stock of ${ + value[Object.keys(value)[0]] + } and a max_price of ${value[Object.keys(value)[1]]}.` + ); + }); + }) + .catch((error) => println(`Error: ${JSON.stringify(error, null, 2)}`)); +``` + + + + +## A Contract with a Map using an unannotated pair/tuple as a key + +Here we have the storage of our contract defined in Michelson. + +It has a `Map` with the annotated name `%theMap`. This `Map` uses a pair consisting of a natural number and an address as its key `(1, tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx)`. Its value is also a pair of values, consisting of an `int` (annotated as `%quantity`) and `mutez` (annotated as `%amount`). + +``` +(pair (pair (address %theAddress) + (map %theMap (pair nat address) (pair (mutez %amount) (int %quantity)))) + (int %theNumber)) +``` + +### Origination of the contract with Pair as Map keys + +Since the key of the map has no annotations, MichelsonMap requires that we use an index value starting at `0` to initialize its elements. + + + + +```js live noInline +import { MichelsonMap } from '@taquito/taquito'; + +const storageMap = new MichelsonMap(); +//First entry of the map +storageMap.set( + { + // Pair as Key + 0: '1', //nat + 1: 'tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx', //address + }, + { quantity: '10', amount: '100' } +); + +//Second entry of the map +storageMap.set( + { + // Pair as Key + 0: '2', //nat + 1: 'tz1h3rQ8wBxFd8L9B3d7Jhaawu6Z568XU3xY', //address + }, + { quantity: '20', amount: '200' } +); + +//Third entry of the map +storageMap.set( + { + 0: '3', //nat + 1: 'tz1eY5Aqa1kXDFoiebL28emyXFoneAoVg1zh', //address + }, + { quantity: '30', amount: '300' } +); + +// contractMapPairKey variable contains the Michelson Smart Contract +Tezos.contract + .originate({ + code: contractMapPairKey, + storage: { + theAddress: 'tz1NAozDvi5e7frVq9cUaC3uXQQannemB8Jw', + theMap: storageMap, + theNumber: 10, + }, + }) + .then((contractOriginated) => { + println(`Waiting for the contract origination of ${contractOriginated.contractAddress}...`); + return contractOriginated.contract(); + }) + .then((contract) => { + println(`Origination completed.`); + }) + .catch((error) => println(`Error: ${JSON.stringify(error, null, 2)}`)); +``` + + + + +```js live noInline wallet +import { MichelsonMap } from '@taquito/taquito'; + +const storageMap = new MichelsonMap(); +//First entry of the map +storageMap.set( + { + // Pair as Key + 0: '1', //nat + 1: 'tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx', //address + }, + { quantity: '10', amount: '100' } +); + +//Second entry of the map +storageMap.set( + { + // Pair as Key + 0: '2', //nat + 1: 'tz1h3rQ8wBxFd8L9B3d7Jhaawu6Z568XU3xY', //address + }, + { quantity: '20', amount: '200' } +); + +//Third entry of the map +storageMap.set( + { + 0: '3', //nat + 1: 'tz1eY5Aqa1kXDFoiebL28emyXFoneAoVg1zh', //address + }, + { quantity: '30', amount: '300' } +); + +// contractMapPairKey variable contains the Michelson Smart Contract +Tezos.wallet + .originate({ + code: contractMapPairKey, + storage: { + theAddress: 'tz1NAozDvi5e7frVq9cUaC3uXQQannemB8Jw', + theMap: storageMap, + theNumber: 10, + }, + }) + .send() + .then((originationOp) => { + println(`Waiting for confirmation of origination...`); + return originationOp.contract(); + }) + .then((contract) => { + println(`Origination completed for ${contract.address}.`); + }) + .catch((error) => println(`Error: ${JSON.stringify(error, null, 2)}`)); +``` + + + + +### Accessing Map values using Pairs + +The `get` method of the `MichelsonMap` class accesses values of the map for a specified key. + +This example accesses the map using its `theMap` annotation. If the storage does not annotate its properties, the caller must use numeric indexes instead. + +Recall that this contract does not annotate the pairs of the key pair either. We use numeric indexes for this also. + + + + +```js live noInline +Tezos.contract + .at('KT1JDDU888CaVWFey2BYxpDzPBaYYn65Q4o3') + .then((myContract) => { + return myContract.storage(); + }) + .then((myStorage) => { + const value = myStorage['theMap'].get({ + 0: '2', //nat + 1: 'tz1h3rQ8wBxFd8L9B3d7Jhaawu6Z568XU3xY', //address + }); + println(`Values associated with this key : amount : ${value[Object.keys(value)[0]]}, quantity : + ${value[Object.keys(value)[1]]}`); + }) + .catch((error) => println(`Error: ${JSON.stringify(error, null, 2)}`)); +``` + + + + +```js live noInline wallet +Tezos.wallet + .at('KT1JDDU888CaVWFey2BYxpDzPBaYYn65Q4o3') + .then((myContract) => { + return myContract.storage(); + }) + .then((myStorage) => { + const value = myStorage['theMap'].get({ + 0: '2', //nat + 1: 'tz1h3rQ8wBxFd8L9B3d7Jhaawu6Z568XU3xY', //address + }); + println(`Values associated with this key : amount : ${value[Object.keys(value)[0]]}, quantity : + ${value[Object.keys(value)[1]]}`); + }) + .catch((error) => println(`Error: ${JSON.stringify(error, null, 2)}`)); +``` + + + + +## A Map with nested Pairs as keys + +This contract schema has a key with eight nested pairs and the value of an int. This example type of key is impractical, but we offer it as an example to illustrate how to work with complex keys. + +The Michelson storage schema with a map using eight pairs as a key: + +``` +(map (pair int + (pair nat + (pair string + (pair bytes + (pair mutez + (pair bool + (pair key_hash + (pair timestamp address)))))))) int) +``` + +### Origination of a contract with complex keys + +In this example, the contract schema does not have map annotations, which means that each value needs to have an index as a property name. + + + + +```js live noInline +const storageMap = new MichelsonMap(); +storageMap.set( + { + 0: '1', // int + 1: '2', // nat + 2: 'test', // string + 3: 'cafe', // bytes + 4: '10', // mutez + 5: true, // bool + 6: 'tz3WXYtyDUNL91qfiCJtVUX746QpNv5i5ve5', // key_hash + 7: '2019-09-06T15:08:29.000Z', // timestamp + 8: 'tz3WXYtyDUNL91qfiCJtVUX746QpNv5i5ve5', // address + }, + 100 +); + +storageMap.set( + { + 0: '10', // int + 1: '20', // nat + 2: 'Hello', // string + 3: 'ffff', // bytes + 4: '100', // mutez + 5: false, // bool + 6: 'tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx', // key_hash + 7: '2019-10-06T15:08:29.000Z', // timestamp + 8: 'tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx', // address + }, + 1000 +); + +// contractMap8pairs variable contains the Michelson Smart Contract +Tezos.contract + .originate({ + code: contractMap8pairs, + storage: storageMap, + }) + .then((contractOriginated) => { + println(`Waiting for the contract origination of ${contractOriginated.contractAddress}...`); + return contractOriginated.contract(); + }) + .then((contract) => { + println(`Origination completed.`); + }) + .catch((error) => println(`Error: ${JSON.stringify(error, null, 2)}`)); +``` + + + + +```js live noInline wallet +const storageMap = new MichelsonMap(); +storageMap.set( + { + 0: '1', // int + 1: '2', // nat + 2: 'test', // string + 3: 'cafe', // bytes + 4: '10', // mutez + 5: true, // bool + 6: 'tz3WXYtyDUNL91qfiCJtVUX746QpNv5i5ve5', // key_hash + 7: '2019-09-06T15:08:29.000Z', // timestamp + 8: 'tz3WXYtyDUNL91qfiCJtVUX746QpNv5i5ve5', // address + }, + 100 +); + +storageMap.set( + { + 0: '10', // int + 1: '20', // nat + 2: 'Hello', // string + 3: 'ffff', // bytes + 4: '100', // mutez + 5: false, // bool + 6: 'tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx', // key_hash + 7: '2019-10-06T15:08:29.000Z', // timestamp + 8: 'tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx', // address + }, + 1000 +); + +// contractMap8pairs variable contains the Michelson Smart Contract +Tezos.wallet + .originate({ + code: contractMap8pairs, + storage: storageMap, + }) + .send() + .then((originationOp) => { + println(`Waiting for confirmation of origination...`); + return originationOp.contract(); + }) + .then((contract) => { + println(`Origination completed for ${contract.address}.`); + }) + .catch((error) => println(`Error: ${JSON.stringify(error, null, 2)}`)); +``` + + + + +### Accessing Map values with complex keys + +The `get` method of the `MichelsonMap` class accesses values of the map for a specified key. + +:::caution Warning +** This example is under migration to a different testnet ** +::: + + + + +```js live noInline +Tezos.contract + .at('KT1PBDZULVwbDW7BqEANmyEJGWuzjk43hDJG') + .then((myContract) => { + return myContract.storage(); + }) + .then((myStorage) => { + const value = myStorage.get({ + 0: '1', // int + 1: '2', // nat + 2: 'test', // string + 3: 'cafe', // bytes + 4: '10', // mutez + 5: true, // bool + 6: 'tz3WXYtyDUNL91qfiCJtVUX746QpNv5i5ve5', // key_hash + 7: '2019-09-06T15:08:29Z', // timestamp + 8: 'tz3WXYtyDUNL91qfiCJtVUX746QpNv5i5ve5', // address + }); + println(`The value associated to this key is ${value}.`); + }) + .catch((error) => println(`Error: ${JSON.stringify(error, null, 2)}`)); +``` + + + + +```js live noInline wallet +Tezos.wallet + .at('KT1PBDZULVwbDW7BqEANmyEJGWuzjk43hDJG') + .then((myContract) => { + return myContract.storage(); + }) + .then((myStorage) => { + const value = myStorage.get({ + 0: '1', // int + 1: '2', // nat + 2: 'test', // string + 3: 'cafe', // bytes + 4: '10', // mutez + 5: true, // bool + 6: 'tz3WXYtyDUNL91qfiCJtVUX746QpNv5i5ve5', // key_hash + 7: '2019-09-06T15:08:29Z', // timestamp + 8: 'tz3WXYtyDUNL91qfiCJtVUX746QpNv5i5ve5', // address + }); + println(`The value associated to this key is ${value}.`); + }) + .catch((error) => println(`Error: ${JSON.stringify(error, null, 2)}`)); +``` + + + + +## BigMaps + +Map and BigMap are semantically the same except for everything you learned about Maps applies to working with BigMaps. The only difference is that when calling `get` on a bigMap will return a Javascript Promise, whereas get on a Map returns directly. In this example, the contract schema does not have map annotations, which means that each value needs to have an index as a property name. + +### Contract storage containing a map and a bigMap + +The `MichelsonMap` class also supports the `bigMap` type. The following example uses a contract containing both a map and a bigMap in its storage. Here is the Michelson definition of storage for this example: + +``` +(pair (big_map %thebigmap (pair nat address) int) (map %themap (pair nat address) int)) +``` + +#### Origination of the contract with an initial storage + + + + +```js live noInline +import { MichelsonMap } from '@taquito/taquito'; + +const storageMap = new MichelsonMap(); +storageMap.set( + { + 0: '1', //nat + 1: 'tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx', //address + }, + 10 +); +storageMap.set( + { + 0: '2', //nat + 1: 'tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx', //address + }, + 20 +); + +const storageBigMap = new MichelsonMap(); +storageBigMap.set( + { + 0: '10', //nat + 1: 'tz3WXYtyDUNL91qfiCJtVUX746QpNv5i5ve5', //address + }, + 100 +); +storageBigMap.set( + { + 0: '20', //nat + 1: 'tz3WXYtyDUNL91qfiCJtVUX746QpNv5i5ve5', //address + }, + 200 +); +// contractMapBigMap variable contains the Michelson Smart Contract +Tezos.contract + .originate({ + code: contractMapBigMap, + storage: { + themap: storageMap, + thebigmap: storageBigMap, + }, + }) + .then((originationOp) => { + println(`Waiting for confirmation of origination...`); + return originationOp.contract(); + }) + .then((contract) => { + println(`Origination completed for ${contract.address}.`); + }) + .catch((error) => println(`Error: ${JSON.stringify(error, null, 2)}`)); +``` + + + + +```js live noInline wallet +import { MichelsonMap } from '@taquito/taquito'; + +const storageMap = new MichelsonMap(); +storageMap.set( + { + 0: '1', //nat + 1: 'tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx', //address + }, + 10 +); +storageMap.set( + { + 0: '2', //nat + 1: 'tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx', //address + }, + 20 +); + +const storageBigMap = new MichelsonMap(); +storageBigMap.set( + { + 0: '10', //nat + 1: 'tz3WXYtyDUNL91qfiCJtVUX746QpNv5i5ve5', //address + }, + 100 +); +storageBigMap.set( + { + 0: '20', //nat + 1: 'tz3WXYtyDUNL91qfiCJtVUX746QpNv5i5ve5', //address + }, + 200 +); +// contractMapBigMap variable contains the Michelson Smart Contract +Tezos.wallet + .originate({ + code: contractMapBigMap, + storage: { + themap: storageMap, + thebigmap: storageBigMap, + }, + }) + .send() + .then((originationOp) => { + println(`Waiting for confirmation of origination...`); + return originationOp.contract(); + }) + .then((contract) => { + println(`Origination completed for ${contract.address}.`); + }) + .catch((error) => println(`Error: ${JSON.stringify(error, null, 2)}`)); +``` + + + + +#### Accessing the values of the map and the bigMap + +The `get` method of the `MichelsonMap` class accesses the values of the map and values of the bigMap. The difference is that the value gets returned directly for a map while the get method on a bigMap returns a promise. + + + + +```js live noInline +Tezos.contract + .at('KT1PZb8sEVvsKQGzLwusyQRkJpSCDQ7WFfny') + .then((myContract) => { + return myContract + .storage() + .then((myStorage) => { + //When called on a map, the get method returns the value directly + const valueMap = myStorage['themap'].get({ + 0: '1', //nat + 1: 'tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx', //address + }); + println(`The value associated with the specified key of the map is ${valueMap}.`); + return myContract.storage(); + }) + + .then((myStorage) => { + //When called on a bigMap, the get method returns a promise + return myStorage['thebigmap'].get({ + 0: '10', //nat + 1: 'tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx', //address + }); + }) + .then((valueBigMap) => { + println(`The value associated with the specified key of the bigMap is ${valueBigMap}.`); + }); + }) + .catch((error) => println(`Error: ${JSON.stringify(error, null, 2)}`)); +``` + + + + +```js live noInline wallet +Tezos.wallet + .at('KT1PZb8sEVvsKQGzLwusyQRkJpSCDQ7WFfny') + .then((myContract) => { + return myContract + .storage() + .then((myStorage) => { + //When called on a map, the get method returns the value directly + const valueMap = myStorage['themap'].get({ + 0: '1', //nat + 1: 'tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx', //address + }); + println(`The value associated with the specified key of the map is ${valueMap}.`); + return myContract.storage(); + }) + + .then((myStorage) => { + //When called on a bigMap, the get method returns a promise + return myStorage['thebigmap'].get({ + 0: '10', //nat + 1: 'tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx', //address + }); + }) + .then((valueBigMap) => { + println(`The value associated with the specified key of the bigMap is ${valueBigMap}.`); + }); + }) + .catch((error) => println(`Error: ${JSON.stringify(error, null, 2)}`)); +``` + + + + +## Local packing for big maps + +By default, a call to an RPC node is used to pack data when fetching values from a big map. Big map keys need to be serialized or packed and Taquito relies on the PACK functionality of a Tezos RPC node to pack the big map keys. This may be considered inefficient as it adds a request to a remote node to fetch data. + +Now, Taquito allows you to pack the required data locally to fetch values from a big map. By relying on the local pack implementation, Taquito eliminates one RPC roundtrip when fetching big map values. This feature makes fetching big map values **50% faster**. + +Implementing this feature is a very easy 2 step process: + +1. Importing the `MichelCodecPacker` class from `@taquito/taquito` +2. Creating an instance of the `MichelCodecPacker` class and passing it to the `setPackerProvider` method of the `TezosToolkit` instance. + +Here is an example: + +```js +import { MichelCodecPacker } from '@taquito/taquito'; +const Tezos = new TezosToolkit(RPC_URL); +Tezos.setPackerProvider(new MichelCodecPacker()); +``` + +After that, Taquito will automatically pack the keys locally when you want to fetch the values of a big map. + +## Fetch multiple big map values at once + +It is possible to fetch multiple big map values using Taquito with one call using the `getMultipleValues` method of the `BigMapAbstraction` class. Taquito will ensure that all fetched big maps come from the same block to ensure a consistent state. + +The method takes an `array` of keys to query as a parameter and an optional block level and returns a `MichelsonMap` containing the keys and their value in a well-formatted JSON object format. The accepted types for the keys are `string`, `number` or `object` (the last one is used when the type of the keys in the big map is a Michelson `pair`). + +In the following example, we will fetch 4 big map values at once. The Michelson type of the big map key is an `address` and the type of its value is a `pair` made of a `nat` and a `map`. We see in the example that the address `tz1QZ6KY7d3BuZDT1d19dUxoQrtFPN2QJ3hn` is not a key of the big map, so its value is set to `undefined` in the returned MichelsonMap. + + + + +```js live noInline +// import { TezosToolkit } from '@taquito/taquito'; +// const Tezos = new TezosToolkit('https://ghostnet.ecadinfra.com'); + +Tezos.contract + .at('KT1LPdW47Aba3kVpNMpRt7sx5yM1M4A8XmAW') + .then((contract) => { + println('Fetching the storage of the contract...'); + return contract.storage(); + }) + .then((storage) => { + println('Fetching the big map values...\n'); + return storage['0'].getMultipleValues([ + 'tz3WXYtyDUNL91qfiCJtVUX746QpNv5i5ve5', + 'tz1h3rQ8wBxFd8L9B3d7Jhaawu6Z568XU3xY', + 'tz1bwsEWCwSEXdRvnJxvegQZKeX5dj6oKEys', + 'tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb', + ]); + }) + .then((values) => { + values.forEach((value, key) => { + println(`The value of the key ${key} is:\n${JSON.stringify(value, null, 2)}.\n`); + }); + }) + .catch((error) => println(JSON.stringify(error))); +``` + + + + +```js live noInline wallet +// import { TezosToolkit } from '@taquito/taquito'; +// const Tezos = new TezosToolkit('https://ghostnet.ecadinfra.com'); + +Tezos.wallet + .at('KT1LPdW47Aba3kVpNMpRt7sx5yM1M4A8XmAW') + .then((contract) => { + println('Fetching the storage of the contract...'); + return contract.storage(); + }) + .then((storage) => { + println('Fetching the big map values...\n'); + return storage['0'].getMultipleValues([ + 'tz3WXYtyDUNL91qfiCJtVUX746QpNv5i5ve5', + 'tz1h3rQ8wBxFd8L9B3d7Jhaawu6Z568XU3xY', + 'tz1bwsEWCwSEXdRvnJxvegQZKeX5dj6oKEys', + 'tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb', + ]); + }) + .then((values) => { + values.forEach((value, key) => { + println(`The value of the key ${key} is:\n${JSON.stringify(value, null, 2)}.\n`); + }); + }) + .catch((error) => println(JSON.stringify(error))); +``` + + + + +--- + +[michelson_map]: https://michelson.nomadic-labs.com/#type-big_map +[michelson_bigmap]: https://michelson.nomadic-labs.com/#type-big_map diff --git a/website/versioned_docs/version-13.0.0/metadata-tzip16.md b/website/versioned_docs/version-15.1.0/metadata-tzip16.md similarity index 90% rename from website/versioned_docs/version-13.0.0/metadata-tzip16.md rename to website/versioned_docs/version-15.1.0/metadata-tzip16.md index c09a8f824a..9044c29065 100644 --- a/website/versioned_docs/version-13.0.0/metadata-tzip16.md +++ b/website/versioned_docs/version-15.1.0/metadata-tzip16.md @@ -99,7 +99,7 @@ values={[ Tezos.addExtension(new Tzip16Module()); -const contractAddress = 'KT1GL5WBtKc6PgFAk4cSGp5Dg8RSXQPk4zkR'; +const contractAddress = 'KT1UoYTsDCFgBx88QYdCd3pgjwV6RiMVpZaY'; Tezos.contract .at(contractAddress, tzip16) @@ -123,7 +123,7 @@ Tezos.contract Tezos.addExtension(new Tzip16Module()); -const contractAddress = 'KT1GL5WBtKc6PgFAk4cSGp5Dg8RSXQPk4zkR'; +const contractAddress = 'KT1UoYTsDCFgBx88QYdCd3pgjwV6RiMVpZaY'; Tezos.wallet .at(contractAddress, tzip16) @@ -157,7 +157,7 @@ values={[ Tezos.addExtension(new Tzip16Module()); -const contractAddress = 'KT1Qrn8qpdZAFwuzh6qrnA3uA2bQJkVdMLRr'; +const contractAddress = 'KT1MJ7wAZ9LBB797zhGJrXByaaUwvLGfe3qz'; Tezos.contract .at(contractAddress, tzip16) @@ -180,7 +180,7 @@ Tezos.contract Tezos.addExtension(new Tzip16Module()); -const contractAddress = 'KT1Qrn8qpdZAFwuzh6qrnA3uA2bQJkVdMLRr'; +const contractAddress = 'KT1MJ7wAZ9LBB797zhGJrXByaaUwvLGfe3qz'; Tezos.wallet .at(contractAddress, tzip16) @@ -213,7 +213,7 @@ values={[ Tezos.addExtension(new Tzip16Module()); -const contractAddress = 'KT1FYBzqkMQ5g4XRiHenHbN43xVgFEEEoPHu'; +const contractAddress = 'KT1JbEzvHn2Y2DjVQ7kgK8H8pxrspG893JsX'; Tezos.contract .at(contractAddress, tzip16) @@ -237,7 +237,7 @@ Tezos.contract Tezos.addExtension(new Tzip16Module()); -const contractAddress = 'KT1FYBzqkMQ5g4XRiHenHbN43xVgFEEEoPHu'; +const contractAddress = 'KT1JbEzvHn2Y2DjVQ7kgK8H8pxrspG893JsX'; Tezos.wallet .at(contractAddress, tzip16) @@ -271,7 +271,7 @@ values={[ Tezos.addExtension(new Tzip16Module()); -const contractAddress = 'KT1PT8xPJZovECeVwAxuSSzAAoKok9EYmy2w'; +const contractAddress = 'KT1SDtsB4DHdh1QwFNgvsavxDwQJBdimgrcL'; Tezos.contract .at(contractAddress, tzip16) @@ -295,7 +295,7 @@ Tezos.contract Tezos.addExtension(new Tzip16Module()); -const contractAddress = 'KT1PT8xPJZovECeVwAxuSSzAAoKok9EYmy2w'; +const contractAddress = 'KT1SDtsB4DHdh1QwFNgvsavxDwQJBdimgrcL'; Tezos.wallet .at(contractAddress, tzip16) @@ -361,7 +361,7 @@ values={[ Tezos.addExtension(new Tzip16Module()); -const contractAddress = 'KT1TzUzfjd8cZsFD3YfuFxKRgCnireksh8M7'; +const contractAddress = 'KT1GZdLX8Zc6vmrifnUhppNVwt9s19yffLLW'; Tezos.contract .at(contractAddress, tzip16) @@ -390,7 +390,7 @@ Tezos.contract Tezos.addExtension(new Tzip16Module()); -const contractAddress = 'KT1TzUzfjd8cZsFD3YfuFxKRgCnireksh8M7'; +const contractAddress = 'KT1GZdLX8Zc6vmrifnUhppNVwt9s19yffLLW'; Tezos.wallet .at(contractAddress, tzip16) @@ -431,7 +431,7 @@ values={[ Tezos.addExtension(new Tzip16Module()); -const contractAddress = 'KT1Q1PFYduhRqWohspCcWdZ7j6mDg5xrgqJG'; +const contractAddress = 'KT1CVoo3PxuvH3BuBpNTYRDafAQ7aRTfj8bd'; Tezos.contract .at(contractAddress, tzip16) @@ -462,7 +462,7 @@ Tezos.contract Tezos.addExtension(new Tzip16Module()); -const contractAddress = 'KT1Q1PFYduhRqWohspCcWdZ7j6mDg5xrgqJG'; +const contractAddress = 'KT1CVoo3PxuvH3BuBpNTYRDafAQ7aRTfj8bd'; Tezos.wallet .at(contractAddress, tzip16) @@ -499,11 +499,11 @@ values={[ ```js live noInline -// import { TezosToolkit } from '@taquito/taquito'; +// import { TezosToolkit, RpcReadAdapter } from '@taquito/taquito'; // import { MichelsonStorageView } from "@taquito/tzip16"; // const Tezos = new TezosToolkit('rpc_url'); -const contractAddress = 'KT1Q1PFYduhRqWohspCcWdZ7j6mDg5xrgqJG'; +const contractAddress = 'KT1CVoo3PxuvH3BuBpNTYRDafAQ7aRTfj8bd'; Tezos.contract .at(contractAddress) @@ -512,7 +512,7 @@ Tezos.contract 'test', // view name contract, // contract abstraction Tezos.rpc, // rpc - Tezos.getFactory(RpcReadAdapter)(), // readProvider + new RpcReadAdapter(Tezos.rpc), // readProvider { prim: 'nat' }, // returnType [ { prim: 'DUP' }, @@ -536,11 +536,11 @@ Tezos.contract ```js live noInline wallet -// import { TezosToolkit } from '@taquito/taquito'; +// import { TezosToolkit, RpcReadAdapter } from '@taquito/taquito'; // import { MichelsonStorageView } from "@taquito/tzip16"; // const Tezos = new TezosToolkit('rpc_url'); -const contractAddress = 'KT1Q1PFYduhRqWohspCcWdZ7j6mDg5xrgqJG'; +const contractAddress = 'KT1CVoo3PxuvH3BuBpNTYRDafAQ7aRTfj8bd'; Tezos.wallet .at(contractAddress) @@ -549,7 +549,7 @@ Tezos.wallet 'test', // view name wallet, // contract abstraction Tezos.rpc, // rpc, - Tezos.getFactory(RpcReadAdapter)(), // readProvider + new RpcReadAdapter(Tezos.rpc), // readProvider { prim: 'nat' }, // returnType [ { prim: 'DUP' }, diff --git a/website/versioned_docs/version-13.0.0/michelson_encoder.md b/website/versioned_docs/version-15.1.0/michelson_encoder.md similarity index 100% rename from website/versioned_docs/version-13.0.0/michelson_encoder.md rename to website/versioned_docs/version-15.1.0/michelson_encoder.md diff --git a/website/versioned_docs/version-13.0.0/michelsonmap.md b/website/versioned_docs/version-15.1.0/michelsonmap.md similarity index 95% rename from website/versioned_docs/version-13.0.0/michelsonmap.md rename to website/versioned_docs/version-15.1.0/michelsonmap.md index a6a300525a..2dfef1e102 100644 --- a/website/versioned_docs/version-13.0.0/michelsonmap.md +++ b/website/versioned_docs/version-15.1.0/michelsonmap.md @@ -15,7 +15,7 @@ Taquito reads maps in the storage of smart contracts and translates them into an - _The key/value methods_: they allow you to manipulate the keys and values in the map - _The update methods_: they transform the map itself, for example, by deleting elements or clearing out the map entirely. -This tutorial uses a [simple smart contract deployed on ithacanet](https://better-call.dev/ithacanet/KT1NzbR52g8TBAKzDH5TXEtxiARFuwzvC4hi/operations) with a map that contains addresses as keys and tez as values. We will use all the methods available in Taquito's `MichelsonMap` to check the map, extract values and modify them! +This tutorial uses a [simple smart contract deployed on ghostnet](https://better-call.dev/ghostnet/KT1M5C76aSjpWXdoBvuzRdi3UJoC3jEzrSUW/operations) with a map that contains addresses as keys and tez as values. We will use all the methods available in Taquito's `MichelsonMap` to check the map, extract values and modify them! > Note: Taquito is written in TypeScript; we will also use TypeScript to interact with the contract storage. @@ -27,9 +27,9 @@ This paragraph is a little reminder of how to use Taquito to fetch the storage o import { TezosToolkit, MichelsonMap } from '@taquito/taquito'; import { BigNumber } from 'bignumber.js'; -const contractAddress: string = 'KT1NzbR52g8TBAKzDH5TXEtxiARFuwzvC4hi'; +const contractAddress: string = 'KT1M5C76aSjpWXdoBvuzRdi3UJoC3jEzrSUW'; -const Tezos = new TezosToolkit('https://testnet-tezos.giganode.io'); +const Tezos = new TezosToolkit('https://ghostnet.ecadinfra.com'); const contract = await Tezos.contract.at(contractAddress); const storage: MichelsonMap = await contract.storage(); diff --git a/website/versioned_docs/version-15.1.0/mobile_bundle.md b/website/versioned_docs/version-15.1.0/mobile_bundle.md new file mode 100644 index 0000000000..b36c363472 --- /dev/null +++ b/website/versioned_docs/version-15.1.0/mobile_bundle.md @@ -0,0 +1,26 @@ +--- +title: Taquito in Native Mobile Environments +id: mobile_bundle +author: Davis Sawali +--- +# Using Taquito in Mobile environments +Taquito works best in Node runtime applications, but some of our users working in native mobile development might not have access to such features. To accommodate for that, we decided to add a separate pure JS bundle that you can import into your native mobile applications. + +Currently the only available bundle is for the `@taquito/local-forging` package. + +The bundle wraps functions in the `@taquito/local-forging` package into a single variable called `taquito_local_forging` + +## Instructions on using the bundle +To use the JS bundle for your project, download the zip file under `Assets` from your preferred Taquito [release](https://github.com/ecadlabs/taquito/releases). + +After that, simply copy the `.js` file and the `.map.js` file into your project. + +Example of how to use the `LocalForger` class in a simple HTML script tag: +``` + + +``` \ No newline at end of file diff --git a/website/versioned_docs/version-15.1.0/multisig_doc.md b/website/versioned_docs/version-15.1.0/multisig_doc.md new file mode 100644 index 0000000000..0ec4e8ae13 --- /dev/null +++ b/website/versioned_docs/version-15.1.0/multisig_doc.md @@ -0,0 +1,331 @@ +--- +title: Multisig contract interactions +author: Claude Barde +--- + +# Interacting with the multisig contract +The `tezos-client` provides a simple multisig contract that you can originate and interact with directly from the command line. + +However, you may want to build a dapp that interacts with the contract, and writing the JavaScript to do so turns out to be tricky. + +After understanding the structure of the contract, you will be able to use Taquito to write code that will send a `transfer` transaction and a `change_keys` transaction to your originated multisig contract. + +## What is the multisig contract? +A multisig contract is a smart contract that allows a group of users to agree and control different actions executed through the contract. + +The multisig contract in the `tezos-client` allows three actions: +- the receiving of tez through the default entrypoint +- the transfer of tez stored in the contract to a given address +- the update of the participants to the multisig contract + +> Note: +> Only the first action is not subject to the agreement of the participants, anybody can send tez to the contract + +In order to transfer tez or to change the participants of the multisig contract, a transaction must be sent to the contract. The transaction must include a payload and a list of signatures generated from the payload, and the length of the list must match or exceed the current threshold stored in the contract storage. + +The storage of the contract includes also a counter that is incremented at every successful transaction to prevent operations from being replayed. + +## Using the `transfer` entrypoint +The multisig contract allows the participants to send a Michelson lambda along with a payload, for example, to authorize the transfer of a certain amount of tez to an implicit account. This operation requires multiple steps: +- Writing a lambda in Michelson that will forge an operation to transfer the tez to the provided address +- Writing the nested pair that will include the different values required by the contract +- Packing the Michelson value created in the previous step +- Having the participants of the contract sign the packed value +- Sending a transaction to the contract with the payload and the obtained signatures + +> Note: +> A `lambda` is an inline function made of Michelson code within curly braces that will be run during the contract execution. + +Let's see how that translates into JavaScript: + +```typescript +const lambda = `{ + DROP ; + NIL operation ; + PUSH key_hash "${RECIPIENT_ADDRESS}" ; + IMPLICIT_ACCOUNT ; + PUSH mutez ${AMOUNT} ; + UNIT ; + TRANSFER_TOKENS ; + CONS +}`; +``` + +First, we write the Michelson lambda that will be executed to transfer the tez, where `RECIPIENT_ADDRESS` is the public key hash of the recipient of the tez and `AMOUNT` is the amount of mutez to be sent. + +The lambda for this particular use case is already offered by Taquito, so you don't have to write it every time, you can just import it: +```typescript +import { MANAGER_LAMBDA } from "@taquito/taquito"; + +const lambda = MANAGER_LAMBDA.transferImplicit(RECIPIENT_ADDRESS, AMOUNT); +``` + +Next, we will use the lambda to create the required payload for this action: +```typescript +import { TezosToolkit } from "@taquito/taquito"; +import { Parser, packDataBytes } from "@taquito/michel-codec"; + +const Tezos = new TezosToolkit(RPC_URL); +const chainId = await Tezos.rpc.getChainId(); +const contract = await Tezos.contract.at(MULTISIG_ADDRESS); +const storage: any = await contract.storage(); +const counter = storage.stored_counter.toNumber(); + +const p = new Parser(); + +const michelsonData = `( + Pair "${chainId}" + ( + Pair "${MULTISIG_ADDRESS}" + ( + Pair ${counter} (Left ${lambda}) + ) + ) +)`; +const dataToPack = p.parseMichelineExpression(michelsonData); +``` + +The payload expected by the multisig contract is a nested pair that contains the chain id, the address of the contract, the current counter (from the contract storage) and the option set to `Left` with the lambda as a value. + +The payload is then parsed using the parser from the `@taquito/michel-codec` package. + +After that, we need to parse the payload type in a similar fashion: +```typescript +const michelsonType = ` +(pair + chain_id + (pair + address + (pair + nat + (or + (lambda unit (list operation)) + (pair + nat + (list key) + ) + ) + ) + ) +) +`; +const typeToPack = p.parseMichelineExpression(michelsonType); +``` + +Now that both the value and its type have been properly parsed, we can pack them: +```typescript +const { bytes: payload } = packDataBytes( + dataToPack as any, + typeToPack as any +); +``` + +This action uses the `packDataBytes` method that you can find in the `@taquito/michel-codec` package to pack the data we created above locally. This will output the payload that will be signed. + +>Note: +> `packDataBytes` allows local packing, which removes any risk of data corruption that may exist when using the packing feature of a remote RPC node. + +```typescript +const sig = ( + await Tezos.signer.sign( + payload, + new Uint8Array() + ) +).prefixSig; +``` + +The instance of the `TezosToolkit` holds a signer that you can use to sign arbitrary data as shown above. It returns different values and we will keep the one under the `prefixSig` property. + +From there, the payload will be shared with the other participants. Each one of them will review it, and sign it and the initiator of the contract call will collect all the signatures to submit them with the transaction. + +Now the transaction can be forged and sent to the contract: +```typescript +try { + const contract = await Tezos.contract.at(MULTISIG_ADDRESS); + const storage: any = await contract.storage(); + const op = await contract.methodsObject.main({ + payload: { + counter: storage.stored_counter.toNumber(), + action: { operation: lambda } + }, + sigs: [sig, ...signatures] + }); + await op.confirmation(); +} catch (err) { + console.error(err); +} +``` + +If everything works correctly, the counter of the multisig contract should be incremented by 1 and the given amount of tez should be transferred to the provided address. + +## Using the `change_keys` entrypoint + +Sending a `change_keys` operation is going to be very similar to sending a `transfer` operation, with a little difference in the arguments you provide. + +The purpose of the `change_keys` operation is to update the threshold and the keys in the list of participants while asking all the current participants if they approve the update. + +First, we want to parse an array of keys into a Michelson value: +```typescript +const listOfKeys = [KEY_1, KEY_2, KEY_3]; +const michelineListOfKeys = `{ ${listOfKeys + .map(key => `"${key}"`) + .join(" ; ")} }`; +``` + +Next, we are going to pack the required nested pair in the same way we did earlier while changing some values in the pair: +```typescript +import { TezosToolkit } from "@taquito/taquito"; +import { Parser } from "@taquito/michel-codec"; + +const Tezos = new TezosToolkit(RPC_URL); +const chainId = await Tezos.rpc.getChainId(); +const contract = await Tezos.contract.at(MULTISIG_ADDRESS); +const storage: any = await contract.storage(); +const counter = storage.stored_counter.toNumber(); + +const p = new Parser(); +const newThreshold = 2; + +const michelsonData = `( + Pair "${chainId}" + ( + Pair "${MULTISIG_ADDRESS}" + ( + Pair ${counter} + (Right (Pair ${newThreshold} ${michelineListOfKeys})) + ) + ) +)`; +const dataToPack = p.parseMichelineExpression(michelsonData); + +const michelsonType = `(pair chain_id (pair address (pair nat (or (lambda unit (list operation)) (pair nat (list key))))))`; + const typeToPack = p.parseMichelineExpression(michelsonType); + + const { bytes: payload } = packDataBytes( + dataToPack as any, + typeToPack as any + ); +``` + +This creates the Michelson value and its type that will be ultimately packed in order to generate the payload that the other participants must sign. + +Now, the signatures can be collected and a transaction can be sent: +```typescript +const signatures = [SIG_1, SIG_2, SIG_3]; +const forgerSig = + (await Tezos.signer.sign(payload, new Uint8Array())).prefixSig; + +try { + const contract = await Tezos.contract.at(MULTISIG_ADDRESS); + const storage: any = await contract.storage(); + const op = await contract.methodsObject.main({ + payload: { + counter: storage.stored_counter.toNumber(), + action: { + change_keys: { + threshold: newThreshold, + keys: listOfKeys + } + }, + sigs: [forgerSig, ...signatures] + }); + await op.confirmation(); +} catch (err) { + console.error(err); +} +``` +After confirmation, the threshold and the list of keys in the contract will be updated accordingly. + +## More about the `transfer` entrypoint +Although called `transfer`, this entrypoint actually has a more general purpose, i.e. the execution of a Michelson lambda approved by the required minimum number of participants in the multisig (the `threshold` value in the storage). + +As an example, let's check how the exchange of 50 XTZ to tzBTC through the Liquidity Baking contract would work. + +The first step is to write the Michelson lambda: +```typescript +const minTokensBought = 360000; // Should be calculated before every transaction +const lambda = `{ + /* checks that the contract has enough balance */ + PUSH mutez 50000000 ; + BALANCE ; + COMPARE ; + GE ; + IF + { + /* prepares payload for transaction */ + NOW ; + PUSH int 600 ; + ADD @timestamp ; + PUSH @minTokensBought nat ${minTokensBought} ; + PAIR ; + SELF_ADDRESS @to ; + PAIR @xtzToToken ; + /* creates contract parameter */ + PUSH address "KT1TxqZ8QtKvLu3V3JH7Gx58n7Co8pgtpQU5" ; + CONTRACT %xtzToToken (pair (address %to) (pair (nat %minTokensBought) (timestamp %deadline))) ; + IF_NONE + { + PUSH string "UNKNOWN_TARGET_CONTRACT" ; + FAILWITH ; + } + { + SWAP ; + PUSH mutez 50000000; + SWAP ; + TRANSFER_TOKENS ; + NIL operation ; + SWAP ; + CONS ; + } ; + } + { + /* insufficient contract balance */ + PUSH string "INSUFFICIENT_BALANCE" ; + FAILWITH ; + } ; +}`; +``` +The lambda here is going to prepare an operation to the liquidity baking DEX (also called "SIRIUS DEX"), the only value that you have to calculate beforehand is the minimum amount of tzBTC expected to be received in exchange for 50 XTZ: + +```typescript +const tokenOut_ = new BigNumber(tokenOut).times(new BigNumber(1000)); +const allowedSlippage_ = new BigNumber( +Math.floor(allowedSlippage * 1000 * 100) +); +const result = tokenOut_ +.minus( + tokenOut_.times(allowedSlippage_).dividedBy(new BigNumber(100000)) +) +.dividedBy(1000); +return BigNumber.maximum(result, new BigNumber(1)); + +const minTokensBought = (({ + xtzIn, + xtzPool, + tokenPool, + feePercent, + burnPercent +}: { + xtzIn: number, + xtzPool: number, + tokenPool: number, + feePercent?: number, + burnPercent?: number + }) => { + xtzPool = xtzPool + 2_500_000; + + const fee = feePercent ? 1000 - Math.floor(feePercent * 10) : 1000; + const burn = burnPercent ? 1000 - Math.floor(burnPercent * 10) : 1000; + const feeMultiplier = fee * burn; + + if(xtzPool > 0 && tokenPool > 0 && xtzIn > 0) { + const numerator = xtzIn * tokenPool * feeMultiplier; + const denominator = (xtzPool * 1_000_000) + (xtzIn * feeMultiplier); + return numerator / denominator; + } else { + return null; + } +})() +``` + +From this point forwards, you can repeat the same steps as in the `Using the transfer entrypoint` above to pack the data, get the signatures and send it to the DEX. \ No newline at end of file diff --git a/website/versioned_docs/version-13.0.0/on_chain_views.md b/website/versioned_docs/version-15.1.0/on_chain_views.md similarity index 94% rename from website/versioned_docs/version-13.0.0/on_chain_views.md rename to website/versioned_docs/version-15.1.0/on_chain_views.md index 5c79f4a5ad..8b160120b0 100644 --- a/website/versioned_docs/version-13.0.0/on_chain_views.md +++ b/website/versioned_docs/version-15.1.0/on_chain_views.md @@ -123,8 +123,8 @@ values={[ ```js live noInline -const contractTopLevelViews = 'KT1EcJTojUXgbMj2s7VowWTxs9ca4qSUqW4s'; -const contractCallFib = 'KT1H7Bg7r7Aa9sci2hoJtmTdS7W64aq4vev8'; +const contractTopLevelViews = 'KT1KPDBat3prp2G81aDDLyJ38Vbq6YLYFQo8'; +const contractCallFib = 'KT1Anag1s3N7erRXrRAtPpRC2PRXrqcCJ43m'; Tezos.contract.at(contractCallFib) .then((contract) => { @@ -152,8 +152,8 @@ Tezos.contract.at(contractCallFib) ```js live noInline wallet -const contractTopLevelViews = 'KT1EcJTojUXgbMj2s7VowWTxs9ca4qSUqW4s'; -const contractCallFib = 'KT1H7Bg7r7Aa9sci2hoJtmTdS7W64aq4vev8'; +const contractTopLevelViews = 'KT1KPDBat3prp2G81aDDLyJ38Vbq6YLYFQo8'; +const contractCallFib = 'KT1Anag1s3N7erRXrRAtPpRC2PRXrqcCJ43m'; Tezos.wallet.at(contractCallFib) .then((contract) => { @@ -207,8 +207,8 @@ values={[ ```js live noInline -const contractTopLevelViews = 'KT1EcJTojUXgbMj2s7VowWTxs9ca4qSUqW4s'; -const contractCallFib = 'KT1H7Bg7r7Aa9sci2hoJtmTdS7W64aq4vev8'; +const contractTopLevelViews = 'KT1KPDBat3prp2G81aDDLyJ38Vbq6YLYFQo8'; +const contractCallFib = 'KT1Anag1s3N7erRXrRAtPpRC2PRXrqcCJ43m'; const fibPosition = 7; Tezos.contract.at(contractTopLevelViews) @@ -225,8 +225,8 @@ Tezos.contract.at(contractTopLevelViews) ```js live noInline wallet -const contractTopLevelViews = 'KT1EcJTojUXgbMj2s7VowWTxs9ca4qSUqW4s'; -const contractCallFib = 'KT1H7Bg7r7Aa9sci2hoJtmTdS7W64aq4vev8'; +const contractTopLevelViews = 'KT1KPDBat3prp2G81aDDLyJ38Vbq6YLYFQo8'; +const contractCallFib = 'KT1Anag1s3N7erRXrRAtPpRC2PRXrqcCJ43m'; const fibPosition = 7; Tezos.wallet.at(contractTopLevelViews) diff --git a/website/versioned_docs/version-13.0.0/originate.md b/website/versioned_docs/version-15.1.0/originate.md similarity index 93% rename from website/versioned_docs/version-13.0.0/originate.md rename to website/versioned_docs/version-15.1.0/originate.md index 354195f183..98a11c140a 100644 --- a/website/versioned_docs/version-13.0.0/originate.md +++ b/website/versioned_docs/version-15.1.0/originate.md @@ -35,7 +35,7 @@ This requires a signer to be configured, ie: ``` import { importKey } from '@taquito/signer'; import { TezosToolkit } from '@taquito/taquito'; -const Tezos = new TezosToolkit('https://ithacanet.ecadinfra.com'); +const Tezos = new TezosToolkit('https://jakartanet.ecadinfra.com'); importKey(Tezos, "p2sk2obfVMEuPUnadAConLWk7Tf4Dt3n4svSgJwrgpamRqJXvaYcg1") ``` @@ -45,10 +45,10 @@ importKey(Tezos, "p2sk2obfVMEuPUnadAConLWk7Tf4Dt3n4svSgJwrgpamRqJXvaYcg1") ``` import { BeaconWallet } from '@taquito/beacon-wallet'; import { TezosToolkit } from '@taquito/taquito'; -const Tezos = new TezosToolkit('https://ithacanet.ecadinfra.com'); +const Tezos = new TezosToolkit('https://jakartanet.ecadinfra.com'); const option = { name: "nameOfWallet" } const wallet = new BeaconWallet(option) -const network = { type: "ithacanet" } +const network = { type: "jakartanet" } await wallet.requestPermissions({ network }) Tezos.setWalletProvider(wallet) ``` @@ -86,7 +86,7 @@ values={[ ```js live noInline // import { TezosToolkit } from '@taquito/taquito'; -// const Tezos = new TezosToolkit('https://ithacanet.ecadinfra.com'); +// const Tezos = new TezosToolkit('https://jakartanet.ecadinfra.com'); // const genericMultisigJSONfile = require('./generic.json') // generic.json is referring to Michelson source code in JSON representation @@ -115,7 +115,7 @@ Tezos.contract ```js live noInline wallet // import { TezosToolkit } from '@taquito/taquito'; -// const Tezos = new TezosToolkit('https://ithacanet.ecadinfra.com'); +// const Tezos = new TezosToolkit('https://jakartanet.ecadinfra.com'); // const genericMultisigJSONfile = require('./generic.json') // generic.json is referring to Michelson source code in JSON representation @@ -157,7 +157,7 @@ values={[ ```js live noInline // import { TezosToolkit } from '@taquito/taquito'; -// const Tezos = new TezosToolkit('https://ithacanet.ecadinfra.com'); +// const Tezos = new TezosToolkit('https://jakartanet.ecadinfra.com'); // const genericMultisigJSONfile = require('./generic.json') // generic.json is referring to Michelson source code in JSON representation @@ -182,7 +182,7 @@ Tezos.contract ```js live noInline wallet // import { TezosToolkit } from '@taquito/taquito'; -// const Tezos = new TezosToolkit('https://ithacanet.ecadinfra.com'); +// const Tezos = new TezosToolkit('https://jakartanet.ecadinfra.com'); // const genericMultisigJSONfile = require('./generic.json') // generic.json is referring to Michelson source code in JSON representation @@ -218,7 +218,7 @@ values={[ ```js live noInline // import { TezosToolkit } from '@taquito/taquito'; -// const Tezos = new TezosToolkit('https://ithacanet.ecadinfra.com'); +// const Tezos = new TezosToolkit('https://jakartanet.ecadinfra.com'); // const genericMultisigJSONfile = require('./generic.json') // generic.json is referring to Michelson source code in JSON representation @@ -255,7 +255,7 @@ Tezos.contract ```js live noInline wallet // import { TezosToolkit } from '@taquito/taquito'; -// const Tezos = new TezosToolkit('https://ithacanet.ecadinfra.com'); +// const Tezos = new TezosToolkit('https://jakartanet.ecadinfra.com'); // const genericMultisigJSONfile = require('./generic.json') // generic.json is referring to Michelson source code in JSON representation diff --git a/website/versioned_docs/version-15.1.0/prepare.md b/website/versioned_docs/version-15.1.0/prepare.md new file mode 100644 index 0000000000..4a9580fb55 --- /dev/null +++ b/website/versioned_docs/version-15.1.0/prepare.md @@ -0,0 +1,88 @@ +--- +title: Preparing Operations +author: Davis Sawali +--- + +:::warning +This feature is currently a work in progress and may be updated in the near future. +::: + +Before operations are _forged_, _signed_, and then _injected_, they first need to go through a _Prepare_ step. + +In Taquito, the act of preparing an operation is to create the Operation Object and the counter in one single object that we name `PreparedOperation`. + +An example of `PreparedOperation` object for a `ballot` operation looks something like this: +```typescript +{ + opOb: { + branch: 'test_block_hash', + contents: [ + { + kind: 'ballot', + ballot: 'yay', + period: 103, + proposal: 'PtKathmankSpLLDALzWw7CGD2j2MtyveTwboEYokqUCP4a1LxMg', + }, + ], + protocol: 'test_protocol', + }, + counter: 0, +} +``` + +The `PreparedOperation` object used to be abstracted from the user and would require a lot of workarounds to expose. We realize some users might want more control and information on what happens before operations are forged and signed. This offers a few benefits, a few of them being: +- The ability to retrieve information about the operation before injecting (operation hash, etc) +- The ability to simulate an operation before injecting + +The `PrepareProvider` class affords extension and control to users when preparing operations while also promoting modularity in Taquito as a design principle. + +## Usage example + +### Individual Operations +The `PrepareProvider` will be accessible via the `TezosToolkit`: +```typescript +// const Tezos = new TezosToolkit('RPC_ENDPOINT'); + +const prepared = await Tezos.prepare.transaction({ + to: 'tz1QZ6KY7d3BuZDT1d19dUxoQrtFPN2QJ3hn', + amount: 5 +}); +``` + +Let's break that transaction prepare call down. + +The interface of the `transaction` member method is as follows: +```typescript +transaction(params: TransferParams , source?: string): Promise; +``` + +- `params` is the Transaction operation parameters. In this case, the required properties are `to` and `amount`. +- `source` is the source public key hash if you do wish to override the source. This parameter is optional by design. If you do not wish to override it, the source will be grabbed from the `Context`. + +### Batch Operations +The `PrepareProvider` also provides support for batch operations: +```typescript +const prepared = await Tezos.prepare.batch([ + { + kind: OpKind.TRANSACTION, + to: 'tz1QZ6KY7d3BuZDT1d19dUxoQrtFPN2QJ3hn', + amount: 2, + }, + { + kind: OpKind.TRANSACTION, + to: 'tz1QZ6KY7d3BuZDT1d19dUxoQrtFPN2QJ3hn', + amount: 2, + }, +]); +``` +- the parameters are the required parameters for each respective operation with the added `kind` property that denotes the operation kind. Users can also utilize `OpKind` which is an enum that holds operation kind values. + +### Contract Calls +Users are also able to utilize the `PrepareProvider` to prepare contract calls: +```typescript +// contractAddress refers to an originated increment/decrement smart contract, +// omitted for brevity +const contractAbs = await Tezos.contract.at(contractAddress); +const method = await contractAbs.methods.increment(1); +const prepared = await Tezos.prepare.contractCall(method); +``` \ No newline at end of file diff --git a/website/versioned_docs/version-13.0.0/quick_start.md b/website/versioned_docs/version-15.1.0/quick_start.md similarity index 73% rename from website/versioned_docs/version-13.0.0/quick_start.md rename to website/versioned_docs/version-15.1.0/quick_start.md index 7ec9a49753..13f119c56f 100644 --- a/website/versioned_docs/version-13.0.0/quick_start.md +++ b/website/versioned_docs/version-15.1.0/quick_start.md @@ -55,7 +55,7 @@ Tezos.setProvider({ ```js live noInline // import { TezosToolkit } from '@taquito/taquito'; -// const Tezos = new TezosToolkit('https://ithacanet.ecadinfra.com'); +// const Tezos = new TezosToolkit('https://ghostnet.ecadinfra.com'); Tezos.tz .getBalance('tz1h3rQ8wBxFd8L9B3d7Jhaawu6Z568XU3xY') @@ -84,49 +84,7 @@ Tezos.setProvider({ }); ``` -#### Importing a Faucet Key - -"Faucet Keys" allows you to get Tezos tokens on the various Tezos "testnets." You can download a faucet key for the current and upcoming protocols at https://teztnets.xyz/. The key is a JSON file, which you can use with Taquito as follows: - -```js -import { TezosToolkit } from '@taquito/taquito'; -import { importKey } from '@taquito/signer'; - -const Tezos = new TezosToolkit('https://YOUR_PREFERRED_RPC_URL'); - -const FAUCET_KEY = { - mnemonic: [ - 'cart', - 'will', - 'page', - 'bench', - 'notice', - 'leisure', - 'penalty', - 'medal', - 'define', - 'odor', - 'ride', - 'devote', - 'cannon', - 'setup', - 'rescue', - ], - activation_code: '35f266fbf0fca752da1342fdfc745a9c608e7b20', - amount: '4219352756', - pkh: 'tz1YBMFg1nLAPxBE6djnCPbMRH5PLXQWt8Mg', - password: 'Fa26j580dQ', - email: 'jxmjvauo.guddusns@tezos.example.org', -}; - -importKey( - Tezos, - FAUCET_KEY.email, - FAUCET_KEY.password, - FAUCET_KEY.mnemonic.join(' '), - FAUCET_KEY.activation_code -).catch((e) => console.error(e)); -``` +The following link can be used to fund an address on the different testnets: https://teztnets.xyz/. ### Transfer @@ -151,7 +109,7 @@ Tezos.contract println(`Waiting for ${op.hash} to be confirmed...`); return op.confirmation(1).then(() => op.hash); }) - .then((hash) => println(`Operation injected: https://ithaca.tzstats.com/${hash}`)) + .then((hash) => println(`Operation injected: https://ghost.tzstats.com/${hash}`)) .catch((error) => println(`Error: ${error} ${JSON.stringify(error, null, 2)}`)); ``` @@ -170,7 +128,7 @@ Tezos.wallet println(`Waiting for ${op.opHash} to be confirmed...`); return op.confirmation(1).then(() => op.opHash); }) - .then((hash) => println(`Operation injected: https://ithaca.tzstats.com/${hash}`)) + .then((hash) => println(`Operation injected: https://ghost.tzstats.com/${hash}`)) .catch((error) => println(`Error: ${error} ${JSON.stringify(error, null, 2)}`)); ``` @@ -179,7 +137,7 @@ Tezos.wallet ### Interact with a smart contract -Calling smart contract operations requires a configured signer; in this example we will use a faucet key. The Ligo source code for the smart contract [KT1A3dyvS4pWd9b9yLLMBKLxc6S6G5b58BsK][smart_contract_on_better_call_dev] used in this example can be found in a [Ligo Web IDE][smart_contract_source]. +Calling smart contract operations requires a configured signer. The Ligo source code for the smart contract [KT1BJadpDyLCACMH7Tt9xtpx4dQZVKw9cDF7][smart_contract_on_better_call_dev] used in this example can be found in a [Ligo Web IDE][smart_contract_source]. { const i = 7; @@ -202,7 +160,7 @@ Tezos.contract println(`Waiting for ${op.hash} to be confirmed...`); return op.confirmation(1).then(() => op.hash); }) - .then((hash) => println(`Operation injected: https://ithaca.tzstats.com/${hash}`)) + .then((hash) => println(`Operation injected: https://ghost.tzstats.com/${hash}`)) .catch((error) => println(`Error: ${JSON.stringify(error, null, 2)}`)); ``` @@ -211,7 +169,7 @@ Tezos.contract ```js live noInline wallet Tezos.wallet - .at('KT1A3dyvS4pWd9b9yLLMBKLxc6S6G5b58BsK') + .at('KT1BJadpDyLCACMH7Tt9xtpx4dQZVKw9cDF7') .then((wallet) => { const i = 7; @@ -222,7 +180,7 @@ Tezos.wallet println(`Waiting for ${op.opHash} to be confirmed...`); return op.confirmation(1).then(() => op.opHash); }) - .then((hash) => println(`Operation injected: https://ithaca.tzstats.com/${hash}`)) + .then((hash) => println(`Operation injected: https://ghost.tzstats.com/${hash}`)) .catch((error) => println(`Error: ${JSON.stringify(error, null, 2)}`)); ``` @@ -232,4 +190,4 @@ Tezos.wallet [boilerplate]: https://github.com/ecadlabs/taquito-boilerplate [smart_contract_source]: https://ide.ligolang.org/p/2sVshnZ_Aat5pIuUypIBsQ -[smart_contract_on_better_call_dev]: https://better-call.dev/ithacanet/KT1A3dyvS4pWd9b9yLLMBKLxc6S6G5b58BsK/operations +[smart_contract_on_better_call_dev]: https://better-call.dev/ghostnet/KT1BJadpDyLCACMH7Tt9xtpx4dQZVKw9cDF7/operations diff --git a/website/versioned_docs/version-15.1.0/react-template.md b/website/versioned_docs/version-15.1.0/react-template.md new file mode 100644 index 0000000000..1dbc9c8c53 --- /dev/null +++ b/website/versioned_docs/version-15.1.0/react-template.md @@ -0,0 +1,11 @@ +--- +title: React dapp template +author: Maksym Bykovskyy +--- + +The React dapp template is a starter kit for developing front-end applications running on the Tezos network with the React framework. + +To get started with the React template, please refer to the [Getting Started][get-started] section in the README found in the [React template][repo] repository on Github. + +[get-started]: https://github.com/ecadlabs/taquito-react-template#getting-started +[repo]: https://github.com/ecadlabs/taquito-react-template \ No newline at end of file diff --git a/website/versioned_docs/version-13.0.0/rpc-cache.md b/website/versioned_docs/version-15.1.0/rpc-cache.md similarity index 100% rename from website/versioned_docs/version-13.0.0/rpc-cache.md rename to website/versioned_docs/version-15.1.0/rpc-cache.md diff --git a/website/versioned_docs/version-15.1.0/rpc_nodes.md b/website/versioned_docs/version-15.1.0/rpc_nodes.md new file mode 100644 index 0000000000..76df01adba --- /dev/null +++ b/website/versioned_docs/version-15.1.0/rpc_nodes.md @@ -0,0 +1,63 @@ +--- +title: RPC nodes +author: Roxane Letourneau +--- +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +## What to consider when choosing a node + +- **Trust**: Choose a node that you can trust the people who operate it. + - It should not alter your requests, for example, changing the operation data before forging it. + - It should not censor your operations; you want to know that your operations will reach the network. +- **Reliability**: Consider your requirements for uptime, and choose your node option accordingly. If node availability is critical for your user-case, consider self-hosting a node or contracting someone to operate a node specifically for you. +- ** End-points support**: Public nodes have different policies on the end-points that they expose. Your use case may require specific end-points to be available to your app. We have made a suite of [integration tests](rpc_nodes_integration_test.md) for the Taquito RPC package. These tests show what RPC end-points are available on a given node. These tests are available here: integration-tests/rpc-nodes.spec.ts. + + + + +| Provider | Net | URL | Header | +|------------------|--------------|------------------------------------------|---------------------------------------------------------------------------------| +| ECAD Labs | Mainnet | https://mainnet.api.tez.ie | [Check](https://mainnet.api.tez.ie/chains/main/blocks/head/header) | +| ECAD Labs | Kathmandunet | https://kathmandunet.ecadinfra.com | [Check](https://kathmandunet.ecadinfra.com/chains/main/blocks/head/header) | +| ECAD Labs | Limanet | https://limanet.ecadinfra.com | [Check](https://limanet.ecadinfra.com/chains/main/blocks/head/header) | +| ECAD Labs | Ghostnet | https://ghostnet.ecadinfra.com | [Check](https://ghostnet.ecadinfra.com/chains/main/blocks/head/header) | +| SmartPy | Mainnet | https://mainnet.smartpy.io | [Check](https://mainnet.smartpy.io/chains/main/blocks/head/header) | +| SmartPy | Kathmandunet | https://kathmandunet.smartpy.io/ | [Check](https://kathmandunet.smartpy.io/chains/main/blocks/head/header) | +| Tezos Foundation | Mainnet | https://rpc.tzbeta.net/ | [Check](https://rpc.tzbeta.net/chains/main/blocks/head/header) | +| Tezos Foundation | Limanet | https://rpczero.tzbeta.net/ | [Check](https://rpczero.tzbeta.net/chains/main/blocks/head/header) | +| Marigold | Mainnet | https://mainnet.tezos.marigold.dev/ | [Check](https://mainnet.tezos.marigold.dev/chains/main/blocks/head/header) | +| Marigold | Kathmandunet | https://kathmandunet.tezos.marigold.dev/ | [Check](https://kathmandunet.tezos.marigold.dev/chains/main/blocks/head/header) | +| Marigold | Ghostnet | https://ghostnet.tezos.marigold.dev/ | [Check](https://ghostnet.tezos.marigold.dev/chains/main/blocks/head/header) | +| TezTools | Mainnet | https://eu01-node.teztools.net/ | [Check](https://eu01-node.teztools.net/chains/main/blocks/head/header) | + +*If you are aware of a public node missing from our list or our information is inaccurate, please help us by submitting an issue or pull request on our GitHub page.* + + + +| Provider | Details | +|------------------|------------------------------------------------------------------------| +| MIDL.dev | https://midl.dev/tezos-rpc/ | +| Cryptonomic | https://github.com/keefertaylor/TezosKit/blob/master/docs/TezosNode.md | +| TezTools.io | https://t.me/teztools (Telegram) | + +*If you are aware of a private node missing from our list or our information is inaccurate, please help us by submitting an issue or pull request on our GitHub page.* + + + + +## How to run a node + +Running a node is a good way of contributing to Tezos by increasing the decentralization of the network. + +There are many ways to set up a node. Here are some links providing general instructions: + +- [Use docker images](https://tezos.gitlab.io/introduction/howtoget.html#docker-images) +- [Build from sources](https://tezos.gitlab.io/introduction/howtoget.html#docker-images) +- [Use Ansible Role](https://github.com/ecadlabs/ansible-role-tezos-node/blob/master/README.md) + diff --git a/website/versioned_docs/version-13.0.0/rpc_nodes_integration_test.md b/website/versioned_docs/version-15.1.0/rpc_nodes_integration_test.md similarity index 93% rename from website/versioned_docs/version-13.0.0/rpc_nodes_integration_test.md rename to website/versioned_docs/version-15.1.0/rpc_nodes_integration_test.md index 862f1ebbf1..35456d8b96 100644 --- a/website/versioned_docs/version-13.0.0/rpc_nodes_integration_test.md +++ b/website/versioned_docs/version-15.1.0/rpc_nodes_integration_test.md @@ -7,10 +7,8 @@ author: Roxane Letourneau 1. The RPC nodes' integration tests are disabled by default. Remove `./rpc-nodes.spec.ts` from `"testPathIgnorePatterns"` in the package.json. -2. In the integration test folder, run one of the following commands: - - **Hanghzounet**: `npm run test:hangzhounet rpc-nodes.spec.ts` - - **Ithacanet**: `npm run test:ithacanet rpc-nodes.spec.ts` - - **Both protocols**: `npm run test rpc-nodes.spec.ts` + + **limanet**: `npm run test:limanet rpc-nodes.spec.ts` **When all endpoints are accessible for a node, you will obtain:** diff --git a/website/versioned_docs/version-13.0.0/rpc_package.md b/website/versioned_docs/version-15.1.0/rpc_package.md similarity index 97% rename from website/versioned_docs/version-13.0.0/rpc_package.md rename to website/versioned_docs/version-15.1.0/rpc_package.md index 14a134719a..e36a1d32bb 100644 --- a/website/versioned_docs/version-13.0.0/rpc_package.md +++ b/website/versioned_docs/version-15.1.0/rpc_package.md @@ -18,7 +18,7 @@ Methods in the RPC package map one-to-one to the corresponding Tezos RPC API end import { RpcClient } from '@taquito/rpc'; -const client = new RpcClient(' https://ithacanet.ecadinfra.com/', 'NetXjD3HPJJjmcd'); +const client = new RpcClient(' https://jakartanet.ecadinfra.com/', 'NetXLH1uAxK7CCh'); ``` The `RpcClient` constructor takes the URL of the node you want to use and the chain ID. diff --git a/website/versioned_docs/version-15.1.0/sapling.md b/website/versioned_docs/version-15.1.0/sapling.md new file mode 100644 index 0000000000..635a543414 --- /dev/null +++ b/website/versioned_docs/version-15.1.0/sapling.md @@ -0,0 +1,360 @@ +--- +title: Sapling Toolkit +author: Roxane Letourneau +--- + +Sapling is a protocol allowing private transactions in a decentralized environment. +Sapling was introduced in Tezos in the Edo protocol. Refer to the Tezos documentation for more information on Sapling: https://tezos.gitlab.io/active/sapling.html + +## Keys + +**Spending key** + +The spending key is used to spend tokens. It must be handled securely to prevent funds from being lost or stolen. + +Taquito offers support for encrypted/unencrypted spending keys and mnemonics. Refer to the following link for more information: [InMemorySpendingKey](./sapling_in_memory_spending_key.md) + +**Proving key** + +The proving key can be used to generate proof without allowing tokens to be spent. Zero-knowledge proofs can be created with either the spending or the proving key. In cases where the device holding the spending key is computationally or memory-limited, such as a hardware wallet, proofs can be produced on a separate device using the proving key. + +**Viewing key** + +The viewing key is derived from the spending key. This key can be used to view all incoming and outgoing transactions. It must be handled securely to prevent a loss of privacy, as anyone accessing it can see the transaction history and the balance. + +Refer to the following link for more information: [InMemoryViewingKey](./sapling_in_memory_viewing_key.md) + +**Sapling address** + +Sapling addresses are used to receive tokens. They are derived from the viewing key. + +Here is an example on how to retrieve addresses: [InMemoryViewingKey](./sapling_in_memory_viewing_key.md#how-to-retrieve-payment-addresses-from-the-viewing-key) + + +# Sapling toolkit + +The `@taquito/sapling` package provides a `SaplingToolkit` class that surfaces all of the Sapling capabilities, allowing it to read from a Sapling state and prepare transactions. + +The constructor of the `SaplingToolkit` takes the following properties: +- the first parameter is an object containing: + - a `saplingSigner` property, an instance of `InMemorySpendingKey` as the spending key is needed to prepare and sign transactions that spend tokens. + - an optional `saplingProver` property which can be an instance of `InMemoryProvingKey` if you want to generate the proofs from a proving key rather than the spending key. +- the second parameter is an object containing: + - the address of the Sapling contract (string) + - the size of the memo of the corresponding Sapling contract (number) + - an optional Sapling id that must be specified if the contract contains more than one Sapling state. +- an instance of a class implementing the `TzReadProvider` interface, which allows getting data from the blockchain +- it is possible to specify a different packer than the `MichelCodecPacker`, which is used by default + +Here is an example of how to instantiate a `SaplingToolkit`: + +```ts +import { TezosToolkit, RpcReadAdapter } from '@taquito/taquito'; +import { SaplingToolkit } from '@taquito/sapling'; +import { RpcClient } from '@taquito/rpc'; + +const tezos = new TezosToolkit('https://ghostnet.ecadinfra.com/'); +const readProvider = new RpcReadAdapter(new RpcClient('https://YOUR_PREFERRED_RPC_URL')); +const saplingContract = await tezos.contract.at('KT1UYwMR6Q6LZnwQEi77DSBrAjKT1tEJb245'); + +const inMemorySpendingKey = await InMemorySpendingKey.fromMnemonic('YOUR_MNEMONIC'); + +const saplingToolkit = new SaplingToolkit( + { saplingSigner: inMemorySpendingKey }, + { contractAddress: saplingContract.address, memoSize: 8 }, + readProvider +) +``` + +## How to retrieve my balance in the Sapling shielded pool? + +When calling the `getSaplingTransactionViewer` method of the `SaplingToolkit` class, an instance of the `SaplingTransactionViewer` class is returned. The `SaplingTransactionViewer` class allows retrieving and decrypting Sapling transactions for the specified viewing key and calculating the unspent balance. + +For each entry in the shielded pool, the `SaplingTransactionViewer` class will try to decrypt them using the viewing key as if it were the receiver. If a ciphertext is successfully decrypted, the configured account was the receiver of the output. The `SaplingTransactionViewer` will find which inputs were not spent by computing their nullifier. If an input is spent, its nullifier will be in the Sapling state. If the nullifier is not present, the input has not been spent, and its value will be considered in the calculated balance. + +Note that the balance is represented in mutez. + +The balance can be retrieved as follows: + +```js live noInline +import { RpcReadAdapter } from '@taquito/taquito'; +import { SaplingToolkit, InMemorySpendingKey } from '@taquito/sapling'; +import { RpcClient } from '@taquito/rpc'; + +// Alice spending key +const aliceSk = 'sask27SLmU9herddHz4qFJBLMjWYMbJF8RtS579w9ej9mfCYK7VUdyCJPHK8AzW9zMsopGZEkYeNjAY7Zz1bkM7CGu8eKLzrjBLTMC5wWJDhxiK91ahA29rhDRsHdJDV2u2jFwb2MNUix8JW7sAkAqYVaJpCehTBPgRQ1KqKwqqUaNmuD8kazd4Q8MCWmgbWs21Yuomdqyi9FLigjRp7oY4m5adaVU19Nj1AHvsMY2tePeU2L'; + +const inMemorySpendingKey = new InMemorySpendingKey(aliceSk); + +const readProvider = new RpcReadAdapter(new RpcClient('https://ghostnet.ecadinfra.com/')); + +const saplingToolkit = new SaplingToolkit( + { saplingSigner: inMemorySpendingKey }, + { contractAddress: 'KT1JMDxmQ4DAbzXpzAJmL6QeZ9HB7DTVnZYd', memoSize: 8 }, + readProvider +); + +saplingToolkit.getSaplingTransactionViewer() + .then((txViewer) => { + println(`Fetching Alice balance in the shielded pool...`); + return txViewer.getBalance(); + }) + .then((balance) => println(`Alice's balance is ${balance.toString()} mutez`)) + .catch((error) => println(`Error: ${JSON.stringify(error, null, 2)}`)); +``` + +## How to retrieve my transaction history? + +The `SaplingTransactionViewer` class exposes a method called `getIncomingAndOutgoingTransactions` which allows decrypting the transactions received and sent based on the viewing key. Information like the value in mutez, the memo or the payment address can be retrieved as well as if the input is spent for the incoming ones. + +Example: + +```js live noInline +import { RpcReadAdapter } from '@taquito/taquito'; +import { SaplingToolkit, InMemorySpendingKey } from '@taquito/sapling'; +import { RpcClient } from '@taquito/rpc'; + +// Alice spending key +const aliceSk = 'sask27SLmU9herddHz4qFJBLMjWYMbJF8RtS579w9ej9mfCYK7VUdyCJPHK8AzW9zMsopGZEkYeNjAY7Zz1bkM7CGu8eKLzrjBLTMC5wWJDhxiK91ahA29rhDRsHdJDV2u2jFwb2MNUix8JW7sAkAqYVaJpCehTBPgRQ1KqKwqqUaNmuD8kazd4Q8MCWmgbWs21Yuomdqyi9FLigjRp7oY4m5adaVU19Nj1AHvsMY2tePeU2L'; + +const inMemorySpendingKey = new InMemorySpendingKey(aliceSk); + +const readProvider = new RpcReadAdapter(new RpcClient('https://ghostnet.ecadinfra.com/')); + +const saplingToolkit = new SaplingToolkit( + { saplingSigner: inMemorySpendingKey }, + { contractAddress: 'KT1JMDxmQ4DAbzXpzAJmL6QeZ9HB7DTVnZYd', memoSize: 8 }, + readProvider +); + +saplingToolkit.getSaplingTransactionViewer() + .then((txViewer) => { + println(`Fetching Alice's history of transactions in the shielded pool...`); + return txViewer.getIncomingAndOutgoingTransactions(); + }) + .then((history) => println(`Alice's transaction history is ${JSON.stringify(history, null, 2)}`)) + .catch((error) => println(`Error: ${JSON.stringify(error, null, 2)}`)); +``` + +## How to prepare a shielded transaction? + +A shielded transaction allows sending tokens from a Tezos account (tz1, tz2, tz3) to a Sapling address (zet). The `prepareShieldedTransaction` method of the `SaplingToolkit` takes an array of `ParametersSaplingTransaction`, making it possible to send tez to multiple addresses at once if needed. + +The `ParametersSaplingTransaction` is an object made of: +- a `to` property, which is the destination address (zet) +- an `amount` property, which is the amount to shield in tez by default +- an optional `memo` that cannot be longer than the specified memo size +- an optional `mutez` property that must be set to true if the specified amount is in mutez rather than tez + +The `prepareShieldedTransaction` method returns the crafted Sapling transaction parameter but does not perform any change on the shielded pool. A subsequent step where the Sapling transaction parameter is submitted to the smart contract must be done. Note that in a case of a shielded transaction, the shielded amount must be sent along when calling the smart contract to transfer the tez to the shielded pool, or it will result in an error. + +Here is an example of how to prepare and inject a shielded transaction using Taquito: + +```js live noInline +// import { TezosToolkit, RpcReadAdapter } from '@taquito/taquito'; +// import { SaplingToolkit, InMemorySpendingKey } from '@taquito/sapling'; +// import { RpcClient } from '@taquito/rpc'; + +const saplingContractAddress = 'KT1JMDxmQ4DAbzXpzAJmL6QeZ9HB7DTVnZYd' +const rpcUrl = 'https://ghostnet.ecadinfra.com/'; +const readProvider = new RpcReadAdapter(new RpcClient(rpcUrl)); +// const Tezos = new TezosToolkit(rpcUrl); +// Note: you need to set up your signer on the TezosToolkit as usual + +// Alice spending key +const aliceSk = 'sask27SLmU9herddHz4qFJBLMjWYMbJF8RtS579w9ej9mfCYK7VUdyCJPHK8AzW9zMsopGZEkYeNjAY7Zz1bkM7CGu8eKLzrjBLTMC5wWJDhxiK91ahA29rhDRsHdJDV2u2jFwb2MNUix8JW7sAkAqYVaJpCehTBPgRQ1KqKwqqUaNmuD8kazd4Q8MCWmgbWs21Yuomdqyi9FLigjRp7oY4m5adaVU19Nj1AHvsMY2tePeU2L'; + +const inMemorySpendingKey = new InMemorySpendingKey(aliceSk); + +const saplingToolkit = new SaplingToolkit( + { saplingSigner: inMemorySpendingKey }, + { contractAddress: saplingContractAddress, memoSize: 8 }, + readProvider +); + +inMemorySpendingKey.getSaplingViewingKeyProvider() + .then((inMemoryViewingKey) => { + println(`Fetching a payment address for Alice (zet)...`); + return inMemoryViewingKey.getAddress(); + }) + .then((paymentAddress) => { + println(`Alice's payment address is: ${paymentAddress.address}`); + println(`Preparing the shielded transaction...`); + return saplingToolkit.prepareShieldedTransaction([{ + to: paymentAddress.address, + amount: 3, + memo: 'test', + mutez: false // set to false by default + }]); + }) + .then((shieldedTx) => { + println(`The sapling transaction parameter is: ${shieldedTx}`); + Tezos.contract.at(saplingContractAddress) + .then((saplingContract) => { + println(`Injecting the Sapling transaction using the ContractAbstraction...`); + // The amount MUST be specified in the send method to transfer the 3 tez to the shielded pool + return saplingContract.methods.default([shieldedTx]).send({ amount: 3 }); + }) + .then((op) => { + println(`Waiting for ${op.hash} to be confirmed...`); + return op.confirmation(1).then(() => op.hash); + }) + .then((hash) => println(`Operation injected: https://ghost.tzstats.com/${hash}`)) + }) + .catch((error) => println(`Error: ${(error)}`)); +``` + +## How to prepare a Sapling transaction? + +A Sapling transaction allows sending tokens from an address (zet) to an address (zet). The `prepareSaplingTransaction` method of the `SaplingToolkit` takes an array of `ParametersSaplingTransaction`, making it possible to send tez to multiple addresses at once if needed. + +The `ParametersSaplingTransaction` is an object made of: +- a `to` property, which is the destination address (zet) +- an `amount` property, which is the amount to shield in tez by default +- an optional `memo` that cannot be longer than the specified memo size +- an optional `mutez` property that must be set to true if the specified amount is in mutez rather than tez + +The `prepareSaplingTransaction` method returns the crafted Sapling transaction parameter but does not perform any change on the shielded pool. A subsequent step where the Sapling transaction parameter is submitted to the smart contract must be done. + +:::note +A user should not use their own implicit account (tz1, tz2, tz3) to submit a Sapling transaction but rather have a third party inject it. +::: + +Here is an example of how to prepare and inject a Sapling transaction using Taquito: + +```js live noInline +// import { TezosToolkit, RpcReadAdapter } from '@taquito/taquito'; +// import { SaplingToolkit, InMemorySpendingKey } from '@taquito/sapling'; +// import { RpcClient } from '@taquito/rpc'; + +const saplingContractAddress = 'KT1JMDxmQ4DAbzXpzAJmL6QeZ9HB7DTVnZYd' +const rpcUrl = 'https://ghostnet.ecadinfra.com/'; +const readProvider = new RpcReadAdapter(new RpcClient(rpcUrl)); +// const Tezos = new TezosToolkit(rpcUrl); +// Note: you need to set up your signer on the TezosToolkit as usual + +// Alice spending key +const aliceSk = 'sask27SLmU9herddHz4qFJBLMjWYMbJF8RtS579w9ej9mfCYK7VUdyCJPHK8AzW9zMsopGZEkYeNjAY7Zz1bkM7CGu8eKLzrjBLTMC5wWJDhxiK91ahA29rhDRsHdJDV2u2jFwb2MNUix8JW7sAkAqYVaJpCehTBPgRQ1KqKwqqUaNmuD8kazd4Q8MCWmgbWs21Yuomdqyi9FLigjRp7oY4m5adaVU19Nj1AHvsMY2tePeU2L'; + +const inMemorySpendingKey = new InMemorySpendingKey(aliceSk); + +const saplingToolkit = new SaplingToolkit( + { saplingSigner: inMemorySpendingKey }, + { contractAddress: saplingContractAddress, memoSize: 8 }, + readProvider +); + +println(`Preparing the sapling transaction...`); +saplingToolkit.prepareSaplingTransaction([{ + to: 'zet14CMN2T4x1f8sgXeAGWQwczSf6SJ8bm8nyP2Tg7HJn2VmtPtB2nE2q7MMgdmMEwpGQ', + amount: 3, + memo: 'test', + mutez: false // set to false by default +}]) +.then((saplingTx) => { + println(`The sapling transaction parameter is: ${saplingTx}`); + Tezos.contract.at(saplingContractAddress) + .then((saplingContract) => { + println(`Injecting the Sapling transaction using the ContractAbstraction...`); + return saplingContract.methods.default([saplingTx]).send(); + }) + .then((op) => { + println(`Waiting for ${op.hash} to be confirmed...`); + return op.confirmation(1).then(() => op.hash); + }) + .then((hash) => println(`Operation injected: https://ghost.tzstats.com/${hash}`)) +}) +.catch((error) => println(`Error: ${(error)}`)); +``` + +## How to prepare an unshielded transaction? + +An unshielded transaction allows sending tokens from an address (zet) to a Tezos address (tz1, tz2, tz3). The `prepareUnshieldedTransaction` method of the `SaplingToolkit` takes a single `ParametersUnshieldedTransaction`. + +The `ParametersUnshieldedTransaction` is an object made of: +- a `to` property, which is the destination account (tz1, tz2, tz3) +- an `amount` property, which is the amount to shield in tez by default +- an optional `mutez` property that must be set to true if the specified amount is in mutez rather than tez + +The `prepareUnshieldedTransaction` method returns the crafted Sapling transaction parameter but does not perform any change on the shielded pool. A subsequent step where the Sapling transaction parameter is submitted to the smart contract must be done to retrieve the tokens from the pool. + +Here is an example of how to prepare and inject an unshielded transaction using Taquito: + +```js live noInline +// import { TezosToolkit, RpcReadAdapter } from '@taquito/taquito'; +// import { SaplingToolkit, InMemorySpendingKey } from '@taquito/sapling'; +// import { RpcClient } from '@taquito/rpc'; + +const saplingContractAddress = 'KT1JMDxmQ4DAbzXpzAJmL6QeZ9HB7DTVnZYd' +const rpcUrl = 'https://ghostnet.ecadinfra.com/'; +const readProvider = new RpcReadAdapter(new RpcClient(rpcUrl)); +// const Tezos = new TezosToolkit(rpcUrl); +// Note: you need to set up your signer on the TezosToolkit as usual + +// Alice spending key +const aliceSk = 'sask27SLmU9herddHz4qFJBLMjWYMbJF8RtS579w9ej9mfCYK7VUdyCJPHK8AzW9zMsopGZEkYeNjAY7Zz1bkM7CGu8eKLzrjBLTMC5wWJDhxiK91ahA29rhDRsHdJDV2u2jFwb2MNUix8JW7sAkAqYVaJpCehTBPgRQ1KqKwqqUaNmuD8kazd4Q8MCWmgbWs21Yuomdqyi9FLigjRp7oY4m5adaVU19Nj1AHvsMY2tePeU2L'; + +const inMemorySpendingKey = new InMemorySpendingKey(aliceSk); + +const saplingToolkit = new SaplingToolkit( + { saplingSigner: inMemorySpendingKey }, + { contractAddress: saplingContractAddress, memoSize: 8 }, + readProvider +); + +println(`Preparing the unshielded transaction...`); +saplingToolkit.prepareUnshieldedTransaction({ + to: 'tz1hDFKpVkT7jzYncaLma4vxh4Gg6JNqvdtB', + amount: 20, + mutez: true // set to false by default +}) +.then((unshieldedTx) => { + println(`The sapling transaction parameter is: ${unshieldedTx}`); + Tezos.contract.at(saplingContractAddress) + .then((saplingContract) => { + println(`Injecting the Sapling transaction using the ContractAbstraction...`); + return saplingContract.methods.default([unshieldedTx]).send(); + }) + .then((op) => { + println(`Waiting for ${op.hash} to be confirmed...`); + return op.confirmation(1).then(() => op.hash); + }) + .then((hash) => println(`Operation injected: https://ghost.tzstats.com/${hash}`)) +}) +.catch((error) => println(`Error: ${(error)}`)); +``` + +# SaplingTransactionViewer + +We don't require the spending key to retrieve the balance and transaction history. It can be done using the viewing key and the SaplingTransactionViewer class. + +The constructor of the `SaplingTransactionViewer` takes the following properties: +- an instance of `InMemoryViewingKey` +- the second parameter is an object containing: + - the address of the Sapling contract or a Sapling id if the contract contains more than one Sapling state. +- an instance of a class implementing the `TzReadProvider` interface, which allows getting data from the blockchain + +Here is an example of how to instantiate a `SaplingTransactionViewer`: + +```ts +import { TezosToolkit, RpcReadAdapter } from '@taquito/taquito'; +import { InMemoryViewingKey } from '@taquito/sapling'; +import { RpcClient } from '@taquito/rpc'; + +const readProvider = new RpcReadAdapter(new RpcClient('https://YOUR_PREFERRED_RPC_URL')); +const tezos = new TezosToolkit('https://ghostnet.ecadinfra.com/'); + +const saplingContract = await tezos.contract.at('KT1JMDxmQ4DAbzXpzAJmL6QeZ9HB7DTVnZYd'); + +const inMemoryViewingKey = new InMemoryViewingKey( + '000000000000000000977d725fc96387e8ec1e603e7ae60c6e63529fb84e36e126770e9db9899d7f2344259fd700dc80120d3c9ca65d698f6064043b048b079caa4f198aed96271740b1d6fd523d71b15cd0b3d75644afbe9abfedb6883e299165665ab692c14ca5c835c61a0e53de553a751c78fbc42d5e7eca807fd441206651c84bf88de803efba837583145a5f338b1a7af8a5f9bec4783054f9d063d365f2352f72cbced95e0a' +); + +const saplingTransactionViewer = new SaplingTransactionViewer( + inMemoryViewingKey, + { contractAddress: saplingContract.address }, + readProvider +) +``` + +Refer to these sections to [retrieve the balance](sapling#how-to-retrieve-my-balance-in-the-sapling-shielded-pool) and [view the transaction history](sapling#how-to-retrieve-my-transaction-history). \ No newline at end of file diff --git a/website/versioned_docs/version-15.1.0/sapling_in_memory_spending_key.md b/website/versioned_docs/version-15.1.0/sapling_in_memory_spending_key.md new file mode 100644 index 0000000000..4548f06634 --- /dev/null +++ b/website/versioned_docs/version-15.1.0/sapling_in_memory_spending_key.md @@ -0,0 +1,48 @@ +--- +title: InMemorySpendingKey +author: Zainen Suzuki +--- + +# Sapling Spending Key Instantiation + +:::caution Warning +**Storing private keys in memory is suitable for development workflows but risky for +production use-cases! Use the `InMemorySpendingKey` appropriately given your risk profile** +::: + +### From Mnemonic + +Instantiation of a `InMemorySpendingkey` from Mnemonic does not require a password as it is only used to change an unencrypted `sask...` to an encrypted `MMXj...` spending key or vice versa + +Params: + - `mnemonic` list of words + - `derivationPath` tezos current standard 'm/' + +Returns: + - InMemorySpendingKey class instantiated + + + +```js + const SaplingKeyProvider = await InMemorySpendingKey.fromMnemonic( + 'leopard crouch simple blind castle they elder enact slow rate mad blanket saddle tail silk fury quarter obscure interest exact veteran volcano fabric cherry', + 'm/' + ) // derivationPath by current standard is 'm/' + +``` + +### From Encrypted Spending Key + +If the spending key is encrypted prefixed with `MMXj...` then a password is required to decrypt to a unencrypted Spending Key `sask...` + +Params: + - `spendingKey` unencrypted sask... or encrypted MMXj... + - `password` required for MMXj encrypted keys + +```js + const SaplingKeyProvider = new InMemorySpendingKey( + 'MMXjN99mhomTm1Y5nQt8NfwEKTHWugsLtucX7oWrpsJd99qxGYJWP5aMb3t8zZaoKHQ898bLu9dwpog71bnjiDZfS9J9hWnTLCGm4fAjKKYeRuwTgCRjSdsP9znCPBUpCvyxeEFvUfamA5URrp8c7AaooAkobLW1PjNh2vjHobtiyNVTEtyTUWTLcjdxaiPbQWs3NaWvcb5Qr6z9MHhKrYNBHmsd9HBeRB2rVnvvL7pMc8f8zqyuXtmAuzMhiqPz3B4BRzuc8a2jkkoL14', + 'test' + ) + +``` diff --git a/website/versioned_docs/version-15.1.0/sapling_in_memory_viewing_key.md b/website/versioned_docs/version-15.1.0/sapling_in_memory_viewing_key.md new file mode 100644 index 0000000000..b8b893f596 --- /dev/null +++ b/website/versioned_docs/version-15.1.0/sapling_in_memory_viewing_key.md @@ -0,0 +1,62 @@ +--- +title: InMemoryViewingKey +author: Roxane Letourneau +--- + +The `InMemoryViewingKey` class can be instantiated from a viewing or spending key. + +### Instantiation from a viewing key: + +```js +import { InMemoryViewingKey } from '@taquito/sapling'; +const inMemoryViewingKey = new InMemoryViewingKey( + '000000000000000000977d725fc96387e8ec1e603e7ae60c6e63529fb84e36e126770e9db9899d7f2344259fd700dc80120d3c9ca65d698f6064043b048b079caa4f198aed96271740b1d6fd523d71b15cd0b3d75644afbe9abfedb6883e299165665ab692c14ca5c835c61a0e53de553a751c78fbc42d5e7eca807fd441206651c84bf88de803efba837583145a5f338b1a7af8a5f9bec4783054f9d063d365f2352f72cbced95e0a' +); +``` + +### Instantiation from an unencrypted spending key: + +```js live noInline +import { InMemoryViewingKey } from '@taquito/sapling'; + +InMemoryViewingKey.fromSpendingKey( + 'sask27SLmU9herddHz4qFJBLMjWYMbJF8RtS579w9ej9mfCYK7VUdyCJPHK8AzW9zMsopGZEkYeNjAY7Zz1bkM7CGu8eKLzrjBLTMC5wWJDhxiK91ahA29rhDRsHdJDV2u2jFwb2MNUix8JW7sAkAqYVaJpCehTBPgRQ1KqKwqqUaNmuD8kazd4Q8MCWmgbWs21Yuomdqyi9FLigjRp7oY4m5adaVU19Nj1AHvsMY2tePeU2L', +).then((inMemoryViewingKey) => { + const viewingKey = inMemoryViewingKey.getFullViewingKey() + println(`The viewing key is ${viewingKey.toString('hex')}`); +}) +.catch((error) => println(`Error: ${JSON.stringify(error, null, 2)}`)); + +``` + +### Instantiation from an encrypted spending key: + +```js live noInline +import { InMemoryViewingKey } from '@taquito/sapling'; + +InMemoryViewingKey.fromSpendingKey( + 'MMXjN99mhomTm1Y5nQt8NfwEKTHWugsLtucX7oWrpsJd99qxGYJWP5aMb3t8zZaoKHQ898bLu9dwpog71bnjiDZfS9J9hWnTLCGm4fAjKKYeRuwTgCRjSdsP9znCPBUpCvyxeEFvUfamA5URrp8c7AaooAkobLW1PjNh2vjHobtiyNVTEtyTUWTLcjdxaiPbQWs3NaWvcb5Qr6z9MHhKrYNBHmsd9HBeRB2rVnvvL7pMc8f8zqyuXtmAuzMhiqPz3B4BRzuc8a2jkkoL14', + 'test' // password +).then((inMemoryViewingKey) => { + const viewingKey = inMemoryViewingKey.getFullViewingKey() + println(`The viewing key is ${viewingKey.toString('hex')}`); +}) +.catch((error) => println(`Error: ${JSON.stringify(error, null, 2)}`)); + +``` + +## How to retrieve payment addresses from the viewing key + +The `InMemoryViewingKey` class has a method named `getAddress`, allowing to derive addresses (zet) from the viewing key. An index can be specified as a parameter, or the default value `0` will be used. + +```js live noInline +import { InMemoryViewingKey } from '@taquito/sapling'; + +const inMemoryViewingKey = new InMemoryViewingKey( + '000000000000000000977d725fc96387e8ec1e603e7ae60c6e63529fb84e36e126770e9db9899d7f2344259fd700dc80120d3c9ca65d698f6064043b048b079caa4f198aed96271740b1d6fd523d71b15cd0b3d75644afbe9abfedb6883e299165665ab692c14ca5c835c61a0e53de553a751c78fbc42d5e7eca807fd441206651c84bf88de803efba837583145a5f338b1a7af8a5f9bec4783054f9d063d365f2352f72cbced95e0a' +); + +inMemoryViewingKey.getAddress() +.then((address) => println(`The address is ${JSON.stringify(address, null, 2)}`)) +.catch((error) => println(`Error: ${JSON.stringify(error, null, 2)}`)); +``` \ No newline at end of file diff --git a/website/versioned_docs/version-13.0.0/set_delegate.md b/website/versioned_docs/version-15.1.0/set_delegate.md similarity index 100% rename from website/versioned_docs/version-13.0.0/set_delegate.md rename to website/versioned_docs/version-15.1.0/set_delegate.md diff --git a/website/versioned_docs/version-13.0.0/signing.md b/website/versioned_docs/version-15.1.0/signing.md similarity index 86% rename from website/versioned_docs/version-13.0.0/signing.md rename to website/versioned_docs/version-15.1.0/signing.md index 0354e96686..b80e2a2c61 100644 --- a/website/versioned_docs/version-13.0.0/signing.md +++ b/website/versioned_docs/version-15.1.0/signing.md @@ -54,14 +54,18 @@ After formatting the string properly, you can convert it into bytes, for example import { char2Bytes } from '@taquito/utils'; const bytes = char2Bytes(formattedInput); -const payloadBytes = '05' + '0100' + char2Bytes(bytes.length) + bytes; +const bytesLength = (bytes.length / 2).toString(16); +const addPadding = `00000000${bytesLength}`; +const paddedBytesLength = addPadding.slice(addPadding.length - 8); +const payloadBytes = '05' + '01' + paddedBytesLength + bytes; ``` -The bytes representation of the string must be prefixed with 3 pieces of information: +The hexadecimal/Micheline representation of the string must contain 4 pieces of information: - "05" indicates that this is a Micheline expression -- "01" indicates that a string was converted to bytes -- the number of characters in the byte string encoded on 4 bytes +- "01" indicates that the data is a Micheline string +- the number of characters in the bytes (hexadecimal string divided by 2) encoded on 4 bytes +- bytes of formatted input to be signed Once you have your bytes, you can send them to the wallet to have them signed: @@ -120,6 +124,20 @@ const signedPayload = await wallet.client.requestSignPayload(payload); const { signature } = signedPayload; ``` +## Verifying a signature + +To verify that the previously generated signature has actually been signed by a wallet, you can use the `veryfySignature` method from the Taquito utils. Here is an example where we check if the payload has been signed by the client wallet, using their public key: + +```js +import { verifySignature } from '@taquito/utils'; + +const isVerified = verifySignature( + payloadBytes, + (await wallet.client.getActiveAccount()).publicKey, + signature +); +``` + ## Signing Michelson data Taquito also offers the possibility to sign Michelson code. This feature can be useful, for example, if you need to send a lambda to a contract to be executed but want to restrict the number of users who can submit a lambda by verifiying the signer's address. The signing of Michelson code requires the use of the `michel-codec` package: @@ -144,9 +162,10 @@ const packed = packDataBytes( dataJSON, // as MichelsonData typeJSON // as MichelsonType ); -Tezos.signer.sign(packed.bytes) -.then((signed) => println(JSON.stringify(signed, null, 2))) -.catch((error) => println(`Error: ${JSON.stringify(error, null, 2)}`)); +Tezos.signer + .sign(packed.bytes) + .then((signed) => println(JSON.stringify(signed, null, 2))) + .catch((error) => println(`Error: ${JSON.stringify(error, null, 2)}`)); ``` First, you provide the Michelson code to be signed as a string along with its type. @@ -164,7 +183,9 @@ After forging a signature, you may want to send it to a contract so it can use i ```js const contract = await Tezos.wallet.at(CONTRACT_ADDRESS); -const op = await contract.methods.check_signature(public_key, signature, payloadBytes).send(); +const op = await contract.methods + .check_signature(public_key, signature, payloadBytes) + .send(); await op.confirmation(); ``` diff --git a/website/versioned_docs/version-13.0.0/smartcontracts.md b/website/versioned_docs/version-15.1.0/smartcontracts.md similarity index 87% rename from website/versioned_docs/version-13.0.0/smartcontracts.md rename to website/versioned_docs/version-15.1.0/smartcontracts.md index e7df3a467d..857ba28530 100644 --- a/website/versioned_docs/version-13.0.0/smartcontracts.md +++ b/website/versioned_docs/version-15.1.0/smartcontracts.md @@ -103,10 +103,10 @@ values={[ ```js live noInline -// const Tezos = new TezosToolkit('https://ithacanet.ecadinfra.com'); +// const Tezos = new TezosToolkit('https://ghostnet.ecadinfra.com'); Tezos.contract - .at('KT1A3dyvS4pWd9b9yLLMBKLxc6S6G5b58BsK') + .at('KT1BJadpDyLCACMH7Tt9xtpx4dQZVKw9cDF7') .then((c) => { let methods = c.parameterSchema.ExtractSignatures(); println(JSON.stringify(methods, null, 2)); @@ -118,10 +118,10 @@ Tezos.contract ```js live noInline wallet -// const Tezos = new TezosToolkit('https://ithacanet.ecadinfra.com'); +// const Tezos = new TezosToolkit('https://ghostnet.ecadinfra.com'); Tezos.wallet - .at('KT1A3dyvS4pWd9b9yLLMBKLxc6S6G5b58BsK') + .at('KT1BJadpDyLCACMH7Tt9xtpx4dQZVKw9cDF7') .then((c) => { let methods = c.parameterSchema.ExtractSignatures(); println(JSON.stringify(methods, null, 2)); @@ -151,10 +151,10 @@ values={[ ```js live noInline -// const Tezos = new TezosToolkit('https://ithacanet.ecadinfra.com'); +// const Tezos = new TezosToolkit('https://ghostnet.ecadinfra.com'); Tezos.contract - .at('KT1A3dyvS4pWd9b9yLLMBKLxc6S6G5b58BsK') + .at('KT1BJadpDyLCACMH7Tt9xtpx4dQZVKw9cDF7') .then((c) => { let incrementParams = c.methods.increment(2).toTransferParams(); println(JSON.stringify(incrementParams, null, 2)); @@ -165,10 +165,10 @@ Tezos.contract ```js live noInline wallet -// const Tezos = new TezosToolkit('https://ithacanet.ecadinfra.com'); +// const Tezos = new TezosToolkit('https://ghostnet.ecadinfra.com'); Tezos.wallet - .at('KT1A3dyvS4pWd9b9yLLMBKLxc6S6G5b58BsK') + .at('KT1BJadpDyLCACMH7Tt9xtpx4dQZVKw9cDF7') .then((c) => { let incrementParams = c.methods.increment(2).toTransferParams(); println(JSON.stringify(incrementParams, null, 2)); @@ -195,10 +195,10 @@ values={[ ```js live noInline -// const Tezos = new TezosToolkit('https://ithacanet.ecadinfra.com'); +// const Tezos = new TezosToolkit('https://ghostnet.ecadinfra.com'); Tezos.contract - .at('KT1A3dyvS4pWd9b9yLLMBKLxc6S6G5b58BsK') + .at('KT1BJadpDyLCACMH7Tt9xtpx4dQZVKw9cDF7') .then((contract) => { const i = 7; @@ -209,17 +209,17 @@ Tezos.contract println(`Waiting for ${op.hash} to be confirmed...`); return op.confirmation(3).then(() => op.hash); }) - .then((hash) => println(`Operation injected: https://ithaca.tzstats.com/${hash}`)) + .then((hash) => println(`Operation injected: https://ghost.tzstats.com/${hash}`)) .catch((error) => println(`Error: ${JSON.stringify(error, null, 2)}`)); ``` ```js live noInline wallet -// const Tezos = new TezosToolkit('https://ithacanet.ecadinfra.com'); +// const Tezos = new TezosToolkit('https://ghostnet.ecadinfra.com'); Tezos.wallet - .at('KT1A3dyvS4pWd9b9yLLMBKLxc6S6G5b58BsK') + .at('KT1BJadpDyLCACMH7Tt9xtpx4dQZVKw9cDF7') .then((contract) => { const i = 7; @@ -230,7 +230,7 @@ Tezos.wallet println(`Waiting for ${op.opHash} to be confirmed...`); return op.confirmation(3).then(() => op.opHash); }) - .then((hash) => println(`Operation injected: https://ithaca.tzstats.com/${hash}`)) + .then((hash) => println(`Operation injected: https://ghost.tzstats.com/${hash}`)) .catch((error) => println(`Error: ${JSON.stringify(error, null, 2)}`)); ``` @@ -259,10 +259,10 @@ values={[ In the following example, a contract's `set_child_record` method will be called by passing the arguments using the flattened representation. The `methods` member of the `ContractAbstraction` class allows doing so. First, it is possible to obtain details about the signature of the `set_child_record` entry point by using the `getSignature` method as follow: ```js live noInline -// const Tezos = new TezosToolkit('https://ithacanet.ecadinfra.com'); +// const Tezos = new TezosToolkit('https://ghostnet.ecadinfra.com'); Tezos.contract - .at('KT1Rf9znRBHPW4BW8NbFuYeHKdykrAyb21si') + .at('KT1B2exfRrGMjfZqWK1bDemr3nBFhHsUWQuN') .then((contract) => { println(`List all contract methods: ${Object.keys(contract.methods)}\n`); println( @@ -280,12 +280,12 @@ The preceding example returns an array which contains the different possible sig ```js live noInline // import { TezosToolkit, MichelsonMap } from '@taquito/taquito'; -// const Tezos = new TezosToolkit('https://ithacanet.ecadinfra.com') +// const Tezos = new TezosToolkit('https://ghostnet.ecadinfra.com') // import { importKey } from '@taquito/signer'; -importKey(Tezos, emailExample, passwordExample, mnemonicExample, secretExample) +importKey(Tezos, secretKey) .then((signer) => { - return Tezos.contract.at('KT1Rf9znRBHPW4BW8NbFuYeHKdykrAyb21si'); + return Tezos.contract.at('KT1B2exfRrGMjfZqWK1bDemr3nBFhHsUWQuN'); }) .then((contract) => { return contract.methods @@ -303,7 +303,7 @@ importKey(Tezos, emailExample, passwordExample, mnemonicExample, secretExample) println(`Awaiting for ${op.hash} to be confirmed...`); return op.confirmation().then(() => op.hash); }) - .then((hash) => println(`Operation injected: https://ithaca.tzstats.com/${hash}`)) + .then((hash) => println(`Operation injected: https://ghost.tzstats.com/${hash}`)) .catch((error) => println(`Error: ${JSON.stringify(error, null, 2)}`)); ``` @@ -313,10 +313,10 @@ importKey(Tezos, emailExample, passwordExample, mnemonicExample, secretExample) In the following example, a contract's `set_child_record` method will be called by passing the parameter in an object format. The `methodsObject` member of the `ContractAbstraction` class allows doing so. First, it is possible to obtain details about the signature of the `set_child_record` entry point by using the `getSignature` method as follow: ```js live noInline -// const Tezos = new TezosToolkit('https://ithacanet.ecadinfra.com'); +// const Tezos = new TezosToolkit('https://ghostnet.ecadinfra.com'); Tezos.contract - .at('KT1Rf9znRBHPW4BW8NbFuYeHKdykrAyb21si') + .at('KT1B2exfRrGMjfZqWK1bDemr3nBFhHsUWQuN') .then((contract) => { println(`List all contract methods: ${Object.keys(contract.methodsObject)}\n`); println( @@ -334,12 +334,12 @@ The preceding example returns an object giving indication on how to structure th ```js live noInline // import { TezosToolkit, MichelsonMap } from '@taquito/taquito'; -// const Tezos = new TezosToolkit('https://ithacanet.ecadinfra.com') +// const Tezos = new TezosToolkit('https://ghostnet.ecadinfra.com') // import { importKey } from '@taquito/signer'; -importKey(Tezos, emailExample, passwordExample, mnemonicExample, secretExample) +importKey(Tezos, secretKey) .then((signer) => { - return Tezos.contract.at('KT1Rf9znRBHPW4BW8NbFuYeHKdykrAyb21si'); + return Tezos.contract.at('KT1B2exfRrGMjfZqWK1bDemr3nBFhHsUWQuN'); }) .then((contract) => { return contract.methodsObject @@ -349,7 +349,6 @@ importKey(Tezos, emailExample, passwordExample, mnemonicExample, secretExample) label: 'EEEE', owner: 'tz1PgQt52JMirBUhhkq1eanX8hVd1Fsg71Lr', parent: 'FFFF', - ttl: '10', }) .send(); }) @@ -357,7 +356,7 @@ importKey(Tezos, emailExample, passwordExample, mnemonicExample, secretExample) println(`Awaiting for ${op.hash} to be confirmed...`); return op.confirmation().then(() => op.hash); }) - .then((hash) => println(`Operation injected: https://ithaca.tzstats.com/${hash}`)) + .then((hash) => println(`Operation injected: https://ghost.tzstats.com/${hash}`)) .catch((error) => println(`Error: ${JSON.stringify(error, null, 2)}`)); ``` @@ -366,4 +365,4 @@ importKey(Tezos, emailExample, passwordExample, mnemonicExample, secretExample) [0]: https://ligolang.org/ [1]: https://smartpy.io/ [2]: https://ide.ligolang.org/p/839HdMaflPsQSA6k1Ce0Wg -[3]: https://tezos.gitlab.io/whitedoc/michelson.html +[3]: https://tezos.gitlab.io/whitedoc/michelson.html \ No newline at end of file diff --git a/website/versioned_docs/version-13.0.0/storage_annotations.md b/website/versioned_docs/version-15.1.0/storage_annotations.md similarity index 92% rename from website/versioned_docs/version-13.0.0/storage_annotations.md rename to website/versioned_docs/version-15.1.0/storage_annotations.md index a34632ff12..6763d67634 100644 --- a/website/versioned_docs/version-13.0.0/storage_annotations.md +++ b/website/versioned_docs/version-15.1.0/storage_annotations.md @@ -36,7 +36,7 @@ values={[ ```js live noInline -// const Tezos = new TezosToolkit('https://ithacanet.ecadinfra.com'); +// const Tezos = new TezosToolkit('https://jakartanet.ecadinfra.com'); Tezos.contract .originate({ @@ -62,7 +62,7 @@ Tezos.contract ```js live noInline wallet -// const Tezos = new TezosToolkit('https://ithacanet.ecadinfra.com'); +// const Tezos = new TezosToolkit('https://jakartanet.ecadinfra.com'); Tezos.wallet .originate({ @@ -111,7 +111,7 @@ values={[ ```js live noInline -// const Tezos = new TezosToolkit('https://ithacanet.ecadinfra.com'); +// const Tezos = new TezosToolkit('https://jakartanet.ecadinfra.com'); Tezos.contract .originate({ @@ -137,7 +137,7 @@ Tezos.contract ```js live noInline wallet -// const Tezos = new TezosToolkit('https://ithacanet.ecadinfra.com'); +// const Tezos = new TezosToolkit('https://jakartanet.ecadinfra.com'); Tezos.wallet .originate({ @@ -188,7 +188,7 @@ values={[ ```js live noInline -// const Tezos = new TezosToolkit('https://ithacanet.ecadinfra.com'); +// const Tezos = new TezosToolkit('https://jakartanet.ecadinfra.com'); Tezos.contract .originate({ @@ -215,7 +215,7 @@ Tezos.contract ```js live noInline wallet -// const Tezos = new TezosToolkit('https://ithacanet.ecadinfra.com'); +// const Tezos = new TezosToolkit('https://jakartanet.ecadinfra.com'); Tezos.wallet .originate({ diff --git a/website/versioned_docs/version-13.0.0/taquito_utils.md b/website/versioned_docs/version-15.1.0/taquito_utils.md similarity index 100% rename from website/versioned_docs/version-13.0.0/taquito_utils.md rename to website/versioned_docs/version-15.1.0/taquito_utils.md diff --git a/website/versioned_docs/version-15.1.0/testing_strategies.md b/website/versioned_docs/version-15.1.0/testing_strategies.md new file mode 100644 index 0000000000..a667b1aa82 --- /dev/null +++ b/website/versioned_docs/version-15.1.0/testing_strategies.md @@ -0,0 +1,110 @@ +--- +title: Taquito Testing Strategies +id: testing_strategies +author: Michael Kernaghan +--- + +### How Taquito is Tested + +#### General Philosophy + +We write and maintain tests so that we may check that the software we create will do what we think it should do and alert us when it doesn’t. +This link offers more detail on software testing philosophy in general: https://www.codesimplicity.com/post/the-philosophy-of-testing/. + +#### Assumptions + +Taquito is a library. It offers tools. To test that Taquito is suitable for use, we must ensure that each tool the library provides does what it is supposed to. We also need to check that changes to support new features have not broken old features. + +We use the following Test Heuristics to achieve these assurance goals. Taquito uses several of these in the CI/CD pipeline. + +### Unit Tests + +Unit Tests are detailed tests of simple software components at the atomic level. Taquito includes unit tests in each of its packages. Here is an example: + + ```javascript + it('Public key returned by ledger device should be compressed adequately for tz1 before b58 encoding', () => { + const buff = Buffer.from( + '02063ed375b28dd2c1841138d4959f57b4a2715730e2e28fcda9144a19876dd3c6', + 'hex' + ); + const compressbuff = compressPublicKey(buff, 0x00); + const compressbuff2hex = Buffer.from(compressbuff).toString('hex'); + expect(compressbuff2hex).toEqual( + '063ed375b28dd2c1841138d4959f57b4a2715730e2e28fcda9144a19876dd3c6' + ); + }); + ``` + + Sometimes a Unit Test will use a Mock to simulate interactions between the software and some external component. + We measure how comprehensive our unit test coverage is by running "test code coverage tools" that report on the lines of code that are not touched when running unit tests. We can verify that unit tests are effecctive with "mutation testing" described below. + +### Integration Tests +Integration Tests look to ensure that multiple software components are working together. These components might be created by different teams or run on separate machines. The integration of various components can make these tests susceptible to random failures, but they will be rerun until they pass. Taquito testing routinely runs hundreds of integration tests daily. + +Here is a simple example of an integration test. The test sends Taquito instructions to a live test node with the transactions processed on the blockchain. This test originates a contract on the chain with transfers and verifies that confirmation is received. + +```javascript + it('Simple transfers with origination', async (done) => { + const batch = await Tezos.batch() + .withTransfer({ to: 'tz1ZfrERcALBwmAqwonRXYVQBDT9BjNjBHJu', amount: 0.02 }) + .withTransfer({ to: 'tz1ZfrERcALBwmAqwonRXYVQBDT9BjNjBHJu', amount: 0.02 }) + .withTransfer({ to: 'tz1ZfrERcALBwmAqwonRXYVQBDT9BjNjBHJu', amount: 0.02 }) + .withOrigination({ + balance: "1", + code: ligoSample, + storage: 0, + }) + + const op = await batch.send(); + await op.confirmation(); + expect(op.status).toEqual('applied') + done(); + }) +``` + +### Code Reviews + +We do Code Reviews whenever a developer seeks to merge code. Other team members review it for correctness, accuracy, conformance with Taquito design overall, and suitability. This process will rapidly find problems that testing would either miss or take wasteful cycles to resolve. We will not merge code changes or new features unless they have been code reviewed and all requested changes are determined. + +### Static Code Analysis + +Static Code Analysis is run during the CICD cycle to do syntactic checks for errors in the code. Often a line marking a merge conflict or a violation of a coding format will cause a static analyzer to complain. During a CICD run, a Pull Request will be examined by [CodeQL](https://codeql.github.com/) and [Snyk](https://snyk.io/). + +### End-to-End Tests + +Taquito uses the Taquito Test Dapp and the Live Code examples in the documentation as end-to-end tests. The tests exercise the entire software stack between the blockchain node and the user-facing interface. These tests show that all the components are working together. At each Taquito release, these tests are checked, and the results are included in the release. + +### Mutation Tests + + Mutation testing is a way to verify the effectiveness of unit tests. In addition to the code coverage of unit tests, we can check that the tests are resilient against all sorts of code changes. We all understand the intuition that if you change some code and no test fails, then the tests are missing something. Mutation testing tools allow us to implement this intuition and find missed test cases, confusing tests, missing assertions, etc. Taquito has been using Stryker to identify test mutations and systematically remove them from the code base. For details on how mutation testing works, please see: https://stryker-mutator.io/docs/. + +### Manual Tests + +When a user raises an issue, Testers will verify the problem using manual methods. For Taquito, such testing could be: +a quick Taquito script, +checking a result with tezos-client, +stepping through code with a debugger, +rerunning scripts with variations each time, +or other exploratory activities around the code base that are not fully scripted tests in the CICD. + +Ledger Devices require manual testing as they have buttons that an operator must press to authorize signatures and transactions. There are emulators for Ledger Devices, but Taquito testing of ledger devices combines manual and scripted exploratory testing. + +### Security Tests + +Taquito has implemented some security tests in its integration test suite. These tests check for regressions in the Tezos code that could open known attack techniques. The tests verify that a particular attack is impossible and that appropriate error messaging and exceptions occur when the tests try some well-known attacks. + +### Performance + +Ecad DevOps maintains an extensive performance tracking monitoring setup using Loki and Grafana, which generates alerts when specific performance parameters are out of band. + +## Managing Tezos Protocol Migrations with Test Nets + +Each time Tezos changes protocol, there is a new test net, and old ones are deprecated. Contracts originated in a more senior test net must be originated again on the new testnet. We have to update RPC content values and recreate Live Code Example contracts. So each protocol change requires an overhaul of some of the test assets to suit the new protocol. + +The Taquito test suite will run tests in CICD against the current and next test net. There is also testing of “Mondaynet,” which represents the bleeding edge of the available Tezos test code. + +ECAD Devops maintains a suite of Tezos public nodes that the Tezos community can use. By supporting and monitoring these nodes, ECAD engineers have an overview and insights into the behaviour of these systems and can contribute to problem isolation, bug fixes and general troubleshooting; or specific test scenarios that require DevOps level node access. + +### Mondaynet and Daily net + +To keep up with the current changes proposed for the following Tezos protocol, we can run our integration test suite against the node called "Mondaynet." This node captures the head of the Tezos development branch each Monday. By regression testing this node, we can ascertain changes Taquito may need to make early in the protocol development process. There is also "Daily net," which offers the current Tezos branch head each day. \ No newline at end of file diff --git a/website/versioned_docs/version-13.0.0/tezbridge_signer.md b/website/versioned_docs/version-15.1.0/tezbridge_signer.md similarity index 100% rename from website/versioned_docs/version-13.0.0/tezbridge_signer.md rename to website/versioned_docs/version-15.1.0/tezbridge_signer.md diff --git a/website/versioned_docs/version-13.0.0/tezos_domains.md b/website/versioned_docs/version-15.1.0/tezos_domains.md similarity index 100% rename from website/versioned_docs/version-13.0.0/tezos_domains.md rename to website/versioned_docs/version-15.1.0/tezos_domains.md diff --git a/website/versioned_docs/version-13.0.0/tickets.md b/website/versioned_docs/version-15.1.0/tickets.md similarity index 100% rename from website/versioned_docs/version-13.0.0/tickets.md rename to website/versioned_docs/version-15.1.0/tickets.md diff --git a/website/versioned_docs/version-13.0.0/transaction_limits.md b/website/versioned_docs/version-15.1.0/transaction_limits.md similarity index 100% rename from website/versioned_docs/version-13.0.0/transaction_limits.md rename to website/versioned_docs/version-15.1.0/transaction_limits.md diff --git a/website/versioned_docs/version-13.0.0/tutorial_links.md b/website/versioned_docs/version-15.1.0/tutorial_links.md similarity index 100% rename from website/versioned_docs/version-13.0.0/tutorial_links.md rename to website/versioned_docs/version-15.1.0/tutorial_links.md diff --git a/website/versioned_docs/version-15.1.0/tx_rollups.md b/website/versioned_docs/version-15.1.0/tx_rollups.md new file mode 100644 index 0000000000..82c737ce9c --- /dev/null +++ b/website/versioned_docs/version-15.1.0/tx_rollups.md @@ -0,0 +1,108 @@ +--- +title: Transaction Optimistic Rollups +id: tx_rollups +author: Davis Sawali +--- + +A Transaction Optimistic Rollup (TORU) is an experimental temporary scaling solution to help Tezos developers and users get acquainted with the idea of working with rollups. + +This is a trimmed, more concise documentation of how to do TORU operations in Taquito. If you aren't yet familiar with rollup node interactions, please refer to this [documentation](https://tezos.gitlab.io/alpha/transaction_rollups.html?highlight=transaction%20rollups#transaction-rollups) by Nomadic Labs. + +TORU currently supports the transferring of funds in the form of [tickets](https://tezostaquito.io/docs/tickets). Fund (or ticket) transfers can be done from: +- Layer-1 to layer 2 (deposit) +- Layer-2 to layer 2 (transfer) +- Layer-2 to layer-1 (withdrawal) + +Taquito currently supports **layer-1** operations that facilitate deposits and withdrawals to and from the rollup node. + +## Deposits +To be able to interact or transfer funds on layer-2, you will first need to deposit an amount to an existing layer-2 (tz4) address. + +Depositing tickets from layer-1 to layer-2 can be done via a smart contract that facilitates the transfer to a tz4 address in a specified rollup node. + +An example of such contract can be found [here](https://tezos.gitlab.io/alpha/transaction_rollups.html?highlight=transaction%20rollups#depositing-assets-on-a-rollup) + +Assuming the contract has been originated, interacting with the contract in Taquito would look something like this: +```javascript +const Tezos = new TezosToolkit('https://jakartanet.ecadinfra.com'); + +const deposit = Tezos.contract.at(SMART_CONTRACT_ADDRESS); + +const op = await deposit.methods.default( + 'foobar', + '15', + 'tz4Jxn8MpRndqWUzkuZbQKmE3aNWJzYsSEso', + 'txr1c9XcfmiLSWeqDPamPytns2ZXvwgYA7EpA' +); + +const confirmation = await op.confirmation(); + +console.log(op.hash); +console.log(op.operationResults); +``` +The `default` entrypoint takes in 4 arguments: +- `foobar` is the ticket string +- `15` is the quantity of a ticket string +- `tz4Jxn8MpRndqWUzkuZbQKmE3aNWJzYsSEso` is the layer-2 address that will be the deposit recipient +- `txr1c9XcfmiLSWeqDPamPytns2ZXvwgYA7EpA` is the rollup node id + +If the deposit is successful, you will be returned an operation hash that can be accessed via `op.hash` + +You also might want to look at `op.operationResults` to retrieve the `ticket_hash`. A ticket hash should look something like this: `exprtz9FgfdzufUADVsvP8Gj8d8PZr9RsBEjZ5GQKM8Kp5cKWww7di` + +## Transfer +The exchange of assets in the form of tickets can be done from a layer-2 (`tz4`) address to another layer-2 address. Not to be confused with the `transfer_ticket` operation, this layer-2 operation will not be supported in Taquito. This may change in the future with SCORU (Smart Contract Optimistic Rollups). + +For instructions on how to conduct a transfer in layer-2 using the rollup client, refer to this [documentation](https://tezos.gitlab.io/alpha/transaction_rollups.html?highlight=transaction%20rollups#exchanging-assets-inside-a-rollup) by Nomadic Labs. + +## Withdrawal +A withdrawal of assets from layer-2 back to layer-1 can be done in several steps. + +The first step is to perform a `withdraw` in layer-2 to a layer-1 address in the rollup client. +``` +tezos-tx-rollup-client-alpha withdraw ${qty} of ${ticket_hash} from ${l2_src} to ${l1_dst} +``` + +- `${qty}` is the quantity of a ticket string that you would like to withdraw +- `${ticket_hash}` is the ticket hash that was returned by a deposit +- `${l2_src}` is the BLS pair of keys generated with `tezos-client bls gen key`; or in other words, the tz4 address that holds the tickets +- `${l1_dst}` is the layer-1 address you would like to withdraw the tickets to + +After a successful withdrawal, your assets will exist back in layer-1 in the form of tickets after the [finality period](#Glossary) ends. + +:::warning +Please note that this first step is a layer-2 operation which Taquito does not currently support. +::: + + + +The second step is to use a Tezos operation that will transfer these tickets to a smart contract. You can use your own contracts to process the tickets as you'd like (e.g. allow access to XTZ existing in the tickets, etc). + +This second step is called a `Transfer Ticket` operation, which Taquito supports. + +``` +const Tezos = new TezosToolkit('https://jakartanet.ecadinfra.com'); + +const op = await Tezos.contract.transferTicket({ + ticketContents: { "string": "foobar" }, + ticketTy: { "prim": "string" } , + ticketTicketer: 'KT1AL8we1Bfajn2M7i3gQM5PJEuyD36sXaYb', + ticketAmount: 5, + destination: KT1SUT2TBFPCknkBxLqM5eJZKoYVY6mB26Fg, + entrypoint: 'default', +}); +``` +- `ticket_amount` is the amount that you would like to transfer to the smart contract +- `destination` is the address of the smart contract you would like to transfer the tickets to +- `entrypoint` is the entrypoint of the destination smart contract +- `ticket_contents`, `ticket_ty`, and `ticket_ticketer` can be retrieved from running this command using the rollup client (see [documentation](https://tezos.gitlab.io/alpha/transaction_rollups.html?highlight=transaction%20rollups#exchanging-assets-inside-a-rollup)) +``` +tezos-tx-rollup-client-alpha rpc get "/context/head/tickets/${ticket_hash}" +``` + +## Glossary +- `Layer-1` refers to our main protocol networks related to on-chain transactions +- `Layer-2` refers to rollup nodes deployed by any individual/group to receive transactions off-chain +- `TORU` is short for Transactional Optimistic Rollup; the experimental, temporary introduction for rollup nodes +- `SCORU` is short for Smart Contract Optimistic Rollup; the more 'permanent' solution that has yet to be be released +- `Finality Period` refers to the number of blocks needed for the chain to finalize transactions on a rollup node (40,000 blocks on mainnet and testnets, 10 blocks on Mondaynet and Dailynet for ease of testing and demo purposes). See [documentation](https://tezos.gitlab.io/alpha/transaction_rollups.html?highlight=transaction%20rollups#commitments-and-rejections). diff --git a/website/versioned_docs/version-13.0.0/tzip12.md b/website/versioned_docs/version-15.1.0/tzip12.md similarity index 95% rename from website/versioned_docs/version-13.0.0/tzip12.md rename to website/versioned_docs/version-15.1.0/tzip12.md index c65c1fa37e..e385f6ca6d 100644 --- a/website/versioned_docs/version-13.0.0/tzip12.md +++ b/website/versioned_docs/version-15.1.0/tzip12.md @@ -92,7 +92,7 @@ values={[ Tezos.addExtension(new Tzip12Module()); -const contractAddress = "KT1PVTW2QkkSsMsnW5GzNweGbsxWbGuBYFmo"; +const contractAddress = "KT1NMtSQq484bDYSFvNrBjfkGtpug2Fm1rrr"; const tokenId = 1; Tezos.contract.at(contractAddress, compose(tzip12, tzip16)) @@ -116,7 +116,7 @@ Tezos.contract.at(contractAddress, compose(tzip12, tzip16)) Tezos.addExtension(new Tzip12Module()); -const contractAddress = "KT1PVTW2QkkSsMsnW5GzNweGbsxWbGuBYFmo"; +const contractAddress = "KT1NMtSQq484bDYSFvNrBjfkGtpug2Fm1rrr"; const tokenId = 1; Tezos.wallet.at(contractAddress, compose(tzip12, tzip16)) @@ -149,7 +149,7 @@ values={[ Tezos.addExtension(new Tzip16Module()); -const contractAddress = "KT1PVTW2QkkSsMsnW5GzNweGbsxWbGuBYFmo"; +const contractAddress = "KT1NMtSQq484bDYSFvNrBjfkGtpug2Fm1rrr"; const tokenId = 1; Tezos.contract.at(contractAddress, tzip16) @@ -178,7 +178,7 @@ Tezos.contract.at(contractAddress, tzip16) Tezos.addExtension(new Tzip16Module()); -const contractAddress = "KT1PVTW2QkkSsMsnW5GzNweGbsxWbGuBYFmo"; +const contractAddress = "KT1NMtSQq484bDYSFvNrBjfkGtpug2Fm1rrr"; const tokenId = 1; Tezos.wallet.at(contractAddress, tzip16) @@ -201,6 +201,7 @@ Tezos.wallet.at(contractAddress, tzip16) *Note that an off-chain view `all-tokens` should also be present in the contract metadata allowing the user to know with which token ID the `token_metadata` can be called.* + ### Example where the token metadata are found in the big map `%token_metadata` :::note @@ -256,7 +257,7 @@ values={[ Tezos.addExtension(new Tzip12Module()); -const contractAddress = "KT1PVTW2QkkSsMsnW5GzNweGbsxWbGuBYFmo"; +const contractAddress = "KT1NMtSQq484bDYSFvNrBjfkGtpug2Fm1rrr"; const tokenId = 1; Tezos.contract.at(contractAddress, tzip12) @@ -279,7 +280,7 @@ Tezos.contract.at(contractAddress, tzip12) Tezos.addExtension(new Tzip12Module()); -const contractAddress = "KT1PVTW2QkkSsMsnW5GzNweGbsxWbGuBYFmo"; +const contractAddress = "KT1NMtSQq484bDYSFvNrBjfkGtpug2Fm1rrr"; const tokenId = 1; Tezos.wallet.at(contractAddress, tzip12) @@ -297,4 +298,4 @@ Tezos.wallet.at(contractAddress, tzip12) #### For more information on the contracts used in the examples: -integration-tests/tzip12-token-metadata.spec.ts +integration-tests/tzip12-token-metadata.spec.ts \ No newline at end of file diff --git a/website/versioned_docs/version-13.0.0/tzip16-sequence-diagram.md b/website/versioned_docs/version-15.1.0/tzip16-sequence-diagram.md similarity index 100% rename from website/versioned_docs/version-13.0.0/tzip16-sequence-diagram.md rename to website/versioned_docs/version-15.1.0/tzip16-sequence-diagram.md diff --git a/website/versioned_docs/version-13.0.0/upgrading_guide.md b/website/versioned_docs/version-15.1.0/upgrading_guide.md similarity index 100% rename from website/versioned_docs/version-13.0.0/upgrading_guide.md rename to website/versioned_docs/version-15.1.0/upgrading_guide.md diff --git a/website/versioned_docs/version-13.0.0/validators.md b/website/versioned_docs/version-15.1.0/validators.md similarity index 100% rename from website/versioned_docs/version-13.0.0/validators.md rename to website/versioned_docs/version-15.1.0/validators.md diff --git a/website/versioned_docs/version-13.0.0/version.md b/website/versioned_docs/version-15.1.0/version.md similarity index 74% rename from website/versioned_docs/version-13.0.0/version.md rename to website/versioned_docs/version-15.1.0/version.md index c72c9d1556..5a94fa1921 100644 --- a/website/versioned_docs/version-13.0.0/version.md +++ b/website/versioned_docs/version-15.1.0/version.md @@ -2,6 +2,699 @@ title: Versions author: Jev Bjorsell --- +# Taquito v15.1.0 +## Summary + +### New Features +- `@taquito/taquito` New provider support `PrepareProvider` to facilitate preparation of operations in Taquito. #2020 +- `@taquito/taquito` Support new operation `increase_paid_storage` on the wallet API #1768 + +### Bug Fixes +- Fixed a bug where `axios-fetch-adapter` was not returning the response body from errors, causing the wrong error to be captured by the calling method #2187 + +### Documentation +- Update Taquito website live code examples to use Ghostnet endpoint. #2224 + +### Internals +- Updated Beacon version to v3.3.1 [PR](https://github.com/ecadlabs/taquito/pull/2266) +- Updated Taquito Github Workflows to use Node LTS/Gallium (v16) [PR](https://github.com/ecadlabs/taquito/pull/2301) + +## `@taquito/taquito` - Added new provider `PrepareProvider` to facilitate operation preparation + +`PrepareProvider` now extends more control to the user to give them the ability to 'prepare' Tezos operations before forging and injection. The preparation step now can be done through the `TezosToolkit` class as such: + +```typescript +// example of a transaction operation preparation +const prepare = await Tezos.prepare.transaction({ + to: 'tz1KvJCU5cNdz5RAS3diEtdRvS9wfhRC7Cwj', + amount: 5 +}); +``` + +The expected output will look something like this: +```typescript +{ + opOb: { + branch: 'BLOCK_HASH', + contents: [ + { + kind: 'transaction', + fee: '391', + gas_limit: '101', + storage_limit: '1000', + amount: '5000000', + destination: 'tz1KvJCU5cNdz5RAS3diEtdRvS9wfhRC7Cwj', + source: 'PUBLIC_KEY_HASH', + counter: '1', + }, + ], + protocol: 'PROTOCOL_HASH', + }, + counter: 0, + } +``` + +## `@taquito/taquito` - Increase paid storage operation support in the wallet API +Taquito now supports `increase_paid_storage` operation in the Wallet API (previously only available in the Contract API). + +```typescript +const op = await Tezos.wallet.increasePaidStorage({ + amount: 1, + destination: simpleContractAddress +}).send(); +``` + +# Taquito v15.0.1 +## Hotfix +- Fixed a bug where the `local-forging` package was using an outdated version of the codec when it's instantiated without passing in a protocol hash. Updated so that the default value uses the current protocol hash. #2242 + +## Summary +- `@taquito/taquito` Support new operation `drain_delegate` in the Contract API #2068 +- `@taquito/local-forging` Support new operation `drain_delegate` #2065 + +## Bug Fixes +- `@taquito/michelson-encoder` fix MapTypecheck bug triggered by nested maps ending with a big_map #1762 + +### Documentation +- Auto hide sticky navbar for mobile view to increase readability on mobile devices. +PR: https://github.com/ecadlabs/taquito/pull/2236 + +### Internals +- Start running integration tests against testnets for external PRs. +PR: https://github.com/ecadlabs/taquito/pull/2221 + +## `@taquito/taquito` drain_delegate operation support +A new manager operation related to the consensus_key change in Lima has been added: +```typescript +const op = await Tezos.contract.updateConsensusKey({ + pk: 'PUBLIC_KEY' +}); + +await op.confirmation(); +``` + +# Taquito v15.0.0 + +**Breaking Changes**: +- Some types have changed to support the `consensus_key` change in Protocol Lima. Refer to issue #2069 for more details + +## Summary + +### Lima Support +- `@taquito/taquito` Support new operation `update_consensus_key` in the Contract API #2067 +- `@taquito/local-forging` Support new operation `update_consensus_key` #2065 +- `@taquito/local-forging` Support new instruction `LAMBDA_REC` and value `Lambda_rec` and support changes related to the `TICKET` instruction #2074 #2072 +- `@taquito/rpc` Support new types and operations for `update_consensus_key` and `drain_delegate` #2066 +- `@taquito/rpc` Support new properties related to Lima #2172 #2071 +- `@taquito/michelson-encoder` Support new type `TICKET_DEPRECATED` #2073 +- `@taquito/michel-codec` Support new instruction `LAMBDA_REC` and value `Lambda_rec` and support changes related to the `TICKET` instruction #2181 #2075 + +### Testing +- Removed tests that referenced Timelock feature (`CHEST_OPEN` Michelson instruction) #2070 +- Added tests for `unparsing_mode` #2077 +- Updated tx-rollup tests to use address from config instead of hard coded addresses #2170 +- Fixed local-forging tests failing in Limanet #2158 + +### Documentation +- Added documentation for consensus key operations (`update_consensus_key`) #2067 #2068 +### Internals +- Removed legacy `lerna bootstrap` commands from build workflow #2188 + +### Deprecation +`@taquito/tezbridge-signer` and `@taquito/tezbridge-wallet` has been deprecated, and references to them have been removed from the codebase #2080 + +### Others +- Removed Jakarta protocol references in on chain view related code #2098 +- Removed temple-wallet/dapp dependency from Taquito website that was producing build errors [PR](https://github.com/ecadlabs/taquito/pull/2202) + + +## `@taquito/taquito` - Added support for `update_consensus_key` +A new manager operation to update consensus keys can be used as follows: +```typescript +const op = await Tezos.contract.updateConsensusKey({ + pk: 'PUBLIC_KEY' +}); + +await op.confirmation(); +``` + +## `@taquito/local-forging` - Added support for Lima operations and instructions +- Updated local-forger to forge and parse `update_consensus_key` and `drain_delegate` +- Updated local-forger to support the new Michelson instruction `LAMBDA_REC` and the new data constructor named `Lambda_rec` which enables recursive LAMBDA + +## `@taquito/rpc` - Updated types to support Lima protocol +Added a few new types to accommodate Lima protocol changes: +- `OperationContentsUpdateConsensusKey` +- `OperationContentsDrainDelegate` +- `OperationContentsAndResultMetadataUpdateConsensusKey` +- `OperationContentsAndResultMetadataDrainDelegate` +- `OperationContentsAndResultUpdateConsensusKey` +- `OperationContentsAndResultDrainDelegate` +- `OperationResultUpdateConsensusKey` + +Also updates to existing types to accommodate changes regarding consensus keys. + +## `@taquito/michelson-encoder` - Support new type `TICKET_DEPRECATED` +- Added support for the new Michelson type `TICKET_DEPRECATED`. More info here: https://tezos.gitlab.io/protocols/015_lima.html#breaking-changes + +## `@taquito/michel-codec` - Support new instruction `LAMBDA_REC` and value `Lambda_rec` + +The Lima protocol introduces a new Michelson type named `LAMBDA_REC`, and a new data constructor named `Lambda_rec`, allowing the creation of recursive lambda functions. Support for those primitives has been added in the michel-codec package enabling users to validate or pack/unpack Michelson code containing them. + +The `TICKET` instruction now returns an optional ticket instead of a ticket. This change has also been reflected in the michel-codec parser. + +# Taquito v14.2.0-beta +## Summary +### New Features + +- `@taquito/taquito` - Added support for `Ballot` operation in the Contract API #1630 +- `@taquito/taquito` - Added support for `Proposals` operation in the Contract API #2099 +- `@taquito/taquito-signer` - Added new method `fromMnemonic` to the `InMemorySigner` #1228 + +### Documentation +- Updated and organized Taquito README to prepare for translations to other languages #2015 + +### Internals +- Added integration test for `Ballot` and `Proposals` operation #2087 +- Configured NPM workspaces for Taquito to improve build process #2127 + +## `@taquito/taquito` - Added support for `Ballot` operation +We added a new Contract API method to support the `Ballot` operation. Bakers can now cast their ballots using this operation from Taquito as follows: + +```typescript +const op = await Tezos.contract.ballot({ + proposal: 'PROTOCOL_HASH', + ballot: 'BALLOT_VOTE_STRING' +}); + +await op.confirmation(); +``` + +## `@taquito/taquito` - Added support for `Proposals` operation +Alongside the `Ballot` operation support, bakers can now also submit proposals using the `Proposals` operation that can be used as follows: + +```typescript +const op = await Tezos.contract.proposals({ + proposals: ['PROTOCOL_HASH1', 'PROTOCOL_HASH2'] +}); + +await op.confirmation(); +``` + +## `@taquito/taquito-signer` - Added new method `fromMnemonic` +Users can now create an `InMemorySigner` instance using the `fromMnemonic` method for a tz1, tz2, or tz3 address: ed25519, secp256k1, or p256 respectively. + +```typescript +const mnemonic = 'author crumble medal dose ribbon permit ankle sport final hood shadow vessel horn hawk enter zebra prefer devote captain during fly found despair business' +const signer = InMemorySigner.fromMnemonic({ mnemonic, password, derivationPath: "44h/1729h/1/0", curve: 'secp256k1' }); +``` +# Taquito v14.1.0-beta + +## Summary + +### New features + +- `@taquito/taquito` - Provide a subscriber to events #1746 +- `@taquiro/rpc` - Support `voting_info` endpoint #1749 +- `@taquito/ledger-signer` - Add support for bip25519 curve #1869 + +### Bug fixes +- `@taquito/http-utils` - Issue using Taquito in service worker environment #2025 +- `@taquito/taquito` - `confirmationPollingTimeoutSecond` not working #2006 +- `@taquito/taquito` - `PollingSubscribeProvider` used in contract confirmations might skip blocks #1783 +- `@taquito/michelson-encoder` - Fixed Michelson encoder for timestamp to handle numbers being passed #1888 + +### Improvement +- `@taquito/taquito` - Allow users to customize the parser #660 +- `@taquito/taquito` - Accept amount, `fee`, `gasLimit`, and `storageLimit` as parameters of the `withContractCall` method #1717 +- `@taquito/tzip16` - Add more high level functions for tzip16 metadata #584 +- `@taquito/taquito` - Support `string` or `number` for the `balance` property for contract origination #1795 + +### Documentation +- Documentation page dedicated to multi-sig: https://tezostaquito.io/docs/next/multisig_doc/ +- Fixed broken link in the Wallet doc #1865 + +### Others +- `@taquito-beacon-wallet` - Updated `@airgap/beacon-dapp` to version 3.3.0: https://github.com/airgap-it/beacon-sdk/releases/tag/v3.3.0 + +### Internals +- Speed up build with nx #2013 +- Integrate the taquito-test-dapp into the Taquito pipeline #663 +- Add a flextesa node to our CI pipeline #457 +- Add unit tests for taquito-beacon-wallet #1863 +- Adapt integration tests config so they can be run against a sandbox. #1971 + + + +## `@taquito/taquito` - Provide a subscriber to events + +Taquito provides a simple way for users to subscribe to certain events on the blockchain via the `PollingSubscribeProvider`. + +```typescript +const Tezos = new TezosToolkit(RPC_URL); + +try { + const sub = Tezos.stream.subscribeEvent({ + tag: 'tagName', + address: 'KT1_CONTRACT_ADDRESS' + }); + + sub.on('data', console.log); + +} catch (e) { + console.log(e); +} +``` + +Please refer to the documentation for more information: https://tezostaquito.io/docs/next/subscribe_event + +## `@taquiro/rpc` - Support `voting_info` endpoint + +We added a new method on the `RpcClient` named `getVotingInfo` to support the new RPC endpoint `voting_info` (Kathmandu). The method returns data found on the voting listings for a delegate as follows : + +```typescript +VotingInfoResponse = { + voting_power?: string; + current_ballot?: BallotListResponseEnum; + current_proposals?: string[]; + remaining_proposals?: number; +}; +``` + +## `@taquito/ledger-signer` - Add support for bip25519 curve + +We added support for the bip32-ed25519 derivation scheme in the ledger package. It can be used as follows: + +```typescript +const transport = await TransportNodeHid.create(); +const signer = new LedgerSigner( + transport, + "44'/1729'/0'/0'", + false, + DerivationType.BIP32_ED25519 +) +``` + +## `@taquito/http-utils` - Issue using Taquito in a service worker environment + +In service worker environments (e.g., Cloudflare workers), `XMLHttpRequest` used by `Axios` is deprecated. When using the `@taquito/http-utils` package in such an environment, the following error was occurring: `TypeError: adapter is not a function`. A fix has been made to use `@vespaiach/axios-fetch-adapter` when not in a nodejs environment. + +## `@taquito/taquito` - confirmationPollingTimeoutSecond not working + +There was an issue with the `confirmationPollingTimeoutSecond` on the `TezosToolkit`. During the operation confirmation (both on the contract and wallet API), the timeout timer restarted on every new block emission. This has been fixed. + +## `@taquito/taquito` - `PollingSubscribeProvider` used in contract confirmations might skip blocks + +When the polling mechanism skipped a block during the operation confirmation for the wallet API, an error `MissedBlockDuringConfirmationError` was thrown. We refactored the implementation to retrieve missed blocks instead of throwing an error. On the contract API side, there was no check whether a block was missed or skipped, and it would just timeout, unable to find the operation after a certain time. The implementation has also been changed to retrieve missed blocks. + +## `@taquito/michelson-encoder` - Fixed Michelson encoder for timestamp to handle numbers being passed + +A bug has been fixed, allowing support of UNIX timestamp number when deploying a contract having a timestamp in storage or calling a contract entry point taking a timestamp in parameter. + +## `@taquito/taquito` - Allow users to customize the parser + +Taquito makes internal uses of the `@taquito/michel-codec` package on smart contract origination, allowing to convert Plain Michelson into JSON Michelson, expand Macros and validate Michelson to ensure its correctness. There is no change in this behavior, but we exposed a `parserProvider` at the TezosToolkit level allowing users to customize if needed. By default, the `parserProvider` is an instance of `MichelCodecParser`. + +## `@taquito/taquito` - Accept amount, `fee`, `gasLimit`, and `storageLimit` as parameters of the `withContractCall` method + +Before version 14.1.0, it was impossible to specify the amount, the fee, the `gasLimit`, and the `storageLimit` when calling a smart contract entry point using the batch API via the withContractCall method. An optional parameter has been added to the method to support this feature and can be used as follows: + +```typescript +const contract = Tezos.contract.at('contactAddress'); +const batch = Tezos.contract.batch() + .withContractCall(contract.methods.entrypointName("entrypointParam", { fee: 100, gasLimit: 1000, storageLimit: 10 }) + .withContractCall(...) + +const batchOp = await batch.send(); +await batchOp.confirmation(); +``` + +## `@taquito/taquito` - Support `string` or `number` for the `balance` property for contract origination + +The balance property was a string in the parameters to pass to originate a new contract. We changed to accept a number and string, which is more intuitive. + +## What's coming next for Taquito? + +We are currently working on compatibility support for the Lima protocol. +We are also investigating the integration of wallet connect 2 in Taquito. + + +If you have feature or issue requests, please create an issue on http://github.com/ecadlabs/taquito/issues or join us on the Taquito community support channel on Telegram https://t.me/tezostaquito + + + +# Taquito v14.0.0-beta + +Note for the users of the lower level APIs: injecting more than one manager operation per block from the same account is now forbidden by Tezos in the Kathmandu protocol. You will now receive the following error message: `Error while applying operation opHash: Only one manager operation per manager per block allowed (found opHash2 with Xtez fee).` This change has no impact if you use the TezosToolkit to send operations. Waiting for the operation to be included in a block is already required before submitting another one. + +**Breaking changes:** +- Be aware that if you implemented the readProvider interface, we added a new method named `getSaplingDiffByContract`. +- We removed the context class in the constructor of the ReadAdapter class and replaced it with RpcClient. + +## Summary +### Kathmandu support +- `@taquito/taquito` - Support new operation `increase_paid_storage` on the Contract API #1767 +- `@taquito/local-forging` - Support the `increase_paid_storage` operation and the `Emit` instruction #1766 #1742 +- `@taquito/michel-codec` - Support EMIT instruction #1743 +- `@taquito/taquito` - Replace `consumed_gas` with `consumed_milligas` #1769 +- `@taquito/rpc` - Support new properties/operations for Kathmandu #1862 #1848 +- `@taquito/rpc` - Add support for `run_script_view` endpoint #1750 + +### New features +- Sapling package +- `@taquito/taquito` - Added support for the `transfer_ticket` operation #1680 + +### Bug fixes +- `@taquito/michelson-encoder` - Display contract storage properly when it contains a `ticket` inside a `map` #1762 +- `@taquito/michelson-encoder` - `Schema.generateSchema()` fails for `sapling_transaction_deprecated` #1763 +- `@taquito/michel-codec`- Fixed comb pairs unpacking #1471 + +### Improvement +- `@taquito/http-utils` - Added request info to the `HttpRequestFailed` error #1091 +- `@taquito/taquito` - Retrieve contract addresses from batched operation #1661 +- `@taquito/michelson-encoder` - Accept hex prefixed with 0x as well #1624 +- `@taquito/taquito` - Use the new `run_script_view` endpoint to execute on chain views #1750 + +### Documentation +- Added documentation feedback to Taquito website #1732 +- Fixed live code example - try temple wallet was getting an error about bad parameters #1698 +- Added documentation on TORU deposit/withdrawals: https://tezostaquito.io/docs/next/tx_rollups +- Added links to commercial nodes (submit a PR if some are missing): https://tezostaquito.io/docs/next/rpc_nodes/ + +### Testing +- Emptying an implicit account does not cost extra gas anymore #1771 +- Added more Manager_lambda scenarios to contract multisig integration tests #1724 + +### Others +- `@taquito-beacon-wallet` - Updated `@airgap/beacon-dapp` to version 3.1.4 +- `@taquito/local-forging` - Pure JS implementation #441 + + +## `@taquito/taquito` - Support new operation `increase_paid_storage` on the Contract API + +The `increase_paid_storage` operation allows increasing the paid storage of a smart contract by a specified bytes amount. The smart contract owner doesn't have to do it; any user can increase the storage. The operation is of interest for high-traffic dapps as it allows prepaying for storage and prevents transactions from failing because of an unpredictable storage burn. + +```typescript +const Tezos = new TezosToolkit('https://ghostnet.ecadinfra.com'); + +const op = await Tezos.contract.increasePaidStorage({ + amount: 5, + destination: 'contract' +}); + +- `amount` is the number of bytes we want to increase the paid storage +- `destination` is the address of the smart contract we want to increase the paid storage +``` + +## `@taquito/local-forger` - Support the `increase_paid_storage` operation and the `Emit` instruction + +We added support to forge and parse the new operation kind `increase_paid_storage`. + +We added support for the new Michelson instruction `Emit`, which can emit contract events when part of a contract script. + +## `@taquito/michel-codec` - Support EMIT instruction + +@taquito/michel-codec is responsible, among others, for validating Michelson code to ensure its correctness. The package now supports the new `EMIT` instruction. + +## `@taquito/taquito` - Replace `consumed_gas` with `consumed_milligas` + +In Kathmandu, the property `consumed_gas` that was previously deprecated in favor of `consumed_milligas` has been removed. + +In Taquito (Contract API), the classes that extend the `Operation` class like `BatchOperation`, `DelegateOperation`, `OriginationOperation`, `TransactionOperation`, and so on, have a `consumedGas` getter. We did an internal change to calculate the consumed gas based on the consumed milligas, so there is no breaking change for the users. We also implemented a new `consumedMilligas` getter which returns the consumed milligas. + +On the wallet API side, the `WalletOperation` class has a `receipt` method that returns a `Receipt` object containing a `totalGas` property. It is now calculated based on the consumed milligas, and we added an additional `totalMilliGas` property. + +## `@taquito/rpc` - Support new properties/operations for Kathmandu + +Kathmandu brings new operation kinds that can be found in a block response. New interfaces representing the new operations have been added to the `OperationContents` and `OperationContentsAndResult` types of the RPC package. The new operation kinds are: `increase_paid_storage`, `vdf_revelation`. There is also a new internal operation named `event`. + +The `DelegatesResponse` interface returned by the `getDelegates` method on the `RpcCLient` has the new properties `current_ballot`, `current_proposals` and `remaining_proposals`. + +The `ConstantsResponse` type returned by the `getConstants` method on the `RpcCLient` has the new properties `max_wrapped_proof_binary_size`, `nonce_revelation_threshold`, `vdf_difficulty`, `testnet_dictator`,`dal_parametric`, `sc_rollup_stake_amount`, `sc_rollup_commitment_period_in_blocks`, `sc_rollup_max_lookahead_in_blocks`, `sc_rollup_max_active_outbox_levels`, `sc_rollup_max_outbox_messages_per_level`. + +## `@taquito/rpc` - Add support for `run_script_view` endpoint + +We added a new method named `runScriptView` on the `RpcClient` class to simulate a contract view. The parameter and response types of the method are as follows: + +``` +RPCRunScriptViewParam = { + contract: string; + view: string; + input: MichelsonV1Expression; + unlimited_gas?: boolean; + chain_id: string; + source?: string; + payer?: string; + gas?: string; + unparsing_mode?: UnparsingModeEnum; + now?: string; + level?: string; +}; + +RunScriptViewResult = { + data: MichelsonV1Expression; +}; +``` + +## Sapling package + +We implemented a package `@taquito/sapling` providing functionality for Sapling. For documentation, please refer to the following link: https://tezostaquito.io/docs/next/sapling + +We added a post-install script that fetches the z cash parameters required to initialize the sapling state. Excluding the files from the package avoids having an unsustainable bundle size. +The files `saplingOutputParams.js` and `saplingSpendParams.js` will be created in the users `node_modules/@taquito/sapling` folder and avoid them having to download and inject those files. + +As the next steps for the sapling package, we will provide interfaces for the key providers, making it easier to generate the proof and produced signature from a remote signer or a ledger. We currently offer an `InMemorySpendingKey` that must be used appropriately, given your risk profile. We will be looking for integration with wallets as well. + +## `@taquito/taquito` - Added support for the `transfer_ticket` operation + +The `transfer_ticket` operation allows transferring tickets from an implicit account to a smart contract. + +```typescript +const Tezos = new TezosToolkit('https://jakartanet.ecadinfra.com'); + +const op = await Tezos.contract.transferTicket({ + ticketContents: { "string": "foobar" }, + ticketTy: { "prim": "string" } , + ticketTicketer: 'KT1AL8we1Bfajn2M7i3gQM5PJEuyD36sXaYb', + ticketAmount: 5, + destination: KT1SUT2TBFPCknkBxLqM5eJZKoYVY6mB26Fg, + entrypoint: 'default', +}); + +- `ticketAmount` is the amount that you would like to transfer to the smart contract +- `destination` is the address of the smart contract you would like to transfer the tickets to +- `entrypoint` is the entrypoint of the smart contract +- `ticketContents`, `ticketTy`, and `ticketTicketer` can be retrieved from the tx rollup client +``` + +## `@taquito/michelson-encoder` - Display contract storage properly when it contains a `ticket` inside a `map` + +We fixed a bug in the michelson-encoder package that prevented displaying the contract storage when it contained tickets inside a map. + +## `@taquito/michelson-encoder` - `Schema.generateSchema()` fails for `sapling_transaction_deprecated` + +Support was missing for `sapling_transaction_deprecated` in the michelson-encoder package and has been added. + +## `@taquito/http-utils` - Added request info to the `HttpRequestFailed` error + +We added the Url and method to the `HttpRequestFailed` error message. This change will make it easier to diagnose timeout error, which was only returning `Request timed out after: 30000ms`. + +## `@taquito/taquito` - Retrieve contract addresses from batched operation + +Added a method named `getOriginatedContractAddresses` on the `BatchWalletOperation` and the `BatchOperation`, which returns an array of contract addresses deployed in the batch. If there is no origination operation, the array will be empty. + +## `@taquito/michelson-encoder` - Accept hex prefixed with 0x as well + +Taquito only accepted hex bytes without the 0x prefix. We added support for this format too. + +## `@taquito/taquito` - Use the new `run_script_view` endpoint to execute on chain views + +The execution of the on-chain views previously relied on the `helpers/scripts/run_code` RPC endpoint. Since there is a new dedicated RPC endpoint, we refactored the implementation to use it. This change makes the code simpler and reduces the number of calls to the RPC by two, as we don't need to retrieve the balance and storage of the contract to execute the view anymore. The refactor is internal and doesn't imply breaking changes to the APIs. + +## Added documentation feedback to the Taquito website + +We added a feedback component at the bottom of each documentation page. We encourage you to provide feedback. It will help us evaluate which pages are the most helpful and which could benefit from improvement. + +## `@taquito-beacon-wallet` - Updated `@airgap/beacon-dapp` to version 3.1.4 + +We are now using the beacon-dapp's `getDAppClientInstance` method instead of the `new DAppClient`. This new method ensures that only one instance is created. The same cached instance is returned if called multiple times. + +## `@taquito/local-forging` - Pure JS implementation + +To accommodate users working in native mobile development, we added a separate pure JS bundle that can be imported. +The bundle wraps functions in the `@taquito/local-forging` package into a single variable called `taquito_local_forging`. +To use the JS bundle for your project, download the zip file under `Assets` on the [release page](https://github.com/ecadlabs/taquito/releases). + + +After that, copy the `.js` file and the `.map.js` file into your project. + +Example of how to use the `LocalForger` class in a simple HTML script tag: +``` + + +``` + + +# Taquito v13.0.0 + +**BREAKING CHANGES** +The `NaiveEstimateProvider` class that was deprecated in v11 has been removed. + +## Summary +### Jakarta support +- `@taquito/rpc` - Allow retrieving the state and inbox of a rollup #1617 +- `@taquito/rpc` - Added appropriate types related to TORU #1614, #1676 +- `@taquito/local-forging` - Added support for the operations `transfer_ticket`, `tx_rollup_origination` and `tx_rollup_submit_batch` #1615 +- `@taquito/michelson-encoder` - Added support for the new type`tx_rollup_l2_address` #1613 +- `@taquito/michel-codec` - Added support for the new type`tx_rollup_l2_address` and the new instruction `MIN_BLOCK_TIME` #1612 +- `@taquito/michel-codec` - Annotating the top-level parameter constructor to designate the root entry point is now forbidden #1611 +- `@taquito/taquito` - Added support for the `tx_rollup_origination` and `tx_rollup_submit_batch` operations #1616 + +### Documentation +- Remove outdated RPC nodes: https://tezostaquito.io/docs/next/rpc_nodes/ +- Fixed broken links #1629 + +### Others +- Add to The Taquito Integration Tests the Contract Security tests from InferenceAG / TezosSecurityBaselineChecking #1631, #1632, #1654 +- `@taquito/beacon-wallet` - The beacon-dapp is updated to version 3.1.1: https://github.com/airgap-it/beacon-sdk/releases/tag/v3.1.1 + + + +## `@taquito/rpc` - Allow retrieving the state and inbox of a rollup + +A new method named `getTxRollupState`, which allows accessing a rollup's state, has been added to the `RpcClient` class. It takes a `txRollupId` (a `string`) as a parameter. + +A new method named `getTxRollupInbox`, which allows accessing the inbox of a transaction rollup, has been added to the RpcClient class. It takes a `txRollupId` as a parameter and a `blockLevel`. + +## `@taquito/rpc` - Added appropriate types related to TORU + +TORU brings several new operation kinds that can be found in a block response. New interfaces representing the new operations have been added to the `OperationContents` and `OperationContentsAndResult` types of the RPC package. The new operation kinds are: `Tx_rollup_origination`, `Tx_rollup_submit_batch`, `Tx_rollup_commit`, `Tx_rollup_return_bond`, `Tx_rollup_finalize_commitment`, `Tx_rollup_remove_commitment`, `Tx_rollup_rejection`, `Tx_rollup_dispatch_tickets` and `Transfer_ticket`. + +The `liquidity_baking_escape_vote` property in `BlockFullHeader` is replaced with `liquidity_baking_toggle_vote` the value of which can be `on`, `off` or `pass`. + +**Breaking change**: The `balance_updates` property of the different `OperationContentsAndResultMetadata` is now optional. + +The `OperationBalanceUpdatesItem` can now contain a `bond_id` property of type `BondId`. `BondId` has a `tx_rollup` property. + +The `OperationResultTxRollupOrigination` can now contain a `ticket_hash` property. + +The `METADATA_BALANCE_UPDATES_CATEGORY` enum contains an additional `BONDS` category. + +Several properties were added in the ConstantsResponse for proto013. + +The `liquidity_baking_escape_ema` property in `BlockMetadata` is replaced by `liquidity_baking_toggle_ema` and `BlockMetadata` also contains a new `consumed_milligas` property. + +The `RPCRunOperationParam` parameter has new optional properties: `self`, `unparsing_mode`, `now` and `level`. + +## `@taquito/local-forging` -Added support for the operations `transfer_ticket`, `tx_rollup_origination` and `tx_rollup_submit_batch` + +Added support to forge and unforge the new operation kinds `transfer_ticket`, `tx_rollup_origination` and `tx_rollup_submit_batch` related to TORU. We plan to add support for the remaining operations in a subsequent release. + +## `@taquito/michelson-encoder` - Added support for the the new type`tx_rollup_l2_address` + +We created a new class `TxRollupL2AddressToken` in the michelson-encoder to support the new Michelson type `tx_rollup_l2_address`. This type is used to identify accounts on transaction rollups' ledgers. Those accounts are prefixed with `tz4`. +The `TxRollupL2AddressToken` class allows users of Taquito to pass `tz4` addresses in storage or smart contract entry points using the Taquito JS abstraction. + +## `@taquito/michel-codec` - Added support for the new type`tx_rollup_l2_address` and the new instruction `MIN_BLOCK_TIME` + +@taquitp/michel-codec is responsible, among others, for validating Michelson code to ensure its correctness. The package now supports the new `MIN_BLOCK_TIME` instruction and the `tx_rollup_l2_address` type. + +> A new instruction MIN_BLOCK_TIME has been added. It can be used to push the current minimal time between blocks onto the stack. The value is obtained from the protocol's minimal_block_delay constant. + +*Reference: https://tezos.gitlab.io/protocols/013jakarta.html#michelson* + +## `@taquito/michel-codec` - Annotating the top-level parameter constructor to designate the root entry point is now forbidden + +If the top-level parameter constructor is annotated when parsing a contract, a `MichelsonValidationError` exception will be thrown. + +> Annotating the parameter toplevel constructor to designate the root entrypoint is now forbidden. Put the annotation on the parameter type instead. E.g. replace parameter %a int; by parameter (int %a); + +*Reference: https://tezos.gitlab.io/protocols/013jakarta.html#michelson* + +## `@taquito/taquito` - Added support for the `tx_rollup_origination` and `tx_rollup_submit_batch` operations + +We added support on the contract, batch, and estimate API allowing users to deploy a tx rollup using Taquito and send a batch to a tx rollup. + +We plan to add support for the remaining operations related to TORU in subsequent releases. + +**Example of originating a rollup with Taquito:** +```typescript= +const op = await Tezos.contract.originateTxRollup(); +await op.confirmation(); + +const rollup = op.originatedRollup; +``` +The `originateTxRollup` method takes optional `storageLimit`, `gasLimit` and `fee` as parameters. + +**Example of sending a batch to a rollup with Taquito:** +```typescript= +const op = await Tezos.contract.txRollupSubmitBatch({ + content: '626c6f62', + rollup: 'txr1YTdi9BktRmybwhgkhRK7WPrutEWVGJT7w' +}); +await op.confirmation(); +``` +The `txRollupSubmitBatch` method also takes optional `storageLimit`, `gasLimit` and `fee` as parameters. + +## Known Issues +- Version stamp is out of date, resulting in `getVersionInfo()` to return the older version (12.1.0) instead of the current release candidate. This will be fixed in the full release. + +# Taquito v12.1.0-beta + +## Summary +### Jakarta initial support +- Compatibility with the Jakarta protocol + +### Improvements +- `@taquito/taquito` - Avoid doing POST call to fetch contract script with the RPC #1532 +- Review and improve Error classes in Taquito #1472 +- `@taquito/http-utils` - Make HttpBackend.defaultTimeout configurable #751 +- `@taquito/local-forging` - Reject Invalid Inputs When Forging #483 + +### Documentation +- How to capture failwith errors: https://tezostaquito.io/docs/next/failwith_errors + + + +## Compatibility with the Jakarta protocol +We addressed the Jakarta protocol's breaking changes, making this version of Taquito compatible with the Jakarta protocol. This early integration has been possible by using the Mondaynet testnet. + +The Jakarta protocol addresses the [malleability issue](https://tezos.gitlab.io/alpha/sapling.html#preventing-malleability) discovered in Sapling. It introduces changes around the sapling related types and instructions that are now supported in Taquito: +- The encoding of `sapling_transaction` has changed; we added support for it in the `@taquito/local-forging` package and support for `sapling_transaction_deprecated`. + +- The optional type returned by the `SAPLING_VERIFY_UPDATE` instruction contains an additional property named `bound_data`. We added support for it in the `@taquito/michel-codec` package. + +This release introduces some breaking changes in the `@taquito/rpc` package: +- The type of the proposal response items returned by the `getProposals` methods has changed from `[string, number]` to `[string, BigNumber]`. +- The type of the properties in the response of the `getBallots` methods have changed from `number` to `BigNumber`. +- In the response of `getVotesListings`, the field `rolls` is now optional as it has been replaced by `voting_power`, which type is a `BigNumber`. +- In the response of `getDelegates`, the type of the `voting_power` property has changed from `number` to `BigNumber`. + +Note that support for new features brought by the Jakarta protocol is not part of the current release. + +## `@taquito/taquito` - Avoid doing POST call to fetch contract script with the RPC + +In the latest versions, the RPC `context/contracts/{contractAddress}/script/normalized` endpoint was used to fetch the script when building the contract abstraction. This endpoint which is a POST call has been replaced with `context/contracts/{contractAddress}`, which is a GET call instead. The reason for changing the endpoints is that it is more convenient to avoid POST calls when reading from the chain, as this prevents caching using standard HTTP caches. Also, both endpoints return expanded global constants for all protocols so far. + +## Review and improve Error classes in Taquito + +Many error classes in Taquito returned a regular `Error` class. We adjusted them to use custom errors to provide a better error handling experience for our users. The errors are now available on the typedoc documentation in an `Error Classes` section for the different packages. + +Note that this improvement results in a potential breaking change for users who were catching the regular Error. + +## `@taquito/http-utils` - Make HttpBackend.defaultTimeout configurable + +The timeout has been added to the construction of the HttpBackend class with a default value of 30000 milliseconds. + +A different timeout value can be configured when creating an instance of RpcClient as follows: + +```javascript= +new RpcClient('url', 'chain', new HttpBackend(50000)); +``` # Taquito v12.1.0-beta diff --git a/website/versioned_docs/version-13.0.0/wallet_API.md b/website/versioned_docs/version-15.1.0/wallet_API.md similarity index 86% rename from website/versioned_docs/version-13.0.0/wallet_API.md rename to website/versioned_docs/version-15.1.0/wallet_API.md index 097516555e..cdd8d45e88 100644 --- a/website/versioned_docs/version-13.0.0/wallet_API.md +++ b/website/versioned_docs/version-15.1.0/wallet_API.md @@ -25,19 +25,16 @@ yarn add @taquito/taquito Make sure you have the latest version (`7.1.0` when this article was written, but the API became available from `6.3.2-beta.0`). -Once the package is downloaded, you can install the wallet of your choice. The wallet API supports different kinds of wallets. _Beacon_, _Temple_ and _TezBridge_ (deprecated v13) wallets are available to use at the moment. You can install one or multiple wallets according to your needs: +Once the package is downloaded, you can install the wallet of your choice. The wallet API supports different kinds of wallets. The _Beacon_ and _Temple_ wallets are available to use at the moment. You can install one or both wallets, depending on your requirements: ``` - -npm install @taquito/tezbridge-wallet - npm install @taquito/beacon-wallet npm install @temple-wallet/dapp ``` -Remember that some wallets may require an extra step in addition to the package installation. For example, TezBridge (deprecated v13) requires a plugin file, Temple must be used with an extension installed in the browser. We will explain the requirements for the different wallets in detail in the sections below. +Remember that some wallets may require an extra step in addition to the package installation. For example, Temple must be used with an extension installed in the browser. We will explain the requirements for the different wallets in detail in the sections below. ## Connecting the wallet @@ -69,7 +66,7 @@ Then, you can start initializing the wallet: const options = { name: 'MyAwesomeDapp', iconUrl: 'https://tezostaquito.io/img/favicon.svg', - preferredNetwork: 'ithacanet', + preferredNetwork: 'ghostnet', eventHandlers: { PERMISSION_REQUEST_SUCCESS: { handler: async (data) => { @@ -81,21 +78,21 @@ const options = { const wallet = new BeaconWallet(options); ``` -The necessary bare minimum to instantiate the wallet is an object with a `name` property that contains the name of your dapp. However, the Beacon wallet allows you to customize your dapp responses to different events. In the example above, instead of getting the default Beacon pop-up after the user connects the wallet, it will display the available data in the console. You can use whatever solution you prefer for feedback. You can find a list of all the default handlers [in the beacon-sdk Github repo](https://github.com/airgap-it/beacon-sdk/blob/master/src/events.ts). +The necessary bare minimum to instantiate the wallet is an object with a `name` property that contains the name of your dapp. However, the Beacon wallet allows you to customize your dapp responses to different events. In the example above, instead of getting the default Beacon pop-up after the user connects the wallet, it will display the available data in the console. You can use whatever solution you prefer for feedback. You can find a list of all the default handlers [in the beacon-sdk Github repo](https://github.com/airgap-it/beacon-sdk/blob/master/packages/beacon-dapp/src/events.ts). -> Note: if you want to use the Kukai wallet for testing on ithacanet, you must use the optional property `preferredNetwork` and set it to `ithacanet`, otherwise the mainnet version of the Kukai wallet will open. +> Note: if you want to use the Kukai wallet for testing on ghostnet, you must use the optional property `preferredNetwork` and set it to `ghostnet`, otherwise the mainnet version of the Kukai wallet will open. The Beacon wallet requires an extra step to set up the network to connect to and the permissions: ```js await wallet.requestPermissions({ network: { - type: 'mainnet' | 'hangzhounet' | 'ithacanet' | 'custom', + type: 'mainnet' | 'ghostnet' | 'jakartanet' | 'custom', }, }); ``` -You can choose among `mainnet`, `ithacanet` `hangzhounet` and `custom` to set up the network. Once the permissions have been configured, you can get the user's address by calling the `getPKH` method on the wallet: +You can choose among `mainnet`, `jakartanet` `ghostnet` and `custom` to set up the network. Once the permissions have been configured, you can get the user's address by calling the `getPKH` method on the wallet: ```js const userAddress = await wallet.getPKH(); @@ -123,7 +120,7 @@ Make sure you have the Beacon browser extension installed (the extension offers // const wallet = new BeaconWallet(options); wallet - .requestPermissions({ network: { type: 'ithacanet' } }) + .requestPermissions({ network: { type: 'ghostnet' } }) .then((_) => wallet.getPKH()) .then((address) => println(`Your address: ${address}`)); @@ -132,7 +129,7 @@ Tezos.setWalletProvider(wallet); ### - Development wallets -During the development of your dapp, you may prefer a less "user-friendly" option that gives you more information and details than a more user-friendly wallet. You may also want to install and set up a wallet quickly that requires less boilerplate than the Beacon SDK. In these cases, you can choose between the Tezbridge wallet(deprecated v13) (for more details in a lightweight format) and the Temple Wallet (for a quick setup using the Temple wallet extension). +During the development of your dapp, you may prefer a less "user-friendly" option that gives you more information and details than a more user-friendly wallet. You may also want to install and set up a wallet quickly that requires less boilerplate than the Beacon SDK. In these cases, use the Temple Wallet (for a quick setup using the Temple wallet extension). - Temple wallet @@ -142,13 +139,13 @@ Just like the other wallets, you have to import the Temple wallet class first: import { TempleWallet } from '@temple-wallet/dapp'; ``` -Then, Temple requires an extra step to verify that the extension is installed and connected in the browser. Temple used to be called Thanos and some Taquito code still uses the name Thanos. The `Thanoswallet` class exposes a static property called `isAvailable` that just does that. You must use it before attempting to connect the wallet: +Then, Temple requires an extra step to verify that the extension is installed and connected in the browser. Temple used to be called Thanos and some Taquito code still uses the name Thanos. The `TempleWallet` class exposes a static property called `isAvailable` that just does that. You must use it before attempting to connect the wallet: ```js try { - const available = await ThanosWallet.isAvailable(); + const available = await TempleWallet.isAvailable(); if (!available) { - throw new Error('Thanos Wallet not installed'); + throw new Error('Temple Wallet not installed'); } } catch (err) { console.log(err); @@ -157,26 +154,26 @@ try { For this to work, you have to enable dapps in the Temple wallet. Under `Settings`, you will find a `DApps` section where the checkbox must be checked to allow interactions between the wallet and the dapps. -Now that we are sure the extension is installed and running, we can continue connecting the wallet. We start by creating a new instance of the `ThanosWallet` class: +Now that we are sure the extension is installed and running, we can continue connecting the wallet. We start by creating a new instance of the `TempleWallet` class: ```js -const wallet = new ThanosWallet('MyAwesomeDapp'); +const wallet = new TempleWallet('MyAwesomeDapp'); ``` The class constructor takes one parameter, the name of your dapp (this will be used later in the transaction confirmation pop-up). After the instantiation, we can connect the wallet by calling the `connect` method: ```js -await wallet.connect('mainnet' | 'ithacanet' | 'hangzhounet' | 'labnet' | 'sandbox'); +await wallet.connect('mainnet' | 'limanet' | 'ghostnet' | 'mondaynet' | 'sandbox'); ``` (Temple used to be called Thanos and some Taquito code still uses the name Thanos.) Once the wallet is connected, there are a couple of things you can get out of it: ```js -const wallet = new ThanosWallet('MyAwesomeDapp'); -// the ThanosWallet can return an instance of the Tezos singleton +const wallet = new TempleWallet('MyAwesomeDapp'); +// the TempleWallet can return an instance of the Tezos singleton const Tezos = await wallet.toTezos(); -// the ThanosWallet can return the user's address +// the TempleWallet can return the user's address const userAddress = wallet.pkh || (await wallet.getPKH()); ``` @@ -194,15 +191,15 @@ Tezos.setProvider({ wallet }); #### Try the Temple wallet! -Make sure you have the Temple browser extension installed first. +*Make sure you have the Temple browser extension installed first.* ```js -//import { ThanosWallet } from '@thanos-wallet/dapp'; -ThanosWallet.isAvailable() +//import { TempleWallet } from '@temple-wallet/dapp'; +TempleWallet.isAvailable() .then(() => { - const mywallet = new ThanosWallet('MyAwesomeDapp'); + const mywallet = new TempleWallet('MyAwesomeDapp'); mywallet - .connect('ithacanet') + .connect('ghostnet') .then(() => { Tezos.setWalletProvider(mywallet); return mywallet.getPKH(); @@ -214,54 +211,9 @@ ThanosWallet.isAvailable() .catch((err) => console.log(err)); ``` -- TezBridge wallet (deprecated v13) - -> Note that the TezBridge wallet may not work correctly since the Delphi upgrade might be deprecated in the future. - -First, we have to import the TezBridge wallet from the package: - -```js -import { TezBridgeWallet } from '@taquito/tezbridge-wallet'; -``` - -Next, we can set up the wallet. In general, you will give your dapp users the choice of the wallet they prefer, so the wallet initialization wouldn't happen when the dapp is mounted but after user's interaction, for example, after pressing a button. It is important to remember that you have to import the TezBridge class in your HTML file before setting up your wallet, or this will throw an error: - -```js - -``` - -To set up TezBridge as your wallet, you use the `setWalletProvider` method of the `Tezos` singleton instance and pass a new instance of the `TezBridgeWallet` class: - -```js -Tezos.setWalletProvider(new TezBridgeWallet()); -``` - -or - -```js -Tezos.setProvider({ wallet: new TezBridgeWallet() }); -``` - -Please note that you don't need to interact directly with the `tezbridge` object that the plugin injects in the `window` object. Taquito will take care of it. You can even get the user's address using the TezBridgeWallet instance like so: - -```js -const wallet = new TezBridgeWallet(); -Tezos.setWalletProvider(wallet); -const userAddress = await wallet.getPKH(); -``` - -#### Try the TezBridge wallet! (deprecated v13) - -```js live noInline wallet -//import { TezBridgeWallet } from '@taquito/tezbridge-wallet'; -const wallet = new TezBridgeWallet(); -Tezos.setWalletProvider(wallet); -wallet.getPKH().then((userAddress) => println(`Your address: ${userAddress}`)); -``` - ## Making transfers -Although it is possible to transfer tokens directly from the wallets, Taquito offers to send tokens programmatically. This method could be a better solution if you want to do calculations before sending the tokens or if the amount of tokens to send is based on a variable value. This could also be preferable to avoid manual inputs that can often be a source of errors. Using Taquito to send tokens only requires to sign a transaction, sit back and relax :) +Although it is possible to transfer tokens directly from the wallets, Taquito can send tokens *programmatically*. This method could be a better solution if you want to do calculations before sending the tokens, or if the amount of tokens to send is based on a variable value. It is also preferable to avoid manual inputs, which are often a source of errors. Using Taquito to send tokens only requires to sign a transaction, sit back and relax :) ### - Transfer between implicit accounts @@ -291,7 +243,7 @@ The `transfer` method takes an object with only two required properties: the `to ```js live noInline wallet Tezos.wallet - .transfer({ to: 'KT1KgtEEbDuw1b7QEFKh3VW6wzvQGYjawDwa', amount: 0.2 }) + .transfer({ to: 'KT1TBxaaeikEUcVN2qdQY7n9Q21ykcX1NLzY', amount: 0.2 }) .send() .then((op) => { println(`Waiting for ${op.opHash} to be confirmed...`); @@ -310,7 +262,7 @@ Sending a transaction to a smart contract to update its storage will be a differ Fortunately, Taquito will make this operation go like a breeze! First, you need the contract abstraction created with the address of the smart contract you are targeting: ```js -const contract = await Tezos.wallet.at('KT1KgtEEbDuw1b7QEFKh3VW6wzvQGYjawDwa'); +const contract = await Tezos.wallet.at('KT1TBxaaeikEUcVN2qdQY7n9Q21ykcX1NLzY'); ``` This line creates a contract abstraction with multiple methods named after the contract entrypoints. For example, if you have a `transfer` entrypoint in your contract, you will also have a `.transfer()` method in the `contract` object. Each method accepts parameters required by the contract entrypoint. @@ -325,7 +277,7 @@ Most of the time, the process is simple: you take the contract abstraction you c ```js live noInline wallet Tezos.wallet - .at('KT1HiLoD3TnPcWwcK51Bbpy4eAVbTuhdB6hf') + .at('KT1SHiNUNmqBFGNysX9pmh1DC2tQ5pGmRagC') .then((contract) => contract.methods.areYouThere(true).send()) .then((op) => { println(`Hash: ${op.opHash}`); @@ -348,7 +300,7 @@ In the case of multiple arguments (for example if the entrypoint expects a pair) ```js live noInline wallet Tezos.wallet - .at('KT1HiLoD3TnPcWwcK51Bbpy4eAVbTuhdB6hf') + .at('KT1SHiNUNmqBFGNysX9pmh1DC2tQ5pGmRagC') .then((contract) => contract.methods.addName('tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb', 'Alice').send() ) @@ -673,7 +625,7 @@ The Tezos singleton object exposes a _wallet_ property in the same fashion it ex We have already seen the `at` method of the Wallet instance earlier in order to create the contract abstraction: ```js -const contract = await Tezos.wallet.at('KT1XW9MAxDqF4LwVps86meQ5ihEXyAepmZDm'); +const contract = await Tezos.wallet.at('KT1HNgQQEUb7mDmnmLKy4xcq1xdPw3ieoKzv'); ``` The method is a promise that expects the contract's address for which you want to create the abstraction. diff --git a/website/versioned_docs/version-13.0.0/wallets.md b/website/versioned_docs/version-15.1.0/wallets.md similarity index 95% rename from website/versioned_docs/version-13.0.0/wallets.md rename to website/versioned_docs/version-15.1.0/wallets.md index 4102d20bd1..93c27dceb4 100644 --- a/website/versioned_docs/version-13.0.0/wallets.md +++ b/website/versioned_docs/version-15.1.0/wallets.md @@ -16,7 +16,6 @@ Here's a list of the Tezos wallets we know of. Wallets that support the TZIP-10: | **Beacon Spire** | Browser Extension | Yes | https://www.walletbeacon.io/ | [![Github](images/github.png)](https://github.com/airgap-it/spire/) | | **Airgap mobile** | Mobile App | Yes | https://airgap.it | [![Github](images/github.png)](https://github.com/airgap-it/airgap-wallet/) | | **Ejara** | Mobile App | No | https://www.ejara.io | | -| **Tezbridge**(deprecated v13) | Web | No | https://www.tezbridge.com | [![Github](images/github.png)](https://github.com/tezbridge/) | | **Ledger NanoS** | Hardware Wallet | N/A | https://www.ledger.com | [![Github](images/github.png)](https://github.com/LedgerHQ/) | | **Ledger NanoX** | Hardware Wallet | N/A | https://www.ledger.com | [![Github](images/github.png)](https://github.com/LedgerHQ/) | | **Naan** | Mobile | No | https://www.naanwallet.com | | diff --git a/website/versioned_docs/version-13.0.0/web3js_taquito.md b/website/versioned_docs/version-15.1.0/web3js_taquito.md similarity index 100% rename from website/versioned_docs/version-13.0.0/web3js_taquito.md rename to website/versioned_docs/version-15.1.0/web3js_taquito.md diff --git a/website/versioned_sidebars/version-13.0.0-sidebars.json b/website/versioned_sidebars/version-15.1.0-sidebars.json similarity index 69% rename from website/versioned_sidebars/version-13.0.0-sidebars.json rename to website/versioned_sidebars/version-15.1.0-sidebars.json index d083f2dd15..9839d8360f 100644 --- a/website/versioned_sidebars/version-13.0.0-sidebars.json +++ b/website/versioned_sidebars/version-15.1.0-sidebars.json @@ -8,29 +8,37 @@ "collapsible": false, "items": [ "quick_start", - "boilerplate", + "react-template", + "amendment_and_voting", "batch_API", + "ballot", "beaconwallet-singleton", "confirmation_event_stream", + "consensus_key", "set_delegate", "dapp_prelaunch", "estimate", + "subscribe_event", "fa2_parameters", + "global_constant", + "increase_paid_storage", "lambda_view", "liquidity_baking", "maps_bigmaps", "michelsonmap", + "multisig_doc", + "on_chain_views", "originate", - "global_constant", + "prepare", "rpc_nodes", "rpc_package", "signing", "smartcontracts", + "contracts_collection", "tezos_domains", "tickets", "transaction_limits", "making_transfers", - "on_chain_views", "tutorial_links", "tzip12", "metadata-tzip16", @@ -38,7 +46,8 @@ "wallet_API", "wallets", "web3js_taquito", - "contracts_collection" + "contracts_collection", + "subscribe_event" ] }, { @@ -49,7 +58,6 @@ "collapsible": false, "items": [ "inmemory_signer", - "tezbridge_signer", "ledger_signer" ] }, @@ -62,7 +70,28 @@ "items": [ "michelson_encoder", "contracts-library", - "taquito_utils" + "taquito_utils", + { + "type": "category", + "label": "Sapling", + "collapsed": true, + "collapsible": true, + "items": [ + "sapling", + "sapling_in_memory_spending_key", + "sapling_in_memory_viewing_key" + ] + } + ] + }, + { + "type": "category", + "label": "Optimistic Rollups", + "className": "sidebarHeader", + "collapsed": false, + "collapsible": false, + "items": [ + "tx_rollups" ] }, { @@ -100,6 +129,16 @@ "rpc_nodes_integration_test" ] }, + { + "type": "category", + "label": "Native Mobile Development", + "className": "sidebarHeader", + "collapsed": false, + "collapsible": false, + "items": [ + "mobile_bundle" + ] + }, { "Upgrading Guide": [ "upgrading_guide" diff --git a/website/versions.json b/website/versions.json index 21d9b5a585..00b81c9b6a 100644 --- a/website/versions.json +++ b/website/versions.json @@ -1,7 +1,7 @@ [ + "15.1.0", "15.0.0", "14.2.0", "14.1.0", - "14.0.0", - "13.0.0" + "14.0.0" ]